pict-rs/src/migrate.rs

98 lines
2 KiB
Rust
Raw Normal View History

2022-03-29 01:47:46 +00:00
use crate::Error;
2020-07-11 20:40:40 +00:00
use std::path::PathBuf;
2020-09-14 21:42:31 +00:00
mod s034;
2022-03-29 01:47:46 +00:00
type SledIter = Box<dyn Iterator<Item = Result<(Vec<u8>, Vec<u8>), Error>>>;
2020-09-14 21:42:31 +00:00
trait SledDb {
type SledTree: SledTree;
2022-03-29 01:47:46 +00:00
fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error>;
2020-09-14 21:42:31 +00:00
fn self_tree(&self) -> &Self::SledTree;
}
impl<T> SledDb for &T
where
T: SledDb,
{
type SledTree = T::SledTree;
2022-03-29 01:47:46 +00:00
fn open_tree(&self, name: &str) -> Result<Self::SledTree, Error> {
2020-09-14 21:42:31 +00:00
(*self).open_tree(name)
}
fn self_tree(&self) -> &Self::SledTree {
(*self).self_tree()
}
}
trait SledTree {
2022-03-29 01:47:46 +00:00
fn get<K>(&self, key: K) -> Result<Option<Vec<u8>>, Error>
2020-09-14 21:42:31 +00:00
where
K: AsRef<[u8]>;
2022-03-29 01:47:46 +00:00
fn insert<K, V>(&self, key: K, value: V) -> Result<(), Error>
2020-09-14 21:42:31 +00:00
where
K: AsRef<[u8]>,
V: AsRef<[u8]>;
fn iter(&self) -> SledIter;
fn range<K, R>(&self, range: R) -> SledIter
where
K: AsRef<[u8]>,
R: std::ops::RangeBounds<K>;
2022-03-29 01:47:46 +00:00
fn flush(&self) -> Result<(), Error>;
2020-09-14 21:42:31 +00:00
}
2020-07-11 20:40:40 +00:00
pub(crate) struct LatestDb {
root_dir: PathBuf,
version: DbVersion,
}
impl LatestDb {
2022-03-25 23:47:50 +00:00
pub(crate) fn exists(root_dir: PathBuf) -> Self {
let version = DbVersion::exists(root_dir.clone());
2020-07-11 20:40:40 +00:00
2022-03-25 23:47:50 +00:00
LatestDb { root_dir, version }
2020-07-11 20:40:40 +00:00
}
2022-03-29 01:47:46 +00:00
pub(crate) fn migrate(self) -> Result<sled::Db, Error> {
2022-03-25 23:47:50 +00:00
let LatestDb { root_dir, version } = self;
2020-07-11 20:40:40 +00:00
loop {
let root_dir2 = root_dir.clone();
2022-03-25 23:47:50 +00:00
let res = std::panic::catch_unwind(move || version.migrate(root_dir2));
if let Ok(res) = res {
return res;
}
}
2020-07-11 20:40:40 +00:00
}
}
#[derive(Clone, Copy)]
2020-07-11 20:40:40 +00:00
enum DbVersion {
2020-09-10 16:12:42 +00:00
Sled034,
2020-07-11 20:40:40 +00:00
Fresh,
}
impl DbVersion {
2022-03-25 23:47:50 +00:00
fn exists(root: PathBuf) -> Self {
if s034::exists(root.clone()) && !s034::migrating(root) {
2020-09-10 16:12:42 +00:00
return DbVersion::Sled034;
}
2020-07-11 20:40:40 +00:00
DbVersion::Fresh
}
2022-03-29 01:47:46 +00:00
fn migrate(self, root: PathBuf) -> Result<sled::Db, Error> {
2020-07-11 20:40:40 +00:00
match self {
2022-03-25 23:47:50 +00:00
DbVersion::Sled034 | DbVersion::Fresh => s034::open(root),
2020-07-11 20:40:40 +00:00
}
}
}