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