diff --git a/sea-orm-codegen/src/entity/column.rs b/sea-orm-codegen/src/entity/column.rs index 698384bd..3cb46da6 100644 --- a/sea-orm-codegen/src/entity/column.rs +++ b/sea-orm-codegen/src/entity/column.rs @@ -95,9 +95,7 @@ impl Column { ColumnType::Money(Some((p, s))) => Some(format!("Money(Some({p}, {s}))")), ColumnType::Text => Some("Text".to_owned()), ColumnType::JsonBinary => Some("JsonBinary".to_owned()), - ColumnType::Custom(iden) => { - Some(format!("Custom(\"{}\".to_owned())", iden.to_string())) - } + ColumnType::Custom(iden) => Some(format!("custom(\"{}\")", iden.to_string())), _ => None, }; col_type.map(|ty| quote! { column_type = #ty }) @@ -152,7 +150,7 @@ impl Column { ColumnType::Uuid => quote! { ColumnType::Uuid }, ColumnType::Custom(s) => { let s = s.to_string(); - quote! { ColumnType::Custom(#s.to_owned()) } + quote! { ColumnType::custom(#s) } } ColumnType::Enum { name, .. } => { let enum_ident = format_ident!("{}", name.to_string().to_camel_case()); @@ -465,7 +463,7 @@ mod tests { let columns = setup(); let col_defs = vec![ "ColumnType::String(Some(255u32)).def()", - "ColumnType::Custom(\"cus_col\".to_owned()).def()", + "ColumnType::custom(\"cus_col\").def()", "ColumnType::TinyInteger.def()", "ColumnType::TinyUnsigned.def()", "ColumnType::SmallInteger.def()", diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index c744ccd1..0eb99396 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -274,8 +274,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res field_type.as_str() }; - let col_type = match sql_type { - Some(t) => quote! { sea_orm::prelude::ColumnType::#t.def() }, + let sea_query_col_type = match sql_type { + Some(t) => quote! { sea_orm::prelude::ColumnType::#t }, None => { let col_type = match field_type { "char" => quote! { Char(None) }, @@ -302,7 +302,9 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res "Uuid" => quote! { Uuid }, "Json" => quote! { Json }, "Decimal" => quote! { Decimal(None) }, - "Vec" => quote! { Binary }, + "Vec" => { + quote! { Binary(sea_orm::sea_query::BlobSize::Blob(None)) } + } _ => { // Assumed it's ActiveEnum if none of the above type matches quote! {} @@ -311,20 +313,21 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res if col_type.is_empty() { let field_span = field.span(); let ty: Type = LitStr::new(field_type, field_span).parse()?; - let def = quote_spanned! { field_span => { + let def = quote_spanned! { field_span => std::convert::Into::::into( <#ty as sea_orm::sea_query::ValueType>::column_type() ) - .def() - }}; + }; quote! { #def } } else { - quote! { sea_orm::prelude::ColumnType::#col_type.def() } + quote! { sea_orm::prelude::ColumnType::#col_type } } } }; + let col_def = + quote! { sea_orm::prelude::ColumnTypeTrait::def(#sea_query_col_type) }; - let mut match_row = quote! { Self::#field_name => #col_type }; + let mut match_row = quote! { Self::#field_name => #col_def }; if nullable { match_row = quote! { #match_row.nullable() }; } diff --git a/src/entity/column.rs b/src/entity/column.rs index ee9712ae..93c40f9f 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -4,6 +4,10 @@ use sea_query::{ }; use std::str::FromStr; +// The original `sea_orm::ColumnType` enum was dropped since 0.11.0 +// It was replaced by `sea_query::ColumnType`, we reexport it here to keep the `ColumnType` symbol +pub use sea_query::ColumnType; + /// Defines a Column for an Entity #[derive(Debug, Clone, PartialEq)] pub struct ColumnDef { @@ -14,109 +18,6 @@ pub struct ColumnDef { pub(crate) default_value: Option, } -/// The type of column as defined in the SQL format -#[derive(Debug, Clone)] -pub enum ColumnType { - /// `CHAR` type of specified fixed length - Char(Option), - /// `STRING` type for variable string length - String(Option), - /// `TEXT` type used for large pieces of string data and stored out of row in case size is too big - Text, - /// `TINYINT` useful for storing one byte of data (range of 0-255) - TinyInteger, - /// `SMALLINT` data type stores small whole numbers that range from –32,767 to 32,767 - SmallInteger, - /// `INTEGER` data types hold numbers that are whole, or without a decimal point - Integer, - /// `BIGINT` is a 64-bit representation of an integer taking up 8 bytes of storage and - /// ranging from -2^63 (-9,223,372,036,854,775,808) to 2^63 (9,223,372,036,854,775,807). - BigInteger, - /// `TINYINT UNSIGNED` data type - TinyUnsigned, - /// `SMALLINT UNSIGNED` data type - SmallUnsigned, - /// `INTEGER UNSIGNED` data type - Unsigned, - /// `BIGINT UNSIGNED` data type - BigUnsigned, - /// `FLOAT` an approximate-number data type, where values range cannot be represented exactly. - Float, - /// `DOUBLE` is a normal-size floating point number where the - /// total number of digits is specified in size. - Double, - /// `DECIMAL` type store numbers that have fixed precision and scale - Decimal(Option<(u32, u32)>), - /// `DATETIME` type is used for values that contain both date and time parts. - DateTime, - /// `TIMESTAMP` is a temporal data type that holds the combination of date and time. - Timestamp, - /// `TIMESTAMP WITH TIME ZONE` (or `TIMESTAMPTZ`) data type stores 8-byte - /// date values that include timestamp and time zone information in UTC format. - TimestampWithTimeZone, - /// `TIME` data type defines a time of a day based on 24-hour clock - Time, - /// `DATE` data type stores the calendar date - Date, - /// `BINARY` data types contain byte strings—a sequence of octets or bytes. - Binary, - /// Tiny Binary - TinyBinary, - /// Medium Binary - MediumBinary, - /// Long Binary - LongBinary, - /// `BOOLEAN` is the result of a comparison operator - Boolean, - /// `MONEY` data type handles monetary data - Money(Option<(u32, u32)>), - /// `JSON` represents the JavaScript Object Notation type - Json, - /// JSON binary format is structured in the way that permits the server to search for - /// values within the JSON document directly by key or array index, which is very fast. - JsonBinary, - /// A custom implementation of a data type - Custom(String), - /// A Universally Unique IDentifier that is specified in RFC 4122 - Uuid, - /// `ENUM` data type with name and variants - Enum { - /// Name of enum - name: DynIden, - /// Variants of enum - variants: Vec, - }, - /// Array of a specific data type (PostgreSQL only) - Array(SeaRc), -} - -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::Money(l0), Self::Money(r0)) => l0 == r0, - (Self::Custom(l0), Self::Custom(r0)) => l0 == r0, - ( - 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()).collect::>() - == r_variants.iter().map(|v| v.to_string()).collect::>() - } - _ => core::mem::discriminant(self) == core::mem::discriminant(other), - } - } -} - macro_rules! bind_oper { ( $op: ident ) => { #[allow(missing_docs)] @@ -378,9 +279,17 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { } } -impl ColumnType { - /// instantiate a new [ColumnDef] - pub fn def(self) -> ColumnDef { +/// SeaORM's utility methods that act on [ColumnType] +pub trait ColumnTypeTrait { + /// Instantiate a new [ColumnDef] + fn def(self) -> ColumnDef; + + /// Get the name of the enum if this is a enum column + fn get_enum_name(&self) -> Option<&DynIden>; +} + +impl ColumnTypeTrait for ColumnType { + fn def(self) -> ColumnDef { ColumnDef { col_type: self, null: false, @@ -390,7 +299,7 @@ impl ColumnType { } } - pub(crate) fn get_enum_name(&self) -> Option<&DynIden> { + fn get_enum_name(&self) -> Option<&DynIden> { fn enum_name(col_type: &ColumnType) -> Option<&DynIden> { match col_type { ColumnType::Enum { name, .. } => Some(name), @@ -446,111 +355,6 @@ impl ColumnDef { } } -impl From for sea_query::ColumnType { - fn from(column_type: ColumnType) -> Self { - fn convert_column_type(column_type: &ColumnType) -> sea_query::ColumnType { - match column_type { - ColumnType::Char(s) => sea_query::ColumnType::Char(*s), - ColumnType::String(s) => sea_query::ColumnType::String(*s), - ColumnType::Text => sea_query::ColumnType::Text, - ColumnType::TinyInteger => sea_query::ColumnType::TinyInteger, - ColumnType::SmallInteger => sea_query::ColumnType::SmallInteger, - ColumnType::Integer => sea_query::ColumnType::Integer, - ColumnType::BigInteger => sea_query::ColumnType::BigInteger, - ColumnType::TinyUnsigned => sea_query::ColumnType::TinyUnsigned, - ColumnType::SmallUnsigned => sea_query::ColumnType::SmallUnsigned, - ColumnType::Unsigned => sea_query::ColumnType::Unsigned, - ColumnType::BigUnsigned => sea_query::ColumnType::BigUnsigned, - ColumnType::Float => sea_query::ColumnType::Float, - ColumnType::Double => sea_query::ColumnType::Double, - ColumnType::Decimal(s) => sea_query::ColumnType::Decimal(*s), - ColumnType::DateTime => sea_query::ColumnType::DateTime, - ColumnType::Timestamp => sea_query::ColumnType::Timestamp, - ColumnType::TimestampWithTimeZone => sea_query::ColumnType::TimestampWithTimeZone, - ColumnType::Time => sea_query::ColumnType::Time, - ColumnType::Date => sea_query::ColumnType::Date, - ColumnType::Binary => { - sea_query::ColumnType::Binary(sea_query::BlobSize::Blob(None)) - } - ColumnType::TinyBinary => sea_query::ColumnType::Binary(sea_query::BlobSize::Tiny), - ColumnType::MediumBinary => { - sea_query::ColumnType::Binary(sea_query::BlobSize::Medium) - } - ColumnType::LongBinary => sea_query::ColumnType::Binary(sea_query::BlobSize::Long), - ColumnType::Boolean => sea_query::ColumnType::Boolean, - ColumnType::Money(s) => sea_query::ColumnType::Money(*s), - ColumnType::Json => sea_query::ColumnType::Json, - ColumnType::JsonBinary => sea_query::ColumnType::JsonBinary, - ColumnType::Custom(s) => { - sea_query::ColumnType::Custom(sea_query::SeaRc::new(sea_query::Alias::new(s))) - } - ColumnType::Uuid => sea_query::ColumnType::Uuid, - ColumnType::Enum { name, variants } => sea_query::ColumnType::Enum { - name: SeaRc::clone(name), - variants: variants.clone(), - }, - ColumnType::Array(column_type) => { - let column_type = convert_column_type(column_type); - sea_query::ColumnType::Array(SeaRc::new(column_type)) - } - } - } - convert_column_type(&column_type) - } -} - -impl From for ColumnType { - fn from(column_type: sea_query::ColumnType) -> Self { - #[allow(clippy::redundant_allocation)] - fn convert_column_type(column_type: &sea_query::ColumnType) -> ColumnType { - #[allow(unreachable_patterns)] - match column_type { - sea_query::ColumnType::Char(s) => ColumnType::Char(*s), - sea_query::ColumnType::String(s) => ColumnType::String(*s), - sea_query::ColumnType::Text => ColumnType::Text, - sea_query::ColumnType::TinyInteger => ColumnType::TinyInteger, - sea_query::ColumnType::SmallInteger => ColumnType::SmallInteger, - sea_query::ColumnType::Integer => ColumnType::Integer, - sea_query::ColumnType::BigInteger => ColumnType::BigInteger, - sea_query::ColumnType::TinyUnsigned => ColumnType::TinyUnsigned, - sea_query::ColumnType::SmallUnsigned => ColumnType::SmallUnsigned, - sea_query::ColumnType::Unsigned => ColumnType::Unsigned, - sea_query::ColumnType::BigUnsigned => ColumnType::BigUnsigned, - sea_query::ColumnType::Float => ColumnType::Float, - sea_query::ColumnType::Double => ColumnType::Double, - sea_query::ColumnType::Decimal(s) => ColumnType::Decimal(*s), - sea_query::ColumnType::DateTime => ColumnType::DateTime, - sea_query::ColumnType::Timestamp => ColumnType::Timestamp, - sea_query::ColumnType::TimestampWithTimeZone => ColumnType::TimestampWithTimeZone, - sea_query::ColumnType::Time => ColumnType::Time, - sea_query::ColumnType::Date => ColumnType::Date, - sea_query::ColumnType::Binary(sea_query::BlobSize::Blob(_)) => ColumnType::Binary, - sea_query::ColumnType::Binary(sea_query::BlobSize::Tiny) => ColumnType::TinyBinary, - sea_query::ColumnType::Binary(sea_query::BlobSize::Medium) => { - ColumnType::MediumBinary - } - sea_query::ColumnType::Binary(sea_query::BlobSize::Long) => ColumnType::LongBinary, - sea_query::ColumnType::Boolean => ColumnType::Boolean, - sea_query::ColumnType::Money(s) => ColumnType::Money(*s), - sea_query::ColumnType::Json => ColumnType::Json, - sea_query::ColumnType::JsonBinary => ColumnType::JsonBinary, - sea_query::ColumnType::Custom(s) => ColumnType::Custom(s.to_string()), - sea_query::ColumnType::Uuid => ColumnType::Uuid, - sea_query::ColumnType::Enum { name, variants } => ColumnType::Enum { - name: SeaRc::clone(name), - variants: variants.clone(), - }, - sea_query::ColumnType::Array(column_type) => { - let column_type = convert_column_type(column_type); - ColumnType::Array(SeaRc::new(column_type)) - } - _ => unimplemented!(), - } - } - convert_column_type(&column_type) - } -} - #[derive(Iden)] struct Text; diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index 164a458b..47b22bcc 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -1,7 +1,7 @@ pub use crate::{ error::*, ActiveEnum, ActiveModelBehavior, ActiveModelTrait, ColumnDef, ColumnTrait, - ColumnType, CursorTrait, DatabaseConnection, DbConn, EntityName, EntityTrait, EnumIter, - ForeignKeyAction, Iden, IdenStatic, Linked, LoaderTrait, ModelTrait, PaginatorTrait, + ColumnType, ColumnTypeTrait, CursorTrait, DatabaseConnection, DbConn, EntityName, EntityTrait, + EnumIter, ForeignKeyAction, Iden, IdenStatic, Linked, LoaderTrait, ModelTrait, PaginatorTrait, PrimaryKeyToColumn, PrimaryKeyTrait, QueryFilter, QueryResult, Related, RelationDef, RelationTrait, Select, Value, }; diff --git a/src/schema/entity.rs b/src/schema/entity.rs index c1d23d83..d65a2064 100644 --- a/src/schema/entity.rs +++ b/src/schema/entity.rs @@ -4,7 +4,7 @@ use crate::{ }; use sea_query::{ extension::postgres::{Type, TypeCreateStatement}, - ColumnDef, Iden, Index, IndexCreateStatement, TableCreateStatement, + ColumnDef, Iden, Index, IndexCreateStatement, SeaRc, TableCreateStatement, }; impl Schema { @@ -194,13 +194,12 @@ where ColumnType::Enum { name, variants } => match backend { DbBackend::MySql => { let variants: Vec = variants.iter().map(|v| v.to_string()).collect(); - ColumnType::Custom(format!("ENUM('{}')", variants.join("', '"))) + ColumnType::custom(format!("ENUM('{}')", variants.join("', '")).as_str()) } - DbBackend::Postgres => ColumnType::Custom(name.to_string()), + DbBackend::Postgres => ColumnType::Custom(SeaRc::clone(&name)), DbBackend::Sqlite => ColumnType::Text, - } - .into(), - _ => orm_column_def.col_type.into(), + }, + _ => orm_column_def.col_type, }; let mut column_def = ColumnDef::new_with_type(column, types); if !orm_column_def.null { diff --git a/tests/common/features/collection.rs b/tests/common/features/collection.rs index 1b020162..487b5da2 100644 --- a/tests/common/features/collection.rs +++ b/tests/common/features/collection.rs @@ -7,7 +7,7 @@ pub struct Model { #[sea_orm(primary_key)] pub id: i32, #[sea_orm( - column_type = r#"Custom("citext".into())"#, + column_type = r#"custom("citext")"#, select_as = "text", save_as = "citext" )]