uqa_storage/mvcc/
restore.rs1use super::{DatabaseId, VersionError, VersionResult};
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub struct DatabaseRestore {
14 source: DatabaseId,
15 target: DatabaseId,
16}
17
18impl DatabaseRestore {
19 pub fn new(source: DatabaseId) -> VersionResult<Self> {
21 let mut target = [0; 16];
22 getrandom::fill(&mut target).map_err(|error| {
23 crate::StorageBackendError::Other(format!(
24 "allocate database restore identity: {error}"
25 ))
26 })?;
27 Self::from_identities(source, DatabaseId::from_bytes(target))
28 }
29
30 pub fn from_identities(source: DatabaseId, target: DatabaseId) -> VersionResult<Self> {
32 if source == target {
33 return Err(VersionError::InvalidRestoreIdentity);
34 }
35 Ok(Self { source, target })
36 }
37
38 pub const fn source(self) -> DatabaseId {
39 self.source
40 }
41
42 pub const fn target(self) -> DatabaseId {
43 self.target
44 }
45
46 pub fn needs_restore(self, current: DatabaseId) -> VersionResult<bool> {
48 if current == self.source {
49 Ok(true)
50 } else if current == self.target {
51 Ok(false)
52 } else {
53 Err(VersionError::WrongDatabase)
54 }
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn restored_history_requests_distinguish_source_completion_and_foreign_databases() {
64 let source = DatabaseId::from_bytes([1; 16]);
65 let target = DatabaseId::from_bytes([2; 16]);
66 let request = DatabaseRestore::from_identities(source, target).unwrap();
67 assert!(request.needs_restore(source).unwrap());
68 assert!(!request.needs_restore(target).unwrap());
69 assert!(matches!(
70 request.needs_restore(DatabaseId::from_bytes([3; 16])),
71 Err(VersionError::WrongDatabase)
72 ));
73 assert!(matches!(
74 DatabaseRestore::from_identities(source, source),
75 Err(VersionError::InvalidRestoreIdentity)
76 ));
77 let generated = DatabaseRestore::new(source).unwrap();
78 assert_eq!(generated.source(), source);
79 assert_ne!(generated.target(), source);
80 assert_eq!(
81 DatabaseRestore::from_identities(generated.source(), generated.target()).unwrap(),
82 generated
83 );
84 }
85}