#![cfg(feature = "std")]
use graphitesql::{Connection, Value};
use std::process::Command;
fn temp_path(name: &str) -> String {
let mut p = std::env::temp_dir();
p.push(format!("graphitesql-wcpe-{}-{name}", std::process::id()));
p.to_string_lossy().into_owned()
}
fn cleanup(path: &str) {
for suffix in ["", "-journal", "-wal", "-shm"] {
let _ = std::fs::remove_file(format!("{path}{suffix}"));
}
}
fn sqlite3_available() -> bool {
Command::new("sqlite3").arg("--version").output().is_ok()
}
fn wal_size(path: &str) -> u64 {
std::fs::metadata(format!("{path}-wal"))
.map(|m| m.len())
.unwrap_or(0)
}
#[test]
fn execute_truncate_checkpoint_zeroes_wal() {
let path = temp_path("truncate.db");
cleanup(&path);
{
let mut c = Connection::create(&path).unwrap();
c.execute("PRAGMA journal_mode = WAL").unwrap();
c.execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v INT)")
.unwrap();
for i in 1..=30 {
c.execute(&format!("INSERT INTO t(v) VALUES ({})", i * 3))
.unwrap();
}
assert!(wal_size(&path) > 32, "expected frames in the -wal");
c.execute("PRAGMA wal_checkpoint(TRUNCATE)").unwrap();
assert_eq!(wal_size(&path), 0, "TRUNCATE must zero the -wal file");
assert_eq!(
c.query("SELECT count(*), sum(v) FROM t").unwrap().rows[0],
vec![Value::Integer(30), Value::Integer(1395)]
);
assert_eq!(
c.query("PRAGMA integrity_check").unwrap().rows[0][0],
Value::Text("ok".into())
);
}
if sqlite3_available() {
let out = Command::new("sqlite3")
.arg(&path)
.arg("PRAGMA integrity_check; SELECT count(*) FROM t;")
.output()
.unwrap();
assert_eq!(String::from_utf8_lossy(&out.stdout).trim(), "ok\n30");
}
cleanup(&path);
}
#[test]
fn execute_default_checkpoint_is_passive() {
let path = temp_path("passive.db");
cleanup(&path);
{
let mut c = Connection::create(&path).unwrap();
c.execute("PRAGMA journal_mode = WAL").unwrap();
c.execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v INT)")
.unwrap();
for i in 1..=10 {
c.execute(&format!("INSERT INTO t(v) VALUES ({i})"))
.unwrap();
}
let before = wal_size(&path);
assert!(before > 32);
c.execute("PRAGMA wal_checkpoint").unwrap();
assert_eq!(
wal_size(&path),
before,
"PASSIVE (default) leaves the -wal bytes in place"
);
assert_eq!(
c.query("PRAGMA integrity_check").unwrap().rows[0][0],
Value::Text("ok".into())
);
}
cleanup(&path);
}
#[test]
fn non_wal_query_reports_minus_one() {
let c = Connection::open_memory().unwrap();
let r = c.query("PRAGMA wal_checkpoint").unwrap();
assert_eq!(r.columns, vec!["busy", "log", "checkpointed"]);
assert_eq!(
r.rows,
vec![vec![
Value::Integer(0),
Value::Integer(-1),
Value::Integer(-1)
]]
);
assert_eq!(
c.query("PRAGMA wal_checkpoint(TRUNCATE)").unwrap().rows,
r.rows
);
}