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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 631cafbf..b7ec5a4d 100644 --- a/examples/graphql_example/migration/src/m20220101_000001_create_table.rs +++ b/examples/graphql_example/migration/src/m20220101_000001_create_table.rs @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220101_000001_create_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { 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 eb0af1b6..a2fa0219 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220120_000001_create_post_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/sea-orm-cli/src/commands.rs b/sea-orm-cli/src/commands.rs index c82426c7..bd1072f2 100644 --- a/sea-orm-cli/src/commands.rs +++ b/sea-orm-cli/src/commands.rs @@ -317,7 +317,7 @@ fn create_new_migration(migration_name: &str, migration_dir: &str) -> Result<(), let migration_content = migration_template.replace("m20220101_000001_create_table", migration_name); let mut migration_file = fs::File::create(migration_filepath)?; - migration_file.write_all(migration_content.as_bytes())?; + migration_file.write_all(migration_template.as_bytes())?; Ok(()) } @@ -508,8 +508,6 @@ mod tests { .join(format!("{}.rs", migration_name)); assert!(migration_filepath.exists()); let migration_content = fs::read_to_string(migration_filepath).unwrap(); - let migration_content = - migration_content.replace(&migration_name, "m20220101_000001_create_table"); assert_eq!( &migration_content, include_str!("../template/migration/src/m20220101_000001_create_table.rs") 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 12a3bec1..b0582446 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 @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220101_000001_create_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/sea-orm-macros/src/derives/migration.rs b/sea-orm-macros/src/derives/migration.rs new file mode 100644 index 00000000..8ba5ef4f --- /dev/null +++ b/sea-orm-macros/src/derives/migration.rs @@ -0,0 +1,32 @@ +use proc_macro2::TokenStream; +use quote::quote; + +struct DeriveMigrationName { + ident: syn::Ident, +} + +impl DeriveMigrationName { + fn new(input: syn::DeriveInput) -> Self { + let ident = input.ident; + + DeriveMigrationName { ident } + } + + fn expand(&self) -> TokenStream { + let ident = &self.ident; + + quote!( + #[automatically_derived] + impl sea_orm_migration::MigrationName for #ident { + fn name(&self) -> &str { + sea_orm_migration::util::get_file_stem(file!()) + } + } + ) + } +} + +/// Method to derive a MigrationName +pub fn expand_derive_migration_name(input: syn::DeriveInput) -> syn::Result { + Ok(DeriveMigrationName::new(input).expand()) +} diff --git a/sea-orm-macros/src/derives/mod.rs b/sea-orm-macros/src/derives/mod.rs index 36b9f669..f65b8358 100644 --- a/sea-orm-macros/src/derives/mod.rs +++ b/sea-orm-macros/src/derives/mod.rs @@ -6,6 +6,7 @@ mod entity; mod entity_model; mod from_query_result; mod into_active_model; +mod migration; mod model; mod primary_key; mod relation; @@ -18,6 +19,7 @@ pub use entity::*; pub use entity_model::*; pub use from_query_result::*; pub use into_active_model::*; +pub use migration::*; pub use model::*; pub use primary_key::*; pub use relation::*; diff --git a/sea-orm-macros/src/lib.rs b/sea-orm-macros/src/lib.rs index 3201907e..64460d66 100644 --- a/sea-orm-macros/src/lib.rs +++ b/sea-orm-macros/src/lib.rs @@ -582,6 +582,33 @@ pub fn derive_relation(input: TokenStream) -> TokenStream { .into() } +/// The DeriveMigrationName derive macro will implement `sea_orm_migration::MigrationName` for a migration. +/// +/// ### Usage +/// +/// ```ignore +/// #[derive(DeriveMigrationName)] +/// pub struct Migration; +/// ``` +/// +/// The derive macro above will provide following implementation, +/// given the file name is `m20220120_000001_create_post_table.rs`. +/// +/// ```ignore +/// impl MigrationName for Migration { +/// fn name(&self) -> &str { +/// "m20220120_000001_create_post_table" +/// } +/// } +/// ``` +#[proc_macro_derive(DeriveMigrationName)] +pub fn derive_migration_name(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + derives::expand_derive_migration_name(input) + .unwrap_or_else(Error::into_compile_error) + .into() +} + #[doc(hidden)] #[proc_macro_attribute] pub fn test(_: TokenStream, input: TokenStream) -> TokenStream { diff --git a/sea-orm-migration/src/lib.rs b/sea-orm-migration/src/lib.rs index b5d440fe..6347ee12 100644 --- a/sea-orm-migration/src/lib.rs +++ b/sea-orm-migration/src/lib.rs @@ -3,6 +3,7 @@ pub mod manager; pub mod migrator; pub mod prelude; pub mod seaql_migrations; +pub mod util; pub use manager::*; pub use migrator::*; diff --git a/sea-orm-migration/src/prelude.rs b/sea-orm-migration/src/prelude.rs index c8047658..836ab168 100644 --- a/sea-orm-migration/src/prelude.rs +++ b/sea-orm-migration/src/prelude.rs @@ -7,3 +7,4 @@ pub use sea_orm; pub use sea_orm::sea_query; pub use sea_orm::sea_query::*; pub use sea_orm::DbErr; +pub use sea_orm::DeriveMigrationName; diff --git a/sea-orm-migration/src/util.rs b/sea-orm-migration/src/util.rs new file mode 100644 index 00000000..69639932 --- /dev/null +++ b/sea-orm-migration/src/util.rs @@ -0,0 +1,36 @@ +pub fn get_file_stem(path: &str) -> &str { + std::path::Path::new(path) + .file_stem() + .map(|f| f.to_str().unwrap()) + .unwrap() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_get_file_stem() { + let pair = vec![ + ( + "m20220101_000001_create_table.rs", + "m20220101_000001_create_table", + ), + ( + "src/m20220101_000001_create_table.rs", + "m20220101_000001_create_table", + ), + ( + "migration/src/m20220101_000001_create_table.rs", + "m20220101_000001_create_table", + ), + ( + "/migration/src/m20220101_000001_create_table.tmp.rs", + "m20220101_000001_create_table.tmp", + ), + ]; + for (path, expect) in pair { + assert_eq!(get_file_stem(path), expect); + } + } +} diff --git a/sea-orm-migration/tests/migrator/m20220118_000001_create_cake_table.rs b/sea-orm-migration/tests/migrator/m20220118_000001_create_cake_table.rs index b1b3d9cf..3ad76eab 100644 --- a/sea-orm-migration/tests/migrator/m20220118_000001_create_cake_table.rs +++ b/sea-orm-migration/tests/migrator/m20220118_000001_create_cake_table.rs @@ -1,13 +1,8 @@ use sea_orm_migration::prelude::*; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220118_000001_create_cake_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/sea-orm-migration/tests/migrator/m20220118_000002_create_fruit_table.rs b/sea-orm-migration/tests/migrator/m20220118_000002_create_fruit_table.rs index 6ffd0a2c..07ead834 100644 --- a/sea-orm-migration/tests/migrator/m20220118_000002_create_fruit_table.rs +++ b/sea-orm-migration/tests/migrator/m20220118_000002_create_fruit_table.rs @@ -2,14 +2,9 @@ use super::m20220118_000001_create_cake_table::Cake; use sea_orm_migration::prelude::*; use sea_orm_migration::sea_orm::DbBackend; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220118_000002_create_fruit_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/sea-orm-migration/tests/migrator/m20220118_000003_seed_cake_table.rs b/sea-orm-migration/tests/migrator/m20220118_000003_seed_cake_table.rs index 3638fd2c..8a31ec4f 100644 --- a/sea-orm-migration/tests/migrator/m20220118_000003_seed_cake_table.rs +++ b/sea-orm-migration/tests/migrator/m20220118_000003_seed_cake_table.rs @@ -1,14 +1,9 @@ use sea_orm_migration::prelude::*; use sea_orm_migration::sea_orm::{entity::*, query::*}; +#[derive(DeriveMigrationName)] pub struct Migration; -impl MigrationName for Migration { - fn name(&self) -> &str { - "m20220118_000003_seed_cake_table" - } -} - #[async_trait::async_trait] impl MigrationTrait for Migration { async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { diff --git a/src/lib.rs b/src/lib.rs index b0604a2c..c9848230 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -329,8 +329,8 @@ pub use schema::*; #[cfg(feature = "macros")] pub use sea_orm_macros::{ DeriveActiveEnum, DeriveActiveModel, DeriveActiveModelBehavior, DeriveColumn, - DeriveCustomColumn, DeriveEntity, DeriveEntityModel, DeriveIntoActiveModel, DeriveModel, - DerivePrimaryKey, DeriveRelation, FromQueryResult, + DeriveCustomColumn, DeriveEntity, DeriveEntityModel, DeriveIntoActiveModel, + DeriveMigrationName, DeriveModel, DerivePrimaryKey, DeriveRelation, FromQueryResult, }; pub use sea_query;