1use 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}