From f809242c1fd71b6dbc57498bbc3d6eed628c36e7 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Tue, 16 Nov 2021 18:40:37 +0800 Subject: [PATCH 1/4] Test [issues] --- .github/workflows/rust.yml | 2 +- issues/324/Cargo.toml | 11 +++ issues/324/src/main.rs | 3 + issues/324/src/model.rs | 83 ++++++++++++++++++++++ sea-orm-macros/src/derives/entity_model.rs | 5 +- 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 issues/324/Cargo.toml create mode 100644 issues/324/src/main.rs create mode 100644 issues/324/src/model.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 40c20d01..e98024b9 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -314,7 +314,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] - path: [86, 249, 262, 319] + path: [86, 249, 262, 319, 324] steps: - uses: actions/checkout@v2 diff --git a/issues/324/Cargo.toml b/issues/324/Cargo.toml new file mode 100644 index 00000000..9effe6d2 --- /dev/null +++ b/issues/324/Cargo.toml @@ -0,0 +1,11 @@ +[workspace] +# A separate workspace + +[package] +name = "sea-orm-issues-324" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +sea-orm = { path = "../../", features = [ "sqlx-mysql", "runtime-async-std-native-tls" ]} diff --git a/issues/324/src/main.rs b/issues/324/src/main.rs new file mode 100644 index 00000000..a9db43c3 --- /dev/null +++ b/issues/324/src/main.rs @@ -0,0 +1,3 @@ +mod model; + +pub fn main() {} diff --git a/issues/324/src/model.rs b/issues/324/src/model.rs new file mode 100644 index 00000000..9ec35a07 --- /dev/null +++ b/issues/324/src/model.rs @@ -0,0 +1,83 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "model")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: AccountId, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} + +#[derive(Clone, Debug, PartialEq)] +pub struct AccountId(Uuid); + +impl From for Uuid { + fn from(account_id: AccountId) -> Self { + account_id.0 + } +} + +macro_rules! impl_try_from_u64_err { + ($newtype: ident) => { + impl sea_orm::TryFromU64 for $newtype { + fn try_from_u64(_n: u64) -> Result { + Err(sea_orm::DbErr::Exec(format!( + "{} cannot be converted from u64", + stringify!($newtype) + ))) + } + } + }; +} + +macro_rules! into_sea_query_value { + ($newtype: ident: Box($name: ident)) => { + impl From<$newtype> for sea_orm::Value { + fn from(source: $newtype) -> Self { + sea_orm::Value::$name(Some(Box::new(source.into()))) + } + } + + impl sea_orm::TryGetable for $newtype { + fn try_get( + res: &sea_orm::QueryResult, + pre: &str, + col: &str, + ) -> Result { + let val: $name = res.try_get(pre, col).map_err(sea_orm::TryGetError::DbErr)?; + Ok($newtype(val)) + } + } + + impl sea_orm::sea_query::Nullable for $newtype { + fn null() -> sea_orm::Value { + sea_orm::Value::$name(None) + } + } + + impl sea_orm::sea_query::ValueType for $newtype { + fn try_from(v: sea_orm::Value) -> Result { + match v { + sea_orm::Value::$name(Some(x)) => Ok($newtype(*x)), + _ => Err(sea_orm::sea_query::ValueTypeErr), + } + } + + fn type_name() -> String { + stringify!($newtype).to_owned() + } + + fn column_type() -> sea_orm::sea_query::ColumnType { + sea_orm::sea_query::ColumnType::$name + } + } + }; +} + +into_sea_query_value!(AccountId: Box(Uuid)); +impl_try_from_u64_err!(AccountId); diff --git a/sea-orm-macros/src/derives/entity_model.rs b/sea-orm-macros/src/derives/entity_model.rs index 5f1508ef..e39fecf1 100644 --- a/sea-orm-macros/src/derives/entity_model.rs +++ b/sea-orm-macros/src/derives/entity_model.rs @@ -237,7 +237,10 @@ pub fn expand_derive_entity_model(data: Data, attrs: Vec) -> syn::Res let field_span = field.span(); let ty = format_ident!("{}", temp); let def = quote_spanned! { field_span => { - <#ty as ActiveEnum>::db_type() + std::convert::Into::::into( + <#ty as sea_orm::sea_query::ValueType>::column_type() + ) + .def() }}; quote! { #def } } else { From cef51ddd3f7675e92a6086f43908d55df3ddae8d Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Tue, 16 Nov 2021 18:45:21 +0800 Subject: [PATCH 2/4] Use SeaQL/sea-query#188 --- Cargo.toml | 2 +- src/entity/column.rs | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 46d972dd..c6d6d335 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.18.0", git = "https://github.com/SeaQL/sea-query.git", features = ["thread-safe"] } +sea-query = { version = "^0.18.0", git = "https://github.com/SeaQL/sea-query.git", branch = "enum-column-type", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true } diff --git a/src/entity/column.rs b/src/entity/column.rs index d5234b31..f2df4b2f 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -364,10 +364,13 @@ impl From for sea_query::ColumnType { ColumnType::Money(s) => sea_query::ColumnType::Money(s), ColumnType::Json => sea_query::ColumnType::Json, ColumnType::JsonBinary => sea_query::ColumnType::JsonBinary, - ColumnType::Custom(s) | ColumnType::Enum(s, _) => { + 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, variants) + } } } } @@ -398,6 +401,7 @@ impl From for ColumnType { sea_query::ColumnType::JsonBinary => Self::JsonBinary, sea_query::ColumnType::Custom(s) => Self::Custom(s.to_string()), sea_query::ColumnType::Uuid => Self::Uuid, + sea_query::ColumnType::Enum(name, variants) => Self::Enum(name, variants), _ => unimplemented!(), } } From 0f904e02f02f7613a13ac2477013803a8ead0a41 Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Wed, 17 Nov 2021 10:38:02 +0800 Subject: [PATCH 3/4] Refactoring --- src/entity/column.rs | 4 +--- tests/common/features/schema.rs | 14 +++++--------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/entity/column.rs b/src/entity/column.rs index f2df4b2f..8beb465b 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -368,9 +368,7 @@ impl From for sea_query::ColumnType { 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, variants) - } + ColumnType::Enum(name, variants) => sea_query::ColumnType::Enum(name, variants), } } } diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 94277604..b50b6a25 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -127,24 +127,17 @@ pub async fn create_byte_primary_key_table(db: &DbConn) -> Result Result { let db_backend = db.get_database_backend(); - let tea_enum = Alias::new("tea"); let create_enum_stmts = match db_backend { DbBackend::MySql | DbBackend::Sqlite => Vec::new(), DbBackend::Postgres => vec![Type::create() - .as_enum(tea_enum.clone()) + .as_enum(Alias::new("tea")) .values(vec![Alias::new("EverydayTea"), Alias::new("BreakfastTea")]) .to_owned()], }; create_enum(db, &create_enum_stmts, ActiveEnum).await?; - let mut tea_col = ColumnDef::new(active_enum::Column::Tea); - match db_backend { - DbBackend::MySql => tea_col.custom(Alias::new("ENUM('EverydayTea', 'BreakfastTea')")), - DbBackend::Sqlite => tea_col.text(), - DbBackend::Postgres => tea_col.custom(tea_enum), - }; let create_table_stmt = sea_query::Table::create() .table(active_enum::Entity) .col( @@ -156,7 +149,10 @@ pub async fn create_active_enum_table(db: &DbConn) -> Result ) .col(ColumnDef::new(active_enum::Column::Category).string_len(1)) .col(ColumnDef::new(active_enum::Column::Color).integer()) - .col(&mut tea_col) + .col( + ColumnDef::new(active_enum::Column::Tea) + .enumeration("tea", vec!["EverydayTea", "BreakfastTea"]), + ) .to_owned(); create_table(db, &create_table_stmt, ActiveEnum).await From a81fb109288407d862c8fd43eac18551be7a4c5a Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Wed, 17 Nov 2021 16:34:30 +0800 Subject: [PATCH 4/4] Revert sea-query --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c6d6d335..46d972dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ futures-util = { version = "^0.3" } log = { version = "^0.4", optional = true } rust_decimal = { version = "^1", optional = true } sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true } -sea-query = { version = "^0.18.0", git = "https://github.com/SeaQL/sea-query.git", branch = "enum-column-type", features = ["thread-safe"] } +sea-query = { version = "^0.18.0", git = "https://github.com/SeaQL/sea-query.git", features = ["thread-safe"] } sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1", optional = true }