use indexmap::IndexMap;
use vantage_dataset::traits::WritableValueSet;
use vantage_types::Record;
use super::Probe;
use crate::{Capability, CborValue, FilterOp, Vista};
const PROBE_ID: &str = "vista-contract-probe";
pub async fn check_advertised_writes(vista: &Vista) {
let caps = *vista.capabilities();
let mut probe = Probe::default();
let empty = Record::<CborValue>::new();
let cleanup = || async {
if caps.has(Capability::Delete) {
let _ = vista.delete(PROBE_ID).await;
}
};
if caps.has(Capability::Insert) {
let inserted = vista.insert_value(PROBE_ID, &empty).await;
probe.check(Capability::Insert, "insert_value", &inserted);
cleanup().await;
}
if caps.has(Capability::Update) {
let patched = vista.patch_value(PROBE_ID, &empty).await;
probe.check(Capability::Update, "patch_value", &patched);
let replaced = vista.replace_value(PROBE_ID, &empty).await;
probe.check(Capability::Update, "replace_value", &replaced);
cleanup().await;
let upserted = vista.upsert_value(PROBE_ID, &empty).await;
probe.check(Capability::Update, "upsert_value", &upserted);
cleanup().await;
}
if caps.has(Capability::Delete) {
probe.check(Capability::Delete, "delete", &vista.delete(PROBE_ID).await);
}
if caps.has(Capability::Import) {
probe.check(
Capability::Import,
"import_values",
&vista.import_values(&IndexMap::new()).await,
);
}
if caps.has(Capability::ConfineWrites) {
probe_confined(vista, &mut probe).await;
} else if caps.has(Capability::Delete) {
probe.check(Capability::Delete, "delete_all", &vista.delete_all().await);
}
probe.finish();
}
async fn probe_confined(vista: &Vista, probe: &mut Probe) {
let caps = *vista.capabilities();
let Some(id) = vista.id_column() else {
return probe.fail(
"`confine_writes` is advertised but the vista has no id column to narrow by"
.to_string(),
);
};
let confined = match vista.clone().with_condition(id, FilterOp::Eq, PROBE_ID) {
Ok(confined) => confined,
Err(e) => {
return probe.check_ok(
Capability::ConfineWrites,
"with_condition(id = probe)",
&Err::<(), _>(e),
);
}
};
let before = vista.count().await;
if caps.has(Capability::Insert) {
let inserted = confined.insert_value(PROBE_ID, &Record::new()).await;
probe.check(
Capability::ConfineWrites,
"narrowed insert_value",
&inserted,
);
}
if caps.has(Capability::Delete) {
let deleted = confined.delete_all().await;
probe.check(Capability::Delete, "narrowed delete_all", &deleted);
match (before, vista.count().await) {
(Ok(before), Ok(after)) if before != after => probe.fail(format!(
"`confine_writes`: a delete_all narrowed to the probe row changed the \
un-narrowed count from {before} to {after}"
)),
(Ok(_), Ok(_)) => {}
(Err(e), _) | (_, Err(e)) => probe.check_ok(
Capability::ConfineWrites,
"count around the narrowed delete_all",
&Err::<(), _>(e),
),
}
}
}