Restore working code
This commit is contained in:
		| @@ -71,8 +71,13 @@ async fn main() { | ||||
|         }, | ||||
|     }; | ||||
|  | ||||
|     let backend = option.backend.clone(); | ||||
|  | ||||
|     // new server | ||||
|     let server = server::Server::new(option.clone()).await; | ||||
|     let mut server = server::Server::new(option).await; | ||||
|  | ||||
|     // Initialize the default database storage | ||||
|     let _ = server.current_storage(); | ||||
|  | ||||
|     // Add a small delay to ensure the port is ready | ||||
|     tokio::time::sleep(std::time::Duration::from_millis(100)).await; | ||||
| @@ -82,7 +87,7 @@ async fn main() { | ||||
|         let rpc_addr = format!("127.0.0.1:{}", args.rpc_port).parse().unwrap(); | ||||
|         let base_dir = args.dir.clone(); | ||||
|  | ||||
|         match rpc_server::start_rpc_server(rpc_addr, base_dir, option).await { | ||||
|         match rpc_server::start_rpc_server(rpc_addr, base_dir, backend).await { | ||||
|             Ok(handle) => { | ||||
|                 println!("RPC management server started on port {}", args.rpc_port); | ||||
|                 Some(handle) | ||||
|   | ||||
							
								
								
									
										115
									
								
								src/rpc.rs
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								src/rpc.rs
									
									
									
									
									
								
							| @@ -78,20 +78,23 @@ pub struct RpcServerImpl { | ||||
|     base_dir: String, | ||||
|     /// Managed database servers | ||||
|     servers: Arc<RwLock<HashMap<u64, Arc<Server>>>>, | ||||
|     /// Next database ID to assign | ||||
|     next_db_id: Arc<RwLock<u64>>, | ||||
|     /// Database options (backend, encryption, etc.) | ||||
|     db_option: DBOption, | ||||
|     /// Next unencrypted database ID to assign | ||||
|     next_unencrypted_id: Arc<RwLock<u64>>, | ||||
|     /// Next encrypted database ID to assign | ||||
|     next_encrypted_id: Arc<RwLock<u64>>, | ||||
|     /// Default backend type | ||||
|     backend: crate::options::BackendType, | ||||
| } | ||||
|  | ||||
| impl RpcServerImpl { | ||||
|     /// Create a new RPC server instance | ||||
|     pub fn new(base_dir: String, db_option: DBOption) -> Self { | ||||
|     pub fn new(base_dir: String, backend: crate::options::BackendType) -> Self { | ||||
|         Self { | ||||
|             base_dir, | ||||
|             servers: Arc::new(RwLock::new(HashMap::new())), | ||||
|             next_db_id: Arc::new(RwLock::new(0)), | ||||
|             db_option, | ||||
|             next_unencrypted_id: Arc::new(RwLock::new(0)), | ||||
|             next_encrypted_id: Arc::new(RwLock::new(10)), | ||||
|             backend, | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -105,31 +108,30 @@ impl RpcServerImpl { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Check if database file exists (either direct or in RPC subdirectory) | ||||
|         let direct_db_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}.db", db_id)); | ||||
|         let rpc_db_path = std::path::PathBuf::from(&self.base_dir) | ||||
|             .join(format!("rpc_db_{}", db_id)) | ||||
|             .join("0.db"); | ||||
|  | ||||
|         let (db_path, db_dir) = if direct_db_path.exists() { | ||||
|             // Main server database | ||||
|             (direct_db_path, self.base_dir.clone()) | ||||
|         } else if rpc_db_path.exists() { | ||||
|             // RPC database | ||||
|             (rpc_db_path, std::path::PathBuf::from(&self.base_dir).join(format!("rpc_db_{}", db_id)).to_string_lossy().to_string()) | ||||
|         } else { | ||||
|         // Check if database file exists | ||||
|         let db_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}.db", db_id)); | ||||
|         if !db_path.exists() { | ||||
|             return Err(jsonrpsee::types::ErrorObjectOwned::owned( | ||||
|                 -32000, | ||||
|                 format!("Database {} not found", db_id), | ||||
|                 None::<()> | ||||
|             )); | ||||
|         } | ||||
|  | ||||
|         // Create server instance with default options | ||||
|         let db_option = DBOption { | ||||
|             dir: self.base_dir.clone(), | ||||
|             port: 0, // Not used for RPC-managed databases | ||||
|             debug: false, | ||||
|             encryption_key: None, | ||||
|             encrypt: false, | ||||
|             backend: self.backend.clone(), | ||||
|         }; | ||||
|  | ||||
|         // Create server instance | ||||
|         let mut db_option = self.db_option.clone(); | ||||
|         db_option.dir = db_dir; | ||||
|         let mut server = Server::new(db_option).await; | ||||
|  | ||||
|         let server = Server::new(db_option).await; | ||||
|         // Set the selected database to the db_id for proper file naming | ||||
|         server.selected_db = db_id; | ||||
|  | ||||
|         // Store the server | ||||
|         let mut servers = self.servers.write().await; | ||||
| @@ -138,29 +140,14 @@ impl RpcServerImpl { | ||||
|         Ok(Arc::new(server)) | ||||
|     } | ||||
|  | ||||
|     /// Discover existing database files in the base directory and RPC subdirectories | ||||
|     /// Discover existing database files in the base directory | ||||
|     async fn discover_databases(&self) -> Vec<u64> { | ||||
|         let mut db_ids = Vec::new(); | ||||
|  | ||||
|         if let Ok(entries) = std::fs::read_dir(&self.base_dir) { | ||||
|             for entry in entries.flatten() { | ||||
|                 let path = entry.path(); | ||||
|  | ||||
|                 // Check if it's a directory starting with "rpc_db_" | ||||
|                 if path.is_dir() { | ||||
|                     if let Some(dir_name) = path.file_name().and_then(|n| n.to_str()) { | ||||
|                         if dir_name.starts_with("rpc_db_") { | ||||
|                             // Extract database ID from directory name (e.g., "rpc_db_1" -> 1) | ||||
|                             if let Some(id_str) = dir_name.strip_prefix("rpc_db_") { | ||||
|                                 if let Ok(db_id) = id_str.parse::<u64>() { | ||||
|                                     db_ids.push(db_id); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 // Also check for direct .db files (for main server databases) | ||||
|                 else if let Some(file_name) = entry.file_name().to_str() { | ||||
|                 if let Ok(file_name) = entry.file_name().into_string() { | ||||
|                     // Check if it's a database file (ends with .db) | ||||
|                     if file_name.ends_with(".db") { | ||||
|                         // Extract database ID from filename (e.g., "11.db" -> 11) | ||||
|                         if let Some(id_str) = file_name.strip_suffix(".db") { | ||||
| @@ -177,11 +164,18 @@ impl RpcServerImpl { | ||||
|     } | ||||
|  | ||||
|     /// Get the next available database ID | ||||
|     async fn get_next_db_id(&self) -> u64 { | ||||
|         let mut id = self.next_db_id.write().await; | ||||
|         let current_id = *id; | ||||
|         *id += 1; | ||||
|         current_id | ||||
|     async fn get_next_db_id(&self, is_encrypted: bool) -> u64 { | ||||
|         if is_encrypted { | ||||
|             let mut id = self.next_encrypted_id.write().await; | ||||
|             let current_id = *id; | ||||
|             *id += 1; | ||||
|             current_id | ||||
|         } else { | ||||
|             let mut id = self.next_unencrypted_id.write().await; | ||||
|             let current_id = *id; | ||||
|             *id += 1; | ||||
|             current_id | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -193,14 +187,14 @@ impl RpcServer for RpcServerImpl { | ||||
|         config: DatabaseConfig, | ||||
|         encryption_key: Option<String>, | ||||
|     ) -> RpcResult<u64> { | ||||
|         let db_id = self.get_next_db_id().await; | ||||
|         let db_id = self.get_next_db_id(encryption_key.is_some()).await; | ||||
|  | ||||
|         // Handle both Redb and Sled backends | ||||
|         match backend { | ||||
|             BackendType::Redb | BackendType::Sled => { | ||||
|                 // Always create RPC databases in subdirectories to avoid conflicts with main server | ||||
|                 // Create database directory | ||||
|                 let db_dir = if let Some(path) = &config.storage_path { | ||||
|                     std::path::PathBuf::from(path).join(format!("rpc_db_{}", db_id)) | ||||
|                     std::path::PathBuf::from(path) | ||||
|                 } else { | ||||
|                     std::path::PathBuf::from(&self.base_dir).join(format!("rpc_db_{}", db_id)) | ||||
|                 }; | ||||
| @@ -228,7 +222,13 @@ impl RpcServer for RpcServerImpl { | ||||
|                 }; | ||||
|  | ||||
|                 // Create server instance | ||||
|                 let server = Server::new(option).await; | ||||
|                 let mut server = Server::new(option).await; | ||||
|  | ||||
|                 // Set the selected database to the db_id for proper file naming | ||||
|                 server.selected_db = db_id; | ||||
|  | ||||
|                 // Initialize the storage to create the database file | ||||
|                 let _ = server.current_storage(); | ||||
|  | ||||
|                 // Store the server | ||||
|                 let mut servers = self.servers.write().await; | ||||
| @@ -309,9 +309,16 @@ impl RpcServer for RpcServerImpl { | ||||
|     async fn delete_database(&self, db_id: u64) -> RpcResult<bool> { | ||||
|         let mut servers = self.servers.write().await; | ||||
|  | ||||
|         if let Some(server) = servers.remove(&db_id) { | ||||
|             // TODO: Clean up database files | ||||
|             let _ = server; | ||||
|         if let Some(_server) = servers.remove(&db_id) { | ||||
|             // Clean up database files | ||||
|             let db_path = std::path::PathBuf::from(&self.base_dir).join(format!("{}.db", db_id)); | ||||
|             if db_path.exists() { | ||||
|                 if db_path.is_dir() { | ||||
|                     std::fs::remove_dir_all(&db_path).ok(); | ||||
|                 } else { | ||||
|                     std::fs::remove_file(&db_path).ok(); | ||||
|                 } | ||||
|             } | ||||
|             Ok(true) | ||||
|         } else { | ||||
|             Ok(false) | ||||
|   | ||||
| @@ -3,12 +3,11 @@ use jsonrpsee::server::{ServerBuilder, ServerHandle}; | ||||
| use jsonrpsee::RpcModule; | ||||
|  | ||||
| use crate::rpc::{RpcServer, RpcServerImpl}; | ||||
| use crate::options::DBOption; | ||||
|  | ||||
| /// Start the RPC server on the specified address | ||||
| pub async fn start_rpc_server(addr: SocketAddr, base_dir: String, db_option: DBOption) -> Result<ServerHandle, Box<dyn std::error::Error + Send + Sync>> { | ||||
| pub async fn start_rpc_server(addr: SocketAddr, base_dir: String, backend: crate::options::BackendType) -> Result<ServerHandle, Box<dyn std::error::Error + Send + Sync>> { | ||||
|     // Create the RPC server implementation | ||||
|     let rpc_impl = RpcServerImpl::new(base_dir, db_option); | ||||
|     let rpc_impl = RpcServerImpl::new(base_dir, backend); | ||||
|  | ||||
|     // Create the RPC module | ||||
|     let mut module = RpcModule::new(()); | ||||
| @@ -36,18 +35,9 @@ mod tests { | ||||
|     async fn test_rpc_server_startup() { | ||||
|         let addr = "127.0.0.1:0".parse().unwrap(); // Use port 0 for auto-assignment | ||||
|         let base_dir = "/tmp/test_rpc".to_string(); | ||||
|         let backend = crate::options::BackendType::Redb; // Default for test | ||||
|  | ||||
|         // Create a dummy DBOption for testing | ||||
|         let db_option = crate::options::DBOption { | ||||
|             dir: base_dir.clone(), | ||||
|             port: 0, | ||||
|             debug: false, | ||||
|             encryption_key: None, | ||||
|             encrypt: false, | ||||
|             backend: crate::options::BackendType::Redb, | ||||
|         }; | ||||
|  | ||||
|         let handle = start_rpc_server(addr, base_dir, db_option).await.unwrap(); | ||||
|         let handle = start_rpc_server(addr, base_dir, backend).await.unwrap(); | ||||
|  | ||||
|         // Give the server a moment to start | ||||
|         tokio::time::sleep(Duration::from_millis(100)).await; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user