From 866025a733e7a7208bb238368a6262ecb8df59b6 Mon Sep 17 00:00:00 2001 From: darkmmon Date: Thu, 13 Jul 2023 16:28:35 +0800 Subject: [PATCH 1/3] implement DeriveIden in sea-orm only (#1740) * WIP, implementing Iden * completed implementation for DeriveIden and added basic test cases * added feature flag to prevent sea-orm::sea-query::DeriveIden from crashing when sea-query is not used * fixed doc test and adjusted test case * enable `sea-query-derive`'s `sea-orm` feature * Bump `sea-query-derive` to v0.4 * Update Cargo.toml * Update Cargo.toml * adjusted test cases and updated so that iden attribute will not be snake cased * Update Cargo.toml * Update main.rs --------- Co-authored-by: Billy Chan Co-authored-by: Chris Tsang --- Cargo.toml | 2 +- issues/1473/Cargo.toml | 13 ++ issues/1473/src/main.rs | 17 +++ sea-orm-macros/src/derives/derive_iden.rs | 146 ++++++++++++++++++++++ sea-orm-macros/src/derives/mod.rs | 2 + sea-orm-macros/src/lib.rs | 42 +++++++ src/entity/column.rs | 2 +- src/lib.rs | 8 +- tests/derive_iden_tests.rs | 46 +++++++ 9 files changed, 271 insertions(+), 7 deletions(-) create mode 100644 issues/1473/Cargo.toml create mode 100644 issues/1473/src/main.rs create mode 100644 sea-orm-macros/src/derives/derive_iden.rs create mode 100644 tests/derive_iden_tests.rs diff --git a/Cargo.toml b/Cargo.toml index bc04951e0..d42f79e17 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ tracing = { version = "0.1", default-features = false, features = ["attributes", rust_decimal = { version = "1", default-features = false, optional = true } bigdecimal = { version = "0.3", default-features = false, optional = true } sea-orm-macros = { version = "0.12.0-rc.4", path = "sea-orm-macros", default-features = false, features = ["strum"] } -sea-query = { version = "0.29.0-rc.2", features = ["thread-safe", "hashable-value"] } +sea-query = { version = "0.29.0", features = ["thread-safe", "hashable-value"] } sea-query-binder = { version = "0.4.0-rc.2", default-features = false, optional = true } strum = { version = "0.25", default-features = false } serde = { version = "1.0", default-features = false } diff --git a/issues/1473/Cargo.toml b/issues/1473/Cargo.toml new file mode 100644 index 000000000..ae5bdae57 --- /dev/null +++ b/issues/1473/Cargo.toml @@ -0,0 +1,13 @@ +[workspace] +# A separate workspace + +[package] +name = "sea-orm-issues-1473" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies.sea-orm] +path = "../../" +default-features = false +features = ["macros", "runtime-tokio-native-tls"] diff --git a/issues/1473/src/main.rs b/issues/1473/src/main.rs new file mode 100644 index 000000000..ed691b825 --- /dev/null +++ b/issues/1473/src/main.rs @@ -0,0 +1,17 @@ +use sea_orm::{sea_query::{self, Iden}}; + +#[derive(Iden)] +enum Character { + Table, + Id, +} + +#[derive(Iden)] +struct Glyph; + +fn main() { + assert_eq!(Character::Table.to_string(), "character"); + assert_eq!(Character::Id.to_string(), "id"); + + assert_eq!(Glyph.to_string(), "glyph"); +} diff --git a/sea-orm-macros/src/derives/derive_iden.rs b/sea-orm-macros/src/derives/derive_iden.rs new file mode 100644 index 000000000..026a97b1c --- /dev/null +++ b/sea-orm-macros/src/derives/derive_iden.rs @@ -0,0 +1,146 @@ +use heck::ToSnakeCase; +use proc_macro2::{self, TokenStream}; +use quote::{quote, quote_spanned}; +use syn::{ + punctuated::Punctuated, DataEnum, DataStruct, DeriveInput, Expr, Fields, LitStr, Variant, +}; + +fn must_be_valid_iden(name: &str) -> bool { + // can only begin with [a-z_] + name.chars() + .take(1) + .all(|c| c == '_' || c.is_ascii_alphabetic()) + && name.chars().all(|c| c == '_' || c.is_ascii_alphanumeric()) +} + +fn impl_iden_for_unit_struct( + ident: &proc_macro2::Ident, + new_iden: &str, +) -> proc_macro2::TokenStream { + let prepare = if must_be_valid_iden(new_iden) { + quote! { + fn prepare(&self, s: &mut dyn ::std::fmt::Write, q: sea_orm::sea_query::Quote) { + write!(s, "{}", q.left()).unwrap(); + self.unquoted(s); + write!(s, "{}", q.right()).unwrap(); + } + } + } else { + quote! {} + }; + quote! { + impl sea_orm::sea_query::Iden for #ident { + #prepare + + fn unquoted(&self, s: &mut dyn ::std::fmt::Write) { + write!(s, #new_iden).unwrap(); + } + } + } +} + +fn impl_iden_for_enum( + ident: &proc_macro2::Ident, + variants: Punctuated, +) -> proc_macro2::TokenStream { + let variants = variants.iter(); + let mut all_valid = true; + + let match_pair: Vec = variants + .map(|v| { + let var_ident = &v.ident; + let mut var_name = var_ident.to_string().to_snake_case(); + v.attrs + .iter() + .filter(|attr| attr.path().is_ident("sea_orm")) + .try_for_each(|attr| { + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("iden") { + let litstr: LitStr = meta.value()?.parse()?; + var_name = litstr.value(); + all_valid &= must_be_valid_iden(var_name.as_str()); + } else { + // Reads the value expression to advance the parse stream. + // Some parameters do not have any value, + // so ignoring an error occurred here. + let _: Option = meta.value().and_then(|v| v.parse()).ok(); + } + Ok(()) + }) + }) + .expect("something something"); + quote! { Self::#var_ident => write!(s, "{}", #var_name).unwrap() } + }) + .collect(); + + let match_arms: TokenStream = quote! { #(#match_pair),* }; + + let prepare = if all_valid { + quote! { + fn prepare(&self, s: &mut dyn ::std::fmt::Write, q: sea_orm::sea_query::Quote) { + write!(s, "{}", q.left()).unwrap(); + self.unquoted(s); + write!(s, "{}", q.right()).unwrap(); + } + } + } else { + quote! {} + }; + + quote! { + impl sea_orm::sea_query::Iden for #ident { + #prepare + + fn unquoted(&self, s: &mut dyn ::std::fmt::Write) { + match self { + #match_arms + }; + } + } + } +} + +pub fn expand_derive_iden(input: DeriveInput) -> syn::Result { + let DeriveInput { ident, data, .. } = input; + + let mut new_iden: TokenStream = ident.to_string().to_snake_case().parse().unwrap(); + input + .attrs + .iter() + .filter(|attr| attr.path().is_ident("sea_orm")) + .try_for_each(|attr| { + attr.parse_nested_meta(|meta| { + if meta.path.is_ident("iden") { + let litstr: LitStr = meta.value()?.parse()?; + new_iden = syn::parse_str::(&litstr.value())?; + } else { + // Reads the value expression to advance the parse stream. + // Some parameters do not have any value, + // so ignoring an error occurred here. + let _: Option = meta.value().and_then(|v| v.parse()).ok(); + } + Ok(()) + }) + })?; + + // Currently we only support enums and unit structs + match data { + syn::Data::Enum(DataEnum { variants, .. }) => { + if variants.is_empty() { + Ok(TokenStream::new()) + } else { + Ok(impl_iden_for_enum(&ident, variants)) + } + } + syn::Data::Struct(DataStruct { + fields: Fields::Unit, + .. + }) => Ok(impl_iden_for_unit_struct( + &ident, + new_iden.to_string().as_str(), + )), + _ => Ok(quote_spanned! { + ident.span() => compile_error!("you can only derive DeriveIden on unit struct or enum"); + }), + } +} diff --git a/sea-orm-macros/src/derives/mod.rs b/sea-orm-macros/src/derives/mod.rs index 168f94eeb..cc63ebb65 100644 --- a/sea-orm-macros/src/derives/mod.rs +++ b/sea-orm-macros/src/derives/mod.rs @@ -4,6 +4,7 @@ mod active_model; mod active_model_behavior; mod attributes; mod column; +mod derive_iden; mod entity; mod entity_model; mod from_query_result; @@ -24,6 +25,7 @@ pub use active_enum_display::*; pub use active_model::*; pub use active_model_behavior::*; pub use column::*; +pub use derive_iden::*; pub use entity::*; pub use entity_model::*; pub use from_query_result::*; diff --git a/sea-orm-macros/src/lib.rs b/sea-orm-macros/src/lib.rs index c9d84d4a3..85a9fee62 100644 --- a/sea-orm-macros/src/lib.rs +++ b/sea-orm-macros/src/lib.rs @@ -852,3 +852,45 @@ pub fn derive_active_enum_display(input: TokenStream) -> TokenStream { Err(e) => e.to_compile_error().into(), } } + +/// The DeriveIden derive macro will implement `sea_orm::sea_query::Iden` for simplify Iden implementation. +/// +/// ## Usage +/// +/// ```rust +/// use sea_orm::DeriveIden; +/// +/// #[derive(DeriveIden)] +/// pub enum Class { +/// Id, +/// Title, +/// Text, +/// } +/// +/// #[derive(DeriveIden)] +/// struct Glyph; +/// ``` +/// +/// You can use iden = "" to customize the name +/// ``` +/// use sea_orm::DeriveIden; +/// +/// #[derive(DeriveIden)] +/// pub enum Class { +/// Id, +/// #[sea_orm(iden = "turtle")] +/// Title, +/// #[sea_orm(iden = "TeXt")] +/// Text, +/// } +/// ``` +#[cfg(feature = "derive")] +#[proc_macro_derive(DeriveIden, attributes(sea_orm))] +pub fn derive_iden(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + + match derives::expand_derive_iden(derive_input) { + Ok(token_stream) => token_stream.into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/src/entity/column.rs b/src/entity/column.rs index e2ade89b5..b85bcb612 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -1,4 +1,4 @@ -use crate::{EntityName, IdenStatic, IntoSimpleExpr, Iterable}; +use crate::{self as sea_orm, EntityName, IdenStatic, IntoSimpleExpr, Iterable}; use sea_query::{ Alias, BinOper, DynIden, Expr, Iden, IntoIden, SeaRc, SelectStatement, SimpleExpr, Value, }; diff --git a/src/lib.rs b/src/lib.rs index c01c2fe75..cdf5bb3da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -349,15 +349,13 @@ pub use schema::*; #[cfg(feature = "macros")] pub use sea_orm_macros::{ DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, - DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIntoActiveModel, - DeriveMigrationName, DeriveModel, DerivePartialModel, DerivePrimaryKey, DeriveRelatedEntity, - DeriveRelation, FromJsonQueryResult, FromQueryResult, + DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden, + DeriveIntoActiveModel, DeriveMigrationName, DeriveModel, DerivePartialModel, DerivePrimaryKey, + DeriveRelatedEntity, DeriveRelation, FromJsonQueryResult, FromQueryResult, }; pub use sea_query; pub use sea_query::Iden; -#[cfg(feature = "macros")] -pub use sea_query::Iden as DeriveIden; pub use sea_orm_macros::EnumIter; pub use strum; diff --git a/tests/derive_iden_tests.rs b/tests/derive_iden_tests.rs new file mode 100644 index 000000000..707a69f1f --- /dev/null +++ b/tests/derive_iden_tests.rs @@ -0,0 +1,46 @@ +pub mod common; +pub use common::{features::*, setup::*, TestContext}; +use sea_orm::entity::prelude::*; +use sea_orm_macros::DeriveIden; + +#[derive(DeriveIden)] +pub enum Class { + Id, + Title, + Text, +} + +#[derive(DeriveIden)] +pub enum Book { + Id, + #[sea_orm(iden = "turtle")] + Title, + #[sea_orm(iden = "TeXt")] + Text, + #[sea_orm(iden = "ty_pe")] + Type, +} + +#[derive(DeriveIden)] +struct Glyph; + +#[derive(DeriveIden)] +#[sea_orm(iden = "weRd")] +struct Word; + +#[test] +fn main() -> Result<(), DbErr> { + assert_eq!(Class::Id.to_string(), "id"); + assert_eq!(Class::Title.to_string(), "title"); + assert_eq!(Class::Text.to_string(), "text"); + + assert_eq!(Book::Id.to_string(), "id"); + assert_eq!(Book::Title.to_string(), "turtle"); + assert_eq!(Book::Text.to_string(), "TeXt"); + assert_eq!(Book::Type.to_string(), "ty_pe"); + + assert_eq!(Glyph.to_string(), "glyph"); + + assert_eq!(Word.to_string(), "weRd"); + Ok(()) +} From ae899d67441ea54cc62aae75b757614278f9789b Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 13 Jul 2023 10:25:59 +0100 Subject: [PATCH 2/3] Remove sea-query's Iden macro --- CHANGELOG.md | 28 +++++++++++++++++++ Cargo.toml | 4 +-- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220101_000001_create_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- .../src/m20220120_000001_create_post_table.rs | 3 +- issues/1473/Cargo.toml | 2 +- issues/1473/src/main.rs | 7 ++--- .../src/m20220101_000001_create_table.rs | 3 +- sea-orm-migration/src/migrator.rs | 21 +++++++------- sea-orm-migration/src/prelude.rs | 2 +- .../m20220118_000001_create_cake_table.rs | 3 +- .../m20220118_000002_create_fruit_table.rs | 3 +- .../m20220118_000004_create_tea_enum.rs | 7 ++--- .../m20220923_000001_seed_cake_table.rs | 3 +- src/entity/active_enum.rs | 6 ++-- src/entity/column.rs | 20 +++++++++---- src/entity/prelude.rs | 5 ++-- 24 files changed, 83 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 915008b78..0bd07bba9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -548,6 +548,34 @@ impl ColumnTrait for Column { * Replace the use of `SeaRc` where `T` isn't `dyn Iden` with `RcOrArc` https://github.com/SeaQL/sea-orm/pull/1661 * Enabled `hashable-value` feature in SeaQuery, thus `Value::Float(NaN) == Value::Float(NaN)` would be true https://github.com/SeaQL/sea-orm/pull/1728, https://github.com/SeaQL/sea-orm/pull/1743 * The `DeriveActiveEnum` derive macro no longer provide `std::fmt::Display` implementation for the enum. You need to derive an extra `DeriveDisplay` macro alongside with `DeriveActiveEnum` derive macro. https://github.com/SeaQL/sea-orm/pull/1726 +* `sea-query/derive` is no longer enabled by `sea-orm`, as such, `Iden` no longer works as a derive macro (it's still a trait). Instead, we are shipping a new macro `DeriveIden`: +```rust +// then: + +#[derive(Iden)] +#[iden = "category"] +pub struct CategoryEnum; + +#[derive(Iden)] +pub enum Tea { + Table, + #[iden = "EverydayTea"] + EverydayTea, +} + +// now: + +#[derive(DeriveIden)] +#[sea_orm(iden = "category")] +pub struct CategoryEnum; + +#[derive(DeriveIden)] +pub enum Tea { + Table, + #[sea_orm(iden = "EverydayTea")] + EverydayTea, +} +``` ## 0.11.3 - 2023-04-24 diff --git a/Cargo.toml b/Cargo.toml index d42f79e17..06f711b6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ tracing = { version = "0.1", default-features = false, features = ["attributes", rust_decimal = { version = "1", default-features = false, optional = true } bigdecimal = { version = "0.3", default-features = false, optional = true } sea-orm-macros = { version = "0.12.0-rc.4", path = "sea-orm-macros", default-features = false, features = ["strum"] } -sea-query = { version = "0.29.0", features = ["thread-safe", "hashable-value"] } +sea-query = { version = "0.29.0", default-features = false, features = ["thread-safe", "hashable-value", "backend-mysql", "backend-postgres", "backend-sqlite"] } sea-query-binder = { version = "0.4.0-rc.2", default-features = false, optional = true } strum = { version = "0.25", default-features = false } serde = { version = "1.0", default-features = false } @@ -74,7 +74,7 @@ default = [ "with-uuid", "with-time", ] -macros = ["sea-orm-macros/derive", "sea-query/derive"] +macros = ["sea-orm-macros/derive"] mock = [] with-json = ["serde_json", "sea-query/with-json", "chrono?/serde", "time?/serde", "uuid?/serde", "sea-query-binder?/with-json", "sqlx?/json"] with-chrono = ["chrono", "sea-query/with-chrono", "sea-query-binder?/with-chrono", "sqlx?/chrono"] diff --git a/examples/actix3_example/migration/src/m20220120_000001_create_post_table.rs b/examples/actix3_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/actix3_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/actix3_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/actix_example/migration/src/m20220120_000001_create_post_table.rs b/examples/actix_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/actix_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/actix_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/axum_example/migration/src/m20220120_000001_create_post_table.rs b/examples/axum_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/axum_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/axum_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/graphql_example/migration/src/m20220101_000001_create_table.rs b/examples/graphql_example/migration/src/m20220101_000001_create_table.rs index b7ec5a4d6..22d0f82d0 100644 --- a/examples/graphql_example/migration/src/m20220101_000001_create_table.rs +++ b/examples/graphql_example/migration/src/m20220101_000001_create_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Notes { Table, Id, diff --git a/examples/jsonrpsee_example/migration/src/m20220120_000001_create_post_table.rs b/examples/jsonrpsee_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/jsonrpsee_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/jsonrpsee_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/poem_example/migration/src/m20220120_000001_create_post_table.rs b/examples/poem_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/poem_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/poem_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/rocket_example/migration/src/m20220120_000001_create_post_table.rs b/examples/rocket_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/rocket_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/rocket_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/rocket_okapi_example/migration/src/m20220120_000001_create_post_table.rs b/examples/rocket_okapi_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/rocket_okapi_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/rocket_okapi_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/salvo_example/migration/src/m20220120_000001_create_post_table.rs b/examples/salvo_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/salvo_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/salvo_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/examples/tonic_example/migration/src/m20220120_000001_create_post_table.rs b/examples/tonic_example/migration/src/m20220120_000001_create_post_table.rs index a2fa0219c..12c9fd7d2 100644 --- a/examples/tonic_example/migration/src/m20220120_000001_create_post_table.rs +++ b/examples/tonic_example/migration/src/m20220120_000001_create_post_table.rs @@ -32,8 +32,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Posts { Table, Id, diff --git a/issues/1473/Cargo.toml b/issues/1473/Cargo.toml index ae5bdae57..84e8f1547 100644 --- a/issues/1473/Cargo.toml +++ b/issues/1473/Cargo.toml @@ -10,4 +10,4 @@ publish = false [dependencies.sea-orm] path = "../../" default-features = false -features = ["macros", "runtime-tokio-native-tls"] +features = ["macros", "runtime-tokio-native-tls"] \ No newline at end of file diff --git a/issues/1473/src/main.rs b/issues/1473/src/main.rs index ed691b825..235b85c5b 100644 --- a/issues/1473/src/main.rs +++ b/issues/1473/src/main.rs @@ -1,17 +1,16 @@ -use sea_orm::{sea_query::{self, Iden}}; +use sea_orm::{DeriveIden, Iden}; -#[derive(Iden)] +#[derive(DeriveIden)] enum Character { Table, Id, } -#[derive(Iden)] +#[derive(DeriveIden)] struct Glyph; fn main() { assert_eq!(Character::Table.to_string(), "character"); assert_eq!(Character::Id.to_string(), "id"); - assert_eq!(Glyph.to_string(), "glyph"); } diff --git a/sea-orm-cli/template/migration/src/m20220101_000001_create_table.rs b/sea-orm-cli/template/migration/src/m20220101_000001_create_table.rs index b05824463..c8f2a5d16 100644 --- a/sea-orm-cli/template/migration/src/m20220101_000001_create_table.rs +++ b/sea-orm-cli/template/migration/src/m20220101_000001_create_table.rs @@ -38,8 +38,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] enum Post { Table, Id, diff --git a/sea-orm-migration/src/migrator.rs b/sea-orm-migration/src/migrator.rs index 84adb17f1..587951ed1 100644 --- a/sea-orm-migration/src/migrator.rs +++ b/sea-orm-migration/src/migrator.rs @@ -6,12 +6,13 @@ use std::time::SystemTime; use tracing::info; use sea_orm::sea_query::{ - self, extension::postgres::Type, Alias, Expr, ForeignKey, Iden, IntoIden, JoinType, Order, - Query, SelectStatement, SimpleExpr, Table, + self, extension::postgres::Type, Alias, Expr, ForeignKey, IntoIden, JoinType, Order, Query, + SelectStatement, SimpleExpr, Table, }; use sea_orm::{ - ActiveModelTrait, ActiveValue, Condition, ConnectionTrait, DbBackend, DbErr, DynIden, - EntityTrait, FromQueryResult, Iterable, QueryFilter, Schema, Statement, TransactionTrait, + ActiveModelTrait, ActiveValue, Condition, ConnectionTrait, DbBackend, DbErr, DeriveIden, + DynIden, EntityTrait, FromQueryResult, Iterable, QueryFilter, Schema, Statement, + TransactionTrait, }; use sea_schema::{mysql::MySql, postgres::Postgres, probe::SchemaProbe, sqlite::Sqlite}; @@ -457,13 +458,13 @@ where } } -#[derive(Iden)] +#[derive(DeriveIden)] enum InformationSchema { - #[iden = "information_schema"] + #[sea_orm(iden = "information_schema")] Schema, - #[iden = "TABLE_NAME"] + #[sea_orm(iden = "TABLE_NAME")] TableName, - #[iden = "CONSTRAINT_NAME"] + #[sea_orm(iden = "CONSTRAINT_NAME")] ConstraintName, TableConstraints, TableSchema, @@ -500,7 +501,7 @@ where stmt } -#[derive(Iden)] +#[derive(DeriveIden)] enum PgType { Table, Typname, @@ -508,7 +509,7 @@ enum PgType { Typelem, } -#[derive(Iden)] +#[derive(DeriveIden)] enum PgNamespace { Table, Oid, diff --git a/sea-orm-migration/src/prelude.rs b/sea-orm-migration/src/prelude.rs index 9b1030ff3..3267b1b16 100644 --- a/sea-orm-migration/src/prelude.rs +++ b/sea-orm-migration/src/prelude.rs @@ -9,5 +9,5 @@ pub use async_trait; pub use sea_orm::{ self, sea_query::{self, *}, - ConnectionTrait, DbErr, DeriveMigrationName, + ConnectionTrait, DbErr, DeriveIden, DeriveMigrationName, }; diff --git a/sea-orm-migration/tests/common/migration/m20220118_000001_create_cake_table.rs b/sea-orm-migration/tests/common/migration/m20220118_000001_create_cake_table.rs index f06513aa6..370697fbf 100644 --- a/sea-orm-migration/tests/common/migration/m20220118_000001_create_cake_table.rs +++ b/sea-orm-migration/tests/common/migration/m20220118_000001_create_cake_table.rs @@ -38,8 +38,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] pub enum Cake { Table, Id, diff --git a/sea-orm-migration/tests/common/migration/m20220118_000002_create_fruit_table.rs b/sea-orm-migration/tests/common/migration/m20220118_000002_create_fruit_table.rs index 07ead8349..4b9ceb458 100644 --- a/sea-orm-migration/tests/common/migration/m20220118_000002_create_fruit_table.rs +++ b/sea-orm-migration/tests/common/migration/m20220118_000002_create_fruit_table.rs @@ -49,8 +49,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] pub enum Fruit { Table, Id, diff --git a/sea-orm-migration/tests/common/migration/m20220118_000004_create_tea_enum.rs b/sea-orm-migration/tests/common/migration/m20220118_000004_create_tea_enum.rs index ba9b68e6b..26661d4a1 100644 --- a/sea-orm-migration/tests/common/migration/m20220118_000004_create_tea_enum.rs +++ b/sea-orm-migration/tests/common/migration/m20220118_000004_create_tea_enum.rs @@ -42,12 +42,11 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] pub enum Tea { Table, - #[iden = "EverydayTea"] + #[sea_orm(iden = "EverydayTea")] EverydayTea, - #[iden = "BreakfastTea"] + #[sea_orm(iden = "BreakfastTea")] BreakfastTea, } diff --git a/sea-orm-migration/tests/common/migration/m20220923_000001_seed_cake_table.rs b/sea-orm-migration/tests/common/migration/m20220923_000001_seed_cake_table.rs index 16c019bf8..5ab38ebb7 100644 --- a/sea-orm-migration/tests/common/migration/m20220923_000001_seed_cake_table.rs +++ b/sea-orm-migration/tests/common/migration/m20220923_000001_seed_cake_table.rs @@ -29,8 +29,7 @@ impl MigrationTrait for Migration { } } -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] +#[derive(DeriveIden)] pub enum Cake { Table, Name, diff --git a/src/entity/active_enum.rs b/src/entity/active_enum.rs index 99e6351da..0f56bd715 100644 --- a/src/entity/active_enum.rs +++ b/src/entity/active_enum.rs @@ -37,7 +37,7 @@ use sea_query::{DynIden, Expr, Nullable, SimpleExpr, Value, ValueType}; /// Small, /// } /// -/// #[derive(Debug, Iden)] +/// #[derive(Debug, DeriveIden)] /// pub struct CategoryEnum; /// /// impl ActiveEnum for Category { @@ -182,8 +182,8 @@ mod tests { Small, } - #[derive(Debug, Iden)] - #[iden = "category"] + #[derive(Debug, DeriveIden)] + #[sea_orm(iden = "category")] pub struct CategoryEnum; impl ActiveEnum for Category { diff --git a/src/entity/column.rs b/src/entity/column.rs index b85bcb612..b263413fd 100644 --- a/src/entity/column.rs +++ b/src/entity/column.rs @@ -1,6 +1,6 @@ -use crate::{self as sea_orm, EntityName, IdenStatic, IntoSimpleExpr, Iterable}; +use crate::{EntityName, Iden, IdenStatic, IntoSimpleExpr, Iterable}; use sea_query::{ - Alias, BinOper, DynIden, Expr, Iden, IntoIden, SeaRc, SelectStatement, SimpleExpr, Value, + Alias, BinOper, DynIden, Expr, IntoIden, SeaRc, SelectStatement, SimpleExpr, Value, }; use std::str::FromStr; @@ -381,13 +381,21 @@ impl ColumnDef { } } -#[derive(Iden)] struct Text; - -#[derive(Iden)] -#[iden = "text[]"] struct TextArray; +impl Iden for Text { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "text").unwrap(); + } +} + +impl Iden for TextArray { + fn unquoted(&self, s: &mut dyn std::fmt::Write) { + write!(s, "text[]").unwrap(); + } +} + fn cast_enum_as(expr: Expr, col: &C, f: F) -> SimpleExpr where C: ColumnTrait, diff --git a/src/entity/prelude.rs b/src/entity/prelude.rs index f335c9c82..ff6d779c5 100644 --- a/src/entity/prelude.rs +++ b/src/entity/prelude.rs @@ -11,8 +11,9 @@ pub use crate::{ #[cfg(feature = "macros")] pub use crate::{ DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, - DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIntoActiveModel, - DeriveModel, DerivePrimaryKey, DeriveRelatedEntity, DeriveRelation, FromJsonQueryResult, + DeriveCustomColumn, DeriveDisplay, DeriveEntity, DeriveEntityModel, DeriveIden, + DeriveIntoActiveModel, DeriveModel, DerivePrimaryKey, DeriveRelatedEntity, DeriveRelation, + FromJsonQueryResult, }; pub use async_trait; From c2d19686279b3581f7de85ed7f0197e903afa192 Mon Sep 17 00:00:00 2001 From: Chris Tsang Date: Thu, 13 Jul 2023 11:30:34 +0100 Subject: [PATCH 3/3] Reinstate Table => type_name semantic --- sea-orm-macros/src/derives/derive_iden.rs | 7 ++++++- tests/derive_iden_tests.rs | 16 ++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/sea-orm-macros/src/derives/derive_iden.rs b/sea-orm-macros/src/derives/derive_iden.rs index 026a97b1c..75442b0c3 100644 --- a/sea-orm-macros/src/derives/derive_iden.rs +++ b/sea-orm-macros/src/derives/derive_iden.rs @@ -49,7 +49,12 @@ fn impl_iden_for_enum( let match_pair: Vec = variants .map(|v| { let var_ident = &v.ident; - let mut var_name = var_ident.to_string().to_snake_case(); + let var_name = if var_ident == "Table" { + ident + } else { + var_ident + }; + let mut var_name = var_name.to_string().to_snake_case(); v.attrs .iter() .filter(|attr| attr.path().is_ident("sea_orm")) diff --git a/tests/derive_iden_tests.rs b/tests/derive_iden_tests.rs index 707a69f1f..e45adda7d 100644 --- a/tests/derive_iden_tests.rs +++ b/tests/derive_iden_tests.rs @@ -4,7 +4,8 @@ use sea_orm::entity::prelude::*; use sea_orm_macros::DeriveIden; #[derive(DeriveIden)] -pub enum Class { +pub enum ClassName { + Table, Id, Title, Text, @@ -12,6 +13,7 @@ pub enum Class { #[derive(DeriveIden)] pub enum Book { + Table, Id, #[sea_orm(iden = "turtle")] Title, @@ -22,7 +24,7 @@ pub enum Book { } #[derive(DeriveIden)] -struct Glyph; +struct GlyphToken; #[derive(DeriveIden)] #[sea_orm(iden = "weRd")] @@ -30,16 +32,18 @@ struct Word; #[test] fn main() -> Result<(), DbErr> { - assert_eq!(Class::Id.to_string(), "id"); - assert_eq!(Class::Title.to_string(), "title"); - assert_eq!(Class::Text.to_string(), "text"); + assert_eq!(ClassName::Table.to_string(), "class_name"); + assert_eq!(ClassName::Id.to_string(), "id"); + assert_eq!(ClassName::Title.to_string(), "title"); + assert_eq!(ClassName::Text.to_string(), "text"); assert_eq!(Book::Id.to_string(), "id"); + assert_eq!(Book::Table.to_string(), "book"); assert_eq!(Book::Title.to_string(), "turtle"); assert_eq!(Book::Text.to_string(), "TeXt"); assert_eq!(Book::Type.to_string(), "ty_pe"); - assert_eq!(Glyph.to_string(), "glyph"); + assert_eq!(GlyphToken.to_string(), "glyph_token"); assert_eq!(Word.to_string(), "weRd"); Ok(())