standalone/
metadata.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use 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
27/// Builds the metadata kvbackend.
28pub 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
40/// Builds the metadata kvbackend from a list of URLs.
41pub 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}