use picante::PicanteResult;
use std::sync::atomic::{AtomicUsize, Ordering};
#[picante::input]
struct A {
#[key]
key: String,
value: String,
}
#[picante::input]
struct B {
#[key]
key: String,
value: String,
}
#[picante::tracked]
async fn compute_len<DB: Db>(db: &DB, a: A) -> PicanteResult<usize> {
QUERY_CALLS.fetch_add(1, Ordering::Relaxed);
let s = a.value(db)?;
Ok(s.len())
}
#[picante::db(inputs(A, B), tracked(compute_len), db_trait(Db))]
struct Database {}
static QUERY_CALLS: AtomicUsize = AtomicUsize::new(0);
#[tokio_test_lite::test]
async fn shared_cache_reuses_across_snapshots_and_unrelated_revisions() -> PicanteResult<()> {
picante::__test_shared_cache_clear();
picante::__test_shared_cache_set_max_entries(1_000);
QUERY_CALLS.store(0, Ordering::Relaxed);
let db = Database::new();
let a = A::new(&db, "a".to_string(), "hello".to_string())?;
let _b = B::new(&db, "b".to_string(), "world".to_string())?;
let snap1 = DatabaseSnapshot::from_database(&db).await;
let v1 = compute_len(&snap1, a).await?;
assert_eq!(v1, 5);
assert_eq!(QUERY_CALLS.load(Ordering::Relaxed), 1);
let snap2 = DatabaseSnapshot::from_database(&db).await;
let v2 = compute_len(&snap2, a).await?;
assert_eq!(v2, 5);
assert_eq!(QUERY_CALLS.load(Ordering::Relaxed), 1);
let _ = B::new(&db, "b".to_string(), "world!!!".to_string())?;
let snap3 = DatabaseSnapshot::from_database(&db).await;
let v3 = compute_len(&snap3, a).await?;
assert_eq!(v3, 5);
assert_eq!(QUERY_CALLS.load(Ordering::Relaxed), 1);
Ok(())
}