junobuild_satellite/db/
impls.rs1use crate::db::types::state::{DbHeapState, Doc, StableKey};
2use crate::SetDoc;
3use candid::Principal;
4use ic_cdk::api::time;
5use ic_stable_structures::storable::Bound;
6use ic_stable_structures::Storable;
7use junobuild_collections::constants::db::DEFAULT_DB_COLLECTIONS;
8use junobuild_collections::types::rules::{Memory, Rule};
9use junobuild_shared::serializers::{deserialize_from_bytes, serialize_to_bytes};
10use junobuild_shared::types::state::{Timestamp, UserId, Version};
11use junobuild_shared::types::state::{Timestamped, Versioned};
12use junobuild_shared::version::next_version;
13use std::borrow::Cow;
14use std::cmp::Ordering;
15use std::collections::{BTreeMap, HashMap};
16
17impl Default for DbHeapState {
18 fn default() -> Self {
19 let now = time();
20
21 DbHeapState {
22 db: HashMap::from(
23 DEFAULT_DB_COLLECTIONS
24 .map(|(collection, _rules)| (collection.to_owned(), BTreeMap::new())),
25 ),
26 rules: HashMap::from(DEFAULT_DB_COLLECTIONS.map(|(collection, rule)| {
27 (
28 collection.to_owned(),
29 Rule {
30 read: rule.read,
31 write: rule.write,
32 memory: Some(rule.memory.unwrap_or(Memory::Stable)),
33 mutable_permissions: Some(rule.mutable_permissions.unwrap_or(false)),
34 max_size: rule.max_size,
35 max_capacity: rule.max_capacity,
36 max_changes_per_user: rule.max_changes_per_user,
37 created_at: now,
38 updated_at: now,
39 version: rule.version,
40 rate_config: rule.rate_config,
41 },
42 )
43 })),
44 config: None,
45 }
46 }
47}
48
49impl Timestamped for Doc {
50 fn created_at(&self) -> Timestamp {
51 self.created_at
52 }
53
54 fn updated_at(&self) -> Timestamp {
55 self.updated_at
56 }
57
58 fn cmp_updated_at(&self, other: &Self) -> Ordering {
59 self.updated_at.cmp(&other.updated_at)
60 }
61
62 fn cmp_created_at(&self, other: &Self) -> Ordering {
63 self.created_at.cmp(&other.created_at)
64 }
65}
66
67impl Storable for Doc {
68 fn to_bytes(&self) -> Cow<[u8]> {
69 serialize_to_bytes(self)
70 }
71
72 fn from_bytes(bytes: Cow<[u8]>) -> Self {
73 deserialize_from_bytes(bytes)
74 }
75
76 const BOUND: Bound = Bound::Unbounded;
77}
78
79impl Storable for StableKey {
80 fn to_bytes(&self) -> Cow<[u8]> {
81 serialize_to_bytes(self)
82 }
83
84 fn from_bytes(bytes: Cow<[u8]>) -> Self {
85 deserialize_from_bytes(bytes)
86 }
87
88 const BOUND: Bound = Bound::Unbounded;
89}
90
91impl Doc {
92 pub fn prepare(caller: Principal, current_doc: &Option<Doc>, user_doc: SetDoc) -> Self {
93 let now = time();
94
95 let created_at: Timestamp = match current_doc {
96 None => now,
97 Some(current_doc) => current_doc.created_at,
98 };
99
100 let version = next_version(current_doc);
101
102 let owner: UserId = match current_doc {
103 None => caller,
104 Some(current_doc) => current_doc.owner,
105 };
106
107 let updated_at: Timestamp = now;
108
109 Doc {
110 owner,
111 data: user_doc.data,
112 description: user_doc.description,
113 created_at,
114 updated_at,
115 version: Some(version),
116 }
117 }
118}
119
120impl Versioned for Doc {
121 fn version(&self) -> Option<Version> {
122 self.version
123 }
124}