1use crate::{
2 db::{unixfile::UnixFileLoader, RemoteClient, DB},
3 filenames::saturn_db,
4 record::{Record, RecurringRecord},
5};
6use anyhow::{anyhow, Result};
7use async_trait::async_trait;
8use serde::{Deserialize, Serialize};
9use std::collections::BTreeMap;
10
11#[derive(Debug, Clone)]
12pub struct RemoteDBClient<T: RemoteClient + Send + Sync + Default + std::fmt::Debug> {
13 client: T,
14 db: RemoteDB,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize, Default)]
18pub struct RemoteDB {
19 primary_key: u64,
20 recurrence_key: u64,
21 id_map: BTreeMap<String, u64>,
22 reverse_id_map: BTreeMap<u64, String>,
23 recurring_id_map: BTreeMap<String, u64>,
24 reverse_recurring_id_map: BTreeMap<u64, String>,
25 fields: BTreeMap<u64, crate::record::Fields>,
26 calendar_id: String,
27}
28
29impl<T: RemoteClient + Send + Sync + Default + std::fmt::Debug> RemoteDBClient<T> {
30 pub fn new(calendar_id: String, client: T) -> Self {
31 let db = RemoteDB::new(calendar_id);
32
33 Self { client, db }
36 }
37}
38
39impl RemoteDB {
40 pub fn new(calendar_id: String) -> Self {
41 Self {
42 primary_key: 0,
43 recurrence_key: 0,
44 id_map: BTreeMap::default(),
45 reverse_id_map: BTreeMap::default(),
46 recurring_id_map: BTreeMap::default(),
47 reverse_recurring_id_map: BTreeMap::default(),
48 fields: BTreeMap::default(),
49 calendar_id,
50 }
51 }
52
53 pub fn add_internal(&mut self, primary_key: u64, remote_key: String) {
54 self.id_map.insert(remote_key.clone(), primary_key);
55 self.reverse_id_map.insert(primary_key, remote_key);
56 }
57
58 pub fn add(&mut self, primary_key: String, remote_key: u64) {
59 self.reverse_id_map.insert(remote_key, primary_key.clone());
60 self.id_map.insert(primary_key, remote_key);
61 }
62
63 pub fn add_recurring_internal(&mut self, primary_key: u64, remote_key: String) {
64 self.recurring_id_map
65 .insert(remote_key.clone(), primary_key);
66 self.reverse_recurring_id_map
67 .insert(primary_key, remote_key);
68 }
69
70 pub fn add_recurring(&mut self, primary_key: String, remote_key: u64) {
71 self.reverse_recurring_id_map
72 .insert(remote_key, primary_key.clone());
73 self.recurring_id_map.insert(primary_key, remote_key);
74 }
75
76 pub fn lookup_internal(&self, id: String) -> Option<u64> {
77 self.id_map.get(&id).cloned()
78 }
79
80 pub fn lookup(&self, id: u64) -> Option<String> {
81 self.reverse_id_map.get(&id).cloned()
82 }
83
84 pub fn recurring_lookup_internal(&self, id: String) -> Option<u64> {
85 self.recurring_id_map.get(&id).cloned()
86 }
87
88 pub fn recurring_lookup(&self, id: u64) -> Option<String> {
89 self.reverse_recurring_id_map.get(&id).cloned()
90 }
91
92 pub fn remove_by_internal_id(&mut self, id: u64) {
93 self.reverse_id_map
94 .remove(&id)
95 .map(|o| self.id_map.remove(&o));
96 }
97
98 pub fn remove_by_public_id(&mut self, id: String) {
99 self.id_map
100 .remove(&id)
101 .map(|o| self.reverse_id_map.remove(&o));
102 }
103
104 pub fn remove_recurring_by_internal_id(&mut self, id: u64) {
105 self.reverse_recurring_id_map
106 .remove(&id)
107 .map(|o| self.recurring_id_map.remove(&o));
108 }
109
110 pub fn remove_recurring_by_public_id(&mut self, id: String) {
111 self.recurring_id_map
112 .remove(&id)
113 .map(|o| self.reverse_recurring_id_map.remove(&o));
114 }
115}
116
117impl RemoteDB {
118 fn record_internal(&mut self, internal_key: String, pk: Option<u64>) -> Result<u64> {
119 let pk = if let Some(pk) = pk {
120 pk
121 } else {
122 self.next_key()
123 };
124
125 self.add_internal(pk, internal_key);
126 Ok(pk)
127 }
128
129 async fn record_updates(&mut self, mut records: Vec<Record>) -> Result<Vec<Record>> {
130 for record in &mut records {
131 if let Some(internal_recurrence_key) = record.internal_recurrence_key() {
132 if record.recurrence_key().is_none() {
133 let key = self.next_recurrence_key();
134 record.set_recurrence_key(Some(key));
135 self.add_recurring(internal_recurrence_key, key);
136 }
137 }
138
139 if let Some(internal_key) = record.internal_key() {
140 if record.primary_key() == 0 {
141 record.set_primary_key(self.record_internal(
142 internal_key.clone(),
143 self.lookup_internal(internal_key),
144 )?);
145 }
146 }
147
148 if let Some(fields) = self.fields.get(&record.primary_key()) {
149 record.set_fields(fields.clone());
150 }
151 }
152
153 Ok(records)
154 }
155
156 async fn record_recurring_updates(
157 &mut self,
158 mut records: Vec<RecurringRecord>,
159 ) -> Result<Vec<RecurringRecord>> {
160 let mut v = Vec::new();
161 for record in &mut records {
162 if let Some(internal_recurrence_key) = record.internal_key() {
163 if let Some(internal) =
164 self.recurring_lookup_internal(internal_recurrence_key.clone())
165 {
166 record.set_recurrence_key(internal);
167 record.record().set_recurrence_key(Some(internal));
168 self.add_recurring(internal_recurrence_key.clone(), internal);
169 } else if record.recurrence_key() == 0 {
170 let key = self.next_recurrence_key();
171 record.set_recurrence_key(key);
172 record.record().set_recurrence_key(Some(key));
173 self.add_recurring(internal_recurrence_key.clone(), key);
174 } else {
175 record.recurrence_key();
176 }
177 }
178
179 if let Some(internal_key) = record.record().internal_key() {
180 if record.record().primary_key() == 0 {
181 record.record().set_primary_key(self.record_internal(
182 internal_key.clone(),
183 self.lookup_internal(internal_key),
184 )?);
185 }
186 }
187
188 v.push(record.clone());
189 }
190
191 Ok(v)
192 }
193}
194
195#[async_trait]
196impl DB for RemoteDB {
197 async fn load(&mut self) -> Result<()> {
198 let db: Self = UnixFileLoader::new(&saturn_db()).load().await?;
199 self.primary_key = db.primary_key;
200 self.recurrence_key = db.recurrence_key;
201 self.id_map = db.id_map;
202 self.reverse_id_map = db.reverse_id_map;
203 self.recurring_id_map = db.recurring_id_map;
204 self.reverse_recurring_id_map = db.reverse_recurring_id_map;
205 self.fields = db.fields;
206 self.update_recurrence().await
207 }
208
209 async fn dump(&self) -> Result<()> {
210 UnixFileLoader::new(&saturn_db()).dump(self.clone()).await
211 }
212
213 fn primary_key(&self) -> u64 {
214 self.primary_key
215 }
216
217 fn set_primary_key(&mut self, primary_key: u64) {
218 self.primary_key = primary_key;
219 }
220
221 fn recurrence_key(&self) -> u64 {
222 self.recurrence_key
223 }
224
225 fn set_recurrence_key(&mut self, recurrence_key: u64) {
226 self.recurrence_key = recurrence_key;
227 }
228
229 async fn delete(&mut self, primary_key: u64) -> Result<()> {
230 self.remove_by_internal_id(primary_key);
231 Ok(())
232 }
233
234 async fn delete_recurrence(&mut self, recurrence_key: u64) -> Result<Vec<String>> {
235 self.remove_by_internal_id(recurrence_key);
236 self.remove_recurring_by_internal_id(recurrence_key);
237 Ok(Vec::new())
239 }
240
241 async fn record(&mut self, _record: Record) -> Result<()> {
242 Ok(())
243 }
244
245 async fn record_recurrence(&mut self, _record: RecurringRecord) -> Result<()> {
246 Ok(())
247 }
248
249 async fn insert_record(&mut self, _record: Record) -> Result<()> {
250 Ok(())
251 }
252
253 async fn insert_recurrence(&mut self, _record: RecurringRecord) -> Result<()> {
254 Ok(())
255 }
256
257 async fn list_recurrence(&mut self) -> Result<Vec<RecurringRecord>> {
258 Ok(Default::default())
259 }
260
261 async fn update_recurrence(&mut self) -> Result<()> {
262 Ok(())
263 }
264
265 async fn list_today(&mut self, _include_completed: bool) -> Result<Vec<Record>> {
266 Ok(Default::default())
267 }
268
269 async fn list_all(&mut self, _include_completed: bool) -> Result<Vec<Record>> {
270 Ok(Default::default())
271 }
272
273 async fn events_now(
274 &mut self,
275 _last: chrono::Duration,
276 _include_completed: bool,
277 ) -> Result<Vec<Record>> {
278 Ok(Default::default())
279 }
280
281 async fn complete_task(&mut self, _primary_key: u64) -> Result<()> {
282 Ok(())
283 }
284
285 async fn get(&mut self, _primary_key: u64) -> Result<Record> {
286 Err(anyhow!("No Record Found"))
287 }
288
289 async fn get_recurring(&mut self, _primary_key: u64) -> Result<RecurringRecord> {
290 Err(anyhow!("No Record Found"))
291 }
292
293 async fn update(&mut self, _record: Record) -> Result<()> {
294 Ok(())
295 }
296
297 async fn update_recurring(&mut self, _record: RecurringRecord) -> Result<()> {
298 Ok(())
299 }
300}
301
302#[async_trait]
303impl<T: RemoteClient + Send + Sync + Default + std::fmt::Debug> DB for RemoteDBClient<T> {
304 async fn load(&mut self) -> Result<()> {
305 self.db.load().await
306 }
307
308 async fn dump(&self) -> Result<()> {
309 self.db.dump().await
310 }
311
312 fn primary_key(&self) -> u64 {
313 self.db.primary_key()
314 }
315
316 fn set_primary_key(&mut self, primary_key: u64) {
317 self.db.set_primary_key(primary_key)
318 }
319
320 fn recurrence_key(&self) -> u64 {
321 self.db.recurrence_key()
322 }
323
324 fn set_recurrence_key(&mut self, recurrence_key: u64) {
325 self.db.set_recurrence_key(recurrence_key);
326 }
327
328 async fn delete(&mut self, primary_key: u64) -> Result<()> {
329 let id = self
330 .db
331 .lookup(primary_key)
332 .map_or_else(|| Err(anyhow!("Invalid ID")), |k| Ok(k))?;
333
334 let calendar_id = self.db.calendar_id.clone();
335
336 self.client.delete(calendar_id, id).await?;
337 self.db.delete(primary_key).await?;
338 Ok(())
339 }
340
341 async fn delete_recurrence(&mut self, recurrence_key: u64) -> Result<Vec<String>> {
342 let id = self
343 .db
344 .recurring_lookup(recurrence_key)
345 .map_or_else(|| Err(anyhow!("Invalid ID")), |k| Ok(k))?;
346 let calendar_id = self.db.calendar_id.clone();
347
348 let list = self
349 .client
350 .delete_recurrence(calendar_id.clone(), id.clone())
351 .await?;
352 for item in list.iter() {
353 if let Some(id) = self.db.lookup_internal(item.clone()) {
354 let res = self.delete(id).await;
355 if matches!(res, Result::Err(_)) {
356 break;
357 }
358 }
359 }
360
361 self.db.delete_recurrence(recurrence_key).await?;
362 if let Some(id) = self.db.lookup_internal(id) {
363 self.db.delete(id).await?;
364 }
365 Ok(list)
367 }
368
369 async fn record(&mut self, record: Record) -> Result<()> {
370 if self.db.lookup(record.primary_key()).is_none() {
371 self.insert_record(record).await
372 } else {
373 Ok(())
374 }
375 }
376
377 async fn record_recurrence(&mut self, record: RecurringRecord) -> Result<()> {
378 if self.db.recurring_lookup(record.recurrence_key()).is_none() {
379 self.insert_recurrence(record).await
380 } else {
381 Ok(())
382 }
383 }
384
385 async fn insert_record(&mut self, record: Record) -> Result<()> {
386 let key = record.primary_key();
387 let calendar_id = self.db.calendar_id.clone();
388
389 let internal_key = self.client.record(calendar_id, record.clone()).await?;
390
391 self.db.add(internal_key, key);
392 self.db.fields.insert(key, record.fields());
393 Ok(())
394 }
395
396 async fn insert_recurrence(&mut self, mut record: RecurringRecord) -> Result<()> {
397 let calendar_id = self.db.calendar_id.clone();
398
399 let (key, recurrence_key) = self
400 .client
401 .record_recurrence(calendar_id, record.clone())
402 .await?;
403
404 record.set_internal_key(Some(key.clone()));
405 record
406 .record()
407 .set_internal_recurrence_key(Some(key.clone()));
408 record.record().set_internal_key(Some(key.clone()));
409 record.record().set_primary_key(self.next_key());
410
411 if record.recurrence_key() == 0 {
412 record.set_recurrence_key(self.next_recurrence_key());
413 record
414 .record()
415 .set_recurrence_key(Some(self.recurrence_key()));
416 }
417
418 self.db
419 .add_recurring(recurrence_key, record.recurrence_key());
420 Ok(())
421 }
422
423 async fn list_recurrence(&mut self) -> Result<Vec<RecurringRecord>> {
424 let calendar_id = self.db.calendar_id.clone();
425
426 self.db
427 .record_recurring_updates(self.client.list_recurrence(calendar_id).await?)
428 .await
429 }
430
431 async fn update_recurrence(&mut self) -> Result<()> {
432 let calendar_id = self.db.calendar_id.clone();
433
434 self.client.update_recurrence(calendar_id).await
435 }
436
437 async fn list_today(&mut self, include_completed: bool) -> Result<Vec<Record>> {
438 let calendar_id = self.db.calendar_id.clone();
439
440 self.db
441 .record_updates(
442 self.client
443 .list_today(calendar_id, include_completed)
444 .await?,
445 )
446 .await
447 }
448
449 async fn list_all(&mut self, include_completed: bool) -> Result<Vec<Record>> {
450 let calendar_id = self.db.calendar_id.clone();
451
452 self.db
453 .record_updates(self.client.list_all(calendar_id, include_completed).await?)
454 .await
455 }
456
457 async fn events_now(
458 &mut self,
459 last: chrono::Duration,
460 include_completed: bool,
461 ) -> Result<Vec<Record>> {
462 let calendar_id = self.db.calendar_id.clone();
463
464 self.db
465 .record_updates(
466 self.client
467 .events_now(calendar_id, last, include_completed)
468 .await?,
469 )
470 .await
471 }
472
473 async fn complete_task(&mut self, primary_key: u64) -> Result<()> {
474 let calendar_id = self.db.calendar_id.clone();
475
476 self.client.complete_task(calendar_id, primary_key).await
477 }
478
479 async fn get(&mut self, primary_key: u64) -> Result<Record> {
480 let calendar_id = self.db.calendar_id.clone();
481 let event_id = self
482 .db
483 .lookup(primary_key)
484 .ok_or(anyhow!("No Record Found"))?;
485 let mut rec = self.client.get(calendar_id, event_id).await?;
486 rec.set_primary_key(primary_key);
487 if let Some(fields) = self.db.fields.get(&primary_key) {
488 rec.set_fields(fields.clone());
489 }
490 Ok(rec)
491 }
492
493 async fn get_recurring(&mut self, recurrence_key: u64) -> Result<RecurringRecord> {
494 let calendar_id = self.db.calendar_id.clone();
495 let event_id = self
496 .db
497 .recurring_lookup(recurrence_key)
498 .ok_or(anyhow!("No Record Found"))?;
499 let mut rec = self
500 .client
501 .get_recurring(calendar_id, event_id.clone())
502 .await?;
503 let primary_key = self.db.lookup_internal(event_id).unwrap_or(0);
504 rec.record().set_primary_key(primary_key);
505 rec.record().set_recurrence_key(Some(recurrence_key));
506 rec.set_recurrence_key(recurrence_key);
507 Ok(rec)
508 }
509
510 async fn update(&mut self, record: Record) -> Result<()> {
511 let calendar_id = self.db.calendar_id.clone();
512 self.db.fields.insert(record.primary_key(), record.fields());
513 self.client.update(calendar_id, record).await
514 }
515
516 async fn update_recurring(&mut self, record: RecurringRecord) -> Result<()> {
517 let calendar_id = self.db.calendar_id.clone();
518 self.client.update_recurring(calendar_id, record).await
519 }
520}