fix invalid values in RPC response about database instance details
This commit is contained in:
133
src/rpc.rs
133
src/rpc.rs
@@ -338,6 +338,92 @@ impl RpcServerImpl {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Build database file path for given server/db_id
|
||||
fn db_file_path(&self, server: &Server, db_id: u64) -> std::path::PathBuf {
|
||||
std::path::PathBuf::from(&server.option.dir).join(format!("{}.db", db_id))
|
||||
}
|
||||
|
||||
/// Recursively compute size on disk for the database path
|
||||
fn compute_size_on_disk(&self, path: &std::path::Path) -> Option<u64> {
|
||||
fn dir_size(p: &std::path::Path) -> u64 {
|
||||
if p.is_file() {
|
||||
std::fs::metadata(p).map(|m| m.len()).unwrap_or(0)
|
||||
} else if p.is_dir() {
|
||||
let mut total = 0u64;
|
||||
if let Ok(read) = std::fs::read_dir(p) {
|
||||
for entry in read.flatten() {
|
||||
total += dir_size(&entry.path());
|
||||
}
|
||||
}
|
||||
total
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
Some(dir_size(path))
|
||||
}
|
||||
|
||||
/// Extract created and last access times (secs) from a path, with fallbacks
|
||||
fn get_file_times_secs(path: &std::path::Path) -> (u64, Option<u64>) {
|
||||
let now = std::time::SystemTime::now();
|
||||
let created = std::fs::metadata(path)
|
||||
.and_then(|m| m.created().or_else(|_| m.modified()))
|
||||
.unwrap_or(now)
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
|
||||
let last_access = std::fs::metadata(path)
|
||||
.and_then(|m| m.accessed())
|
||||
.ok()
|
||||
.and_then(|t| t.duration_since(std::time::UNIX_EPOCH).ok().map(|d| d.as_secs()));
|
||||
|
||||
(created, last_access)
|
||||
}
|
||||
|
||||
/// Compose a DatabaseInfo by probing storage, metadata and filesystem
|
||||
async fn build_database_info(&self, db_id: u64, server: &Server) -> DatabaseInfo {
|
||||
// Probe storage to determine encryption state
|
||||
let storage = server.current_storage().ok();
|
||||
let encrypted = storage.as_ref().map(|s| s.is_encrypted()).unwrap_or(server.option.encrypt);
|
||||
|
||||
// Load meta to get access key count
|
||||
let meta = Self::load_meta_static(&self.base_dir, db_id).await.unwrap_or(DatabaseMeta {
|
||||
public: true,
|
||||
keys: HashMap::new(),
|
||||
});
|
||||
let key_count = Some(meta.keys.len() as u64);
|
||||
|
||||
// Compute size on disk and timestamps
|
||||
let db_path = self.db_file_path(server, db_id);
|
||||
let size_on_disk = self.compute_size_on_disk(&db_path);
|
||||
|
||||
let meta_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}_meta.json", db_id));
|
||||
let (created_at, last_access) = if meta_path.exists() {
|
||||
Self::get_file_times_secs(&meta_path)
|
||||
} else {
|
||||
Self::get_file_times_secs(&db_path)
|
||||
};
|
||||
|
||||
let backend = match server.option.backend {
|
||||
crate::options::BackendType::Redb => BackendType::Redb,
|
||||
crate::options::BackendType::Sled => BackendType::Sled,
|
||||
};
|
||||
|
||||
DatabaseInfo {
|
||||
id: db_id,
|
||||
name: None,
|
||||
backend,
|
||||
encrypted,
|
||||
redis_version: Some("7.0".to_string()),
|
||||
storage_path: Some(server.option.dir.clone()),
|
||||
size_on_disk,
|
||||
key_count,
|
||||
created_at,
|
||||
last_access,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[jsonrpsee::core::async_trait]
|
||||
@@ -426,28 +512,9 @@ impl RpcServer for RpcServerImpl {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for db_id in db_ids {
|
||||
// Try to get or create server for this database
|
||||
if let Ok(server) = self.get_or_create_server(db_id).await {
|
||||
let backend = match server.option.backend {
|
||||
crate::options::BackendType::Redb => BackendType::Redb,
|
||||
crate::options::BackendType::Sled => BackendType::Sled,
|
||||
};
|
||||
|
||||
let info = DatabaseInfo {
|
||||
id: db_id,
|
||||
name: None, // TODO: Store name in server metadata
|
||||
backend,
|
||||
encrypted: server.option.encrypt,
|
||||
redis_version: Some("7.0".to_string()), // Default Redis compatibility
|
||||
storage_path: Some(server.option.dir.clone()),
|
||||
size_on_disk: None, // TODO: Calculate actual size
|
||||
key_count: None, // TODO: Get key count from storage
|
||||
created_at: std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
last_access: None,
|
||||
};
|
||||
// Build accurate info from storage/meta/fs
|
||||
let info = self.build_database_info(db_id, &server).await;
|
||||
result.push(info);
|
||||
}
|
||||
}
|
||||
@@ -457,27 +524,9 @@ impl RpcServer for RpcServerImpl {
|
||||
|
||||
async fn get_database_info(&self, db_id: u64) -> RpcResult<DatabaseInfo> {
|
||||
let server = self.get_or_create_server(db_id).await?;
|
||||
|
||||
let backend = match server.option.backend {
|
||||
crate::options::BackendType::Redb => BackendType::Redb,
|
||||
crate::options::BackendType::Sled => BackendType::Sled,
|
||||
};
|
||||
|
||||
Ok(DatabaseInfo {
|
||||
id: db_id,
|
||||
name: None,
|
||||
backend,
|
||||
encrypted: server.option.encrypt,
|
||||
redis_version: Some("7.0".to_string()),
|
||||
storage_path: Some(server.option.dir.clone()),
|
||||
size_on_disk: None,
|
||||
key_count: None,
|
||||
created_at: std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_secs(),
|
||||
last_access: None,
|
||||
})
|
||||
// Build accurate info from storage/meta/fs
|
||||
let info = self.build_database_info(db_id, &server).await;
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
async fn delete_database(&self, db_id: u64) -> RpcResult<bool> {
|
||||
|
Reference in New Issue
Block a user