fedimint_cursed_redb/
native.rs1use std::path::Path;
2
3use fedimint_db_locked::{Locked, LockedBuilder};
4use redb::Database;
5
6use crate::{MemAndRedb, MemAndRedbOpenError};
7
8impl MemAndRedb {
9 pub async fn new(db_path: impl AsRef<Path>) -> Result<Locked<MemAndRedb>, MemAndRedbOpenError> {
10 let db_path = db_path.as_ref();
11 fedimint_core::task::block_in_place(|| Self::open_blocking(db_path))
12 }
13
14 fn open_blocking(db_path: &Path) -> Result<Locked<MemAndRedb>, MemAndRedbOpenError> {
15 std::fs::create_dir_all(db_path.parent().ok_or(MemAndRedbOpenError::NoBaseDir)?)?;
16 LockedBuilder::new(db_path)?.with_db(|| {
17 let db = match Database::create(db_path) {
18 Ok(db) => db,
19 Err(redb::DatabaseError::UpgradeRequired(_)) => {
20 Self::migrate_v2_to_v3(db_path)?;
21 Database::create(db_path)
22 .map_err(|e| MemAndRedbOpenError::OpenMigrated(e.into()))?
23 }
24 Err(e) => return Err(MemAndRedbOpenError::Open(e.into())),
25 };
26 Ok(Self::new_from_redb(db)?)
27 })
28 }
29
30 fn migrate_v2_to_v3(db_path: &Path) -> Result<(), MemAndRedbOpenError> {
31 tracing::info!("Migrating redb database from v2 to v3 file format");
32 let mut old_db =
33 redb2::Database::open(db_path).map_err(|e| MemAndRedbOpenError::OpenV2(e.into()))?;
34 old_db
35 .upgrade()
36 .map_err(|e| MemAndRedbOpenError::UpgradeV2(e.into()))?;
37 tracing::info!("Successfully migrated redb database to v3 format");
38 Ok(())
39 }
40}