#[path = "common/harness.rs"]
mod harness;
use harness::TestHarness;
use macrame::prelude::*;
const TS: &str = "2026-01-01T00:00:00.000000Z";
const OPEN: &str = "9999-12-31T23:59:59.999999Z";
async fn db(harness: &TestHarness) -> Database {
Database::open_with_cadence(&harness.db_path, None)
.await
.unwrap()
}
async fn populate(db: &Database) {
db.write_concepts(
(0..200)
.map(|i| ConceptUpsert::new(format!("c{i:04}"), format!("C{i}")).valid_from(TS))
.collect(),
)
.await
.unwrap();
let mut edges = Vec::new();
for i in 1..150 {
edges.push(
EdgeAssertion::new("c0000", format!("c{i:04}"), "LINKS")
.valid_from(TS)
.valid_to(OPEN),
);
}
for i in 150..199 {
edges.push(
EdgeAssertion::new(format!("c{i:04}"), format!("c{:04}", i + 1), "LINKS")
.valid_from(TS)
.valid_to(OPEN),
);
}
db.bulk_import(edges).await.unwrap();
}
async fn stat1_rows(db: &Database) -> Vec<(String, String)> {
let conn = db.diagnostic_conn().await.unwrap();
let Ok(mut rows) = conn
.query("SELECT tbl, idx FROM sqlite_stat1 ORDER BY tbl, idx", ())
.await
else {
return Vec::new();
};
let mut out = Vec::new();
while let Some(r) = rows.next().await.unwrap() {
out.push((
r.get::<String>(0).unwrap_or_default(),
r.get::<String>(1).unwrap_or_default(),
));
}
out
}
#[tokio::test]
async fn analyze_creates_statistics_that_did_not_exist() {
let harness = TestHarness::new();
let db = db(&harness).await;
populate(&db).await;
let before = stat1_rows(&db).await;
assert!(
before.is_empty(),
"sqlite_stat1 already had rows before any analyze() call — either the \
engine now analyses on its own, or something else in this crate started \
calling ANALYZE. Either way D-149's premise has changed and the entry \
needs revisiting. Found: {before:?}"
);
db.analyze().await.unwrap();
let after = stat1_rows(&db).await;
assert!(
!after.is_empty(),
"analyze() returned Ok and sqlite_stat1 is still empty"
);
for idx in [
"idx_lc_traversal_cover",
"idx_lc_open_interval",
"idx_txlog_time",
"idx_txlog_entity",
] {
assert!(
after.iter().any(|(_, i)| i == idx),
"{idx} has no row in sqlite_stat1 after analyze(); got {after:?}"
);
}
db.close().await.unwrap();
}
#[test]
fn the_analysis_limit_is_applied_where_connections_are_configured() {
let source = include_str!("../src/connection.rs");
let body: String = source
.lines()
.skip_while(|l| !l.starts_with("async fn configure_writable("))
.take_while(|l| !l.starts_with('}'))
.collect::<Vec<_>>()
.join("\n");
assert!(
!body.is_empty(),
"`configure_writable` has moved or been renamed"
);
assert!(
body.contains("ANALYSIS_LIMIT"),
"`configure_writable` no longer applies ddl::ANALYSIS_LIMIT. Without it ANALYZE \
scans every index in full, which is a write-lock hold proportional to \
the table rather than to the index count — the thing D-149 exists to \
make schedulable."
);
}
#[tokio::test]
async fn optimize_is_repeatable_and_preserves_what_analyze_wrote() {
let harness = TestHarness::new();
let db = db(&harness).await;
populate(&db).await;
db.analyze().await.unwrap();
let after_analyze = stat1_rows(&db).await;
assert!(!after_analyze.is_empty());
db.optimize().await.unwrap();
db.optimize().await.unwrap();
let after_optimize = stat1_rows(&db).await;
assert_eq!(
after_analyze, after_optimize,
"optimize() changed the set of analysed indices on an idle database"
);
db.close().await.unwrap();
}
#[tokio::test]
async fn close_leaves_statistics_behind_without_being_asked() {
let harness = TestHarness::new();
let first = db(&harness).await;
populate(&first).await;
first.close().await.unwrap();
let reopened = db(&harness).await;
let rows = stat1_rows(&reopened).await;
assert!(
!rows.is_empty(),
"close() ran PRAGMA optimize on a database that had just been bulk \
loaded, and sqlite_stat1 is still empty. The next process will plan on \
built-in defaults (D-149)."
);
reopened.close().await.unwrap();
}