sea_query/table/
column.rs

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