1use std::{path::Path, sync::Arc};
20
21use sp_blockchain::HeaderBackend;
23use sp_runtime::traits::Block as BlockT;
24
25use super::{Database, DatabaseSettings, DatabaseSource, DbHash};
26
27pub fn open_database<Block: BlockT, C: HeaderBackend<Block>>(
28 client: Arc<C>,
29 config: &DatabaseSettings,
30) -> Result<Arc<dyn Database<DbHash>>, String> {
31 let db: Arc<dyn Database<DbHash>> = match &config.source {
32 DatabaseSource::Auto {
33 paritydb_path,
34 rocksdb_path,
35 ..
36 } => {
37 match open_kvdb_rocksdb::<Block, C>(client.clone(), rocksdb_path, false, &config.source)
38 {
39 Ok(db) => db,
40 Err(_) => open_parity_db::<Block, C>(client, paritydb_path, &config.source)?,
41 }
42 }
43 #[cfg(feature = "rocksdb")]
44 DatabaseSource::RocksDb { path, .. } => {
45 open_kvdb_rocksdb::<Block, C>(client, path, true, &config.source)?
46 }
47 DatabaseSource::ParityDb { path } => {
48 open_parity_db::<Block, C>(client, path, &config.source)?
49 }
50 _ => return Err("Supported db sources: `auto` | `rocksdb` | `paritydb`".to_string()),
51 };
52 Ok(db)
53}
54
55#[allow(unused_variables)]
56#[cfg(feature = "rocksdb")]
57fn open_kvdb_rocksdb<Block: BlockT, C: HeaderBackend<Block>>(
58 client: Arc<C>,
59 path: &Path,
60 create: bool,
61 _source: &DatabaseSource,
62) -> Result<Arc<dyn Database<DbHash>>, String> {
63 #[cfg(not(test))]
65 match super::upgrade::upgrade_db::<Block, C>(client, path, _source) {
66 Ok(_) => (),
67 Err(_) => return Err("Frontier DB upgrade error".to_string()),
68 }
69
70 let mut db_config = kvdb_rocksdb::DatabaseConfig::with_columns(super::columns::NUM_COLUMNS);
71 db_config.create_if_missing = create;
72
73 let db = kvdb_rocksdb::Database::open(&db_config, path).map_err(|err| format!("{err}"))?;
74 #[cfg(not(test))]
76 super::upgrade::update_version(path).map_err(|_| "Cannot update db version".to_string())?;
77 Ok(sp_database::as_database(db))
78}
79
80#[cfg(not(feature = "rocksdb"))]
81fn open_kvdb_rocksdb<Block: BlockT, C: HeaderBackend<Block>>(
82 _client: Arc<C>,
83 _path: &Path,
84 _create: bool,
85 _source: &DatabaseSource,
86) -> Result<Arc<dyn Database<DbHash>>, String> {
87 Err("Missing feature flags `rocksdb`".to_string())
88}
89
90#[allow(unused_variables)]
91fn open_parity_db<Block: BlockT, C: HeaderBackend<Block>>(
92 client: Arc<C>,
93 path: &Path,
94 _source: &DatabaseSource,
95) -> Result<Arc<dyn Database<DbHash>>, String> {
96 #[cfg(not(test))]
98 match super::upgrade::upgrade_db::<Block, C>(client, path, _source) {
99 Ok(_) => (),
100 Err(_) => return Err("Frontier DB upgrade error".to_string()),
101 }
102 let mut config = parity_db::Options::with_columns(path, super::columns::NUM_COLUMNS as u8);
103 config.columns[super::columns::BLOCK_MAPPING as usize].btree_index = true;
104
105 let db = parity_db::Db::open_or_create(&config).map_err(|err| format!("{err}"))?;
106 #[cfg(not(test))]
108 super::upgrade::update_version(path).map_err(|_| "Cannot update db version".to_string())?;
109 Ok(Arc::new(super::parity_db_adapter::DbAdapter(db)))
110}