1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use holochain_serialized_bytes::prelude::*;
use holochain_sqlite::rusqlite;
use holochain_sqlite::rusqlite::named_params;
use holochain_sqlite::rusqlite::OptionalExtension;
use holochain_sqlite::rusqlite::ToSql;
use holochain_sqlite::rusqlite::Transaction;
use holochain_types::prelude::EntryDefBufferKey;
use holochain_zome_types::EntryDef;

use crate::mutations;
use crate::prelude::from_blob;
use crate::prelude::StateMutationResult;
use crate::prelude::StateQueryResult;

#[derive(Debug, Clone, Hash, Eq, PartialEq, PartialOrd, Ord)]
pub struct EntryDefStoreKey(SerializedBytes);

impl AsRef<[u8]> for EntryDefStoreKey {
    fn as_ref(&self) -> &[u8] {
        self.0.bytes()
    }
}

impl From<Vec<u8>> for EntryDefStoreKey {
    fn from(bytes: Vec<u8>) -> Self {
        Self(UnsafeBytes::from(bytes).into())
    }
}

impl ToSql for EntryDefStoreKey {
    fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
        Ok(rusqlite::types::ToSqlOutput::Borrowed(self.as_ref().into()))
    }
}

pub fn get(txn: &Transaction<'_>, key: EntryDefBufferKey) -> StateQueryResult<Option<EntryDef>> {
    let key: EntryDefStoreKey = key.into();
    let item = txn
        .query_row(
            "SELECT blob FROM EntryDef WHERE key = :key",
            named_params! {
                ":key": key
            },
            |row| {
                let item = row.get("blob")?;
                Ok(item)
            },
        )
        .optional()?;
    match item {
        Some(item) => Ok(Some(from_blob(item)?)),
        None => Ok(None),
    }
}

pub fn get_all(txn: &Transaction<'_>) -> StateQueryResult<Vec<(EntryDefBufferKey, EntryDef)>> {
    let mut stmt = txn.prepare(
        "
            SELECT key, blob FROM EntryDef
        ",
    )?;
    let items = stmt
        .query_and_then([], |row| {
            let key: Vec<u8> = row.get("key")?;
            let key: EntryDefStoreKey = key.into();
            let item = row.get("blob")?;
            StateQueryResult::Ok((key.into(), from_blob(item)?))
        })?
        .collect::<StateQueryResult<Vec<_>>>();

    items
}

pub fn contains(txn: &Transaction<'_>, key: EntryDefBufferKey) -> StateQueryResult<bool> {
    let key: EntryDefStoreKey = key.into();
    Ok(txn.query_row(
        "SELECT EXISTS(SELECT 1 FROM EntryDef WHERE key = :key)",
        named_params! {
            ":key": key
        },
        |row| row.get(0),
    )?)
}

pub fn put(
    txn: &mut Transaction,
    key: EntryDefBufferKey,
    entry_def: EntryDef,
) -> StateMutationResult<()> {
    let key: EntryDefStoreKey = key.into();
    mutations::insert_entry_def(txn, key, entry_def)
}

impl From<EntryDefBufferKey> for EntryDefStoreKey {
    fn from(a: EntryDefBufferKey) -> Self {
        Self(
            a.try_into()
                .expect("EntryDefStoreKey serialization cannot fail"),
        )
    }
}

impl From<&[u8]> for EntryDefStoreKey {
    fn from(bytes: &[u8]) -> Self {
        Self(UnsafeBytes::from(bytes.to_vec()).into())
    }
}

impl From<EntryDefStoreKey> for EntryDefBufferKey {
    fn from(a: EntryDefStoreKey) -> Self {
        a.0.try_into()
            .expect("Database corruption when retrieving EntryDefBufferKeys")
    }
}