Skip to main content

p2panda_store/groups/
sqlite.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3use p2panda_core::cbor::{decode_cbor, encode_cbor};
4use serde::{Deserialize, Serialize};
5use sqlx::query;
6use sqlx::query_as;
7
8use crate::groups::traits::GroupsStore;
9use crate::{SqliteError, SqliteStore};
10
11impl<ID, S> GroupsStore<ID, S> for SqliteStore
12where
13    ID: for<'a> Deserialize<'a> + Serialize,
14    S: for<'a> Deserialize<'a> + Serialize,
15{
16    type Error = SqliteError;
17
18    async fn set_groups_state(&self, id: &ID, state: &S) -> Result<(), SqliteError> {
19        self.tx(async |tx| {
20            query(
21                "
22                INSERT OR REPLACE
23                INTO
24                    groups_v1 (
25                        id,
26                        state
27                    )
28                VALUES
29                    (?, ?)
30                ",
31            )
32            .bind(encode_cbor(&id).map_err(|err| SqliteError::Encode("id".to_string(), err))?)
33            .bind(encode_cbor(&state).map_err(|err| SqliteError::Encode("state".to_string(), err))?)
34            .execute(&mut **tx)
35            .await
36            .map_err(SqliteError::Sqlite)
37        })
38        .await?;
39
40        Ok(())
41    }
42
43    async fn get_groups_state(&self, id: &ID) -> Result<Option<S>, SqliteError> {
44        let row = self
45            .tx(async |tx| {
46                query_as::<_, (Vec<u8>,)>(
47                    "
48                    SELECT
49                        state
50                    FROM
51                        groups_v1
52                    WHERE
53                        id = ?
54                    ",
55                )
56                .bind(encode_cbor(&id).map_err(|err| SqliteError::Encode("id".to_string(), err))?)
57                .fetch_optional(&mut **tx)
58                .await
59                .map_err(SqliteError::Sqlite)
60            })
61            .await?;
62
63        let Some((state_bytes,)) = row else {
64            return Ok(None);
65        };
66
67        let state = decode_cbor(&state_bytes[..])
68            .map_err(|err| SqliteError::Decode("state".into(), err.into()))?;
69
70        Ok(Some(state))
71    }
72}