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