use std::time::Duration;
use futures::Stream;
use rusqlite::Connection;
use crate::error::Result;
use crate::store::{Store, connect};
pub struct Watcher {
conn: Connection,
version: i64,
}
impl Store {
pub fn watcher(&self) -> Result<Watcher> {
let conn = connect(self.path())?;
let version = data_version(&conn)?;
Ok(Watcher { conn, version })
}
}
fn data_version(conn: &Connection) -> Result<i64> {
Ok(conn.query_row("PRAGMA data_version", [], |r| r.get(0))?)
}
impl Watcher {
pub fn changed(&mut self) -> Result<bool> {
let version = data_version(&self.conn)?;
let changed = version != self.version;
self.version = version;
Ok(changed)
}
pub fn changes(self, interval: Duration) -> impl Stream<Item = Result<()>> {
futures::stream::unfold(self, move |mut watcher| async move {
loop {
tokio::time::sleep(interval).await;
match watcher.changed() {
Ok(true) => return Some((Ok(()), watcher)),
Ok(false) => continue,
Err(e) => return Some((Err(e), watcher)),
}
}
})
}
}