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(A, B)                   |
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("character")
312    ///     .col(ColumnDef::new("font_id").integer().default(12i32))
313    ///     .col(
314    ///         ColumnDef::new("font_id_2")
315    ///             .integer()
316    ///             .default(Expr::val(12).add(2)),
317    ///     )
318    ///     .col(
319    ///         ColumnDef::new("created_at")
320    ///             .timestamp()
321    ///             .default(Expr::current_timestamp())
322    ///             .not_null(),
323    ///     )
324    ///     .to_owned();
325    ///
326    /// assert_eq!(
327    ///     table.to_string(MysqlQueryBuilder),
328    ///     [
329    ///         "CREATE TABLE `character` (",
330    ///         "`font_id` int DEFAULT 12,",
331    ///         "`font_id_2` int DEFAULT (12 + 2),",
332    ///         "`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP",
333    ///         ")",
334    ///     ]
335    ///     .join(" ")
336    /// );
337    ///
338    /// assert_eq!(
339    ///     table.to_string(PostgresQueryBuilder),
340    ///     [
341    ///         r#"CREATE TABLE "character" ("#,
342    ///         r#""font_id" integer DEFAULT 12,"#,
343    ///         r#""font_id_2" integer DEFAULT (12 + 2),"#,
344    ///         r#""created_at" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP"#,
345    ///         r#")"#,
346    ///     ]
347    ///     .join(" ")
348    /// );
349    /// ```
350    pub fn default<T>(&mut self, value: T) -> &mut Self
351    where
352        T: Into<Expr>,
353    {
354        self.spec.default = Some(value.into());
355        self
356    }
357
358    /// Set column auto increment
359    pub fn auto_increment(&mut self) -> &mut Self {
360        self.spec.auto_increment = true;
361        self
362    }
363
364    /// Set column unique constraint
365    pub fn unique_key(&mut self) -> &mut Self {
366        self.spec.unique = true;
367        self
368    }
369
370    /// Set column as primary key
371    pub fn primary_key(&mut self) -> &mut Self {
372        self.spec.primary_key = true;
373        self
374    }
375
376    /// Set column type as char with custom length
377    pub fn char_len(&mut self, length: u32) -> &mut Self {
378        self.types = Some(ColumnType::Char(Some(length)));
379        self
380    }
381
382    /// Set column type as char
383    pub fn char(&mut self) -> &mut Self {
384        self.types = Some(ColumnType::Char(None));
385        self
386    }
387
388    /// Set column type as string with custom length
389    pub fn string_len(&mut self, length: u32) -> &mut Self {
390        self.types = Some(ColumnType::String(StringLen::N(length)));
391        self
392    }
393
394    /// Set column type as string
395    pub fn string(&mut self) -> &mut Self {
396        self.types = Some(ColumnType::String(Default::default()));
397        self
398    }
399
400    /// Set column type as text
401    pub fn text(&mut self) -> &mut Self {
402        self.types = Some(ColumnType::Text);
403        self
404    }
405
406    /// Set column type as tiny_integer
407    pub fn tiny_integer(&mut self) -> &mut Self {
408        self.types = Some(ColumnType::TinyInteger);
409        self
410    }
411
412    /// Set column type as small_integer
413    pub fn small_integer(&mut self) -> &mut Self {
414        self.types = Some(ColumnType::SmallInteger);
415        self
416    }
417
418    /// Set column type as integer
419    pub fn integer(&mut self) -> &mut Self {
420        self.types = Some(ColumnType::Integer);
421        self
422    }
423
424    /// Set column type as big_integer
425    pub fn big_integer(&mut self) -> &mut Self {
426        self.types = Some(ColumnType::BigInteger);
427        self
428    }
429
430    /// Set column type as tiny_unsigned
431    pub fn tiny_unsigned(&mut self) -> &mut Self {
432        self.types = Some(ColumnType::TinyUnsigned);
433        self
434    }
435
436    /// Set column type as small_unsigned
437    pub fn small_unsigned(&mut self) -> &mut Self {
438        self.types = Some(ColumnType::SmallUnsigned);
439        self
440    }
441
442    /// Set column type as unsigned
443    pub fn unsigned(&mut self) -> &mut Self {
444        self.types = Some(ColumnType::Unsigned);
445        self
446    }
447
448    /// Set column type as big_unsigned
449    pub fn big_unsigned(&mut self) -> &mut Self {
450        self.types = Some(ColumnType::BigUnsigned);
451        self
452    }
453
454    /// Set column type as float
455    pub fn float(&mut self) -> &mut Self {
456        self.types = Some(ColumnType::Float);
457        self
458    }
459
460    /// Set column type as double
461    pub fn double(&mut self) -> &mut Self {
462        self.types = Some(ColumnType::Double);
463        self
464    }
465
466    /// Set column type as decimal with custom precision and scale
467    pub fn decimal_len(&mut self, precision: u32, scale: u32) -> &mut Self {
468        self.types = Some(ColumnType::Decimal(Some((precision, scale))));
469        self
470    }
471
472    /// Set column type as decimal
473    pub fn decimal(&mut self) -> &mut Self {
474        self.types = Some(ColumnType::Decimal(None));
475        self
476    }
477
478    /// Set column type as date_time
479    pub fn date_time(&mut self) -> &mut Self {
480        self.types = Some(ColumnType::DateTime);
481        self
482    }
483
484    /// Set column type as interval type with optional fields and precision. Postgres only
485    ///
486    /// ```
487    /// use sea_query::{tests_cfg::*, *};
488    /// assert_eq!(
489    ///     Table::create()
490    ///         .table(Glyph::Table)
491    ///         .col(ColumnDef::new("I1").interval(None, None).not_null())
492    ///         .col(
493    ///             ColumnDef::new("I2")
494    ///                 .interval(Some(PgInterval::YearToMonth), None)
495    ///                 .not_null()
496    ///         )
497    ///         .col(ColumnDef::new("I3").interval(None, Some(42)).not_null())
498    ///         .col(
499    ///             ColumnDef::new("I4")
500    ///                 .interval(Some(PgInterval::Hour), Some(43))
501    ///                 .not_null()
502    ///         )
503    ///         .to_string(PostgresQueryBuilder),
504    ///     [
505    ///         r#"CREATE TABLE "glyph" ("#,
506    ///         r#""I1" interval NOT NULL,"#,
507    ///         r#""I2" interval YEAR TO MONTH NOT NULL,"#,
508    ///         r#""I3" interval(42) NOT NULL,"#,
509    ///         r#""I4" interval HOUR(43) NOT NULL"#,
510    ///         r#")"#,
511    ///     ]
512    ///     .join(" ")
513    /// );
514    /// ```
515    #[cfg(feature = "backend-postgres")]
516    pub fn interval(&mut self, fields: Option<PgInterval>, precision: Option<u32>) -> &mut Self {
517        self.types = Some(ColumnType::Interval(fields, precision));
518        self
519    }
520
521    #[cfg(feature = "postgres-vector")]
522    pub fn vector(&mut self, size: Option<u32>) -> &mut Self {
523        self.types = Some(ColumnType::Vector(size));
524        self
525    }
526
527    /// Set column type as timestamp
528    pub fn timestamp(&mut self) -> &mut Self {
529        self.types = Some(ColumnType::Timestamp);
530        self
531    }
532
533    /// Set column type as timestamp with time zone. Postgres only
534    pub fn timestamp_with_time_zone(&mut self) -> &mut Self {
535        self.types = Some(ColumnType::TimestampWithTimeZone);
536        self
537    }
538
539    /// Set column type as time
540    pub fn time(&mut self) -> &mut Self {
541        self.types = Some(ColumnType::Time);
542        self
543    }
544
545    /// Set column type as date
546    pub fn date(&mut self) -> &mut Self {
547        self.types = Some(ColumnType::Date);
548        self
549    }
550
551    /// Set column type as year
552    /// Only MySQL supports year
553    pub fn year(&mut self) -> &mut Self {
554        self.types = Some(ColumnType::Year);
555        self
556    }
557
558    /// Set column type as binary with custom length
559    pub fn binary_len(&mut self, length: u32) -> &mut Self {
560        self.types = Some(ColumnType::Binary(length));
561        self
562    }
563
564    /// Set column type as binary with default length of 1
565    pub fn binary(&mut self) -> &mut Self {
566        self.binary_len(1)
567    }
568
569    /// Set column type as binary with variable length
570    pub fn var_binary(&mut self, length: u32) -> &mut Self {
571        self.types = Some(ColumnType::VarBinary(StringLen::N(length)));
572        self
573    }
574
575    /// Set column type as bit with variable length
576    pub fn bit(&mut self, length: Option<u32>) -> &mut Self {
577        self.types = Some(ColumnType::Bit(length));
578        self
579    }
580
581    /// Set column type as varbit with variable length
582    pub fn varbit(&mut self, length: u32) -> &mut Self {
583        self.types = Some(ColumnType::VarBit(length));
584        self
585    }
586
587    /// Set column type as blob
588    pub fn blob(&mut self) -> &mut Self {
589        self.types = Some(ColumnType::Blob);
590        self
591    }
592
593    /// Set column type as boolean
594    pub fn boolean(&mut self) -> &mut Self {
595        self.types = Some(ColumnType::Boolean);
596        self
597    }
598
599    /// Set column type as money with custom precision and scale
600    pub fn money_len(&mut self, precision: u32, scale: u32) -> &mut Self {
601        self.types = Some(ColumnType::Money(Some((precision, scale))));
602        self
603    }
604
605    /// Set column type as money
606    pub fn money(&mut self) -> &mut Self {
607        self.types = Some(ColumnType::Money(None));
608        self
609    }
610
611    /// Set column type as json.
612    pub fn json(&mut self) -> &mut Self {
613        self.types = Some(ColumnType::Json);
614        self
615    }
616
617    /// Set column type as json binary.
618    pub fn json_binary(&mut self) -> &mut Self {
619        self.types = Some(ColumnType::JsonBinary);
620        self
621    }
622
623    /// Set column type as uuid
624    pub fn uuid(&mut self) -> &mut Self {
625        self.types = Some(ColumnType::Uuid);
626        self
627    }
628
629    /// Use a custom type on this column.
630    ///
631    /// # Example
632    ///
633    /// ```
634    /// use sea_query::{tests_cfg::*, *};
635    ///
636    /// let table = Table::create()
637    ///     .table(Char::Table)
638    ///     .col(
639    ///         ColumnDef::new(Char::Id)
640    ///             .custom("new_type")
641    ///             .not_null()
642    ///             .primary_key(),
643    ///     )
644    ///     .to_owned();
645    ///
646    /// assert_eq!(
647    ///     table.to_string(MysqlQueryBuilder),
648    ///     [
649    ///         r#"CREATE TABLE `character` ("#,
650    ///         r#"`id` new_type NOT NULL PRIMARY KEY"#,
651    ///         r#")"#,
652    ///     ]
653    ///     .join(" ")
654    /// );
655    /// assert_eq!(
656    ///     table.to_string(PostgresQueryBuilder),
657    ///     [
658    ///         r#"CREATE TABLE "character" ("#,
659    ///         r#""id" new_type NOT NULL PRIMARY KEY"#,
660    ///         r#")"#,
661    ///     ]
662    ///     .join(" ")
663    /// );
664    /// assert_eq!(
665    ///     table.to_string(SqliteQueryBuilder),
666    ///     [
667    ///         r#"CREATE TABLE "character" ("#,
668    ///         r#""id" new_type NOT NULL PRIMARY KEY"#,
669    ///         r#")"#,
670    ///     ]
671    ///     .join(" ")
672    /// );
673    /// ```
674    pub fn custom<T>(&mut self, name: T) -> &mut Self
675    where
676        T: IntoIden,
677    {
678        self.types = Some(ColumnType::Custom(name.into_iden()));
679        self
680    }
681
682    /// Set column type as enum.
683    pub fn enumeration<N, S, V>(&mut self, name: N, variants: V) -> &mut Self
684    where
685        N: IntoIden,
686        S: IntoIden,
687        V: IntoIterator<Item = S>,
688    {
689        self.types = Some(ColumnType::Enum {
690            name: name.into_iden(),
691            variants: variants.into_iter().map(IntoIden::into_iden).collect(),
692        });
693        self
694    }
695
696    /// Set column type as an array with a specified element type.
697    /// This is only supported on Postgres.
698    pub fn array(&mut self, elem_type: ColumnType) -> &mut Self {
699        self.types = Some(ColumnType::Array(RcOrArc::new(elem_type)));
700        self
701    }
702
703    /// Set columnt type as cidr.
704    /// This is only supported on Postgres.
705    pub fn cidr(&mut self) -> &mut Self {
706        self.types = Some(ColumnType::Cidr);
707        self
708    }
709
710    /// Set columnt type as inet.
711    /// This is only supported on Postgres.
712    pub fn inet(&mut self) -> &mut Self {
713        self.types = Some(ColumnType::Inet);
714        self
715    }
716
717    /// Set columnt type as macaddr.
718    /// This is only supported on Postgres.
719    pub fn mac_address(&mut self) -> &mut Self {
720        self.types = Some(ColumnType::MacAddr);
721        self
722    }
723
724    /// Set column type as `ltree`
725    /// This is only supported on Postgres.
726    ///
727    /// ```
728    /// use sea_query::{tests_cfg::*, *};
729    /// assert_eq!(
730    ///     Table::create()
731    ///         .table(Glyph::Table)
732    ///         .col(
733    ///             ColumnDef::new(Glyph::Id)
734    ///                 .integer()
735    ///                 .not_null()
736    ///                 .auto_increment()
737    ///                 .primary_key()
738    ///         )
739    ///         .col(ColumnDef::new(Glyph::Tokens).ltree())
740    ///         .to_string(PostgresQueryBuilder),
741    ///     [
742    ///         r#"CREATE TABLE "glyph" ("#,
743    ///         r#""id" integer GENERATED BY DEFAULT AS IDENTITY NOT NULL PRIMARY KEY,"#,
744    ///         r#""tokens" ltree"#,
745    ///         r#")"#,
746    ///     ]
747    ///     .join(" ")
748    /// );
749    /// ```
750    pub fn ltree(&mut self) -> &mut Self {
751        self.types = Some(ColumnType::LTree);
752        self
753    }
754
755    /// Set constraints as Expr
756    ///
757    /// ```
758    /// use sea_query::{tests_cfg::*, *};
759    ///
760    /// assert_eq!(
761    ///     Table::create()
762    ///         .table(Glyph::Table)
763    ///         .col(
764    ///             ColumnDef::new(Glyph::Id)
765    ///                 .integer()
766    ///                 .not_null()
767    ///                 .check(Expr::col(Glyph::Id).gt(10))
768    ///         )
769    ///         .to_string(MysqlQueryBuilder),
770    ///     r#"CREATE TABLE `glyph` ( `id` int NOT NULL CHECK (`id` > 10) )"#,
771    /// );
772    ///
773    /// assert_eq!(
774    ///     Table::create()
775    ///         .table(Glyph::Table)
776    ///         .col(
777    ///             ColumnDef::new(Glyph::Id)
778    ///                 .integer()
779    ///                 .not_null()
780    ///                 .check(("positive_id", Expr::col(Glyph::Id).gt(10)))
781    ///         )
782    ///         .to_string(MysqlQueryBuilder),
783    ///     r#"CREATE TABLE `glyph` ( `id` int NOT NULL CONSTRAINT `positive_id` CHECK (`id` > 10) )"#,
784    /// );
785    /// ```
786    pub fn check<T>(&mut self, check: T) -> &mut Self
787    where
788        T: Into<Check>,
789    {
790        self.spec.check = Some(check.into());
791        self
792    }
793
794    /// Sets the column as generated with Expr
795    pub fn generated<T>(&mut self, expr: T, stored: bool) -> &mut Self
796    where
797        T: Into<Expr>,
798    {
799        self.spec.generated = Some(Generated {
800            expr: expr.into(),
801            stored,
802        });
803        self
804    }
805
806    /// Some extra options in custom string
807    /// ```
808    /// use sea_query::{tests_cfg::*, *};
809    /// let table = Table::create()
810    ///     .table(Char::Table)
811    ///     .col(
812    ///         ColumnDef::new(Char::Id)
813    ///             .uuid()
814    ///             .extra("DEFAULT gen_random_uuid()")
815    ///             .primary_key()
816    ///             .not_null(),
817    ///     )
818    ///     .col(
819    ///         ColumnDef::new(Char::CreatedAt)
820    ///             .timestamp_with_time_zone()
821    ///             .extra("DEFAULT NOW()")
822    ///             .not_null(),
823    ///     )
824    ///     .to_owned();
825    /// assert_eq!(
826    ///     table.to_string(PostgresQueryBuilder),
827    ///     [
828    ///         r#"CREATE TABLE "character" ("#,
829    ///         r#""id" uuid NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(),"#,
830    ///         r#""created_at" timestamp with time zone NOT NULL DEFAULT NOW()"#,
831    ///         r#")"#,
832    ///     ]
833    ///     .join(" ")
834    /// );
835    /// ```
836    pub fn extra<T>(&mut self, string: T) -> &mut Self
837    where
838        T: Into<String>,
839    {
840        self.spec.extra = Some(string.into());
841        self
842    }
843
844    /// Some extra options in custom string
845    /// ```
846    /// use sea_query::{tests_cfg::*, *};
847    /// let table = Table::alter()
848    ///     .table(Char::Table)
849    ///     .modify_column(
850    ///         ColumnDef::new(Char::Id)
851    ///             .integer()
852    ///             .using(Expr::col(Char::Id).cast_as("integer")),
853    ///     )
854    ///     .to_owned();
855    /// assert_eq!(
856    ///     table.to_string(PostgresQueryBuilder),
857    ///     [
858    ///         r#"ALTER TABLE "character""#,
859    ///         r#"ALTER COLUMN "id" TYPE integer USING CAST("id" AS integer)"#,
860    ///     ]
861    ///     .join(" ")
862    /// );
863    /// ```
864    pub fn using<T>(&mut self, value: T) -> &mut Self
865    where
866        T: Into<Expr>,
867    {
868        self.spec.using = Some(value.into());
869        self
870    }
871
872    /// MySQL only.
873    pub fn comment<T>(&mut self, string: T) -> &mut Self
874    where
875        T: Into<String>,
876    {
877        self.spec.comment = Some(string.into());
878        self
879    }
880
881    pub fn get_column_name(&self) -> String {
882        self.name.to_string()
883    }
884
885    pub fn get_column_type(&self) -> Option<&ColumnType> {
886        self.types.as_ref()
887    }
888
889    pub fn get_column_spec(&self) -> &ColumnSpec {
890        &self.spec
891    }
892
893    pub fn take(&mut self) -> Self {
894        Self {
895            table: self.table.take(),
896            name: std::mem::replace(&mut self.name, NullAlias::new().into_iden()),
897            types: self.types.take(),
898            spec: std::mem::take(&mut self.spec),
899        }
900    }
901}