Skip to main content

p2panda_store/groups/
sqlite.rs

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