use log::{error, warn};
use sled;
use lazy_static::lazy_static;
pub trait StoreInterface: Sync {
fn get(&self, key: &str) -> String;
fn set(&self, key: &str, value: &str);
fn clean(&self, prefix: &str); }
struct LocalStore {
backend: sled::Db,
}
impl LocalStore {
fn new() -> Self {
let db_path = "/tmp/.pipeless_kv_store";
let db = sled::open(db_path)
.expect(&format!("Failed to open KV store. Ensure pipeless can write at {}", db_path));
Self { backend: db }
}
}
impl StoreInterface for LocalStore {
fn set(&self, key: &str, value: &str) {
if let Err(err) = self.backend.insert(key, value) {
error!("Error inserting key {} with value {} in local KV store. Error: {}", key, value, err);
}
}
fn get(&self, key: &str) -> String {
match self.backend.get(key) {
Ok(v) => {
match v.as_deref() {
Some(v) => std::str::from_utf8(v).unwrap().into(),
None => String::from("")
}
},
Err(err) => {
error!("Error getting value for key {} from local KV store. Error: {}", key, err);
String::from("")
}
}
}
fn clean(&self, prefix: &str) {
let keys_to_remove: Vec<sled::IVec> = self.backend
.scan_prefix(prefix)
.keys()
.filter_map(Result::ok)
.collect();
for key in keys_to_remove {
if let Err(err) = self.backend.remove(&key) {
warn!("Failed to remove key from KV store. {}", err);
}
}
}
}
lazy_static! {
pub static ref KV_STORE: Box<dyn StoreInterface> = Box::new(LocalStore::new());
}