Skip to main content

vs_store/store/
refs.rs

1//! `refs` table CRUD.
2
3use rusqlite::params;
4
5use super::{epoch_secs, Store};
6use crate::error::{Result, StoreError};
7use crate::types::StoredRef;
8
9impl Store {
10    pub fn record_ref(&mut self, sr: &StoredRef) -> Result<()> {
11        self.conn().execute(
12            "INSERT INTO refs(session_id, page_id, ref, dom_path, role,
13                              content_hash, created_at, retired_at)
14             VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)",
15            params![
16                sr.session_id,
17                sr.page_id,
18                i64::from(sr.r),
19                sr.dom_path,
20                sr.role,
21                sr.content_hash,
22                sr.created_at,
23                sr.retired_at,
24            ],
25        )?;
26        Ok(())
27    }
28
29    pub fn retire_ref(&mut self, session_id: &str, page_id: &str, r: u32) -> Result<()> {
30        let now = epoch_secs();
31        let n = self.conn().execute(
32            "UPDATE refs
33                SET retired_at=?4
34              WHERE session_id=?1 AND page_id=?2 AND ref=?3 AND retired_at IS NULL",
35            params![session_id, page_id, i64::from(r), now],
36        )?;
37        if n == 0 {
38            return Err(StoreError::NotFound {
39                kind: "ref",
40                id: format!("{session_id}/{page_id}/{r}"),
41            });
42        }
43        Ok(())
44    }
45
46    pub fn list_refs(&self, session_id: &str, page_id: &str) -> Result<Vec<StoredRef>> {
47        let mut stmt = self
48            .conn()
49            .prepare("SELECT * FROM refs WHERE session_id=?1 AND page_id=?2 ORDER BY ref ASC")?;
50        let rows = stmt.query_map([session_id, page_id], StoredRef::from_row)?;
51        Ok(rows.collect::<rusqlite::Result<Vec<_>>>()?)
52    }
53}