oca_rs/repositories/
oca_bundle_cache_repo.rs

1use oca_bundle_semantics::{state::oca::OCABundle, Encode};
2use said::{derivation::HashFunctionCode, sad::SerializationFormats};
3
4use crate::facade::Connection;
5
6#[derive(Debug)]
7pub struct OCABundleCacheRecord {
8    pub said: String,
9    pub oca_bundle: String,
10}
11
12impl OCABundleCacheRecord {
13    pub fn new(oca_bundle: &OCABundle) -> Self {
14        let code = HashFunctionCode::Blake3_256;
15        let format = SerializationFormats::JSON;
16        Self {
17            said: oca_bundle.said.clone().unwrap().to_string(),
18            oca_bundle: String::from_utf8(oca_bundle.encode(&code, &format).unwrap()).unwrap(),
19        }
20    }
21}
22
23#[derive(Debug)]
24pub struct AllOCABundleRecord {
25    pub cache_record: Option<OCABundleCacheRecord>,
26    pub total: usize,
27}
28
29pub struct OCABundleCacheRepo {
30    connection: Connection,
31}
32
33impl OCABundleCacheRepo {
34    pub fn new(connection: Connection) -> Self {
35        let create_table_query = r#"
36        CREATE TABLE IF NOT EXISTS oca_bundle_cache(
37            said TEXT PRIMARY KEY,
38            oca_bundle TEXT
39        )"#;
40        connection.execute(create_table_query, ()).unwrap();
41
42        Self { connection }
43    }
44
45    pub fn insert(&self, model: OCABundleCacheRecord) {
46        let query = r#"
47        INSERT INTO oca_bundle_cache(said, oca_bundle)
48            VALUES (?1, ?2)"#;
49        let _ = self
50            .connection
51            .execute(query, [&model.said, &model.oca_bundle]);
52    }
53
54    pub fn fetch_all(&self, limit: usize, page: usize) -> Vec<AllOCABundleRecord> {
55        let offset = (page - 1) * limit;
56        let mut results = vec![];
57        let query = "
58        SELECT results.*, count.total
59        FROM
60        (
61            SELECT COUNT(*) OVER() AS total
62            FROM oca_bundle_cache
63        ) AS count
64        LEFT JOIN
65        (
66            SELECT *
67            FROM oca_bundle_cache
68            LIMIT ?1 OFFSET ?2
69        ) AS results
70        ON true
71        GROUP BY said";
72
73        let connection = self.connection.connection.lock().unwrap();
74        let mut statement = connection.prepare(query).unwrap();
75        let models = statement
76            .query_map([limit, offset], |row| {
77                let cache_record =
78                    row.get::<_, Option<String>>(0)
79                        .unwrap()
80                        .map(|said| OCABundleCacheRecord {
81                            said,
82                            oca_bundle: row.get(1).unwrap(),
83                        });
84                Ok(AllOCABundleRecord {
85                    cache_record,
86                    total: row.get(2).unwrap(),
87                })
88            })
89            .unwrap();
90        models.for_each(|model| results.push(model.unwrap()));
91        results
92    }
93}