feat: report store durability status
This commit is contained in:
parent
2921e5e976
commit
6953e3acde
7 changed files with 124 additions and 18 deletions
|
|
@ -2,6 +2,8 @@ use rusqlite::{Connection, OptionalExtension, Transaction, params};
|
|||
use std::path::Path;
|
||||
|
||||
pub const CURRENT_SCHEMA_VERSION: i64 = 2;
|
||||
pub const FILE_JOURNAL_MODE: &str = "wal";
|
||||
pub const SYNCHRONOUS_MODE: &str = "normal";
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum StoreError {
|
||||
|
|
@ -17,9 +19,31 @@ pub struct Store {
|
|||
conn: Connection,
|
||||
}
|
||||
|
||||
fn configure_file_connection(conn: &Connection) -> Result<(), StoreError> {
|
||||
conn.execute_batch(
|
||||
r#"
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA synchronous = NORMAL;
|
||||
PRAGMA foreign_keys = ON;
|
||||
"#,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn configure_memory_connection(conn: &Connection) -> Result<(), StoreError> {
|
||||
conn.execute_batch(
|
||||
r#"
|
||||
PRAGMA synchronous = NORMAL;
|
||||
PRAGMA foreign_keys = ON;
|
||||
"#,
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Store {
|
||||
pub fn open(path: &Path) -> Result<Self, StoreError> {
|
||||
let conn = Connection::open(path)?;
|
||||
configure_file_connection(&conn)?;
|
||||
let store = Self { conn };
|
||||
store.migrate()?;
|
||||
Ok(store)
|
||||
|
|
@ -27,6 +51,7 @@ impl Store {
|
|||
|
||||
pub fn open_memory() -> Result<Self, StoreError> {
|
||||
let conn = Connection::open_in_memory()?;
|
||||
configure_memory_connection(&conn)?;
|
||||
let store = Self { conn };
|
||||
store.migrate()?;
|
||||
Ok(store)
|
||||
|
|
@ -58,7 +83,7 @@ impl Store {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn schema_version(&self) -> Result<i64, StoreError> {
|
||||
pub fn schema_version(&self) -> Result<i64, StoreError> {
|
||||
let version = self
|
||||
.conn
|
||||
.query_row(
|
||||
|
|
@ -75,6 +100,26 @@ impl Store {
|
|||
.map_err(|_| StoreError::InvalidSchemaVersion(version))
|
||||
}
|
||||
|
||||
pub fn journal_mode(&self) -> Result<String, StoreError> {
|
||||
self.conn
|
||||
.query_row("PRAGMA journal_mode", [], |row| row.get::<_, String>(0))
|
||||
.map(|mode| mode.to_ascii_lowercase())
|
||||
.map_err(StoreError::from)
|
||||
}
|
||||
|
||||
pub fn synchronous_mode(&self) -> Result<String, StoreError> {
|
||||
let mode = self
|
||||
.conn
|
||||
.query_row("PRAGMA synchronous", [], |row| row.get::<_, i64>(0))?;
|
||||
Ok(match mode {
|
||||
0 => "off".to_owned(),
|
||||
1 => "normal".to_owned(),
|
||||
2 => "full".to_owned(),
|
||||
3 => "extra".to_owned(),
|
||||
other => format!("unknown-{other}"),
|
||||
})
|
||||
}
|
||||
|
||||
fn apply_schema_v1(&self) -> Result<(), StoreError> {
|
||||
let tx = self.conn.unchecked_transaction()?;
|
||||
tx.execute_batch(
|
||||
|
|
@ -1817,6 +1862,25 @@ mod tests {
|
|||
let _ = std::fs::remove_file(path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_store_uses_documented_durability_pragmas() {
|
||||
let path = std::env::temp_dir().join(format!("geth-store-durability-{}.sqlite", now_ms()));
|
||||
let store = Store::open(&path).expect("open file store");
|
||||
assert_eq!(
|
||||
store.journal_mode().expect("journal mode"),
|
||||
FILE_JOURNAL_MODE
|
||||
);
|
||||
assert_eq!(
|
||||
store.synchronous_mode().expect("synchronous mode"),
|
||||
SYNCHRONOUS_MODE
|
||||
);
|
||||
|
||||
drop(store);
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let _ = std::fs::remove_file(path.with_extension("sqlite-wal"));
|
||||
let _ = std::fs::remove_file(path.with_extension("sqlite-shm"));
|
||||
}
|
||||
|
||||
fn column_exists(store: &Store, table: &str, column: &str) -> bool {
|
||||
let mut stmt = store
|
||||
.conn
|
||||
|
|
|
|||
Loading…
Reference in a new issue