Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions sea-orm-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,12 @@ pub enum GenerateSubcommands {
help = "Control how the codegen version is displayed in the top banner of the generated file."
)]
banner_version: BannerVersion,

#[arg(
long,
help = "Make generated code require a specific crate feature to enable SeaORM-related code. Without that feature enabled, your entities will be available without SeaORM-specific traits and types."
)]
sea_orm_feature: Option<String>,
},
}

Expand Down
2 changes: 2 additions & 0 deletions sea-orm-cli/src/commands/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub async fn run_generate_command(
impl_active_model_behavior,
preserve_user_modifications,
banner_version,
sea_orm_feature,
} => {
if verbose {
let _ = tracing_subscriber::fmt()
Expand Down Expand Up @@ -249,6 +250,7 @@ pub async fn run_generate_command(
seaography,
impl_active_model_behavior,
banner_version.into(),
sea_orm_feature,
);
let output = EntityTransformer::transform(table_stmts)?.generate(&writer_context);

Expand Down
75 changes: 53 additions & 22 deletions sea-orm-codegen/src/entity/active_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use proc_macro2::TokenStream;
use quote::{format_ident, quote};
use sea_query::DynIden;

use crate::{EntityFormat, WithSerde};
use crate::{EntityFormat, WithSerde, entity::writer::feature_flag_derives};

#[derive(Clone, Debug)]
pub struct ActiveEnum {
Expand All @@ -19,6 +19,7 @@ impl ActiveEnum {
extra_derives: &TokenStream,
extra_attributes: &TokenStream,
entity_format: EntityFormat,
sea_orm_feature: &Option<String>,
) -> TokenStream {
let enum_name = &self.enum_name.to_string();
let enum_iden = format_ident!("{}", enum_name.to_upper_camel_case());
Expand Down Expand Up @@ -72,27 +73,51 @@ impl ActiveEnum {
quote! {}
};

if entity_format == EntityFormat::Frontend {
quote! {
#[derive(Debug, Clone, PartialEq, Eq #copy_derive #serde_derive #extra_derives)]
#extra_attributes
pub enum #enum_iden {
#(
#variants,
)*
}
}
} else {
quote! {
#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum #copy_derive #serde_derive #extra_derives)]
#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = #enum_name)]
#extra_attributes
pub enum #enum_iden {
#(
#[sea_orm(string_value = #values)]
#variants,
)*
}
let is_frontend = entity_format == EntityFormat::Frontend;

let (additional_derives, additional_attributes, sea_orm_enum_attr, variant_sea_orm_attrs) =
if is_frontend {
let variant_attrs = values.iter().map(|_| quote! {}).collect();
(quote! {}, quote! {}, quote! {}, variant_attrs)
} else {
let (add_derives, add_attrs) =
feature_flag_derives(sea_orm_feature, quote! { EnumIter, DeriveActiveEnum });
let add_derives = if !add_derives.is_empty() {
quote! { , #add_derives }
} else {
quote! {}
};

let enum_attr = if let Some(feature) = sea_orm_feature {
quote! { #[cfg_attr(feature = #feature, sea_orm(rs_type = "String", db_type = "Enum", enum_name = #enum_name))] }
} else {
quote! { #[sea_orm(rs_type = "String", db_type = "Enum", enum_name = #enum_name)] }
};

let variant_attrs: Vec<TokenStream> = values
.iter()
.map(|v| {
if let Some(feature) = sea_orm_feature {
quote! { #[cfg_attr(feature = #feature, sea_orm(string_value = #v))] }
} else {
quote! { #[sea_orm(string_value = #v)] }
}
})
.collect();

(add_derives, add_attrs, enum_attr, variant_attrs)
};

quote! {
#[derive(Debug, Clone, PartialEq, Eq #additional_derives #copy_derive #serde_derive #extra_derives)]
#additional_attributes
#sea_orm_enum_attr
#extra_attributes
pub enum #enum_iden {
#(
#variant_sea_orm_attrs
#variants,
)*
}
}
}
Expand Down Expand Up @@ -121,6 +146,7 @@ mod tests {
&TokenStream::new(),
&TokenStream::new(),
EntityFormat::Compact,
&None,
)
.to_string(),
quote!(
Expand Down Expand Up @@ -164,6 +190,7 @@ mod tests {
&TokenStream::new(),
&TokenStream::new(),
EntityFormat::Compact,
&None,
)
.to_string(),
quote!(
Expand Down Expand Up @@ -216,6 +243,7 @@ mod tests {
&bonus_derive(["specta::Type", "ts_rs::TS"]),
&TokenStream::new(),
EntityFormat::Compact,
&None,
)
.to_string(),
build_generated_enum(),
Expand Down Expand Up @@ -253,6 +281,7 @@ mod tests {
&TokenStream::new(),
&bonus_attributes([r#"serde(rename_all = "camelCase")"#]),
EntityFormat::Compact,
&None,
)
.to_string(),
quote!(
Expand Down Expand Up @@ -286,6 +315,7 @@ mod tests {
&TokenStream::new(),
&bonus_attributes([r#"serde(rename_all = "camelCase")"#, "ts(export)"]),
EntityFormat::Compact,
&None,
)
.to_string(),
quote!(
Expand Down Expand Up @@ -337,6 +367,7 @@ mod tests {
&TokenStream::new(),
&TokenStream::new(),
EntityFormat::Compact,
&None,
)
.to_string(),
quote!(
Expand Down
11 changes: 7 additions & 4 deletions sea-orm-codegen/src/entity/base_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,11 @@ impl Entity {
self.relations.iter().map(|rel| rel.get_def()).collect()
}

pub fn get_relation_attrs(&self) -> Vec<TokenStream> {
self.relations.iter().map(|rel| rel.get_attrs()).collect()
pub fn get_relation_attrs(&self, sea_orm_feature: &Option<String>) -> Vec<TokenStream> {
self.relations
.iter()
.map(|rel| rel.get_attrs(sea_orm_feature))
.collect()
}

/// Trimmed get_related_entity_attrs down to just the entity module
Expand Down Expand Up @@ -488,10 +491,10 @@ mod tests {
fn test_get_relation_attrs() {
let entity = setup();

for (i, elem) in entity.get_relation_attrs().into_iter().enumerate() {
for (i, elem) in entity.get_relation_attrs(&None).into_iter().enumerate() {
assert_eq!(
elem.to_string(),
entity.relations[i].get_attrs().to_string()
entity.relations[i].get_attrs(&None).to_string()
);
}
}
Expand Down
27 changes: 21 additions & 6 deletions sea-orm-codegen/src/entity/relation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl Relation {
}
}

pub fn get_attrs(&self) -> TokenStream {
pub fn get_attrs(&self, sea_orm_feature: &Option<String>) -> TokenStream {
let rel_type = self.get_rel_type();
let module_name = if let Some(module_name) = self.get_module_name() {
format!("super::{module_name}::")
Expand All @@ -103,8 +103,14 @@ impl Relation {
let ref_entity = format!("{module_name}Entity");
match self.rel_type {
RelationType::HasOne | RelationType::HasMany => {
quote! {
#[sea_orm(#rel_type = #ref_entity)]
if let Some(feature) = sea_orm_feature {
quote! {
#[cfg_attr(feature = #feature, sea_orm(#rel_type = #ref_entity))]
}
} else {
quote! {
#[sea_orm(#rel_type = #ref_entity)]
}
}
}
RelationType::BelongsTo => {
Expand Down Expand Up @@ -138,14 +144,23 @@ impl Relation {
} else {
quote! {}
};
quote! {
#[sea_orm(
let sea_orm_attr_inner = quote! {
sea_orm(
#rel_type = #ref_entity,
from = #from,
to = #to,
#on_update
#on_delete
)]
)
};
if let Some(feature) = sea_orm_feature {
quote! {
#[cfg_attr(feature = #feature, #sea_orm_attr_inner)]
}
} else {
quote! {
#[#sea_orm_attr_inner]
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions sea-orm-codegen/src/entity/transformer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ mod tests {
&Default::default(),
false,
true,
&None,
)
.into_iter()
.skip(1)
Expand Down
Loading