Skip to main content

fedimint_cursed_redb/
native.rs

1use 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}