sea_query/table/
column.rs

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