use crate::ambiguity::{
first_schema::FirstTableColumnTrait as _, first_schema::SecondTableColumnTrait as _,
second_schema::SecondTableColumnTrait as _,
};
use std::sync::{Arc, LazyLock};
use tank::{
Entity, Executor, expr,
stream::{StreamExt, TryStreamExt},
};
use tokio::sync::Mutex;
static MUTEX: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
mod first_schema {
use std::sync::Arc;
use tank::Entity;
#[derive(Entity, PartialEq, Debug)]
#[tank(schema = "first_schema")]
pub struct FirstTable {
#[tank(primary_key)]
pub first_col: String,
#[cfg(not(feature = "disable-large-integers"))]
pub second_col: Option<u128>,
}
#[derive(Entity, PartialEq, Debug)]
#[tank(schema = "first_schema")]
pub struct SecondTable {
#[tank(primary_key)]
pub first_col: String,
pub second_col: Option<f64>,
pub third_col: Option<Arc<u8>>,
}
}
mod second_schema {
use std::sync::Arc;
use tank::Entity;
#[derive(Entity, PartialEq, Debug)]
#[tank(schema = "second_schema")]
pub struct FirstTable {
#[tank(primary_key)]
pub first_col: String,
#[cfg(not(feature = "disable-large-integers"))]
pub second_col: Option<u128>,
}
#[derive(Entity, PartialEq, Debug)]
#[tank(schema = "second_schema")]
pub struct SecondTable {
#[tank(primary_key)]
pub first_col: String,
pub second_col: Option<f64>,
pub third_col: Option<Arc<u8>>,
}
}
pub async fn ambiguity(executor: &mut impl Executor) {
let _lock = MUTEX.lock().await;
first_schema::FirstTable::drop_table(executor, true, false)
.await
.expect("Could not drop the first_schema::FirstTable table");
first_schema::FirstTable::create_table(executor, false, true)
.await
.expect("Could not create the first_schema::FirstTable table");
first_schema::SecondTable::drop_table(executor, true, false)
.await
.expect("Could not drop the first_schema::SecondTable table");
first_schema::SecondTable::create_table(executor, false, true)
.await
.expect("Could not create the first_schema::SecondTable table");
second_schema::FirstTable::drop_table(executor, true, false)
.await
.expect("Could not drop the second_schema::FirstTable table");
second_schema::FirstTable::create_table(executor, false, true)
.await
.expect("Could not create the second_schema::FirstTable table");
second_schema::SecondTable::drop_table(executor, true, false)
.await
.expect("Could not drop the second_schema::SecondTable table");
second_schema::SecondTable::create_table(executor, false, true)
.await
.expect("Could not create the second_schema::SecondTable table");
first_schema::FirstTable {
first_col: "a value".into(),
#[cfg(not(feature = "disable-large-integers"))]
second_col: 83721.into(),
}
.save(executor)
.await
.expect("Could not save the first entity");
assert_eq!(
first_schema::FirstTable::find_many(
executor,
expr!(first_schema::FirstTable::first_col == "a value"),
None
)
.try_collect::<Vec<_>>()
.await
.expect(""),
[first_schema::FirstTable {
first_col: "a value".into(),
#[cfg(not(feature = "disable-large-integers"))]
second_col: 83721.into(),
}]
);
assert_eq!(
first_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
assert_eq!(
first_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
let insert_result = second_schema::SecondTable::insert_one(
executor,
&second_schema::SecondTable {
first_col: "another_value".into(),
second_col: None,
third_col: Some(Arc::new(19)),
},
)
.await
.expect("Could not insert second_schema::SecondTable");
if let Some(affected) = insert_result.rows_affected {
assert_eq!(affected, 1);
}
assert_eq!(
second_schema::SecondTable::find_many(
executor,
expr!(second_schema::SecondTable::first_col == "another_value"),
None
)
.try_collect::<Vec<_>>()
.await
.expect(""),
[second_schema::SecondTable {
first_col: "another_value".into(),
second_col: None,
third_col: Some(Arc::new(19)),
}]
);
assert_eq!(
first_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
assert_eq!(
first_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
let mut fetched = second_schema::SecondTable::find_one(
executor,
expr!(second_schema::SecondTable::first_col == "another_value"),
)
.await
.expect("Failed to fetch inserted second_schema::SecondTable")
.expect("Inserted row not found");
assert_eq!(fetched.third_col, Some(Arc::new(19)));
fetched.third_col = Some(Arc::new(20));
fetched
.save(executor)
.await
.expect("Could not save updated second_schema::SecondTable");
let fetched2 = second_schema::SecondTable::find_one(
executor,
expr!(second_schema::SecondTable::first_col == "another_value"),
)
.await
.expect("Failed to refetch second_schema::SecondTable")
.expect("Refetched row not found");
assert_eq!(fetched2.third_col, Some(Arc::new(20)));
assert_eq!(
first_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
assert_eq!(
first_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
let insert_result2 = first_schema::SecondTable::insert_one(
executor,
&first_schema::SecondTable {
first_col: "another_value".into(),
second_col: Some(3.14),
third_col: Some(Arc::new(21)),
},
)
.await
.expect("Could not insert first_schema::SecondTable");
if let Some(affected) = insert_result2.rows_affected {
assert_eq!(affected, 1);
}
assert_eq!(
first_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
assert_eq!(
first_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
assert_eq!(
second_schema::FirstTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
0
);
assert_eq!(
second_schema::SecondTable::find_many(executor, true, None)
.map_err(|e| panic!("{e:#}"))
.count()
.await,
1
);
let fs = first_schema::SecondTable::find_one(
executor,
expr!(first_schema::SecondTable::first_col == "another_value"),
)
.await
.expect("Failed to fetch first_schema::SecondTable")
.expect("Row in first_schema::SecondTable not found");
assert_eq!(fs.third_col, Some(Arc::new(21)));
first_schema::FirstTable::delete_many(executor, true)
.await
.expect("Failed to clear first_schema::FirstTable");
#[allow(unused_mut)]
let mut entity = first_schema::FirstTable {
first_col: "pk_only".into(),
#[cfg(not(feature = "disable-large-integers"))]
second_col: None,
};
entity.save(executor).await.expect("Failed to save entity");
#[cfg(not(feature = "disable-large-integers"))]
{
entity.second_col = Some(12345678901234567890u128);
}
entity
.save(executor)
.await
.expect("Failed to update entity");
assert_eq!(
first_schema::FirstTable::find_many(
executor,
expr!(first_schema::FirstTable::first_col == "pk_only"),
None
)
.count()
.await,
1
);
}