diff --git a/src/executor/insert.rs b/src/executor/insert.rs index b4da10c0..9e186ccd 100644 --- a/src/executor/insert.rs +++ b/src/executor/insert.rs @@ -96,10 +96,10 @@ where ValueTypeOf::::try_from_u64(last_insert_id).ok() } }; - let last_insert_id = match last_insert_id_opt { - Some(last_insert_id) => last_insert_id, - None => match primary_key { - Some(value_tuple) => FromValueTuple::from_value_tuple(value_tuple), + let last_insert_id = match primary_key { + Some(value_tuple) => FromValueTuple::from_value_tuple(value_tuple), + None => match last_insert_id_opt { + Some(last_insert_id) => last_insert_id, None => return Err(DbErr::Exec("Fail to unpack last_insert_id".to_owned())), }, }; diff --git a/tests/common/bakery_chain/mod.rs b/tests/common/bakery_chain/mod.rs index 36f2a16e..d9e4535b 100644 --- a/tests/common/bakery_chain/mod.rs +++ b/tests/common/bakery_chain/mod.rs @@ -7,6 +7,7 @@ pub mod customer; pub mod lineitem; pub mod metadata; pub mod order; +pub mod repository; pub use super::applog::Entity as Applog; pub use super::baker::Entity as Baker; @@ -17,3 +18,4 @@ pub use super::customer::Entity as Customer; pub use super::lineitem::Entity as Lineitem; pub use super::metadata::Entity as Metadata; pub use super::order::Entity as Order; +pub use super::repository::Entity as Repository; diff --git a/tests/common/bakery_chain/repository.rs b/tests/common/bakery_chain/repository.rs new file mode 100644 index 00000000..6092abf2 --- /dev/null +++ b/tests/common/bakery_chain/repository.rs @@ -0,0 +1,16 @@ +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel)] +#[sea_orm(table_name = "repository")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + pub owner: String, + pub name: String, + pub description: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/tests/common/setup/mod.rs b/tests/common/setup/mod.rs index b9195edb..dc6a7472 100644 --- a/tests/common/setup/mod.rs +++ b/tests/common/setup/mod.rs @@ -54,6 +54,7 @@ pub async fn setup(base_url: &str, db_name: &str) -> DatabaseConnection { schema::create_lineitem_table(&db).await.unwrap(); schema::create_metadata_table(&db).await.unwrap(); schema::create_log_table(&db).await.unwrap(); + schema::create_repository_table(&db).await.unwrap(); db } diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index 741a2042..5b9e34dd 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -317,3 +317,24 @@ pub async fn create_log_table(db: &DbConn) -> Result { create_table(db, &stmt, Applog).await } + +pub async fn create_repository_table(db: &DbConn) -> Result { + let stmt = sea_query::Table::create() + .table(repository::Entity) + .col( + ColumnDef::new(repository::Column::Id) + .string() + .not_null() + .primary_key(), + ) + .col( + ColumnDef::new(repository::Column::Owner) + .string() + .not_null(), + ) + .col(ColumnDef::new(repository::Column::Name).string().not_null()) + .col(ColumnDef::new(repository::Column::Description).string()) + .to_owned(); + + create_table(db, &stmt, Repository).await +} diff --git a/tests/string_primary_key_tests.rs b/tests/string_primary_key_tests.rs new file mode 100644 index 00000000..76916012 --- /dev/null +++ b/tests/string_primary_key_tests.rs @@ -0,0 +1,91 @@ +pub mod common; + +pub use common::{bakery_chain::*, setup::*, TestContext}; +use pretty_assertions::assert_eq; +use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection}; + +#[sea_orm_macros::test] +#[cfg(any( + feature = "sqlx-mysql", + feature = "sqlx-sqlite", + feature = "sqlx-postgres" +))] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("bakery_chain_schema_string_primary_key_tests").await; + create_and_update_repository(&ctx.db).await?; + insert_repository(&ctx.db).await?; + ctx.delete().await; + + Ok(()) +} + +pub async fn insert_repository(db: &DatabaseConnection) -> Result<(), DbErr> { + let repository = repository::Model { + id: "unique-id-001".to_owned(), + owner: "GC".to_owned(), + name: "G.C.".to_owned(), + description: None, + } + .into_active_model(); + + let result = repository.clone().insert(db).await?; + + assert_eq!(repository, result); + + Ok(()) +} + +pub async fn create_and_update_repository(db: &DatabaseConnection) -> Result<(), DbErr> { + let repository = repository::Model { + id: "unique-id-002".to_owned(), + owner: "GC".to_owned(), + name: "G.C.".to_owned(), + description: None, + }; + + let res = Repository::insert(repository.clone().into_active_model()) + .exec(db) + .await?; + + assert_eq!(Repository::find().one(db).await?, Some(repository.clone())); + + assert_eq!(res.last_insert_id, repository.id); + + let updated_active_model = repository::ActiveModel { + description: Set(Some("description...".to_owned())), + ..repository.clone().into_active_model() + }; + + let update_res = Repository::update(updated_active_model.clone()) + .filter(repository::Column::Id.eq("not-exists-id".to_owned())) + .exec(db) + .await; + + assert_eq!( + update_res, + Err(DbErr::RecordNotFound( + "None of the database rows are affected".to_owned() + )) + ); + + let update_res = Repository::update(updated_active_model.clone()) + .filter(repository::Column::Id.eq("unique-id-002".to_owned())) + .exec(db) + .await?; + + assert_eq!(update_res, updated_active_model); + + let updated_active_model = repository::ActiveModel { + description: Set(None), + ..repository.clone().into_active_model() + }; + + let update_res = Repository::update(updated_active_model.clone()) + .filter(repository::Column::Id.eq("unique-id-002".to_owned())) + .exec(db) + .await?; + + assert_eq!(update_res, updated_active_model); + + Ok(()) +}