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}