diff --git a/Cargo.toml b/Cargo.toml index c7075ed7..39a5fc1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,6 +60,7 @@ pretty_assertions = { version = "0.7" } time = { version = "0.3", features = ["macros"] } uuid = { version = "1", features = ["v4"] } once_cell = "1.8" +arraystring = "0.3" [features] debug-print = [] diff --git a/tests/common/features/dyn_table_name_lazy_static.rs b/tests/common/features/dyn_table_name_lazy_static.rs new file mode 100644 index 00000000..cb2b3b85 --- /dev/null +++ b/tests/common/features/dyn_table_name_lazy_static.rs @@ -0,0 +1,56 @@ +use arraystring::{typenum::U32, ArrayString}; +use sea_orm::entity::prelude::*; + +pub type TableName = ArrayString; + +#[derive(Copy, Clone, Default, Debug, DeriveEntity)] +pub struct Entity { + pub table_name: TableName, +} + +impl EntityName for Entity { + fn table_name(&self) -> &str { + self.table_name.as_str() + } +} + +#[derive(Clone, Debug, PartialEq, Eq, DeriveModel, DeriveActiveModel)] +pub struct Model { + pub id: i32, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)] +pub enum Column { + Id, + Name, +} + +#[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 ColumnTrait for Column { + type EntityName = Entity; + + fn def(&self) -> ColumnDef { + match self { + Self::Id => ColumnType::Integer.def(), + Self::Name => ColumnType::String(None).def(), + } + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/features/mod.rs b/tests/common/features/mod.rs index a30a6dd3..ed4f8818 100644 --- a/tests/common/features/mod.rs +++ b/tests/common/features/mod.rs @@ -5,6 +5,7 @@ pub mod binary; pub mod byte_primary_key; pub mod collection; pub mod custom_active_model; +pub mod dyn_table_name_lazy_static; pub mod edit_log; pub mod event_trigger; pub mod insert_default; @@ -27,6 +28,7 @@ pub use applog::Entity as Applog; pub use binary::Entity as Binary; pub use byte_primary_key::Entity as BytePrimaryKey; pub use collection::Entity as Collection; +pub use dyn_table_name_lazy_static::Entity as DynTableNameLazyStatic; pub use edit_log::Entity as EditLog; pub use event_trigger::Entity as EventTrigger; pub use insert_default::Entity as InsertDefault; diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 57d04340..b0431995 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -48,6 +48,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { create_edit_log_table(db).await?; create_teas_table(db).await?; create_binary_table(db).await?; + create_dyn_table_name_lazy_static_table(db).await?; if DbBackend::Postgres == db_backend { create_collection_table(db).await?; @@ -559,3 +560,33 @@ pub async fn create_binary_table(db: &DbConn) -> Result { create_table(db, &create_table_stmt, Binary).await } + +pub async fn create_dyn_table_name_lazy_static_table(db: &DbConn) -> Result<(), DbErr> { + use dyn_table_name_lazy_static::*; + + let entities = [ + Entity { + table_name: TableName::from_str_truncate("dyn_table_name_lazy_static_1"), + }, + Entity { + table_name: TableName::from_str_truncate("dyn_table_name_lazy_static_2"), + }, + ]; + for entity in entities { + let create_table_stmt = sea_query::Table::create() + .table(entity.table_ref()) + .col( + ColumnDef::new(Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col(ColumnDef::new(Column::Name).string().not_null()) + .to_owned(); + + create_table(db, &create_table_stmt, entity).await?; + } + + Ok(()) +} diff --git a/tests/dyn_table_name_tests.rs b/tests/dyn_table_name_tests.rs new file mode 100644 index 00000000..b71baa7b --- /dev/null +++ b/tests/dyn_table_name_tests.rs @@ -0,0 +1,79 @@ +pub mod common; + +pub use common::{features::*, setup::*, TestContext}; +use pretty_assertions::assert_eq; +use sea_orm::{ + entity::prelude::*, DatabaseConnection, Delete, IntoActiveModel, Iterable, QueryTrait, Set, + Update, +}; +use sea_query::{Expr, IntoIden, Query}; + +#[sea_orm_macros::test] +#[cfg(any( + feature = "sqlx-mysql", + feature = "sqlx-sqlite", + feature = "sqlx-postgres" +))] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("dyn_table_name_tests").await; + create_tables(&ctx.db).await?; + dyn_table_name_lazy_static(&ctx.db).await?; + ctx.delete().await; + + Ok(()) +} + +pub async fn dyn_table_name_lazy_static(db: &DatabaseConnection) -> Result<(), DbErr> { + use dyn_table_name_lazy_static::*; + + for i in 1..=2 { + let entity = Entity { + table_name: TableName::from_str_truncate(format!("dyn_table_name_lazy_static_{}", i)), + }; + + let model = Model { + id: 1, + name: "1st Row".into(), + }; + // Prepare insert statement + let mut insert = Entity::insert(model.clone().into_active_model()); + // Reset the table name of insert statement + insert.query().into_table(entity.table_ref()); + // Execute the insert statement + assert_eq!(insert.exec(db).await?.last_insert_id, 1); + + // Prepare select statement + let mut select = Entity::find(); + // Override the select statement + *QueryTrait::query(&mut select) = Query::select() + .exprs(Column::iter().map(|col| col.select_as(Expr::col(col)))) + .from(entity.table_ref()) + .to_owned(); + // Execute the select statement + assert_eq!(select.clone().one(db).await?, Some(model.clone())); + + // Prepare update statement + let update = Update::many(entity).set(ActiveModel { + name: Set("1st Row (edited)".into()), + ..model.clone().into_active_model() + }); + // Execute the update statement + assert_eq!(update.exec(db).await?.rows_affected, 1); + + assert_eq!( + select.clone().one(db).await?, + Some(Model { + id: 1, + name: "1st Row (edited)".into(), + }) + ); + + // Prepare delete statement + let delete = Delete::many(entity).filter(Expr::col(Column::Id).eq(1)); + // Execute the delete statement + assert_eq!(delete.exec(db).await?.rows_affected, 1); + assert_eq!(select.one(db).await?, None); + } + + Ok(()) +}