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