Skip to main content

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