39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
use rusqlite::{Connection, OptionalExtension, Transaction, TransactionBehavior};
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
|
pub(crate) struct HeaderSync {
|
|
generation: u64,
|
|
}
|
|
|
|
impl HeaderSync {
|
|
pub(crate) fn capture(conn: &Connection) -> Result<Self, String> {
|
|
let generation = conn
|
|
.query_row(
|
|
crate::queries::sqlite::queries::db_header_sync::Q_001,
|
|
[],
|
|
|row| row.get::<_, String>(0),
|
|
)
|
|
.optional()
|
|
.map_err(|e| e.to_string())?
|
|
.map(|value| value.parse::<u64>().map_err(|e| e.to_string()))
|
|
.transpose()?
|
|
.unwrap_or(0);
|
|
Ok(Self { generation })
|
|
}
|
|
|
|
pub(crate) fn begin_write(self, conn: &Connection) -> Result<Transaction<'_>, String> {
|
|
let transaction = Transaction::new_unchecked(conn, TransactionBehavior::Immediate)
|
|
.map_err(|e| e.to_string())?;
|
|
if Self::capture(conn)?.generation != self.generation {
|
|
return Err("Header sync superseded by cache removal; retry on next sync".into());
|
|
}
|
|
Ok(transaction)
|
|
}
|
|
}
|
|
|
|
pub(crate) fn invalidate(conn: &Transaction<'_>) -> Result<(), String> {
|
|
conn.execute(crate::queries::sqlite::queries::db_header_sync::Q_002, [])
|
|
.map_err(|e| e.to_string())?;
|
|
Ok(())
|
|
}
|