use crate::{expr::*, types::*};
#[derive(Debug, Clone)]
pub struct ColumnDef {
pub(crate) table: Option<TableRef>,
pub(crate) name: DynIden,
pub(crate) types: Option<ColumnType>,
pub(crate) spec: Vec<ColumnSpec>,
}
#[non_exhaustive]
#[derive(Debug, Clone)]
pub enum ColumnType {
Char(Option<u32>),
String(Option<u32>),
Text,
TinyInteger,
SmallInteger,
Integer,
BigInteger,
TinyUnsigned,
SmallUnsigned,
Unsigned,
BigUnsigned,
Float,
Double,
Decimal(Option<(u32, u32)>),
DateTime,
Timestamp,
TimestampWithTimeZone,
Time,
Date,
Year(Option<MySqlYear>),
Interval(Option<PgInterval>, Option<u32>),
Binary(BlobSize),
VarBinary(u32),
Bit(Option<u32>),
VarBit(u32),
Boolean,
Money(Option<(u32, u32)>),
Json,
JsonBinary,
Uuid,
Custom(DynIden),
Enum {
name: DynIden,
variants: Vec<DynIden>,
},
Array(SeaRc<ColumnType>),
Cidr,
Inet,
MacAddr,
}
impl PartialEq for ColumnType {
fn eq(&self, other: &Self) -> bool {
match (self, other) {
(Self::Char(l0), Self::Char(r0)) => l0 == r0,
(Self::String(l0), Self::String(r0)) => l0 == r0,
(Self::Decimal(l0), Self::Decimal(r0)) => l0 == r0,
(Self::Year(l0), Self::Year(r0)) => l0 == r0,
(Self::Interval(l0, l1), Self::Interval(r0, r1)) => l0 == r0 && l1 == r1,
(Self::Binary(l0), Self::Binary(r0)) => l0 == r0,
(Self::VarBinary(l0), Self::VarBinary(r0)) => l0 == r0,
(Self::Bit(l0), Self::Bit(r0)) => l0 == r0,
(Self::VarBit(l0), Self::VarBit(r0)) => l0 == r0,
(Self::Money(l0), Self::Money(r0)) => l0 == r0,
(Self::Custom(l0), Self::Custom(r0)) => l0.to_string() == r0.to_string(),
(
Self::Enum {
name: l_name,
variants: l_variants,
},
Self::Enum {
name: r_name,
variants: r_variants,
},
) => {
l_name.to_string() == r_name.to_string()
&& l_variants
.iter()
.map(|v| v.to_string())
.eq(r_variants.iter().map(|v| v.to_string()))
}
(Self::Array(l0), Self::Array(r0)) => l0 == r0,
_ => core::mem::discriminant(self) == core::mem::discriminant(other),
}
}
}
impl ColumnType {
pub fn custom(ty: &str) -> ColumnType {
ColumnType::Custom(Alias::new(ty).into_iden())
}
}
#[derive(Debug, Clone)]
pub enum ColumnSpec {
Null,
NotNull,
Default(SimpleExpr),
AutoIncrement,
UniqueKey,
PrimaryKey,
Extra(String),
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum PgInterval {
Year,
Month,
Day,
Hour,
Minute,
Second,
YearToMonth,
DayToHour,
DayToMinute,
DayToSecond,
HourToMinute,
HourToSecond,
MinuteToSecond,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum MySqlYear {
Two,
Four,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum BlobSize {
Tiny,
Blob(Option<u32>),
Medium,
Long,
}
#[cfg(feature = "postgres-interval")]
impl quote::ToTokens for PgInterval {
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
use quote::{quote, TokenStreamExt};
tokens.append_all(match self {
PgInterval::Year => quote! { PgInterval::Year },
PgInterval::Month => quote! { PgInterval::Month },
PgInterval::Day => quote! { PgInterval::Day },
PgInterval::Hour => quote! { PgInterval::Hour },
PgInterval::Minute => quote! { PgInterval::Minute },
PgInterval::Second => quote! { PgInterval::Second },
PgInterval::YearToMonth => quote! { PgInterval::YearToMonth },
PgInterval::DayToHour => quote! { PgInterval::DayToHour },
PgInterval::DayToMinute => quote! { PgInterval::DayToMinute },
PgInterval::DayToSecond => quote! { PgInterval::DayToSecond },
PgInterval::HourToMinute => quote! { PgInterval::HourToMinute },
PgInterval::HourToSecond => quote! { PgInterval::HourToSecond },
PgInterval::MinuteToSecond => quote! { PgInterval::MinuteToSecond },
});
}
}
impl ColumnDef {
pub fn new<T>(name: T) -> Self
where
T: IntoIden,
{
Self {
table: None,
name: name.into_iden(),
types: None,
spec: Vec::new(),
}
}
pub fn new_with_type<T>(name: T, types: ColumnType) -> Self
where
T: IntoIden,
{
Self {
table: None,
name: name.into_iden(),
types: Some(types),
spec: Vec::new(),
}
}
pub fn not_null(&mut self) -> &mut Self {
self.spec.push(ColumnSpec::NotNull);
self
}
pub fn null(&mut self) -> &mut Self {
self.spec.push(ColumnSpec::Null);
self
}
pub fn default<T>(&mut self, value: T) -> &mut Self
where
T: Into<SimpleExpr>,
{
self.spec.push(ColumnSpec::Default(value.into()));
self
}
pub fn auto_increment(&mut self) -> &mut Self {
self.spec.push(ColumnSpec::AutoIncrement);
self
}
pub fn unique_key(&mut self) -> &mut Self {
self.spec.push(ColumnSpec::UniqueKey);
self
}
pub fn primary_key(&mut self) -> &mut Self {
self.spec.push(ColumnSpec::PrimaryKey);
self
}
pub fn char_len(&mut self, length: u32) -> &mut Self {
self.types = Some(ColumnType::Char(Some(length)));
self
}
pub fn char(&mut self) -> &mut Self {
self.types = Some(ColumnType::Char(None));
self
}
pub fn string_len(&mut self, length: u32) -> &mut Self {
self.types = Some(ColumnType::String(Some(length)));
self
}
pub fn string(&mut self) -> &mut Self {
self.types = Some(ColumnType::String(None));
self
}
pub fn text(&mut self) -> &mut Self {
self.types = Some(ColumnType::Text);
self
}
pub fn tiny_integer(&mut self) -> &mut Self {
self.types = Some(ColumnType::TinyInteger);
self
}
pub fn small_integer(&mut self) -> &mut Self {
self.types = Some(ColumnType::SmallInteger);
self
}
pub fn integer(&mut self) -> &mut Self {
self.types = Some(ColumnType::Integer);
self
}
pub fn big_integer(&mut self) -> &mut Self {
self.types = Some(ColumnType::BigInteger);
self
}
pub fn tiny_unsigned(&mut self) -> &mut Self {
self.types = Some(ColumnType::TinyUnsigned);
self
}
pub fn small_unsigned(&mut self) -> &mut Self {
self.types = Some(ColumnType::SmallUnsigned);
self
}
pub fn unsigned(&mut self) -> &mut Self {
self.types = Some(ColumnType::Unsigned);
self
}
pub fn big_unsigned(&mut self) -> &mut Self {
self.types = Some(ColumnType::BigUnsigned);
self
}
pub fn float(&mut self) -> &mut Self {
self.types = Some(ColumnType::Float);
self
}
pub fn double(&mut self) -> &mut Self {
self.types = Some(ColumnType::Double);
self
}
pub fn decimal_len(&mut self, precision: u32, scale: u32) -> &mut Self {
self.types = Some(ColumnType::Decimal(Some((precision, scale))));
self
}
pub fn decimal(&mut self) -> &mut Self {
self.types = Some(ColumnType::Decimal(None));
self
}
pub fn date_time(&mut self) -> &mut Self {
self.types = Some(ColumnType::DateTime);
self
}
#[cfg(feature = "backend-postgres")]
pub fn interval(&mut self, fields: Option<PgInterval>, precision: Option<u32>) -> &mut Self {
self.types = Some(ColumnType::Interval(fields, precision));
self
}
pub fn timestamp(&mut self) -> &mut Self {
self.types = Some(ColumnType::Timestamp);
self
}
pub fn timestamp_with_time_zone(&mut self) -> &mut Self {
self.types = Some(ColumnType::TimestampWithTimeZone);
self
}
pub fn time(&mut self) -> &mut Self {
self.types = Some(ColumnType::Time);
self
}
pub fn date(&mut self) -> &mut Self {
self.types = Some(ColumnType::Date);
self
}
pub fn year(&mut self, length: Option<MySqlYear>) -> &mut Self {
self.types = Some(ColumnType::Year(length));
self
}
pub fn binary_len(&mut self, length: u32) -> &mut Self {
self.types = Some(ColumnType::Binary(BlobSize::Blob(Some(length))));
self
}
pub fn binary(&mut self) -> &mut Self {
self.types = Some(ColumnType::Binary(BlobSize::Blob(None)));
self
}
pub fn blob(&mut self, size: BlobSize) -> &mut Self {
self.types = Some(ColumnType::Binary(size));
self
}
pub fn var_binary(&mut self, length: u32) -> &mut Self {
self.types = Some(ColumnType::VarBinary(length));
self
}
pub fn bit(&mut self, length: Option<u32>) -> &mut Self {
self.types = Some(ColumnType::Bit(length));
self
}
pub fn varbit(&mut self, length: u32) -> &mut Self {
self.types = Some(ColumnType::VarBit(length));
self
}
pub fn boolean(&mut self) -> &mut Self {
self.types = Some(ColumnType::Boolean);
self
}
pub fn money_len(&mut self, precision: u32, scale: u32) -> &mut Self {
self.types = Some(ColumnType::Money(Some((precision, scale))));
self
}
pub fn money(&mut self) -> &mut Self {
self.types = Some(ColumnType::Money(None));
self
}
pub fn json(&mut self) -> &mut Self {
self.types = Some(ColumnType::Json);
self
}
pub fn json_binary(&mut self) -> &mut Self {
self.types = Some(ColumnType::JsonBinary);
self
}
pub fn uuid(&mut self) -> &mut Self {
self.types = Some(ColumnType::Uuid);
self
}
pub fn custom<T>(&mut self, name: T) -> &mut Self
where
T: IntoIden,
{
self.types = Some(ColumnType::Custom(name.into_iden()));
self
}
pub fn enumeration<N, S, V>(&mut self, name: N, variants: V) -> &mut Self
where
N: IntoIden,
S: IntoIden,
V: IntoIterator<Item = S>,
{
self.types = Some(ColumnType::Enum {
name: name.into_iden(),
variants: variants.into_iter().map(IntoIden::into_iden).collect(),
});
self
}
pub fn array(&mut self, elem_type: ColumnType) -> &mut Self {
self.types = Some(ColumnType::Array(SeaRc::new(elem_type)));
self
}
pub fn cidr(&mut self) -> &mut Self {
self.types = Some(ColumnType::Cidr);
self
}
pub fn inet(&mut self) -> &mut Self {
self.types = Some(ColumnType::Inet);
self
}
pub fn mac_address(&mut self) -> &mut Self {
self.types = Some(ColumnType::MacAddr);
self
}
pub fn extra(&mut self, string: String) -> &mut Self {
self.spec.push(ColumnSpec::Extra(string));
self
}
pub fn get_column_name(&self) -> String {
self.name.to_string()
}
pub fn get_column_type(&self) -> Option<&ColumnType> {
self.types.as_ref()
}
pub fn get_column_spec(&self) -> &Vec<ColumnSpec> {
self.spec.as_ref()
}
pub fn take(&mut self) -> Self {
Self {
table: self.table.take(),
name: std::mem::replace(&mut self.name, SeaRc::new(NullAlias::new())),
types: self.types.take(),
spec: std::mem::take(&mut self.spec),
}
}
}