persistence.rs

 1use anyhow::Result;
 2use db::{define_connection, query, sqlez::statement::Statement, sqlez_macros::sql};
 3
 4use workspace::{WorkspaceDb, WorkspaceId};
 5
 6define_connection! {
 7    pub static ref ONBOARDING_DB: OnboardingDb<WorkspaceDb> =
 8        &[sql!(
 9            CREATE TABLE onboarding_state (
10                workspace_id INTEGER,
11                item_id INTEGER UNIQUE,
12                current_page TEXT,
13                completed_pages TEXT,
14                PRIMARY KEY(workspace_id, item_id),
15                FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id)
16                ON DELETE CASCADE
17            ) STRICT;
18        )];
19}
20
21impl OnboardingDb {
22    pub async fn save_state(
23        &self,
24        item_id: u64,
25        workspace_id: WorkspaceId,
26        current_page: String,
27        completed_pages: String,
28    ) -> Result<()> {
29        let query =
30            "INSERT INTO onboarding_state(item_id, workspace_id, current_page, completed_pages)
31            VALUES (?1, ?2, ?3, ?4)
32            ON CONFLICT DO UPDATE SET
33                current_page = ?3,
34                completed_pages = ?4";
35        self.write(move |conn| {
36            let mut statement = Statement::prepare(conn, query)?;
37            let mut next_index = statement.bind(&item_id, 1)?;
38            next_index = statement.bind(&workspace_id, next_index)?;
39            next_index = statement.bind(&current_page, next_index)?;
40            statement.bind(&completed_pages, next_index)?;
41            statement.exec()
42        })
43        .await
44    }
45
46    query! {
47        pub fn get_state(item_id: u64, workspace_id: WorkspaceId) -> Result<Option<(String, String)>> {
48            SELECT current_page, completed_pages
49            FROM onboarding_state
50            WHERE item_id = ? AND workspace_id = ?
51        }
52    }
53}