diff --git a/Cargo.toml b/Cargo.toml index 5670161c..436b5042 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,8 +42,9 @@ chrono = { version = "^0", optional = true } futures = { version = "^0.3" } futures-util = { version = "^0.3" } rust_decimal = { version = "^1", optional = true } -sea-query = { version = "^0.12" } +# sea-query = { version = "^0.12" } # sea-query = { path = "../sea-query" } +sea-query = { version = "^0.12", git = "https://github.com/samsamai/sea-query.git", branch = "ss/uuid" } sea-orm-macros = { path = "sea-orm-macros", optional = true } sea-orm-codegen = { path = "sea-orm-codegen", optional = true } serde = { version = "^1.0", features = ["derive"] } diff --git a/src/executor/query.rs b/src/executor/query.rs index e182494c..aad4c3fa 100644 --- a/src/executor/query.rs +++ b/src/executor/query.rs @@ -1,5 +1,6 @@ use crate::DbErr; use chrono::NaiveDateTime; +use serde_json::Value as Json; use std::fmt; #[derive(Debug)] @@ -165,6 +166,7 @@ try_getable_all!(f32); try_getable_all!(f64); try_getable_all!(String); try_getable_all!(NaiveDateTime); +try_getable_all!(Json); #[cfg(feature = "with-uuid")] use uuid::Uuid; diff --git a/tests/bakery_chain_tests.rs b/tests/bakery_chain_tests.rs index 01062a35..d564d0b2 100644 --- a/tests/bakery_chain_tests.rs +++ b/tests/bakery_chain_tests.rs @@ -18,7 +18,7 @@ async fn main() { async fn create_entities(db: &DatabaseConnection) { crud::test_create_bakery(db).await; - crud::test_create_baker(db).await; + crud::create_baker::test_create_baker(db).await; crud::test_create_customer(db).await; crud::create_cake::test_create_cake(db).await; crud::create_lineitem::test_create_lineitem(db).await; diff --git a/tests/common/bakery_chain/baker.rs b/tests/common/bakery_chain/baker.rs index b359e7ef..93544311 100644 --- a/tests/common/bakery_chain/baker.rs +++ b/tests/common/bakery_chain/baker.rs @@ -1,4 +1,5 @@ use sea_orm::entity::prelude::*; +use serde_json::Value as Json; #[derive(Copy, Clone, Default, Debug, DeriveEntity)] pub struct Entity; @@ -13,6 +14,7 @@ impl EntityName for Entity { pub struct Model { pub id: i32, pub name: String, + pub contact_details: Json, pub bakery_id: Option, } @@ -20,6 +22,7 @@ pub struct Model { pub enum Column { Id, Name, + ContactDetails, BakeryId, } @@ -46,6 +49,7 @@ impl ColumnTrait for Column { match self { Self::Id => ColumnType::Integer.def(), Self::Name => ColumnType::String(None).def(), + Self::ContactDetails => ColumnType::Json.def(), Self::BakeryId => ColumnType::Integer.def(), } } diff --git a/tests/common/bakery_chain/bakery_chain_erd.drawio b/tests/common/bakery_chain/bakery_chain_erd.drawio index 32ff22d6..0e782312 100644 --- a/tests/common/bakery_chain/bakery_chain_erd.drawio +++ b/tests/common/bakery_chain/bakery_chain_erd.drawio @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/tests/common/bakery_chain/bakery_chain_erd.jpg b/tests/common/bakery_chain/bakery_chain_erd.jpg index 8bf98b10..4d20a32c 100644 Binary files a/tests/common/bakery_chain/bakery_chain_erd.jpg and b/tests/common/bakery_chain/bakery_chain_erd.jpg differ diff --git a/tests/common/setup/schema.rs b/tests/common/setup/schema.rs index b1871cfb..5550994d 100644 --- a/tests/common/setup/schema.rs +++ b/tests/common/setup/schema.rs @@ -38,6 +38,7 @@ pub async fn create_baker_table(db: &DbConn) -> Result { .primary_key(), ) .col(ColumnDef::new(baker::Column::Name).string()) + .col(ColumnDef::new(baker::Column::ContactDetails).json()) .col(ColumnDef::new(baker::Column::BakeryId).integer()) .foreign_key( ForeignKey::create() diff --git a/tests/crud/create_baker.rs b/tests/crud/create_baker.rs new file mode 100644 index 00000000..2a4da6e5 --- /dev/null +++ b/tests/crud/create_baker.rs @@ -0,0 +1,79 @@ +pub use super::*; +use serde::{Deserialize, Serialize}; + +pub async fn test_create_baker(db: &DbConn) { + let seaside_bakery = bakery::ActiveModel { + name: Set("SeaSide Bakery".to_owned()), + profit_margin: Set(10.4), + ..Default::default() + }; + let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery) + .exec(db) + .await + .expect("could not insert bakery"); + + #[derive(Serialize, Deserialize)] + struct ContactDetails { + mobile: String, + home: String, + address: String, + } + + let baker_bob_contact = ContactDetails { + mobile: "+61424000000".to_owned(), + home: "0395555555".to_owned(), + address: "12 Test St, Testville, Vic, Australia".to_owned(), + }; + let baker_bob = baker::ActiveModel { + name: Set("Baker Bob".to_owned()), + contact_details: Set(serde_json::json!(baker_bob_contact)), + bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), + ..Default::default() + }; + let res: InsertResult = Baker::insert(baker_bob) + .exec(db) + .await + .expect("could not insert baker"); + + let baker: Option = Baker::find_by_id(res.last_insert_id) + .one(db) + .await + .expect("could not find baker"); + + assert!(baker.is_some()); + let baker_model = baker.unwrap(); + assert_eq!(baker_model.name, "Baker Bob"); + assert_eq!( + baker_model.contact_details["mobile"], + baker_bob_contact.mobile + ); + assert_eq!(baker_model.contact_details["home"], baker_bob_contact.home); + assert_eq!( + baker_model.contact_details["address"], + baker_bob_contact.address + ); + assert_eq!( + baker_model + .find_related(Bakery) + .one(db) + .await + .expect("Bakery not found") + .unwrap() + .name, + "SeaSide Bakery" + ); + + let bakery: Option = Bakery::find_by_id(bakery_insert_res.last_insert_id) + .one(db) + .await + .unwrap(); + + let related_bakers: Vec = bakery + .unwrap() + .find_related(Baker) + .all(db) + .await + .expect("could not find related bakers"); + assert_eq!(related_bakers.len(), 1); + assert_eq!(related_bakers[0].name, "Baker Bob") +} diff --git a/tests/crud/create_cake.rs b/tests/crud/create_cake.rs index 8c76d8c1..07f9c4b3 100644 --- a/tests/crud/create_cake.rs +++ b/tests/crud/create_cake.rs @@ -15,6 +15,11 @@ pub async fn test_create_cake(db: &DbConn) { let baker_bob = baker::ActiveModel { name: Set("Baker Bob".to_owned()), + contact_details: Set(serde_json::json!({ + "mobile": "+61424000000", + "home": "0395555555", + "address": "12 Test St, Testville, Vic, Australia" + })), bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), ..Default::default() }; diff --git a/tests/crud/create_lineitem.rs b/tests/crud/create_lineitem.rs index d3f36233..4d2b2a14 100644 --- a/tests/crud/create_lineitem.rs +++ b/tests/crud/create_lineitem.rs @@ -18,6 +18,11 @@ pub async fn test_create_lineitem(db: &DbConn) { // Baker let baker_bob = baker::ActiveModel { name: Set("Baker Bob".to_owned()), + contact_details: Set(serde_json::json!({ + "mobile": "+61424000000", + "home": "0395555555", + "address": "12 Test St, Testville, Vic, Australia" + })), bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), ..Default::default() }; diff --git a/tests/crud/create_order.rs b/tests/crud/create_order.rs index 98afba3e..e1ec90f5 100644 --- a/tests/crud/create_order.rs +++ b/tests/crud/create_order.rs @@ -18,6 +18,11 @@ pub async fn test_create_order(db: &DbConn) { // Baker let baker_bob = baker::ActiveModel { name: Set("Baker Bob".to_owned()), + contact_details: Set(serde_json::json!({ + "mobile": "+61424000000", + "home": "0395555555", + "address": "12 Test St, Testville, Vic, Australia" + })), bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), ..Default::default() }; diff --git a/tests/crud/mod.rs b/tests/crud/mod.rs index bec87ced..457f639d 100644 --- a/tests/crud/mod.rs +++ b/tests/crud/mod.rs @@ -2,6 +2,7 @@ use sea_orm::{entity::*, DbConn, InsertResult}; pub use super::common::bakery_chain::*; +pub mod create_baker; pub mod create_cake; pub mod create_lineitem; pub mod create_order; @@ -30,61 +31,6 @@ pub async fn test_create_bakery(db: &DbConn) { assert_eq!(bakery_model.profit_margin, 10.4); } -pub async fn test_create_baker(db: &DbConn) { - let seaside_bakery = bakery::ActiveModel { - name: Set("SeaSide Bakery".to_owned()), - profit_margin: Set(10.4), - ..Default::default() - }; - let bakery_insert_res: InsertResult = Bakery::insert(seaside_bakery) - .exec(db) - .await - .expect("could not insert bakery"); - - let baker_bob = baker::ActiveModel { - name: Set("Baker Bob".to_owned()), - bakery_id: Set(Some(bakery_insert_res.last_insert_id as i32)), - ..Default::default() - }; - let res: InsertResult = Baker::insert(baker_bob) - .exec(db) - .await - .expect("could not insert baker"); - - let baker: Option = Baker::find_by_id(res.last_insert_id) - .one(db) - .await - .expect("could not find baker"); - - assert!(baker.is_some()); - let baker_model = baker.unwrap(); - assert_eq!(baker_model.name, "Baker Bob"); - assert_eq!( - baker_model - .find_related(Bakery) - .one(db) - .await - .expect("Bakery not found") - .unwrap() - .name, - "SeaSide Bakery" - ); - - let bakery: Option = Bakery::find_by_id(bakery_insert_res.last_insert_id) - .one(db) - .await - .unwrap(); - - let related_bakers: Vec = bakery - .unwrap() - .find_related(Baker) - .all(db) - .await - .expect("could not find related bakers"); - assert_eq!(related_bakers.len(), 1); - assert_eq!(related_bakers[0].name, "Baker Bob") -} - pub async fn test_create_customer(db: &DbConn) { let customer_kate = customer::ActiveModel { name: Set("Kate".to_owned()), diff --git a/tests/relational_tests.rs b/tests/relational_tests.rs index 1d6b82d3..33c43659 100644 --- a/tests/relational_tests.rs +++ b/tests/relational_tests.rs @@ -23,6 +23,11 @@ pub async fn left_join() { let _baker_1 = baker::ActiveModel { name: Set("Baker 1".to_owned()), + contact_details: Set(serde_json::json!({ + "mobile": "+61424000000", + "home": "0395555555", + "address": "12 Test St, Testville, Vic, Australia" + })), bakery_id: Set(Some(bakery.id.clone().unwrap())), ..Default::default() } @@ -32,6 +37,7 @@ pub async fn left_join() { let _baker_2 = baker::ActiveModel { name: Set("Baker 2".to_owned()), + contact_details: Set(serde_json::json!({})), bakery_id: Set(None), ..Default::default() }