Skip to main content

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::{ClosableKvBackendRef, 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/// Opens the metadata kvbackend, which the caller has to close on shutdown.
28pub fn open_metadata_kvbackend(
29    dir: String,
30    config: KvBackendConfig,
31) -> Result<ClosableKvBackendRef> {
32    info!(
33        "Creating metadata kvbackend with dir: {}, config: {:?}",
34        dir, config
35    );
36    let kv_backend = RaftEngineBackend::try_open_with_cfg(dir, &config)
37        .map_err(BoxedError::new)
38        .context(OpenMetadataKvBackendSnafu)?;
39
40    Ok(Arc::new(kv_backend))
41}
42
43/// Builds the metadata kvbackend.
44pub fn build_metadata_kvbackend(dir: String, config: KvBackendConfig) -> Result<KvBackendRef> {
45    open_metadata_kvbackend(dir, config).map(|kv_backend| kv_backend as KvBackendRef)
46}
47
48/// Builds the metadata kvbackend from a list of URLs.
49pub fn build_metadata_kv_from_url(url: &str) -> Result<KvBackendRef> {
50    debug!("Building metadata kvbackend from url: {}", url);
51    let url = Url::parse(url).context(ParseUrlSnafu { url })?;
52    ensure!(
53        url.scheme() == "raftengine",
54        InvalidUrlSchemeSnafu {
55            scheme: url.scheme(),
56        }
57    );
58
59    let path = normalize_raftengine_path(url.path());
60    build_metadata_kvbackend(path, Default::default())
61}
62
63fn normalize_raftengine_path(path: &str) -> String {
64    if cfg!(windows) {
65        let mut path = path.replace('\\', "/");
66        if let Some(stripped) = path.strip_prefix('/') {
67            let bytes = stripped.as_bytes();
68            if bytes.len() >= 2 && bytes[0].is_ascii_alphabetic() && bytes[1] == b':' {
69                path = stripped.to_string();
70            }
71        }
72        path
73    } else {
74        path.to_string()
75    }
76}