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