From 524f8569e78f2410b6fbd2afed7cb0d7d5c5add6 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 14 Dec 2022 18:08:03 +0800 Subject: [PATCH 1/8] Cast select and value --- src/entity/column.rs | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/src/entity/column.rs b/src/entity/column.rs index 56606730b..50cf7ceef 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -338,6 +338,42 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { fn into_expr(self) -> Expr { Expr::expr(self.into_simple_expr()) } + + /// Cast column expression used in select statement. + /// By default it only cast database enum as text. + fn cast_select(&self, expr: Expr) -> SimpleExpr { + self.cast_select_enum(expr) + } + + /// Cast enum column as text + fn cast_select_enum(&self, expr: Expr) -> SimpleExpr { + cast_enum_text_inner(expr, self, |col, _, col_type| { + let type_name = match col_type { + ColumnType::Array(_) => TextArray.into_iden(), + _ => Text.into_iden(), + }; + col.as_enum(type_name) + }) + } + + /// Cast value of a column into the correct type for database storage. + /// By default it only cast text as enum type if it's an enum column. + fn cast_value(&self, val: Expr) -> SimpleExpr { + self.cast_value_enum(val) + } + + /// Cast value of a enum column as enum type + fn cast_value_enum(&self, val: Expr) -> SimpleExpr { + cast_enum_text_inner(val, self, |col, enum_name, col_type| { + let type_name = match col_type { + ColumnType::Array(_) => { + Alias::new(&format!("{}[]", enum_name.to_string())).into_iden() + } + _ => enum_name, + }; + col.as_enum(type_name) + }) + } } impl ColumnType { @@ -512,6 +548,26 @@ impl From for ColumnType { } } +#[derive(Iden)] +struct Text; + +#[derive(Iden)] +#[iden = "text[]"] +struct TextArray; + +fn cast_enum_text_inner(expr: Expr, col: &C, f: F) -> SimpleExpr +where + C: ColumnTrait, + F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr, +{ + let col_def = col.def(); + let col_type = col_def.get_column_type(); + match col_type.get_enum_name() { + Some(enum_name) => f(expr, SeaRc::clone(enum_name), col_type), + None => expr.into(), + } +} + #[cfg(test)] mod tests { use crate::{ From f79a4f975dc19eee8de98fbfd7be64e0979206cd Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 14 Dec 2022 18:10:55 +0800 Subject: [PATCH 2/8] Refactoring --- src/entity/column.rs | 8 ++++--- src/executor/insert.rs | 7 +++--- src/executor/update.rs | 5 ++-- src/query/combine.rs | 5 ++-- src/query/helper.rs | 54 ++++-------------------------------------- src/query/insert.rs | 4 ++-- src/query/join.rs | 4 ++-- src/query/select.rs | 7 ++---- src/query/update.rs | 6 ++--- 9 files changed, 25 insertions(+), 75 deletions(-) diff --git a/src/entity/column.rs b/src/entity/column.rs index 50cf7ceef..b5bb1605f 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -1,5 +1,7 @@ -use crate::{cast_text_as_enum, EntityName, IdenStatic, IntoSimpleExpr, Iterable}; -use sea_query::{BinOper, DynIden, Expr, SeaRc, SelectStatement, SimpleExpr, Value}; +use crate::{EntityName, IdenStatic, IntoSimpleExpr, Iterable}; +use sea_query::{ + Alias, BinOper, DynIden, Expr, Iden, IntoIden, SeaRc, SelectStatement, SimpleExpr, Value, +}; use std::str::FromStr; /// Defines a Column for an Entity @@ -134,7 +136,7 @@ macro_rules! bind_oper_with_enum_casting { where V: Into, { - let expr = cast_text_as_enum(Expr::val(v), self); + let expr = self.cast_value(Expr::val(v)); Expr::tbl(self.entity_name(), *self).binary(BinOper::$bin_op, expr) } }; diff --git a/src/executor/insert.rs b/src/executor/insert.rs index 29ab6b440..d25b22b8f 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -1,6 +1,6 @@ use crate::{ - cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Insert, - IntoActiveModel, Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64, + error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel, + Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64, }; use sea_query::{Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple}; use std::{future::Future, marker::PhantomData}; @@ -186,8 +186,7 @@ where let found = match db.support_returning() { true => { let returning = Query::returning().exprs( - ::Column::iter() - .map(|c| cast_enum_as_text(Expr::col(c), &c)), + ::Column::iter().map(|c| c.cast_select(Expr::col(c))), ); insert_statement.returning(returning); SelectorRaw::::Model>>::from_statement( diff --git a/src/executor/update.rs b/src/executor/update.rs index 190347e02..5c4649f71 100644 --- a/src/executor/update.rs +++ b/src/executor/update.rs @@ -1,5 +1,5 @@ use crate::{ - cast_enum_as_text, error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel, + error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel, Iterable, SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne, }; use sea_query::{Expr, FromValueTuple, Query, UpdateStatement}; @@ -92,8 +92,7 @@ where match db.support_returning() { true => { let returning = Query::returning().exprs( - ::Column::iter() - .map(|c| cast_enum_as_text(Expr::col(c), &c)), + ::Column::iter().map(|c| c.cast_select(Expr::col(c))), ); query.returning(returning); let db_backend = db.get_database_backend(); diff --git a/src/query/combine.rs b/src/query/combine.rs index 677d7aa0a..7eb2eaccb 100644 --- a/src/query/combine.rs +++ b/src/query/combine.rs @@ -1,6 +1,5 @@ use crate::{ - cast_enum_as_text, ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select, - SelectTwo, SelectTwoMany, + ColumnTrait, EntityTrait, IdenStatic, Iterable, QueryTrait, Select, SelectTwo, SelectTwoMany, }; use core::marker::PhantomData; pub use sea_query::JoinType; @@ -149,7 +148,7 @@ where for col in ::iter() { let alias = format!("{}{}", SelectB.as_str(), col.as_str()); selector.query().expr(SelectExpr { - expr: cast_enum_as_text(col.into_expr(), &col), + expr: col.cast_select(col.into_expr()), alias: Some(SeaRc::new(Alias::new(&alias))), window: None, }); diff --git a/src/query/helper.rs b/src/query/helper.rs index 42e70fe37..30e3ebfab 100644 --- a/src/query/helper.rs +++ b/src/query/helper.rs @@ -1,6 +1,6 @@ use crate::{ - ColumnTrait, ColumnType, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable, - ModelTrait, PrimaryKeyToColumn, RelationDef, + ColumnTrait, EntityTrait, Identity, IntoIdentity, IntoSimpleExpr, Iterable, ModelTrait, + PrimaryKeyToColumn, RelationDef, }; use sea_query::{ Alias, Expr, Iden, IntoCondition, IntoIden, LockType, SeaRc, SelectExpr, SelectStatement, @@ -67,7 +67,7 @@ pub trait QuerySelect: Sized { where C: ColumnTrait, { - self.query().expr(cast_enum_as_text(col.into_expr(), &col)); + self.query().expr(col.cast_select(col.into_expr())); self } @@ -90,7 +90,7 @@ pub trait QuerySelect: Sized { I: IntoIdentity, { self.query().expr(SelectExpr { - expr: col.into_simple_expr(), + expr: col.cast_select(col.into_simple_expr()), alias: Some(SeaRc::new(alias.into_identity())), window: None, }); @@ -678,49 +678,3 @@ pub(crate) fn unpack_table_alias(table_ref: &TableRef) -> Option { | TableRef::DatabaseSchemaTableAlias(_, _, _, alias) => Some(SeaRc::clone(alias)), } } - -#[derive(Iden)] -struct Text; - -#[derive(Iden)] -#[iden = "text[]"] -struct TextArray; - -pub(crate) fn cast_enum_as_text(expr: Expr, col: &C) -> SimpleExpr -where - C: ColumnTrait, -{ - cast_enum_text_inner(expr, col, |col, _, col_type| { - let type_name = match col_type { - ColumnType::Array(_) => TextArray.into_iden(), - _ => Text.into_iden(), - }; - col.as_enum(type_name) - }) -} - -pub(crate) fn cast_text_as_enum(expr: Expr, col: &C) -> SimpleExpr -where - C: ColumnTrait, -{ - cast_enum_text_inner(expr, col, |col, enum_name, col_type| { - let type_name = match col_type { - ColumnType::Array(_) => Alias::new(&format!("{}[]", enum_name.to_string())).into_iden(), - _ => enum_name, - }; - col.as_enum(type_name) - }) -} - -fn cast_enum_text_inner(expr: Expr, col: &C, f: F) -> SimpleExpr -where - C: ColumnTrait, - F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr, -{ - let col_def = col.def(); - let col_type = col_def.get_column_type(); - match col_type.get_enum_name() { - Some(enum_name) => f(expr, SeaRc::clone(enum_name), col_type), - None => expr.into(), - } -} diff --git a/src/query/insert.rs b/src/query/insert.rs index f95e44640..0c1044e9d 100644 --- a/src/query/insert.rs +++ b/src/query/insert.rs @@ -1,5 +1,5 @@ use crate::{ - cast_text_as_enum, ActiveModelTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, + ActiveModelTrait, ColumnTrait, EntityName, EntityTrait, IntoActiveModel, Iterable, PrimaryKeyTrait, QueryTrait, }; use core::marker::PhantomData; @@ -134,7 +134,7 @@ where } if av_has_val { columns.push(col); - values.push(cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col)); + values.push(col.cast_value(Expr::val(av.into_value().unwrap()))); } } self.query.columns(columns); diff --git a/src/query/join.rs b/src/query/join.rs index 744ed3544..d91df6eb2 100644 --- a/src/query/join.rs +++ b/src/query/join.rs @@ -1,5 +1,5 @@ use crate::{ - cast_enum_as_text, join_tbl_on_condition, unpack_table_ref, EntityTrait, IdenStatic, Iterable, + join_tbl_on_condition, unpack_table_ref, ColumnTrait, EntityTrait, IdenStatic, Iterable, Linked, QuerySelect, Related, Select, SelectA, SelectB, SelectTwo, SelectTwoMany, }; pub use sea_query::JoinType; @@ -100,7 +100,7 @@ where col.into_iden(), ); select_two.query().expr(SelectExpr { - expr: cast_enum_as_text(expr, &col), + expr: col.cast_select(expr), alias: Some(SeaRc::new(Alias::new(&alias))), window: None, }); diff --git a/src/query/select.rs b/src/query/select.rs index 3f53430e9..5f1006e80 100644 --- a/src/query/select.rs +++ b/src/query/select.rs @@ -1,7 +1,4 @@ -use crate::{ - cast_enum_as_text, ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, - QueryTrait, -}; +use crate::{ColumnTrait, EntityTrait, Iterable, QueryFilter, QueryOrder, QuerySelect, QueryTrait}; use core::fmt::Debug; use core::marker::PhantomData; pub use sea_query::JoinType; @@ -123,7 +120,7 @@ where fn column_list(&self) -> Vec { E::Column::iter() - .map(|col| cast_enum_as_text(col.into_expr(), &col)) + .map(|col| col.cast_select(col.into_expr())) .collect() } diff --git a/src/query/update.rs b/src/query/update.rs index b5d404a05..515ded3b6 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -1,6 +1,6 @@ use crate::{ - cast_text_as_enum, ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, - QueryFilter, QueryTrait, + ActiveModelTrait, ColumnTrait, EntityTrait, Iterable, PrimaryKeyToColumn, QueryFilter, + QueryTrait, }; use core::marker::PhantomData; use sea_query::{Expr, IntoIden, SimpleExpr, UpdateStatement}; @@ -109,7 +109,7 @@ where } let av = self.model.get(col); if av.is_set() { - let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col); + let expr = col.cast_value(Expr::val(av.into_value().unwrap())); self.query.value(col, expr); } } From fb1f42e82113d7cf19046ad769af1c0563be1175 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 14 Dec 2022 18:11:21 +0800 Subject: [PATCH 3/8] Test casting Postgres citext --- sea-orm-macros/src/derives/entity_model.rs | 53 ++++++++++++++++++++++ tests/collection_tests.rs | 7 +++ tests/common/features/collection.rs | 6 +++ tests/common/features/schema.rs | 13 +++++- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index bf42699d1..931a713ca 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -63,6 +63,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res // generate Column enum and it's ColumnTrait impl let mut columns_enum: Punctuated<_, Comma> = Punctuated::new(); let mut columns_trait: Punctuated<_, Comma> = Punctuated::new(); + let mut cast_selects: Punctuated<_, Comma> = Punctuated::new(); + let mut cast_values: Punctuated<_, Comma> = Punctuated::new(); let mut primary_keys: Punctuated<_, Comma> = Punctuated::new(); let mut primary_key_types: Punctuated<_, Comma> = Punctuated::new(); let mut auto_increment = true; @@ -90,6 +92,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res let mut nullable = false; let mut default_value = None; let mut default_expr = None; + let mut cast_select = None; + let mut cast_value = None; let mut indexed = false; let mut ignore = false; let mut unique = false; @@ -169,6 +173,24 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res format!("Invalid enum_name {:?}", nv.lit), )); } + } else if name == "cast_select" { + if let Lit::Str(litstr) = &nv.lit { + cast_select = Some(litstr.value()); + } else { + return Err(Error::new( + field.span(), + format!("Invalid cast_select {:?}", nv.lit), + )); + } + } else if name == "cast_value" { + if let Lit::Str(litstr) = &nv.lit { + cast_value = Some(litstr.value()); + } else { + return Err(Error::new( + field.span(), + format!("Invalid cast_value {:?}", nv.lit), + )); + } } } } @@ -224,6 +246,23 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res }); } + if let Some(cast_select) = cast_select { + cast_selects.push(quote! { + Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as( + Into::::into(expr), + sea_orm::sea_query::Alias::new(&#cast_select), + ), + }); + } + if let Some(cast_value) = cast_value { + cast_values.push(quote! { + Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as( + Into::::into(val), + sea_orm::sea_query::Alias::new(&#cast_value), + ), + }); + } + let field_type = &field.ty; let field_type = quote! { #field_type } .to_string() //E.g.: "Option < String >" @@ -347,6 +386,20 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res #columns_trait } } + + fn cast_select(&self, expr: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { + match self { + #cast_selects + _ => sea_orm::prelude::ColumnTrait::cast_select_enum(self, expr), + } + } + + fn cast_value(&self, val: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { + match self { + #cast_values + _ => sea_orm::prelude::ColumnTrait::cast_value_enum(self, val), + } + } } #entity_def diff --git a/tests/collection_tests.rs b/tests/collection_tests.rs index f95c81a0a..5ca6d17ac 100644 --- a/tests/collection_tests.rs +++ b/tests/collection_tests.rs @@ -22,6 +22,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { assert_eq!( Model { id: 1, + name: "Collection 1".into(), integers: vec![1, 2, 3], integers_opt: Some(vec![1, 2, 3]), teas: vec![Tea::BreakfastTea], @@ -34,6 +35,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { .await?, Model { id: 1, + name: "Collection 1".into(), integers: vec![1, 2, 3], integers_opt: Some(vec![1, 2, 3]), teas: vec![Tea::BreakfastTea], @@ -46,6 +48,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { assert_eq!( Model { id: 2, + name: "Collection 2".into(), integers: vec![10, 9], integers_opt: None, teas: vec![Tea::BreakfastTea], @@ -58,6 +61,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { .await?, Model { id: 2, + name: "Collection 2".into(), integers: vec![10, 9], integers_opt: None, teas: vec![Tea::BreakfastTea], @@ -70,6 +74,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { assert_eq!( Model { id: 3, + name: "Collection 3".into(), integers: vec![], integers_opt: Some(vec![]), teas: vec![], @@ -82,6 +87,7 @@ pub async fn insert_collection(db: &DatabaseConnection) -> Result<(), DbErr> { .await?, Model { id: 3, + name: "Collection 3".into(), integers: vec![], integers_opt: Some(vec![]), teas: vec![], @@ -113,6 +119,7 @@ pub async fn update_collection(db: &DatabaseConnection) -> Result<(), DbErr> { ActiveModel { id: Unchanged(3), + name: Set("Collection 3".into()), integers: Set(vec![3, 1, 4]), integers_opt: Set(None), teas: Set(vec![Tea::EverydayTea]), diff --git a/tests/common/features/collection.rs b/tests/common/features/collection.rs index b08aa26ff..f42d721ca 100644 --- a/tests/common/features/collection.rs +++ b/tests/common/features/collection.rs @@ -6,6 +6,12 @@ use sea_orm::entity::prelude::*; pub struct Model { #[sea_orm(primary_key)] pub id: i32, + #[sea_orm( + column_type = r#"Custom("citext".into())"#, + cast_select = "text", + cast_value = "citext" + )] + pub name: String, pub integers: Vec, pub integers_opt: Option>, pub teas: Vec, diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 13ca8c237..9cfcb3de2 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -149,7 +149,7 @@ pub async fn create_byte_primary_key_table(db: &DbConn) -> Result Result } pub async fn create_collection_table(db: &DbConn) -> Result { + db.execute(sea_orm::Statement::from_string( + db.get_database_backend(), + "CREATE EXTENSION IF NOT EXISTS citext".into(), + )) + .await?; + let stmt = sea_query::Table::create() .table(collection::Entity) .col( @@ -342,6 +348,11 @@ pub async fn create_collection_table(db: &DbConn) -> Result { .auto_increment() .primary_key(), ) + .col( + ColumnDef::new(collection::Column::Name) + .custom(Alias::new("citext")) + .not_null(), + ) .col( ColumnDef::new(collection::Column::Integers) .array(sea_query::ColumnType::Integer(None)) From 2b943c21f84144bf272cda359d1bb09160827a93 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 14 Dec 2022 18:30:47 +0800 Subject: [PATCH 4/8] Fixup --- src/query/helper.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/helper.rs b/src/query/helper.rs index 30e3ebfab..0bac74f86 100644 --- a/src/query/helper.rs +++ b/src/query/helper.rs @@ -90,7 +90,7 @@ pub trait QuerySelect: Sized { I: IntoIdentity, { self.query().expr(SelectExpr { - expr: col.cast_select(col.into_simple_expr()), + expr: col.into_simple_expr(), alias: Some(SeaRc::new(alias.into_identity())), window: None, }); From 673e541ad792b36e6a53b8c49a57b154edc34101 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 14 Dec 2022 18:50:34 +0800 Subject: [PATCH 5/8] Revert --- tests/common/features/schema.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 9cfcb3de2..079dc975c 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -149,7 +149,7 @@ pub async fn create_byte_primary_key_table(db: &DbConn) -> Result Date: Thu, 5 Jan 2023 15:39:00 +0800 Subject: [PATCH 6/8] Add test cases --- src/entity/column.rs | 410 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 410 insertions(+) diff --git a/src/entity/column.rs b/src/entity/column.rs index b5bb1605f..47d13edc8 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -1074,4 +1074,414 @@ mod tests { assert_eq!(my_entity::Column::IdentityColumn.to_string().as_str(), "id"); assert_eq!(my_entity::Column::Type.to_string().as_str(), "type"); } + + #[test] + #[cfg(feature = "macros")] + fn cast_select_1() { + use crate::{ActiveModelTrait, ActiveValue, Update}; + + mod hello_expanded { + use crate as sea_orm; + use crate::entity::prelude::*; + use crate::sea_query::{Alias, Expr, SimpleExpr}; + + #[derive(Copy, Clone, Default, Debug, DeriveEntity)] + pub struct Entity; + + impl EntityName for Entity { + fn table_name(&self) -> &str { + "hello" + } + } + + #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)] + pub struct Model { + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] + pub enum Column { + Id, + One1, + Two, + Three3, + } + + impl ColumnTrait for Column { + type EntityName = Entity; + + fn def(&self) -> ColumnDef { + match self { + Column::Id => ColumnType::Integer.def(), + Column::One1 => ColumnType::Integer.def(), + Column::Two => ColumnType::Integer.def(), + Column::Three3 => ColumnType::Integer.def(), + } + } + + fn cast_select(&self, expr: Expr) -> SimpleExpr { + match self { + Self::Two => SimpleExpr::cast_as( + Into::::into(expr), + Alias::new("integer"), + ), + _ => self.cast_select_enum(expr), + } + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] + pub enum PrimaryKey { + Id, + } + + impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + #[allow(clippy::enum_variant_names)] + mod hello_compact { + use crate as sea_orm; + use crate::entity::prelude::*; + + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] + #[sea_orm(table_name = "hello")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + #[sea_orm(cast_select = "integer")] + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + fn assert_it(active_model: A) + where + E: EntityTrait, + A: ActiveModelTrait, + { + assert_eq!( + E::find().build(DbBackend::Postgres).to_string(), + r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#, + ); + assert_eq!( + Update::one(active_model) + .build(DbBackend::Postgres) + .to_string(), + r#"UPDATE "hello" SET "one1" = 1, "two" = 2, "three3" = 3 WHERE "hello"."id" = 1"#, + ); + } + + assert_it(hello_expanded::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + assert_it(hello_compact::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + } + + #[test] + #[cfg(feature = "macros")] + fn cast_value_1() { + use crate::{ActiveModelTrait, ActiveValue, Update}; + + mod hello_expanded { + use crate as sea_orm; + use crate::entity::prelude::*; + use crate::sea_query::{Alias, Expr, SimpleExpr}; + + #[derive(Copy, Clone, Default, Debug, DeriveEntity)] + pub struct Entity; + + impl EntityName for Entity { + fn table_name(&self) -> &str { + "hello" + } + } + + #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)] + pub struct Model { + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] + pub enum Column { + Id, + One1, + Two, + Three3, + } + + impl ColumnTrait for Column { + type EntityName = Entity; + + fn def(&self) -> ColumnDef { + match self { + Column::Id => ColumnType::Integer.def(), + Column::One1 => ColumnType::Integer.def(), + Column::Two => ColumnType::Integer.def(), + Column::Three3 => ColumnType::Integer.def(), + } + } + + fn cast_value(&self, expr: Expr) -> SimpleExpr { + match self { + Self::Two => { + SimpleExpr::cast_as(Into::::into(expr), Alias::new("text")) + } + _ => self.cast_value_enum(expr), + } + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] + pub enum PrimaryKey { + Id, + } + + impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + #[allow(clippy::enum_variant_names)] + mod hello_compact { + use crate as sea_orm; + use crate::entity::prelude::*; + + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] + #[sea_orm(table_name = "hello")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + #[sea_orm(cast_value = "text")] + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + fn assert_it(active_model: A) + where + E: EntityTrait, + A: ActiveModelTrait, + { + assert_eq!( + E::find().build(DbBackend::Postgres).to_string(), + r#"SELECT "hello"."id", "hello"."one1", "hello"."two", "hello"."three3" FROM "hello""#, + ); + assert_eq!( + Update::one(active_model) + .build(DbBackend::Postgres) + .to_string(), + r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#, + ); + } + + assert_it(hello_expanded::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + assert_it(hello_compact::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + } + + #[test] + #[cfg(feature = "macros")] + fn cast_select_and_value_1() { + use crate::{ActiveModelTrait, ActiveValue, Update}; + + mod hello_expanded { + use crate as sea_orm; + use crate::entity::prelude::*; + use crate::sea_query::{Alias, Expr, SimpleExpr}; + + #[derive(Copy, Clone, Default, Debug, DeriveEntity)] + pub struct Entity; + + impl EntityName for Entity { + fn table_name(&self) -> &str { + "hello" + } + } + + #[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)] + pub struct Model { + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] + pub enum Column { + Id, + One1, + Two, + Three3, + } + + impl ColumnTrait for Column { + type EntityName = Entity; + + fn def(&self) -> ColumnDef { + match self { + Column::Id => ColumnType::Integer.def(), + Column::One1 => ColumnType::Integer.def(), + Column::Two => ColumnType::Integer.def(), + Column::Three3 => ColumnType::Integer.def(), + } + } + + fn cast_select(&self, expr: Expr) -> SimpleExpr { + match self { + Self::Two => SimpleExpr::cast_as( + Into::::into(expr), + Alias::new("integer"), + ), + _ => self.cast_select_enum(expr), + } + } + + fn cast_value(&self, expr: Expr) -> SimpleExpr { + match self { + Self::Two => { + SimpleExpr::cast_as(Into::::into(expr), Alias::new("text")) + } + _ => self.cast_value_enum(expr), + } + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DerivePrimaryKey)] + pub enum PrimaryKey { + Id, + } + + impl PrimaryKeyTrait for PrimaryKey { + type ValueType = i32; + + fn auto_increment() -> bool { + true + } + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + #[allow(clippy::enum_variant_names)] + mod hello_compact { + use crate as sea_orm; + use crate::entity::prelude::*; + + #[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] + #[sea_orm(table_name = "hello")] + pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(enum_name = "One1")] + pub one: i32, + #[sea_orm(cast_select = "integer", cast_value = "text")] + pub two: i32, + #[sea_orm(enum_name = "Three3")] + pub three: i32, + } + + #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] + pub enum Relation {} + + impl ActiveModelBehavior for ActiveModel {} + } + + fn assert_it(active_model: A) + where + E: EntityTrait, + A: ActiveModelTrait, + { + assert_eq!( + E::find().build(DbBackend::Postgres).to_string(), + r#"SELECT "hello"."id", "hello"."one1", CAST("hello"."two" AS integer), "hello"."three3" FROM "hello""#, + ); + assert_eq!( + Update::one(active_model) + .build(DbBackend::Postgres) + .to_string(), + r#"UPDATE "hello" SET "one1" = 1, "two" = CAST(2 AS text), "three3" = 3 WHERE "hello"."id" = 1"#, + ); + } + + assert_it(hello_expanded::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + assert_it(hello_compact::ActiveModel { + id: ActiveValue::set(1), + one: ActiveValue::set(1), + two: ActiveValue::set(2), + three: ActiveValue::set(3), + }); + } } From 702c11b8bb8a2cc8ea6d97258dcfa41fc1b4eefe Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Thu, 5 Jan 2023 16:07:17 +0800 Subject: [PATCH 7/8] Fixup --- src/query/update.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/query/update.rs b/src/query/update.rs index 6df8489f8..705d4a969 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -189,7 +189,7 @@ where for col in E::Column::iter() { let av = model.get(col); if av.is_set() { - let expr = cast_text_as_enum(Expr::val(av.into_value().unwrap()), &col); + let expr = col.cast_value(Expr::val(av.into_value().unwrap())); self.query.value(col, expr); } } From faf196923ca1b2be30b10801d4eb2d904ffd1ee4 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 11 Jan 2023 19:37:35 +0800 Subject: [PATCH 8/8] Rename methods --- sea-orm-macros/src/derives/entity_model.rs | 44 ++++++++++---------- src/entity/column.rs | 48 +++++++++++----------- src/executor/insert.rs | 2 +- src/executor/update.rs | 2 +- src/query/combine.rs | 2 +- src/query/helper.rs | 2 +- src/query/insert.rs | 2 +- src/query/join.rs | 2 +- src/query/select.rs | 2 +- src/query/update.rs | 4 +- tests/common/features/collection.rs | 4 +- 11 files changed, 57 insertions(+), 57 deletions(-) diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 931a713ca..c744ccd18 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -63,8 +63,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res // generate Column enum and it's ColumnTrait impl let mut columns_enum: Punctuated<_, Comma> = Punctuated::new(); let mut columns_trait: Punctuated<_, Comma> = Punctuated::new(); - let mut cast_selects: Punctuated<_, Comma> = Punctuated::new(); - let mut cast_values: Punctuated<_, Comma> = Punctuated::new(); + let mut columns_select_as: Punctuated<_, Comma> = Punctuated::new(); + let mut columns_save_as: Punctuated<_, Comma> = Punctuated::new(); let mut primary_keys: Punctuated<_, Comma> = Punctuated::new(); let mut primary_key_types: Punctuated<_, Comma> = Punctuated::new(); let mut auto_increment = true; @@ -92,8 +92,8 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res let mut nullable = false; let mut default_value = None; let mut default_expr = None; - let mut cast_select = None; - let mut cast_value = None; + let mut select_as = None; + let mut save_as = None; let mut indexed = false; let mut ignore = false; let mut unique = false; @@ -173,22 +173,22 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res format!("Invalid enum_name {:?}", nv.lit), )); } - } else if name == "cast_select" { + } else if name == "select_as" { if let Lit::Str(litstr) = &nv.lit { - cast_select = Some(litstr.value()); + select_as = Some(litstr.value()); } else { return Err(Error::new( field.span(), - format!("Invalid cast_select {:?}", nv.lit), + format!("Invalid select_as {:?}", nv.lit), )); } - } else if name == "cast_value" { + } else if name == "save_as" { if let Lit::Str(litstr) = &nv.lit { - cast_value = Some(litstr.value()); + save_as = Some(litstr.value()); } else { return Err(Error::new( field.span(), - format!("Invalid cast_value {:?}", nv.lit), + format!("Invalid save_as {:?}", nv.lit), )); } } @@ -246,19 +246,19 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res }); } - if let Some(cast_select) = cast_select { - cast_selects.push(quote! { + if let Some(select_as) = select_as { + columns_select_as.push(quote! { Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as( Into::::into(expr), - sea_orm::sea_query::Alias::new(&#cast_select), + sea_orm::sea_query::Alias::new(&#select_as), ), }); } - if let Some(cast_value) = cast_value { - cast_values.push(quote! { + if let Some(save_as) = save_as { + columns_save_as.push(quote! { Self::#field_name => sea_orm::sea_query::SimpleExpr::cast_as( Into::::into(val), - sea_orm::sea_query::Alias::new(&#cast_value), + sea_orm::sea_query::Alias::new(&#save_as), ), }); } @@ -387,17 +387,17 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res } } - fn cast_select(&self, expr: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { + fn select_as(&self, expr: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { match self { - #cast_selects - _ => sea_orm::prelude::ColumnTrait::cast_select_enum(self, expr), + #columns_select_as + _ => sea_orm::prelude::ColumnTrait::select_enum_as(self, expr), } } - fn cast_value(&self, val: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { + fn save_as(&self, val: sea_orm::sea_query::Expr) -> sea_orm::sea_query::SimpleExpr { match self { - #cast_values - _ => sea_orm::prelude::ColumnTrait::cast_value_enum(self, val), + #columns_save_as + _ => sea_orm::prelude::ColumnTrait::save_enum_as(self, val), } } } diff --git a/src/entity/column.rs b/src/entity/column.rs index 47d13edc8..67388a116 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -136,7 +136,7 @@ macro_rules! bind_oper_with_enum_casting { where V: Into, { - let expr = self.cast_value(Expr::val(v)); + let expr = self.save_as(Expr::val(v)); Expr::tbl(self.entity_name(), *self).binary(BinOper::$bin_op, expr) } }; @@ -343,13 +343,13 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { /// Cast column expression used in select statement. /// By default it only cast database enum as text. - fn cast_select(&self, expr: Expr) -> SimpleExpr { - self.cast_select_enum(expr) + fn select_as(&self, expr: Expr) -> SimpleExpr { + self.select_enum_as(expr) } /// Cast enum column as text - fn cast_select_enum(&self, expr: Expr) -> SimpleExpr { - cast_enum_text_inner(expr, self, |col, _, col_type| { + fn select_enum_as(&self, expr: Expr) -> SimpleExpr { + cast_enum_as(expr, self, |col, _, col_type| { let type_name = match col_type { ColumnType::Array(_) => TextArray.into_iden(), _ => Text.into_iden(), @@ -360,13 +360,13 @@ pub trait ColumnTrait: IdenStatic + Iterable + FromStr { /// Cast value of a column into the correct type for database storage. /// By default it only cast text as enum type if it's an enum column. - fn cast_value(&self, val: Expr) -> SimpleExpr { - self.cast_value_enum(val) + fn save_as(&self, val: Expr) -> SimpleExpr { + self.save_enum_as(val) } /// Cast value of a enum column as enum type - fn cast_value_enum(&self, val: Expr) -> SimpleExpr { - cast_enum_text_inner(val, self, |col, enum_name, col_type| { + fn save_enum_as(&self, val: Expr) -> SimpleExpr { + cast_enum_as(val, self, |col, enum_name, col_type| { let type_name = match col_type { ColumnType::Array(_) => { Alias::new(&format!("{}[]", enum_name.to_string())).into_iden() @@ -557,7 +557,7 @@ struct Text; #[iden = "text[]"] struct TextArray; -fn cast_enum_text_inner(expr: Expr, col: &C, f: F) -> SimpleExpr +fn cast_enum_as(expr: Expr, col: &C, f: F) -> SimpleExpr where C: ColumnTrait, F: Fn(Expr, DynIden, &ColumnType) -> SimpleExpr, @@ -1077,7 +1077,7 @@ mod tests { #[test] #[cfg(feature = "macros")] - fn cast_select_1() { + fn select_as_1() { use crate::{ActiveModelTrait, ActiveValue, Update}; mod hello_expanded { @@ -1124,13 +1124,13 @@ mod tests { } } - fn cast_select(&self, expr: Expr) -> SimpleExpr { + fn select_as(&self, expr: Expr) -> SimpleExpr { match self { Self::Two => SimpleExpr::cast_as( Into::::into(expr), Alias::new("integer"), ), - _ => self.cast_select_enum(expr), + _ => self.select_enum_as(expr), } } } @@ -1166,7 +1166,7 @@ mod tests { pub id: i32, #[sea_orm(enum_name = "One1")] pub one: i32, - #[sea_orm(cast_select = "integer")] + #[sea_orm(select_as = "integer")] pub two: i32, #[sea_orm(enum_name = "Three3")] pub three: i32, @@ -1211,7 +1211,7 @@ mod tests { #[test] #[cfg(feature = "macros")] - fn cast_value_1() { + fn save_as_1() { use crate::{ActiveModelTrait, ActiveValue, Update}; mod hello_expanded { @@ -1258,12 +1258,12 @@ mod tests { } } - fn cast_value(&self, expr: Expr) -> SimpleExpr { + fn save_as(&self, expr: Expr) -> SimpleExpr { match self { Self::Two => { SimpleExpr::cast_as(Into::::into(expr), Alias::new("text")) } - _ => self.cast_value_enum(expr), + _ => self.save_enum_as(expr), } } } @@ -1299,7 +1299,7 @@ mod tests { pub id: i32, #[sea_orm(enum_name = "One1")] pub one: i32, - #[sea_orm(cast_value = "text")] + #[sea_orm(save_as = "text")] pub two: i32, #[sea_orm(enum_name = "Three3")] pub three: i32, @@ -1344,7 +1344,7 @@ mod tests { #[test] #[cfg(feature = "macros")] - fn cast_select_and_value_1() { + fn select_as_and_value_1() { use crate::{ActiveModelTrait, ActiveValue, Update}; mod hello_expanded { @@ -1391,22 +1391,22 @@ mod tests { } } - fn cast_select(&self, expr: Expr) -> SimpleExpr { + fn select_as(&self, expr: Expr) -> SimpleExpr { match self { Self::Two => SimpleExpr::cast_as( Into::::into(expr), Alias::new("integer"), ), - _ => self.cast_select_enum(expr), + _ => self.select_enum_as(expr), } } - fn cast_value(&self, expr: Expr) -> SimpleExpr { + fn save_as(&self, expr: Expr) -> SimpleExpr { match self { Self::Two => { SimpleExpr::cast_as(Into::::into(expr), Alias::new("text")) } - _ => self.cast_value_enum(expr), + _ => self.save_enum_as(expr), } } } @@ -1442,7 +1442,7 @@ mod tests { pub id: i32, #[sea_orm(enum_name = "One1")] pub one: i32, - #[sea_orm(cast_select = "integer", cast_value = "text")] + #[sea_orm(select_as = "integer", save_as = "text")] pub two: i32, #[sea_orm(enum_name = "Three3")] pub three: i32, diff --git a/src/executor/insert.rs b/src/executor/insert.rs index d25b22b8f..854549ad4 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -186,7 +186,7 @@ where let found = match db.support_returning() { true => { let returning = Query::returning().exprs( - ::Column::iter().map(|c| c.cast_select(Expr::col(c))), + ::Column::iter().map(|c| c.select_as(Expr::col(c))), ); insert_statement.returning(returning); SelectorRaw::::Model>>::from_statement( diff --git a/src/executor/update.rs b/src/executor/update.rs index 5c4649f71..6d1237879 100644 --- a/src/executor/update.rs +++ b/src/executor/update.rs @@ -92,7 +92,7 @@ where match db.support_returning() { true => { let returning = Query::returning().exprs( - ::Column::iter().map(|c| c.cast_select(Expr::col(c))), + ::Column::iter().map(|c| c.select_as(Expr::col(c))), ); query.returning(returning); let db_backend = db.get_database_backend(); diff --git a/src/query/combine.rs b/src/query/combine.rs index 7eb2eaccb..99f2d8021 100644 --- a/src/query/combine.rs +++ b/src/query/combine.rs @@ -148,7 +148,7 @@ where for col in ::iter() { let alias = format!("{}{}", SelectB.as_str(), col.as_str()); selector.query().expr(SelectExpr { - expr: col.cast_select(col.into_expr()), + expr: col.select_as(col.into_expr()), alias: Some(SeaRc::new(Alias::new(&alias))), window: None, }); diff --git a/src/query/helper.rs b/src/query/helper.rs index 0bac74f86..53ca0e022 100644 --- a/src/query/helper.rs +++ b/src/query/helper.rs @@ -67,7 +67,7 @@ pub trait QuerySelect: Sized { where C: ColumnTrait, { - self.query().expr(col.cast_select(col.into_expr())); + self.query().expr(col.select_as(col.into_expr())); self } diff --git a/src/query/insert.rs b/src/query/insert.rs index 0c1044e9d..a3a78e1e9 100644 --- a/src/query/insert.rs +++ b/src/query/insert.rs @@ -134,7 +134,7 @@ where } if av_has_val { columns.push(col); - values.push(col.cast_value(Expr::val(av.into_value().unwrap()))); + values.push(col.save_as(Expr::val(av.into_value().unwrap()))); } } self.query.columns(columns); diff --git a/src/query/join.rs b/src/query/join.rs index d91df6eb2..618fd1d3b 100644 --- a/src/query/join.rs +++ b/src/query/join.rs @@ -100,7 +100,7 @@ where col.into_iden(), ); select_two.query().expr(SelectExpr { - expr: col.cast_select(expr), + expr: col.select_as(expr), alias: Some(SeaRc::new(Alias::new(&alias))), window: None, }); diff --git a/src/query/select.rs b/src/query/select.rs index 5f1006e80..4942c96eb 100644 --- a/src/query/select.rs +++ b/src/query/select.rs @@ -120,7 +120,7 @@ where fn column_list(&self) -> Vec { E::Column::iter() - .map(|col| col.cast_select(col.into_expr())) + .map(|col| col.select_as(col.into_expr())) .collect() } diff --git a/src/query/update.rs b/src/query/update.rs index 705d4a969..b98d93b92 100644 --- a/src/query/update.rs +++ b/src/query/update.rs @@ -109,7 +109,7 @@ where } let av = self.model.get(col); if av.is_set() { - let expr = col.cast_value(Expr::val(av.into_value().unwrap())); + let expr = col.save_as(Expr::val(av.into_value().unwrap())); self.query.value(col, expr); } } @@ -189,7 +189,7 @@ where for col in E::Column::iter() { let av = model.get(col); if av.is_set() { - let expr = col.cast_value(Expr::val(av.into_value().unwrap())); + let expr = col.save_as(Expr::val(av.into_value().unwrap())); self.query.value(col, expr); } } diff --git a/tests/common/features/collection.rs b/tests/common/features/collection.rs index f42d721ca..fb09e29d3 100644 --- a/tests/common/features/collection.rs +++ b/tests/common/features/collection.rs @@ -8,8 +8,8 @@ pub struct Model { pub id: i32, #[sea_orm( column_type = r#"Custom("citext".into())"#, - cast_select = "text", - cast_value = "citext" + select_as = "text", + save_as = "citext" )] pub name: String, pub integers: Vec,