Skip to main content

vs_store/store/
pages.rs

1//! `pages` table CRUD.
2
3use rusqlite::params;
4
5use super::{epoch_secs, Store};
6use crate::error::{Result, StoreError};
7use crate::types::Page;
8
9impl Store {
10    pub fn create_page(&mut self, id: &str, session_id: &str, url: &str) -> Result<Page> {
11        let now = epoch_secs();
12        self.conn().execute(
13            "INSERT INTO pages(id, session_id, url, title, last_token, last_dom_hash,
14                               last_seen_at, closed_at)
15             VALUES (?1, ?2, ?3, NULL, NULL, NULL, ?4, NULL)",
16            params![id, session_id, url, now],
17        )?;
18        Ok(Page {
19            id: id.to_string(),
20            session_id: session_id.to_string(),
21            url: url.to_string(),
22            title: None,
23            last_token: None,
24            last_dom_hash: None,
25            last_seen_at: now,
26            closed_at: None,
27        })
28    }
29
30    pub fn close_page(&mut self, id: &str) -> Result<()> {
31        let now = epoch_secs();
32        let n = self.conn().execute(
33            "UPDATE pages SET closed_at=?2 WHERE id=?1 AND closed_at IS NULL",
34            params![id, now],
35        )?;
36        if n == 0 {
37            return Err(StoreError::NotFound {
38                kind: "page",
39                id: id.to_string(),
40            });
41        }
42        Ok(())
43    }
44
45    pub fn update_page_token(
46        &mut self,
47        id: &str,
48        token: &str,
49        dom_hash: &str,
50        title: Option<&str>,
51    ) -> Result<()> {
52        let now = epoch_secs();
53        let n = self.conn().execute(
54            "UPDATE pages
55                SET last_token=?2, last_dom_hash=?3, last_seen_at=?4,
56                    title=COALESCE(?5, title)
57              WHERE id=?1",
58            params![id, token, dom_hash, now, title],
59        )?;
60        if n == 0 {
61            return Err(StoreError::NotFound {
62                kind: "page",
63                id: id.to_string(),
64            });
65        }
66        Ok(())
67    }
68
69    pub fn get_page(&self, id: &str) -> Result<Option<Page>> {
70        let mut stmt = self.conn().prepare("SELECT * FROM pages WHERE id=?1")?;
71        let mut rows = stmt.query([id])?;
72        if let Some(row) = rows.next()? {
73            Ok(Some(Page::from_row(row)?))
74        } else {
75            Ok(None)
76        }
77    }
78
79    pub fn list_pages(&self, session_id: &str) -> Result<Vec<Page>> {
80        let mut stmt = self
81            .conn()
82            .prepare("SELECT * FROM pages WHERE session_id=?1 ORDER BY last_seen_at DESC")?;
83        let rows = stmt.query_map([session_id], Page::from_row)?;
84        Ok(rows.collect::<rusqlite::Result<Vec<_>>>()?)
85    }
86}