From d205338f3f1c8922b0327a30884ed18ed00da06d Mon Sep 17 00:00:00 2001 From: Billy Chan Date: Mon, 19 Dec 2022 17:08:32 +0800 Subject: [PATCH] Try custom vector field (#1273) --- tests/common/features/event_trigger.rs | 70 ++++++++++++++++++++++++++ tests/common/features/mod.rs | 2 + tests/common/features/schema.rs | 21 ++++++++ tests/event_trigger_tests.rs | 48 ++++++++++++++++++ 4 files changed, 141 insertions(+) create mode 100644 tests/common/features/event_trigger.rs create mode 100644 tests/event_trigger_tests.rs diff --git a/tests/common/features/event_trigger.rs b/tests/common/features/event_trigger.rs new file mode 100644 index 000000000..cea0a8063 --- /dev/null +++ b/tests/common/features/event_trigger.rs @@ -0,0 +1,70 @@ +use sea_orm::entity::prelude::*; +use sea_orm::{ + sea_query::{ArrayType, ColumnType, SeaRc, ValueType}, + TryGetError, TryGetable, +}; + +#[derive(Clone, Debug, PartialEq, Eq, DeriveEntityModel)] +#[sea_orm(table_name = "event_trigger")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub events: Events, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Event(pub String); + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Events(pub Vec); + +impl From for Value { + fn from(events: Events) -> Self { + let Events(events) = events; + Value::Array( + ArrayType::String, + Some(Box::new( + events + .into_iter() + .map(|Event(s)| Value::String(Some(Box::new(s)))) + .collect(), + )), + ) + } +} + +impl TryGetable for Events { + fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result { + let vec: Vec = res.try_get(pre, col).map_err(TryGetError::DbErr)?; + Ok(Events(vec.into_iter().map(Event).collect())) + } +} + +impl ValueType for Events { + fn try_from(v: Value) -> Result { + let value: Option> = + v.expect("This Value::Array should consist of Value::String"); + let vec = match value { + Some(v) => v.into_iter().map(Event).collect(), + None => vec![], + }; + Ok(Events(vec)) + } + + fn type_name() -> String { + stringify!(Events).to_owned() + } + + fn array_type() -> ArrayType { + ArrayType::String + } + + fn column_type() -> ColumnType { + ColumnType::Array(SeaRc::new(Box::new(ColumnType::String(None)))) + } +} diff --git a/tests/common/features/mod.rs b/tests/common/features/mod.rs index ea6a39bc1..420c162c2 100644 --- a/tests/common/features/mod.rs +++ b/tests/common/features/mod.rs @@ -4,6 +4,7 @@ pub mod applog; pub mod byte_primary_key; pub mod collection; pub mod custom_active_model; +pub mod event_trigger; pub mod insert_default; pub mod json_struct; pub mod json_vec; @@ -21,6 +22,7 @@ pub use active_enum_child::Entity as ActiveEnumChild; pub use applog::Entity as Applog; pub use byte_primary_key::Entity as BytePrimaryKey; pub use collection::Entity as Collection; +pub use event_trigger::Entity as EventTrigger; pub use insert_default::Entity as InsertDefault; pub use json_struct::Entity as JsonStruct; pub use json_vec::Entity as JsonVec; diff --git a/tests/common/features/schema.rs b/tests/common/features/schema.rs index 13ca8c237..c50683beb 100644 --- a/tests/common/features/schema.rs +++ b/tests/common/features/schema.rs @@ -45,6 +45,7 @@ pub async fn create_tables(db: &DatabaseConnection) -> Result<(), DbErr> { if DbBackend::Postgres == db_backend { create_collection_table(db).await?; + create_event_trigger_table(db).await?; } Ok(()) @@ -411,3 +412,23 @@ pub async fn create_pi_table(db: &DbConn) -> Result { create_table(db, &stmt, Pi).await } + +pub async fn create_event_trigger_table(db: &DbConn) -> Result { + let stmt = sea_query::Table::create() + .table(event_trigger::Entity) + .col( + ColumnDef::new(event_trigger::Column::Id) + .integer() + .not_null() + .auto_increment() + .primary_key(), + ) + .col( + ColumnDef::new(event_trigger::Column::Events) + .array(sea_query::ColumnType::String(None)) + .not_null(), + ) + .to_owned(); + + create_table(db, &stmt, EventTrigger).await +} diff --git a/tests/event_trigger_tests.rs b/tests/event_trigger_tests.rs new file mode 100644 index 000000000..2d8712c5b --- /dev/null +++ b/tests/event_trigger_tests.rs @@ -0,0 +1,48 @@ +pub mod common; + +pub use common::{ + features::{ + event_trigger::{Event, Events}, + *, + }, + setup::*, + TestContext, +}; +use pretty_assertions::assert_eq; +use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection}; + +#[sea_orm_macros::test] +#[cfg(all(feature = "sqlx-postgres", feature = "postgres-array"))] +async fn main() -> Result<(), DbErr> { + let ctx = TestContext::new("event_trigger_tests").await; + create_tables(&ctx.db).await?; + insert_event_trigger(&ctx.db).await?; + ctx.delete().await; + + Ok(()) +} + +pub async fn insert_event_trigger(db: &DatabaseConnection) -> Result<(), DbErr> { + let event_trigger = event_trigger::Model { + id: 1, + events: Events( + ["A", "B", "C"] + .into_iter() + .map(|s| Event(s.to_owned())) + .collect(), + ), + }; + + let result = event_trigger.clone().into_active_model().insert(db).await?; + + assert_eq!(result, event_trigger); + + let model = event_trigger::Entity::find() + .filter(event_trigger::Column::Id.eq(event_trigger.id)) + .one(db) + .await?; + + assert_eq!(model, Some(event_trigger)); + + Ok(()) +}