selene_core/database/
database_entry.rs1use std::borrow::Borrow;
2
3use serde::{Deserialize, Serialize, de::DeserializeOwned};
4use sled::{Db, Tree};
5
6use crate::database::{
7 self, CompareAndSwapTransaction, Createable, DatabaseError, EntryId, Mergeable, Patchable,
8 deserialize_from_ivec, library_db, sled_get_all_raw, sled_get_batch_raw, sled_get_raw,
9 sled_version_from_raw,
10 transaction_args::{apply_cas_tx, db_transaction},
11};
12
13pub trait DatabaseEntry:
14 Serialize + DeserializeOwned + for<'de> Deserialize<'de> + Clone + std::fmt::Debug + 'static
15{
16 type Id: EntryId<Entry = Self>;
17 const VERSION_NUMBER: u32;
19
20 fn db_check(id: Self::Id) -> database::Result<bool> {
26 let db = library_db();
27 Ok(Self::tree(&db).contains_key(id.as_bytes())?)
28 }
29
30 fn db_check_version(id: Self::Id) -> Result<Option<u32>, DatabaseError> {
31 let db = library_db();
32 Ok(sled_get_raw(&Self::tree(&db), id.as_bytes())?.map(sled_version_from_raw))
33 }
34
35 fn db_create(args: <Self as Createable>::CreateArgs) -> database::Result<Self>
37 where
38 Self: Createable,
39 {
40 let mut cas_tx = CompareAndSwapTransaction::new();
41 let created_id = Self::tx_create(&mut cas_tx, args)?;
42 apply_cas_tx(cas_tx, false)?;
43
44 Ok(Self::db_get(created_id)?.expect("Item was just created"))
45 }
46
47 fn db_get(id: Self::Id) -> database::Result<Option<Self>> {
53 let db = library_db();
54 Ok(sled_get_raw(&Self::tree(&db), id.as_bytes())?.map(deserialize_from_ivec))
55 }
56
57 fn db_get_all() -> database::Result<Vec<Self>> {
63 let db = library_db();
64 Ok(sled_get_all_raw(&Self::tree(&db))?
65 .into_iter()
66 .map(deserialize_from_ivec)
67 .collect())
68 }
69
70 fn db_get_batch<I, A>(ids: I) -> database::Result<Vec<Self>>
76 where
77 I: IntoIterator<Item = A>,
78 A: Borrow<Self::Id>,
79 {
80 let db = library_db();
81 let items = sled_get_batch_raw(
82 &Self::tree(&db),
83 ids.into_iter().map(|a| *a.borrow().as_bytes()),
84 )?;
85
86 Ok(items.into_iter().map(deserialize_from_ivec).collect())
87 }
88
89 fn db_merge(&self, into: Self::Id) -> database::Result<()>
93 where
94 Self: Mergeable,
95 {
96 db_transaction(|cas_tx| self.tx_merge(into, cas_tx), None, false)?;
97 Ok(())
98 }
99
100 fn db_patch(&mut self) -> database::Result<()>
104 where
105 Self: Patchable<Self>,
106 {
107 let db = library_db();
108 let old_raw = Self::tree(&db).get(self.id().as_bytes())?;
109 let old: Option<Self> = old_raw.clone().map(deserialize_from_ivec);
110
111 if let Some(mut old) = old {
112 old.patch(self.clone());
113 old.db_upsert()
114 } else {
115 self.db_upsert()
116 }
117 }
118
119 fn pre_upsert(&mut self, _cas_tx: &CompareAndSwapTransaction) -> Result<(), DatabaseError> {
120 Ok(())
121 }
122
123 fn db_upsert(&self) -> database::Result<()> {
124 db_transaction(
125 |cas_tx| cas_tx.tx_upsert(self.id(), Some(self.clone())),
126 None,
127 false,
128 )
129 }
130
131 fn id(&self) -> Self::Id;
132
133 fn tree(db: &Db) -> Tree;
134}