Test cases improvement (#1811)
* adds find_with_linked test * WIP(related test) * mock related test done * complete relation test * loader update * find_with/also_related missing test case for empty from other side * comments fixup * revert loader test * related select test done * find with/also linked test cases * removed due to it being functionally same as the new one * fmt, remove excess import * improved model generation * issue related test case #1790 * added loader test cases and slight improvement to find_related/linked * miscellaneous changes * added empty insert, merge load_one test case * completed loader many to many test case, fmt * removed empty_insert test case for now * commented insert_test * added Cargo.toml for issue 1790's folder * buffed salvo version for ci(0.49 yanked) * revert version for salvo example
This commit is contained in:
parent
2a8efed98d
commit
d50312c081
18
issues/1790/Cargo.toml
Normal file
18
issues/1790/Cargo.toml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[workspace]
|
||||||
|
# A separate workspace
|
||||||
|
|
||||||
|
[package]
|
||||||
|
name = "sea-orm-issues-1790"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2023"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
anyhow = "1"
|
||||||
|
serde = "1"
|
||||||
|
tokio = { version = "1", features = ["rt", "rt-multi-thread", "macros"] }
|
||||||
|
|
||||||
|
[dependencies.sea-orm]
|
||||||
|
path = "../../"
|
||||||
|
default-features = false
|
||||||
|
features = ["macros", "runtime-tokio-native-tls", "sqlx-sqlite"]
|
58
issues/1790/insert_test.rs
Normal file
58
issues/1790/insert_test.rs
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
mod tests {
|
||||||
|
// currently ok
|
||||||
|
#[test]
|
||||||
|
fn insert_do_nothing_postgres() {
|
||||||
|
assert_eq!(
|
||||||
|
Insert::<cake::ActiveModel>::new()
|
||||||
|
.add(cake::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "Apple Pie".to_owned(),
|
||||||
|
})
|
||||||
|
.on_conflict(OnConflict::new()
|
||||||
|
.do_nothing()
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.build(DbBackend::Postgres)
|
||||||
|
.to_string(),
|
||||||
|
r#"INSERT INTO "cake" ("id", "name") VALUES (1, 'Apple Pie') ON CONFLICT DO NOTHING"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//failed to run
|
||||||
|
#[test]
|
||||||
|
fn insert_do_nothing_mysql() {
|
||||||
|
assert_eq!(
|
||||||
|
Insert::<cake::ActiveModel>::new()
|
||||||
|
.add(cake::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "Apple Pie".to_owned(),
|
||||||
|
})
|
||||||
|
.on_conflict(OnConflict::new()
|
||||||
|
.do_nothing()
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.build(DbBackend::Mysql)
|
||||||
|
.to_string(),
|
||||||
|
r#"INSERT IGNORE INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// currently ok
|
||||||
|
#[test]
|
||||||
|
fn insert_do_nothing() {
|
||||||
|
assert_eq!(
|
||||||
|
Insert::<cake::ActiveModel>::new()
|
||||||
|
.add(cake::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "Apple Pie".to_owned(),
|
||||||
|
})
|
||||||
|
.on_conflict(OnConflict::new()
|
||||||
|
.do_nothing()
|
||||||
|
.to_owned()
|
||||||
|
)
|
||||||
|
.build(DbBackend::Sqlite)
|
||||||
|
.to_string(),
|
||||||
|
r#"INSERT IGNORE INTO "cake" ("id", "name") VALUES (1, 'Apple Pie')"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -285,6 +285,33 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<M, N> IntoMockRow for (M, Option<N>)
|
||||||
|
where
|
||||||
|
M: ModelTrait,
|
||||||
|
N: ModelTrait,
|
||||||
|
{
|
||||||
|
fn into_mock_row(self) -> MockRow {
|
||||||
|
let mut mapped_join = BTreeMap::new();
|
||||||
|
|
||||||
|
for column in <<M as ModelTrait>::Entity as EntityTrait>::Column::iter() {
|
||||||
|
mapped_join.insert(
|
||||||
|
format!("{}{}", SelectA.as_str(), column.as_str()),
|
||||||
|
self.0.get(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if let Some(b_entity) = self.1 {
|
||||||
|
for column in <<N as ModelTrait>::Entity as EntityTrait>::Column::iter() {
|
||||||
|
mapped_join.insert(
|
||||||
|
format!("{}{}", SelectB.as_str(), column.as_str()),
|
||||||
|
b_entity.get(column),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mapped_join.into_mock_row()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T> IntoMockRow for BTreeMap<T, Value>
|
impl<T> IntoMockRow for BTreeMap<T, Value>
|
||||||
where
|
where
|
||||||
T: Into<String>,
|
T: Into<String>,
|
||||||
|
@ -960,7 +960,6 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_by_id("UUID".to_string());
|
|
||||||
delete_by_id("UUID".to_string());
|
delete_by_id("UUID".to_string());
|
||||||
delete_by_id("UUID");
|
delete_by_id("UUID");
|
||||||
delete_by_id(Cow::from("UUID"));
|
delete_by_id(Cow::from("UUID"));
|
||||||
|
@ -595,7 +595,7 @@ where
|
|||||||
///
|
///
|
||||||
/// > `SelectTwoMany::one()` method has been dropped (#486)
|
/// > `SelectTwoMany::one()` method has been dropped (#486)
|
||||||
/// >
|
/// >
|
||||||
/// > You can get `(Entity, Vec<RelatedEntity>)` by first querying a single model from Entity,
|
/// > You can get `(Entity, Vec<relatedEntity>)` by first querying a single model from Entity,
|
||||||
/// > then use [`ModelTrait::find_related`] on the model.
|
/// > then use [`ModelTrait::find_related`] on the model.
|
||||||
/// >
|
/// >
|
||||||
/// > See https://www.sea-ql.org/SeaORM/docs/basic-crud/select#lazy-loading for details.
|
/// > See https://www.sea-ql.org/SeaORM/docs/basic-crud/select#lazy-loading for details.
|
||||||
@ -1107,3 +1107,565 @@ where
|
|||||||
}
|
}
|
||||||
acc
|
acc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
|
fn cake_fruit_model(
|
||||||
|
cake_id: i32,
|
||||||
|
fruit_id: i32,
|
||||||
|
) -> (
|
||||||
|
sea_orm::tests_cfg::cake::Model,
|
||||||
|
sea_orm::tests_cfg::fruit::Model,
|
||||||
|
) {
|
||||||
|
(cake_model(cake_id), fruit_model(fruit_id, Some(cake_id)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cake_model(id: i32) -> sea_orm::tests_cfg::cake::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "apple cake",
|
||||||
|
2 => "orange cake",
|
||||||
|
3 => "fruit cake",
|
||||||
|
4 => "chocolate cake",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::cake::Model { id, name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fruit_model(id: i32, cake_id: Option<i32>) -> sea_orm::tests_cfg::fruit::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "apple",
|
||||||
|
2 => "orange",
|
||||||
|
3 => "grape",
|
||||||
|
4 => "strawberry",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::fruit::Model { id, name, cake_id }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cake_vendor_link(
|
||||||
|
cake_id: i32,
|
||||||
|
vendor_id: i32,
|
||||||
|
) -> (
|
||||||
|
sea_orm::tests_cfg::cake::Model,
|
||||||
|
sea_orm::tests_cfg::vendor::Model,
|
||||||
|
) {
|
||||||
|
(cake_model(cake_id), vendor_model(vendor_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn vendor_model(id: i32) -> sea_orm::tests_cfg::vendor::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "Apollo",
|
||||||
|
2 => "Benny",
|
||||||
|
3 => "Christine",
|
||||||
|
4 => "David",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::vendor::Model { id, name }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_related() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[cake_fruit_model(1, 1)]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_also_related(Fruit).all(&db).await?,
|
||||||
|
[(cake_model(1), Some(fruit_model(1, Some(1))))]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
[
|
||||||
|
r#"SELECT "cake"."id" AS "A_id", "cake"."name" AS "A_name","#,
|
||||||
|
r#""fruit"."id" AS "B_id", "fruit"."name" AS "B_name", "fruit"."cake_id" AS "B_cake_id""#,
|
||||||
|
r#"FROM "cake""#,
|
||||||
|
r#"LEFT JOIN "fruit" ON "cake"."id" = "fruit"."cake_id""#,
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
.as_str(),
|
||||||
|
[]
|
||||||
|
),])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_related_2() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[cake_fruit_model(1, 1), cake_fruit_model(1, 2)]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_also_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(fruit_model(1, Some(1)))),
|
||||||
|
(cake_model(1), Some(fruit_model(2, Some(1))))
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_related_3() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_fruit_model(1, 1),
|
||||||
|
cake_fruit_model(1, 2),
|
||||||
|
cake_fruit_model(2, 2),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_also_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(fruit_model(1, Some(1)))),
|
||||||
|
(cake_model(1), Some(fruit_model(2, Some(1)))),
|
||||||
|
(cake_model(2), Some(fruit_model(2, Some(2))))
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_related_4() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_fruit_model(1, 1).into_mock_row(),
|
||||||
|
cake_fruit_model(1, 2).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 2).into_mock_row(),
|
||||||
|
(cake_model(3), None::<fruit::Model>).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_also_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(fruit_model(1, Some(1)))),
|
||||||
|
(cake_model(1), Some(fruit_model(2, Some(1)))),
|
||||||
|
(cake_model(2), Some(fruit_model(2, Some(2)))),
|
||||||
|
(cake_model(3), None)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_related() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_fruit_model(1, 1),
|
||||||
|
cake_fruit_model(2, 2),
|
||||||
|
cake_fruit_model(2, 3),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_with_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![fruit_model(1, Some(1))]),
|
||||||
|
(
|
||||||
|
cake_model(2),
|
||||||
|
vec![fruit_model(2, Some(2)), fruit_model(3, Some(2))]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
[
|
||||||
|
r#"SELECT "cake"."id" AS "A_id", "cake"."name" AS "A_name","#,
|
||||||
|
r#""fruit"."id" AS "B_id", "fruit"."name" AS "B_name", "fruit"."cake_id" AS "B_cake_id""#,
|
||||||
|
r#"FROM "cake""#,
|
||||||
|
r#"LEFT JOIN "fruit" ON "cake"."id" = "fruit"."cake_id""#,
|
||||||
|
r#"ORDER BY "cake"."id" ASC"#
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
.as_str(),
|
||||||
|
[]
|
||||||
|
),])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_related_2() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_fruit_model(1, 1).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 1).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 2).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 3).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_with_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![fruit_model(1, Some(1)),]),
|
||||||
|
(
|
||||||
|
cake_model(2),
|
||||||
|
vec![
|
||||||
|
fruit_model(1, Some(2)),
|
||||||
|
fruit_model(2, Some(2)),
|
||||||
|
fruit_model(3, Some(2)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_related_empty() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_fruit_model(1, 1).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 1).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 2).into_mock_row(),
|
||||||
|
cake_fruit_model(2, 3).into_mock_row(),
|
||||||
|
(cake_model(3), None::<fruit::Model>).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find().find_with_related(Fruit).all(&db).await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![fruit_model(1, Some(1)),]),
|
||||||
|
(
|
||||||
|
cake_model(2),
|
||||||
|
vec![
|
||||||
|
fruit_model(1, Some(2)),
|
||||||
|
fruit_model(2, Some(2)),
|
||||||
|
fruit_model(3, Some(2)),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
(cake_model(3), vec![])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_linked_base() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[cake_vendor_link(1, 1)]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_also_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[(cake_model(1), Some(vendor_model(1)))]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
[
|
||||||
|
r#"SELECT "cake"."id" AS "A_id", "cake"."name" AS "A_name","#,
|
||||||
|
r#""r2"."id" AS "B_id", "r2"."name" AS "B_name""#,
|
||||||
|
r#"FROM "cake""#,
|
||||||
|
r#"LEFT JOIN "cake_filling" AS "r0" ON "cake"."id" = "r0"."cake_id""#,
|
||||||
|
r#"LEFT JOIN "filling" AS "r1" ON "r0"."filling_id" = "r1"."id""#,
|
||||||
|
r#"LEFT JOIN "vendor" AS "r2" ON "r1"."vendor_id" = "r2"."id""#,
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
.as_str(),
|
||||||
|
[]
|
||||||
|
),])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_linked_same_cake() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1),
|
||||||
|
cake_vendor_link(1, 2),
|
||||||
|
cake_vendor_link(2, 3),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_also_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(vendor_model(1))),
|
||||||
|
(cake_model(1), Some(vendor_model(2))),
|
||||||
|
(cake_model(2), Some(vendor_model(3)))
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_linked_same_vendor() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(3, 2).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_also_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(vendor_model(1))),
|
||||||
|
(cake_model(2), Some(vendor_model(1))),
|
||||||
|
(cake_model(3), Some(vendor_model(2))),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_linked_many_to_many() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(1, 2).into_mock_row(),
|
||||||
|
cake_vendor_link(1, 3).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 2).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_also_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(vendor_model(1))),
|
||||||
|
(cake_model(1), Some(vendor_model(2))),
|
||||||
|
(cake_model(1), Some(vendor_model(3))),
|
||||||
|
(cake_model(2), Some(vendor_model(1))),
|
||||||
|
(cake_model(2), Some(vendor_model(2))),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn also_linked_empty() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 2).into_mock_row(),
|
||||||
|
cake_vendor_link(3, 3).into_mock_row(),
|
||||||
|
(cake_model(4), None::<vendor::Model>).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_also_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), Some(vendor_model(1))),
|
||||||
|
(cake_model(2), Some(vendor_model(2))),
|
||||||
|
(cake_model(3), Some(vendor_model(3))),
|
||||||
|
(cake_model(4), None)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_linked_base() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, MockDatabase, Statement, Transaction};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1),
|
||||||
|
cake_vendor_link(2, 2),
|
||||||
|
cake_vendor_link(2, 3),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_with_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![vendor_model(1)]),
|
||||||
|
(cake_model(2), vec![vendor_model(2), vendor_model(3)])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
db.into_transaction_log(),
|
||||||
|
[Transaction::many([Statement::from_sql_and_values(
|
||||||
|
DbBackend::Postgres,
|
||||||
|
[
|
||||||
|
r#"SELECT "cake"."id" AS "A_id", "cake"."name" AS "A_name","#,
|
||||||
|
r#""r2"."id" AS "B_id", "r2"."name" AS "B_name" FROM "cake""#,
|
||||||
|
r#"LEFT JOIN "cake_filling" AS "r0" ON "cake"."id" = "r0"."cake_id""#,
|
||||||
|
r#"LEFT JOIN "filling" AS "r1" ON "r0"."filling_id" = "r1"."id""#,
|
||||||
|
r#"LEFT JOIN "vendor" AS "r2" ON "r1"."vendor_id" = "r2"."id""#,
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
.as_str(),
|
||||||
|
[]
|
||||||
|
),])]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_linked_same_vendor() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 2).into_mock_row(),
|
||||||
|
cake_vendor_link(3, 2).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_with_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![vendor_model(1)]),
|
||||||
|
(cake_model(2), vec![vendor_model(2)]),
|
||||||
|
(cake_model(3), vec![vendor_model(2)])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_linked_empty() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 2).into_mock_row(),
|
||||||
|
(cake_model(3), None::<vendor::Model>).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_with_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![vendor_model(1)]),
|
||||||
|
(cake_model(2), vec![vendor_model(1), vendor_model(2)]),
|
||||||
|
(cake_model(3), vec![])
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// normally would not happen
|
||||||
|
#[smol_potat::test]
|
||||||
|
pub async fn with_linked_repeated() -> Result<(), sea_orm::DbErr> {
|
||||||
|
use sea_orm::tests_cfg::*;
|
||||||
|
use sea_orm::{DbBackend, EntityTrait, IntoMockRow, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(1, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 1).into_mock_row(),
|
||||||
|
cake_vendor_link(2, 2).into_mock_row(),
|
||||||
|
]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Cake::find()
|
||||||
|
.find_with_linked(entity_linked::CakeToFillingVendor)
|
||||||
|
.all(&db)
|
||||||
|
.await?,
|
||||||
|
[
|
||||||
|
(cake_model(1), vec![vendor_model(1), vendor_model(1)]),
|
||||||
|
(cake_model(2), vec![vendor_model(1), vendor_model(2)]),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -440,72 +440,138 @@ fn table_column(tbl: &TableRef, col: &DynIden) -> ColumnRef {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
fn cake_model(id: i32) -> sea_orm::tests_cfg::cake::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "apple cake",
|
||||||
|
2 => "orange cake",
|
||||||
|
3 => "fruit cake",
|
||||||
|
4 => "chocolate cake",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::cake::Model { id, name }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fruit_model(id: i32, cake_id: Option<i32>) -> sea_orm::tests_cfg::fruit::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "apple",
|
||||||
|
2 => "orange",
|
||||||
|
3 => "grape",
|
||||||
|
4 => "strawberry",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::fruit::Model { id, name, cake_id }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filling_model(id: i32) -> sea_orm::tests_cfg::filling::Model {
|
||||||
|
let name = match id {
|
||||||
|
1 => "apple juice",
|
||||||
|
2 => "orange jam",
|
||||||
|
3 => "chocolate crust",
|
||||||
|
4 => "strawberry jam",
|
||||||
|
_ => "",
|
||||||
|
}
|
||||||
|
.to_string();
|
||||||
|
sea_orm::tests_cfg::filling::Model {
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
vendor_id: Some(1),
|
||||||
|
ignored_attr: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cake_filling_model(
|
||||||
|
cake_id: i32,
|
||||||
|
filling_id: i32,
|
||||||
|
) -> sea_orm::tests_cfg::cake_filling::Model {
|
||||||
|
sea_orm::tests_cfg::cake_filling::Model {
|
||||||
|
cake_id,
|
||||||
|
filling_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_load_one() {
|
async fn test_load_one() {
|
||||||
use crate::{
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, LoaderTrait, MockDatabase};
|
||||||
entity::prelude::*, tests_cfg::*, DbBackend, IntoMockRow, LoaderTrait, MockDatabase,
|
|
||||||
};
|
|
||||||
|
|
||||||
let db = MockDatabase::new(DbBackend::Postgres)
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
.append_query_results([[
|
.append_query_results([[cake_model(1), cake_model(2)]])
|
||||||
cake::Model {
|
|
||||||
id: 1,
|
|
||||||
name: "New York Cheese".to_owned(),
|
|
||||||
}
|
|
||||||
.into_mock_row(),
|
|
||||||
cake::Model {
|
|
||||||
id: 2,
|
|
||||||
name: "London Cheese".to_owned(),
|
|
||||||
}
|
|
||||||
.into_mock_row(),
|
|
||||||
]])
|
|
||||||
.into_connection();
|
.into_connection();
|
||||||
|
|
||||||
let fruits = vec![fruit::Model {
|
let fruits = vec![fruit_model(1, Some(1))];
|
||||||
id: 1,
|
|
||||||
name: "Apple".to_owned(),
|
|
||||||
cake_id: Some(1),
|
|
||||||
}];
|
|
||||||
|
|
||||||
let cakes = fruits
|
let cakes = fruits
|
||||||
.load_one(cake::Entity::find(), &db)
|
.load_one(cake::Entity::find(), &db)
|
||||||
.await
|
.await
|
||||||
.expect("Should return something");
|
.expect("Should return something");
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(cakes, [Some(cake_model(1))]);
|
||||||
cakes,
|
}
|
||||||
[Some(cake::Model {
|
|
||||||
id: 1,
|
#[tokio::test]
|
||||||
name: "New York Cheese".to_owned(),
|
async fn test_load_one_same_cake() {
|
||||||
})]
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, LoaderTrait, MockDatabase};
|
||||||
);
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[cake_model(1), cake_model(2)]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let fruits = vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))];
|
||||||
|
|
||||||
|
let cakes = fruits
|
||||||
|
.load_one(cake::Entity::find(), &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
assert_eq!(cakes, [Some(cake_model(1)), Some(cake_model(1))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_load_one_empty() {
|
||||||
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, LoaderTrait, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[cake_model(1), cake_model(2)]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let fruits: Vec<fruit::Model> = vec![];
|
||||||
|
|
||||||
|
let cakes = fruits
|
||||||
|
.load_one(cake::Entity::find(), &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
assert_eq!(cakes, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_load_many() {
|
async fn test_load_many() {
|
||||||
use crate::{
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, LoaderTrait, MockDatabase};
|
||||||
entity::prelude::*, tests_cfg::*, DbBackend, IntoMockRow, LoaderTrait, MockDatabase,
|
|
||||||
};
|
|
||||||
|
|
||||||
let db = MockDatabase::new(DbBackend::Postgres)
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
.append_query_results([[fruit::Model {
|
.append_query_results([[fruit_model(1, Some(1))]])
|
||||||
id: 1,
|
|
||||||
name: "Apple".to_owned(),
|
|
||||||
cake_id: Some(1),
|
|
||||||
}
|
|
||||||
.into_mock_row()]])
|
|
||||||
.into_connection();
|
.into_connection();
|
||||||
|
|
||||||
let cakes = vec![
|
let cakes = vec![cake_model(1), cake_model(2)];
|
||||||
cake::Model {
|
|
||||||
id: 1,
|
let fruits = cakes
|
||||||
name: "New York Cheese".to_owned(),
|
.load_many(fruit::Entity::find(), &db)
|
||||||
},
|
.await
|
||||||
cake::Model {
|
.expect("Should return something");
|
||||||
id: 2,
|
|
||||||
name: "London Cheese".to_owned(),
|
assert_eq!(fruits, [vec![fruit_model(1, Some(1))], vec![]]);
|
||||||
},
|
}
|
||||||
];
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_load_many_same_fruit() {
|
||||||
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, LoaderTrait, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[fruit_model(1, Some(1)), fruit_model(2, Some(1))]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let cakes = vec![cake_model(1), cake_model(2)];
|
||||||
|
|
||||||
let fruits = cakes
|
let fruits = cakes
|
||||||
.load_many(fruit::Entity::find(), &db)
|
.load_many(fruit::Entity::find(), &db)
|
||||||
@ -515,13 +581,120 @@ mod tests {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
fruits,
|
fruits,
|
||||||
[
|
[
|
||||||
vec![fruit::Model {
|
vec![fruit_model(1, Some(1)), fruit_model(2, Some(1))],
|
||||||
id: 1,
|
|
||||||
name: "Apple".to_owned(),
|
|
||||||
cake_id: Some(1),
|
|
||||||
}],
|
|
||||||
vec![]
|
vec![]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: load many with empty vector will panic
|
||||||
|
// #[tokio::test]
|
||||||
|
async fn test_load_many_empty() {
|
||||||
|
use sea_orm::{entity::prelude::*, tests_cfg::*, DbBackend, MockDatabase};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([[fruit_model(1, Some(1)), fruit_model(2, Some(1))]])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let cakes: Vec<cake::Model> = vec![];
|
||||||
|
|
||||||
|
let fruits = cakes
|
||||||
|
.load_many(fruit::Entity::find(), &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
let empty_vec: Vec<Vec<fruit::Model>> = vec![];
|
||||||
|
|
||||||
|
assert_eq!(fruits, empty_vec);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_load_many_to_many_base() {
|
||||||
|
use sea_orm::{
|
||||||
|
entity::prelude::*, tests_cfg::*, DbBackend, IntoMockRow, LoaderTrait, MockDatabase,
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([
|
||||||
|
[cake_filling_model(1, 1).into_mock_row()],
|
||||||
|
[filling_model(1).into_mock_row()],
|
||||||
|
])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let cakes = vec![cake_model(1)];
|
||||||
|
|
||||||
|
let fillings = cakes
|
||||||
|
.load_many_to_many(Filling, CakeFilling, &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
assert_eq!(fillings, vec![vec![filling_model(1)]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_load_many_to_many_complex() {
|
||||||
|
use sea_orm::{
|
||||||
|
entity::prelude::*, tests_cfg::*, DbBackend, IntoMockRow, LoaderTrait, MockDatabase,
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([
|
||||||
|
[
|
||||||
|
cake_filling_model(1, 1).into_mock_row(),
|
||||||
|
cake_filling_model(1, 2).into_mock_row(),
|
||||||
|
cake_filling_model(1, 3).into_mock_row(),
|
||||||
|
cake_filling_model(2, 1).into_mock_row(),
|
||||||
|
cake_filling_model(2, 2).into_mock_row(),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
filling_model(1).into_mock_row(),
|
||||||
|
filling_model(2).into_mock_row(),
|
||||||
|
filling_model(3).into_mock_row(),
|
||||||
|
filling_model(4).into_mock_row(),
|
||||||
|
filling_model(5).into_mock_row(),
|
||||||
|
],
|
||||||
|
])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let cakes = vec![cake_model(1), cake_model(2), cake_model(3)];
|
||||||
|
|
||||||
|
let fillings = cakes
|
||||||
|
.load_many_to_many(Filling, CakeFilling, &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
fillings,
|
||||||
|
vec![
|
||||||
|
vec![filling_model(1), filling_model(2), filling_model(3)],
|
||||||
|
vec![filling_model(1), filling_model(2)],
|
||||||
|
vec![],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_load_many_to_many_empty() {
|
||||||
|
use sea_orm::{
|
||||||
|
entity::prelude::*, tests_cfg::*, DbBackend, IntoMockRow, LoaderTrait, MockDatabase,
|
||||||
|
};
|
||||||
|
|
||||||
|
let db = MockDatabase::new(DbBackend::Postgres)
|
||||||
|
.append_query_results([
|
||||||
|
[cake_filling_model(1, 1).into_mock_row()],
|
||||||
|
[filling_model(1).into_mock_row()],
|
||||||
|
])
|
||||||
|
.into_connection();
|
||||||
|
|
||||||
|
let cakes: Vec<cake::Model> = vec![];
|
||||||
|
|
||||||
|
let fillings = cakes
|
||||||
|
.load_many_to_many(Filling, CakeFilling, &db)
|
||||||
|
.await
|
||||||
|
.expect("Should return something");
|
||||||
|
|
||||||
|
let empty_vec: Vec<Vec<filling::Model>> = vec![];
|
||||||
|
|
||||||
|
assert_eq!(fillings, empty_vec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,27 @@ pub async fn find_linked_active_enum(db: &DatabaseConnection) -> Result<(), DbEr
|
|||||||
})
|
})
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ActiveEnum::find()
|
||||||
|
.find_with_linked(active_enum::ActiveEnumChildLink)
|
||||||
|
.all(db)
|
||||||
|
.await?,
|
||||||
|
[(
|
||||||
|
active_enum::Model {
|
||||||
|
id: 2,
|
||||||
|
category: Some(Category::Small),
|
||||||
|
color: Some(Color::White),
|
||||||
|
tea: Some(Tea::BreakfastTea),
|
||||||
|
},
|
||||||
|
vec![active_enum_child::Model {
|
||||||
|
id: 1,
|
||||||
|
parent_id: 2,
|
||||||
|
category: Some(Category::Big),
|
||||||
|
color: Some(Color::Black),
|
||||||
|
tea: Some(Tea::EverydayTea),
|
||||||
|
}]
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
active_enum_child::Model {
|
active_enum_child::Model {
|
||||||
@ -411,6 +432,27 @@ pub async fn find_linked_active_enum(db: &DatabaseConnection) -> Result<(), DbEr
|
|||||||
})
|
})
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
ActiveEnumChild::find()
|
||||||
|
.find_with_linked(active_enum_child::ActiveEnumLink)
|
||||||
|
.all(db)
|
||||||
|
.await?,
|
||||||
|
[(
|
||||||
|
active_enum_child::Model {
|
||||||
|
id: 1,
|
||||||
|
parent_id: 2,
|
||||||
|
category: Some(Category::Big),
|
||||||
|
color: Some(Color::Black),
|
||||||
|
tea: Some(Tea::EverydayTea),
|
||||||
|
},
|
||||||
|
vec![active_enum::Model {
|
||||||
|
id: 2,
|
||||||
|
category: Some(Category::Small),
|
||||||
|
color: Some(Color::White),
|
||||||
|
tea: Some(Tea::BreakfastTea),
|
||||||
|
}]
|
||||||
|
)]
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,7 @@ pub async fn test_update_cake(db: &DbConn) {
|
|||||||
let cake_model = cake.unwrap();
|
let cake_model = cake.unwrap();
|
||||||
assert_eq!(cake_model.name, "Extra chocolate mud cake");
|
assert_eq!(cake_model.name, "Extra chocolate mud cake");
|
||||||
assert_eq!(cake_model.price, dec!(20.00));
|
assert_eq!(cake_model.price, dec!(20.00));
|
||||||
|
assert!(!cake_model.gluten_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_update_bakery(db: &DbConn) {
|
pub async fn test_update_bakery(db: &DbConn) {
|
||||||
|
@ -9,6 +9,7 @@ pub use sea_orm::{
|
|||||||
pub use crud::*;
|
pub use crud::*;
|
||||||
// use common::bakery_chain::*;
|
// use common::bakery_chain::*;
|
||||||
use sea_orm::{DbConn, TryInsertResult};
|
use sea_orm::{DbConn, TryInsertResult};
|
||||||
|
use sea_query::OnConflict;
|
||||||
|
|
||||||
#[sea_orm_macros::test]
|
#[sea_orm_macros::test]
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
@ -37,6 +38,12 @@ pub async fn test(db: &DbConn) {
|
|||||||
|
|
||||||
assert!(matches!(res, Ok(TryInsertResult::Inserted(_))));
|
assert!(matches!(res, Ok(TryInsertResult::Inserted(_))));
|
||||||
|
|
||||||
|
let double_seaside_bakery = bakery::ActiveModel {
|
||||||
|
name: Set("SeaSide Bakery".to_owned()),
|
||||||
|
profit_margin: Set(10.4),
|
||||||
|
id: Set(1),
|
||||||
|
};
|
||||||
|
|
||||||
let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>())
|
let empty_insert = Bakery::insert_many(std::iter::empty::<bakery::ActiveModel>())
|
||||||
.on_empty_do_nothing()
|
.on_empty_do_nothing()
|
||||||
.exec(db)
|
.exec(db)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub mod common;
|
pub mod common;
|
||||||
|
|
||||||
pub use common::{bakery_chain::*, setup::*, TestContext};
|
pub use common::{bakery_chain::*, setup::*, TestContext};
|
||||||
use sea_orm::{entity::*, query::*, DbConn, DbErr};
|
use sea_orm::{entity::*, query::*, DbConn, DbErr, RuntimeErr};
|
||||||
|
|
||||||
#[sea_orm_macros::test]
|
#[sea_orm_macros::test]
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
@ -32,6 +32,17 @@ async fn loader_load_one() -> Result<(), DbErr> {
|
|||||||
assert_eq!(bakers, [baker_1, baker_2, baker_3]);
|
assert_eq!(bakers, [baker_1, baker_2, baker_3]);
|
||||||
assert_eq!(bakeries, [Some(bakery_0.clone()), Some(bakery_0), None]);
|
assert_eq!(bakeries, [Some(bakery_0.clone()), Some(bakery_0), None]);
|
||||||
|
|
||||||
|
// has many find, should use load_many instead
|
||||||
|
let bakeries = bakery::Entity::find().all(&ctx.db).await?;
|
||||||
|
let bakers = bakeries.load_one(baker::Entity, &ctx.db).await;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
bakers,
|
||||||
|
Err(DbErr::Query(RuntimeErr::Internal(
|
||||||
|
"Relation is HasMany instead of HasOne".to_string()
|
||||||
|
)))
|
||||||
|
);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +58,7 @@ async fn loader_load_many() -> Result<(), DbErr> {
|
|||||||
|
|
||||||
let bakery_1 = insert_bakery(&ctx.db, "SeaSide Bakery").await?;
|
let bakery_1 = insert_bakery(&ctx.db, "SeaSide Bakery").await?;
|
||||||
let bakery_2 = insert_bakery(&ctx.db, "Offshore Bakery").await?;
|
let bakery_2 = insert_bakery(&ctx.db, "Offshore Bakery").await?;
|
||||||
|
let bakery_3 = insert_bakery(&ctx.db, "Rocky Bakery").await?;
|
||||||
|
|
||||||
let baker_1 = insert_baker(&ctx.db, "Baker 1", bakery_1.id).await?;
|
let baker_1 = insert_baker(&ctx.db, "Baker 1", bakery_1.id).await?;
|
||||||
let baker_2 = insert_baker(&ctx.db, "Baker 2", bakery_1.id).await?;
|
let baker_2 = insert_baker(&ctx.db, "Baker 2", bakery_1.id).await?;
|
||||||
@ -57,12 +69,16 @@ async fn loader_load_many() -> Result<(), DbErr> {
|
|||||||
let bakeries = bakery::Entity::find().all(&ctx.db).await?;
|
let bakeries = bakery::Entity::find().all(&ctx.db).await?;
|
||||||
let bakers = bakeries.load_many(baker::Entity, &ctx.db).await?;
|
let bakers = bakeries.load_many(baker::Entity, &ctx.db).await?;
|
||||||
|
|
||||||
assert_eq!(bakeries, [bakery_1.clone(), bakery_2.clone()]);
|
assert_eq!(
|
||||||
|
bakeries,
|
||||||
|
[bakery_1.clone(), bakery_2.clone(), bakery_3.clone()]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
bakers,
|
bakers,
|
||||||
[
|
[
|
||||||
[baker_1.clone(), baker_2.clone()],
|
vec![baker_1.clone(), baker_2.clone()],
|
||||||
[baker_3.clone(), baker_4.clone()]
|
vec![baker_3.clone(), baker_4.clone()],
|
||||||
|
vec![]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -79,7 +95,8 @@ async fn loader_load_many() -> Result<(), DbErr> {
|
|||||||
bakers,
|
bakers,
|
||||||
[
|
[
|
||||||
vec![baker_1.clone(), baker_2.clone()],
|
vec![baker_1.clone(), baker_2.clone()],
|
||||||
vec![baker_4.clone()]
|
vec![baker_4.clone()],
|
||||||
|
vec![]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -150,6 +167,7 @@ async fn loader_load_many_to_many() -> Result<(), DbErr> {
|
|||||||
|
|
||||||
let baker_1 = insert_baker(&ctx.db, "Jane", bakery_1.id).await?;
|
let baker_1 = insert_baker(&ctx.db, "Jane", bakery_1.id).await?;
|
||||||
let baker_2 = insert_baker(&ctx.db, "Peter", bakery_1.id).await?;
|
let baker_2 = insert_baker(&ctx.db, "Peter", bakery_1.id).await?;
|
||||||
|
let baker_3 = insert_baker(&ctx.db, "Fred", bakery_1.id).await?; // does not make cake
|
||||||
|
|
||||||
let cake_1 = insert_cake(&ctx.db, "Cheesecake", None).await?;
|
let cake_1 = insert_cake(&ctx.db, "Cheesecake", None).await?;
|
||||||
let cake_2 = insert_cake(&ctx.db, "Coffee", None).await?;
|
let cake_2 = insert_cake(&ctx.db, "Coffee", None).await?;
|
||||||
@ -166,12 +184,13 @@ async fn loader_load_many_to_many() -> Result<(), DbErr> {
|
|||||||
.load_many_to_many(cake::Entity, cakes_bakers::Entity, &ctx.db)
|
.load_many_to_many(cake::Entity, cakes_bakers::Entity, &ctx.db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
assert_eq!(bakers, [baker_1.clone(), baker_2.clone()]);
|
assert_eq!(bakers, [baker_1.clone(), baker_2.clone(), baker_3.clone()]);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cakes,
|
cakes,
|
||||||
[
|
[
|
||||||
vec![cake_1.clone(), cake_2.clone()],
|
vec![cake_1.clone(), cake_2.clone()],
|
||||||
vec![cake_2.clone(), cake_3.clone()]
|
vec![cake_2.clone(), cake_3.clone()],
|
||||||
|
vec![]
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -184,7 +203,7 @@ async fn loader_load_many_to_many() -> Result<(), DbErr> {
|
|||||||
&ctx.db,
|
&ctx.db,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()]]);
|
assert_eq!(cakes, [vec![cake_1.clone()], vec![cake_3.clone()], vec![]]);
|
||||||
|
|
||||||
// now, start again from cakes
|
// now, start again from cakes
|
||||||
|
|
||||||
|
@ -494,6 +494,255 @@ pub async fn having() {
|
|||||||
ctx.delete().await;
|
ctx.delete().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[sea_orm_macros::test]
|
||||||
|
#[cfg(any(
|
||||||
|
feature = "sqlx-mysql",
|
||||||
|
feature = "sqlx-sqlite",
|
||||||
|
feature = "sqlx-postgres"
|
||||||
|
))]
|
||||||
|
pub async fn related() -> Result<(), DbErr> {
|
||||||
|
use sea_orm::{SelectA, SelectB};
|
||||||
|
|
||||||
|
let ctx = TestContext::new("test_related").await;
|
||||||
|
create_tables(&ctx.db).await?;
|
||||||
|
|
||||||
|
// SeaSide Bakery
|
||||||
|
let seaside_bakery = bakery::ActiveModel {
|
||||||
|
name: Set("SeaSide Bakery".to_owned()),
|
||||||
|
profit_margin: Set(10.4),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let seaside_bakery_res = Bakery::insert(seaside_bakery).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
// Bob's 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(seaside_bakery_res.last_insert_id)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _baker_bob_res = Baker::insert(baker_bob).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
// Bobby's Baker
|
||||||
|
let baker_bobby = baker::ActiveModel {
|
||||||
|
name: Set("Baker Bobby".to_owned()),
|
||||||
|
contact_details: Set(serde_json::json!({
|
||||||
|
"mobile": "+85212345678",
|
||||||
|
})),
|
||||||
|
bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _baker_bobby_res = Baker::insert(baker_bobby).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
// Terres Bakery
|
||||||
|
let terres_bakery = bakery::ActiveModel {
|
||||||
|
name: Set("Terres Bakery".to_owned()),
|
||||||
|
profit_margin: Set(13.5),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let terres_bakery_res = Bakery::insert(terres_bakery).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
// Ada's Baker
|
||||||
|
let baker_ada = baker::ActiveModel {
|
||||||
|
name: Set("Baker Ada".to_owned()),
|
||||||
|
contact_details: Set(serde_json::json!({
|
||||||
|
"mobile": "+61424000000",
|
||||||
|
"home": "0395555555",
|
||||||
|
"address": "12 Test St, Testville, Vic, Australia"
|
||||||
|
})),
|
||||||
|
bakery_id: Set(Some(terres_bakery_res.last_insert_id)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _baker_ada_res = Baker::insert(baker_ada).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
// Stone Bakery, with no baker
|
||||||
|
let stone_bakery = bakery::ActiveModel {
|
||||||
|
name: Set("Stone Bakery".to_owned()),
|
||||||
|
profit_margin: Set(13.5),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _stone_bakery_res = Bakery::insert(stone_bakery).exec(&ctx.db).await?;
|
||||||
|
|
||||||
|
#[derive(Debug, FromQueryResult, PartialEq)]
|
||||||
|
struct BakerLite {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, FromQueryResult, PartialEq)]
|
||||||
|
struct BakeryLite {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all bakery and baker's name and put them into tuples
|
||||||
|
let bakers_in_bakery: Vec<(BakeryLite, Option<BakerLite>)> = Bakery::find()
|
||||||
|
.find_also_related(Baker)
|
||||||
|
.select_only()
|
||||||
|
.column_as(bakery::Column::Name, (SelectA, bakery::Column::Name))
|
||||||
|
.column_as(baker::Column::Name, (SelectB, baker::Column::Name))
|
||||||
|
.order_by_asc(bakery::Column::Id)
|
||||||
|
.order_by_asc(baker::Column::Id)
|
||||||
|
.into_model()
|
||||||
|
.all(&ctx.db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
bakers_in_bakery,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
BakeryLite {
|
||||||
|
name: "SeaSide Bakery".to_owned(),
|
||||||
|
},
|
||||||
|
Some(BakerLite {
|
||||||
|
name: "Baker Bob".to_owned(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
(
|
||||||
|
BakeryLite {
|
||||||
|
name: "SeaSide Bakery".to_owned(),
|
||||||
|
},
|
||||||
|
Some(BakerLite {
|
||||||
|
name: "Baker Bobby".to_owned(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
(
|
||||||
|
BakeryLite {
|
||||||
|
name: "Terres Bakery".to_owned(),
|
||||||
|
},
|
||||||
|
Some(BakerLite {
|
||||||
|
name: "Baker Ada".to_owned(),
|
||||||
|
})
|
||||||
|
),
|
||||||
|
(
|
||||||
|
BakeryLite {
|
||||||
|
name: "Stone Bakery".to_owned(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
let seaside_bakery = Bakery::find()
|
||||||
|
.filter(bakery::Column::Id.eq(1))
|
||||||
|
.one(&ctx.db)
|
||||||
|
.await?
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let bakers = seaside_bakery.find_related(Baker).all(&ctx.db).await?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
bakers,
|
||||||
|
[
|
||||||
|
baker::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "Baker Bob".to_owned(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+61424000000",
|
||||||
|
"home": "0395555555",
|
||||||
|
"address": "12 Test St, Testville, Vic, Australia"
|
||||||
|
}),
|
||||||
|
bakery_id: Some(1),
|
||||||
|
},
|
||||||
|
baker::Model {
|
||||||
|
id: 2,
|
||||||
|
name: "Baker Bobby".to_owned(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+85212345678",
|
||||||
|
}),
|
||||||
|
bakery_id: Some(1),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
let select_bakery_with_baker = Bakery::find()
|
||||||
|
.find_with_related(Baker)
|
||||||
|
.order_by_asc(baker::Column::Id);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
select_bakery_with_baker
|
||||||
|
.build(sea_orm::DatabaseBackend::MySql)
|
||||||
|
.to_string(),
|
||||||
|
[
|
||||||
|
"SELECT `bakery`.`id` AS `A_id`,",
|
||||||
|
"`bakery`.`name` AS `A_name`,",
|
||||||
|
"`bakery`.`profit_margin` AS `A_profit_margin`,",
|
||||||
|
"`baker`.`id` AS `B_id`,",
|
||||||
|
"`baker`.`name` AS `B_name`,",
|
||||||
|
"`baker`.`contact_details` AS `B_contact_details`,",
|
||||||
|
"`baker`.`bakery_id` AS `B_bakery_id`",
|
||||||
|
"FROM `bakery`",
|
||||||
|
"LEFT JOIN `baker` ON `bakery`.`id` = `baker`.`bakery_id`",
|
||||||
|
"ORDER BY `bakery`.`id` ASC, `baker`.`id` ASC"
|
||||||
|
]
|
||||||
|
.join(" ")
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
select_bakery_with_baker.all(&ctx.db).await?,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
bakery::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "SeaSide Bakery".to_owned(),
|
||||||
|
profit_margin: 10.4,
|
||||||
|
},
|
||||||
|
vec![
|
||||||
|
baker::Model {
|
||||||
|
id: 1,
|
||||||
|
name: "Baker Bob".to_owned(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+61424000000",
|
||||||
|
"home": "0395555555",
|
||||||
|
"address": "12 Test St, Testville, Vic, Australia"
|
||||||
|
}),
|
||||||
|
bakery_id: Some(seaside_bakery_res.last_insert_id),
|
||||||
|
},
|
||||||
|
baker::Model {
|
||||||
|
id: 2,
|
||||||
|
name: "Baker Bobby".to_owned(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+85212345678",
|
||||||
|
}),
|
||||||
|
bakery_id: Some(seaside_bakery_res.last_insert_id),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
bakery::Model {
|
||||||
|
id: 2,
|
||||||
|
name: "Terres Bakery".to_owned(),
|
||||||
|
profit_margin: 13.5,
|
||||||
|
},
|
||||||
|
vec![baker::Model {
|
||||||
|
id: 3,
|
||||||
|
name: "Baker Ada".to_owned(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+61424000000",
|
||||||
|
"home": "0395555555",
|
||||||
|
"address": "12 Test St, Testville, Vic, Australia"
|
||||||
|
}),
|
||||||
|
bakery_id: Some(terres_bakery_res.last_insert_id),
|
||||||
|
}]
|
||||||
|
),
|
||||||
|
(
|
||||||
|
bakery::Model {
|
||||||
|
id: 3,
|
||||||
|
name: "Stone Bakery".to_owned(),
|
||||||
|
profit_margin: 13.5,
|
||||||
|
},
|
||||||
|
vec![]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
ctx.delete().await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[sea_orm_macros::test]
|
#[sea_orm_macros::test]
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "sqlx-mysql",
|
feature = "sqlx-mysql",
|
||||||
@ -586,6 +835,17 @@ pub async fn linked() -> Result<(), DbErr> {
|
|||||||
.exec(&ctx.db)
|
.exec(&ctx.db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// Freerider's Baker, no cake baked
|
||||||
|
let baker_freerider = baker::ActiveModel {
|
||||||
|
name: Set("Freerider".to_owned()),
|
||||||
|
contact_details: Set(serde_json::json!({
|
||||||
|
"mobile": "+85298765432",
|
||||||
|
})),
|
||||||
|
bakery_id: Set(Some(seaside_bakery_res.last_insert_id)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
let _baker_freerider_res = Baker::insert(baker_freerider).exec(&ctx.db).await?;
|
||||||
|
|
||||||
// Kate's Customer, Order & Line Item
|
// Kate's Customer, Order & Line Item
|
||||||
let customer_kate = customer::ActiveModel {
|
let customer_kate = customer::ActiveModel {
|
||||||
name: Set("Kate".to_owned()),
|
name: Set("Kate".to_owned()),
|
||||||
@ -680,6 +940,7 @@ pub async fn linked() -> Result<(), DbErr> {
|
|||||||
name: String,
|
name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// filtered find
|
||||||
let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find()
|
let baked_for_customers: Vec<(BakerLite, Option<CustomerLite>)> = Baker::find()
|
||||||
.find_also_linked(baker::BakedForCustomer)
|
.find_also_linked(baker::BakedForCustomer)
|
||||||
.select_only()
|
.select_only()
|
||||||
@ -725,9 +986,16 @@ pub async fn linked() -> Result<(), DbErr> {
|
|||||||
name: "Kara".to_owned(),
|
name: "Kara".to_owned(),
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
BakerLite {
|
||||||
|
name: "Freerider".to_owned(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// try to use find_linked instead
|
||||||
let baker_bob = Baker::find()
|
let baker_bob = Baker::find()
|
||||||
.filter(baker::Column::Id.eq(1))
|
.filter(baker::Column::Id.eq(1))
|
||||||
.one(&ctx.db)
|
.one(&ctx.db)
|
||||||
@ -748,6 +1016,7 @@ pub async fn linked() -> Result<(), DbErr> {
|
|||||||
}]
|
}]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// find full model using with_linked
|
||||||
let select_baker_with_customer = Baker::find()
|
let select_baker_with_customer = Baker::find()
|
||||||
.find_with_linked(baker::BakedForCustomer)
|
.find_with_linked(baker::BakedForCustomer)
|
||||||
.order_by_asc(baker::Column::Id)
|
.order_by_asc(baker::Column::Id)
|
||||||
@ -823,6 +1092,17 @@ pub async fn linked() -> Result<(), DbErr> {
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
baker::Model {
|
||||||
|
id: 3,
|
||||||
|
name: "Freerider".into(),
|
||||||
|
contact_details: serde_json::json!({
|
||||||
|
"mobile": "+85298765432",
|
||||||
|
}),
|
||||||
|
bakery_id: Some(1),
|
||||||
|
},
|
||||||
|
vec![]
|
||||||
|
),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -64,4 +64,7 @@ pub async fn test_error(db: &DatabaseConnection) {
|
|||||||
fk_error.sql_err(),
|
fk_error.sql_err(),
|
||||||
Some(SqlErr::ForeignKeyConstraintViolation(_))
|
Some(SqlErr::ForeignKeyConstraintViolation(_))
|
||||||
));
|
));
|
||||||
|
|
||||||
|
let invalid_error = DbErr::Custom("random error".to_string());
|
||||||
|
assert_eq!(invalid_error.sql_err(), None)
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,7 @@ pub fn type_test() {
|
|||||||
assert_eq!(Integer::array_type(), ArrayType::Int);
|
assert_eq!(Integer::array_type(), ArrayType::Int);
|
||||||
assert_eq!(Boolbean::column_type(), ColumnType::Boolean);
|
assert_eq!(Boolbean::column_type(), ColumnType::Boolean);
|
||||||
assert_eq!(Boolbean::array_type(), ArrayType::Bool);
|
assert_eq!(Boolbean::array_type(), ArrayType::Bool);
|
||||||
|
|
||||||
// self implied
|
// self implied
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
StringVec::column_type(),
|
StringVec::column_type(),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user