sea_query/table/
column.rs

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