Skip to content
This repository has been archived by the owner on Jun 6, 2024. It is now read-only.

Add Namespace functions for rocksdb interaction #3

Merged
merged 10 commits into from
Mar 25, 2024
37 changes: 31 additions & 6 deletions src/database/database.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
use rocksdb::{ColumnFamilyDescriptor, Options, DB};
use rocksdb::{ColumnFamilyDescriptor, IteratorMode, Options, DB};
use serde::{Deserialize, Serialize};
use std::io::{self, ErrorKind};
use std::path::Path;
use std::sync::Arc;

pub struct Database {
db: DB,
db: Arc<DB>,
}

impl Clone for Database {
fn clone(&self) -> Self {
Self {
db: Arc::clone(&self.db),
}
}
}

impl Database {
Expand All @@ -27,8 +36,27 @@ impl Database {
let db = DB::open_cf_descriptors(&opts, path, cfs_vec)
.map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?;

Ok(Self { db })
Ok(Self { db: db.into() })
}

pub fn list_all_keys(&self, cf: &str) -> Result<Vec<String>, io::Error> {
let cf_handle = self.db.cf_handle(cf).ok_or_else(|| {
io::Error::new(
ErrorKind::NotFound,
format!("Column family {} not found", cf),
)
})?;
let mut keys = Vec::new();
let iter = self.db.iterator_cf(cf_handle, IteratorMode::Start);
for item in iter {
let (key, _) = item.map_err(|e| io::Error::new(ErrorKind::Other, e.to_string()))?;
let key_str = String::from_utf8(key.to_vec())
.map_err(|e| io::Error::new(ErrorKind::Other, e.to_string()))?;
keys.push(key_str);
}
Ok(keys)
}

pub fn insert<V: Serialize>(&self, cf: &str, key: &str, value: &V) -> Result<(), io::Error> {
let cf_handle = self.db.cf_handle(cf).ok_or_else(|| {
io::Error::new(
Expand Down Expand Up @@ -96,7 +124,4 @@ impl Database {
Ok(())
}

pub fn close(self) {
drop(self);
}
}
1 change: 1 addition & 0 deletions src/repository/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod namespace;
59 changes: 59 additions & 0 deletions src/repository/namespace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use crate::database::database::Database;
use crate::dto::namespace_data::NamespaceData;
use serde_json::{json, Value};
use std::io;
use std::sync::Arc;

pub struct NamespaceRepository {
db: Arc<Database>,
}

impl NamespaceRepository {
pub fn new(db: Arc<Database>) -> Self {
Self { db }
}

pub fn list_all_namespaces(&self) -> io::Result<Vec<String>> {
self.db
.list_all_keys("NamespaceData")
.map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))
}

pub fn create_namespace(&self, name: &str, properties: Option<Value>) -> io::Result<()> {
let namespace_data = NamespaceData {
name: name.to_string(),
properties: properties.unwrap_or_else(|| json!({"last_modified_time": current_time()})),
};
self.db.insert("NamespaceData", name, &namespace_data)
}

pub fn load_namespace(&self, name: &str) -> io::Result<Option<NamespaceData>> {
self.db.get("NamespaceData", name)
}

pub fn namespace_exists(&self, name: &str) -> io::Result<bool> {
self.db
.get::<NamespaceData>("NamespaceData", name)
.map(|data| data.is_some())
}

pub fn delete_namespace(&self, name: &str) -> io::Result<()> {
self.db.delete("NamespaceData", name)
}

pub fn set_namespace_properties(&self, name: &str, properties: Value) -> io::Result<()> {
if let Some(mut namespace_data) = self.load_namespace(name)? {
namespace_data.properties = properties;
self.db.update("NamespaceData", name, &namespace_data)
} else {
Err(io::Error::new(
io::ErrorKind::NotFound,
"Namespace not found",
))
}
}
}

fn current_time() -> String {
"current_time".to_string()
}
Loading