1use std::sync::Arc;
16
17use common_config::KvBackendConfig;
18use common_error::ext::BoxedError;
19use common_meta::kv_backend::KvBackendRef;
20use common_telemetry::{debug, info};
21use log_store::raft_engine::RaftEngineBackend;
22use snafu::{ResultExt, ensure};
23use url::Url;
24
25use crate::error::{InvalidUrlSchemeSnafu, OpenMetadataKvBackendSnafu, ParseUrlSnafu, Result};
26
27pub fn build_metadata_kvbackend(dir: String, config: KvBackendConfig) -> Result<KvBackendRef> {
29 info!(
30 "Creating metadata kvbackend with dir: {}, config: {:?}",
31 dir, config
32 );
33 let kv_backend = RaftEngineBackend::try_open_with_cfg(dir, &config)
34 .map_err(BoxedError::new)
35 .context(OpenMetadataKvBackendSnafu)?;
36
37 Ok(Arc::new(kv_backend))
38}
39
40pub fn build_metadata_kv_from_url(url: &str) -> Result<KvBackendRef> {
42 debug!("Building metadata kvbackend from url: {}", url);
43 let url = Url::parse(url).context(ParseUrlSnafu { url })?;
44 ensure!(
45 url.scheme() == "raftengine",
46 InvalidUrlSchemeSnafu {
47 scheme: url.scheme(),
48 }
49 );
50
51 let path = normalize_raftengine_path(url.path());
52 build_metadata_kvbackend(path, Default::default())
53}
54
55fn normalize_raftengine_path(path: &str) -> String {
56 if cfg!(windows) {
57 let mut path = path.replace('\\', "/");
58 if let Some(stripped) = path.strip_prefix('/') {
59 let bytes = stripped.as_bytes();
60 if bytes.len() >= 2 && bytes[0].is_ascii_alphabetic() && bytes[1] == b':' {
61 path = stripped.to_string();
62 }
63 }
64 path
65 } else {
66 path.to_string()
67 }
68}