sled backend
This commit is contained in:
		@@ -1,5 +1,4 @@
 | 
				
			|||||||
use crate::{error::DBError, protocol::Protocol, server::Server};
 | 
					use crate::{error::DBError, protocol::Protocol, server::Server};
 | 
				
			||||||
use serde::Serialize;
 | 
					 | 
				
			||||||
use tokio::time::{timeout, Duration};
 | 
					use tokio::time::{timeout, Duration};
 | 
				
			||||||
use futures::future::select_all;
 | 
					use futures::future::select_all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1093,26 +1092,23 @@ async fn dbsize_cmd(server: &Server) -> Result<Protocol, DBError> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize)]
 | 
					 | 
				
			||||||
struct ServerInfo {
 | 
					 | 
				
			||||||
    redis_version: String,
 | 
					 | 
				
			||||||
    encrypted: bool,
 | 
					 | 
				
			||||||
    selected_db: u64,
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
async fn info_cmd(server: &Server, section: &Option<String>) -> Result<Protocol, DBError> {
 | 
					async fn info_cmd(server: &Server, section: &Option<String>) -> Result<Protocol, DBError> {
 | 
				
			||||||
    let info = ServerInfo {
 | 
					    let storage_info = server.current_storage()?.info()?;
 | 
				
			||||||
        redis_version: "7.0.0".to_string(),
 | 
					    let mut info_map: std::collections::HashMap<String, String> = storage_info.into_iter().collect();
 | 
				
			||||||
        encrypted: server.current_storage()?.is_encrypted(),
 | 
					
 | 
				
			||||||
        selected_db: server.selected_db,
 | 
					    info_map.insert("redis_version".to_string(), "7.0.0".to_string());
 | 
				
			||||||
    };
 | 
					    info_map.insert("selected_db".to_string(), server.selected_db.to_string());
 | 
				
			||||||
 | 
					    info_map.insert("backend".to_string(), format!("{:?}", server.option.backend));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut info_string = String::new();
 | 
					    let mut info_string = String::new();
 | 
				
			||||||
    info_string.push_str(&format!("# Server\n"));
 | 
					    info_string.push_str("# Server\n");
 | 
				
			||||||
    info_string.push_str(&format!("redis_version:{}\n", info.redis_version));
 | 
					    info_string.push_str(&format!("redis_version:{}\n", info_map.get("redis_version").unwrap()));
 | 
				
			||||||
    info_string.push_str(&format!("encrypted:{}\n", if info.encrypted { 1 } else { 0 }));
 | 
					    info_string.push_str(&format!("backend:{}\n", info_map.get("backend").unwrap()));
 | 
				
			||||||
    info_string.push_str(&format!("# Keyspace\n"));
 | 
					    info_string.push_str(&format!("encrypted:{}\n", info_map.get("is_encrypted").unwrap()));
 | 
				
			||||||
    info_string.push_str(&format!("db{}:keys=0,expires=0,avg_ttl=0\n", info.selected_db));
 | 
					    
 | 
				
			||||||
 | 
					    info_string.push_str("# Keyspace\n");
 | 
				
			||||||
 | 
					    info_string.push_str(&format!("db{}:keys={},expires=0,avg_ttl=0\n", info_map.get("selected_db").unwrap(), info_map.get("db_size").unwrap()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match section {
 | 
					    match section {
 | 
				
			||||||
        Some(s) => {
 | 
					        Some(s) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,10 +12,12 @@ use crate::error::DBError;
 | 
				
			|||||||
use crate::options;
 | 
					use crate::options;
 | 
				
			||||||
use crate::protocol::Protocol;
 | 
					use crate::protocol::Protocol;
 | 
				
			||||||
use crate::storage::Storage;
 | 
					use crate::storage::Storage;
 | 
				
			||||||
 | 
					use crate::storage_sled::SledStorage;
 | 
				
			||||||
 | 
					use crate::storage_trait::StorageBackend;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone)]
 | 
					#[derive(Clone)]
 | 
				
			||||||
pub struct Server {
 | 
					pub struct Server {
 | 
				
			||||||
    pub db_cache: std::sync::Arc<std::sync::RwLock<HashMap<u64, Arc<Storage>>>>,
 | 
					    pub db_cache: std::sync::Arc<std::sync::RwLock<HashMap<u64, Arc<dyn StorageBackend>>>>,
 | 
				
			||||||
    pub option: options::DBOption,
 | 
					    pub option: options::DBOption,
 | 
				
			||||||
    pub client_name: Option<String>,
 | 
					    pub client_name: Option<String>,
 | 
				
			||||||
    pub selected_db: u64, // Changed from usize to u64
 | 
					    pub selected_db: u64, // Changed from usize to u64
 | 
				
			||||||
@@ -52,7 +54,7 @@ impl Server {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pub fn current_storage(&self) -> Result<Arc<Storage>, DBError> {
 | 
					    pub fn current_storage(&self) -> Result<Arc<dyn StorageBackend>, DBError> {
 | 
				
			||||||
        let mut cache = self.db_cache.write().unwrap();
 | 
					        let mut cache = self.db_cache.write().unwrap();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if let Some(storage) = cache.get(&self.selected_db) {
 | 
					        if let Some(storage) = cache.get(&self.selected_db) {
 | 
				
			||||||
@@ -73,11 +75,22 @@ impl Server {
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        println!("Creating new db file: {}", db_file_path.display());
 | 
					        println!("Creating new db file: {}", db_file_path.display());
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        let storage = Arc::new(Storage::new(
 | 
					        let storage: Arc<dyn StorageBackend> = match self.option.backend {
 | 
				
			||||||
            db_file_path,
 | 
					            options::BackendType::Redb => {
 | 
				
			||||||
            self.should_encrypt_db(self.selected_db),
 | 
					                Arc::new(Storage::new(
 | 
				
			||||||
            self.option.encryption_key.as_deref()
 | 
					                    db_file_path,
 | 
				
			||||||
        )?);
 | 
					                    self.should_encrypt_db(self.selected_db),
 | 
				
			||||||
 | 
					                    self.option.encryption_key.as_deref()
 | 
				
			||||||
 | 
					                )?)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            options::BackendType::Sled => {
 | 
				
			||||||
 | 
					                Arc::new(SledStorage::new(
 | 
				
			||||||
 | 
					                    db_file_path,
 | 
				
			||||||
 | 
					                    self.should_encrypt_db(self.selected_db),
 | 
				
			||||||
 | 
					                    self.option.encryption_key.as_deref()
 | 
				
			||||||
 | 
					                )?)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        cache.insert(self.selected_db, storage.clone());
 | 
					        cache.insert(self.selected_db, storage.clone());
 | 
				
			||||||
        Ok(storage)
 | 
					        Ok(storage)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -277,6 +277,10 @@ impl StorageBackend for Storage {
 | 
				
			|||||||
        self.is_encrypted()
 | 
					        self.is_encrypted()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    fn info(&self) -> Result<Vec<(String, String)>, DBError> {
 | 
				
			||||||
 | 
					        self.info()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn clone_arc(&self) -> Arc<dyn StorageBackend> {
 | 
					    fn clone_arc(&self) -> Arc<dyn StorageBackend> {
 | 
				
			||||||
        unimplemented!("Storage cloning not yet implemented for redb backend")
 | 
					        unimplemented!("Storage cloning not yet implemented for redb backend")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -208,6 +208,14 @@ impl Storage {
 | 
				
			|||||||
        write_txn.commit()?;
 | 
					        write_txn.commit()?;
 | 
				
			||||||
        Ok(applied)
 | 
					        Ok(applied)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn info(&self) -> Result<Vec<(String, String)>, DBError> {
 | 
				
			||||||
 | 
					        let dbsize = self.dbsize()?;
 | 
				
			||||||
 | 
					        Ok(vec![
 | 
				
			||||||
 | 
					            ("db_size".to_string(), dbsize.to_string()),
 | 
				
			||||||
 | 
					            ("is_encrypted".to_string(), self.is_encrypted().to_string()),
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Utility function for glob pattern matching
 | 
					// Utility function for glob pattern matching
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -825,6 +825,14 @@ impl StorageBackend for SledStorage {
 | 
				
			|||||||
        self.crypto.is_some()
 | 
					        self.crypto.is_some()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    fn info(&self) -> Result<Vec<(String, String)>, DBError> {
 | 
				
			||||||
 | 
					        let dbsize = self.dbsize()?;
 | 
				
			||||||
 | 
					        Ok(vec![
 | 
				
			||||||
 | 
					            ("db_size".to_string(), dbsize.to_string()),
 | 
				
			||||||
 | 
					            ("is_encrypted".to_string(), self.is_encrypted().to_string()),
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn clone_arc(&self) -> Arc<dyn StorageBackend> {
 | 
					    fn clone_arc(&self) -> Arc<dyn StorageBackend> {
 | 
				
			||||||
        // Note: This is a simplified clone - in production you might want to
 | 
					        // Note: This is a simplified clone - in production you might want to
 | 
				
			||||||
        // handle this differently as sled::Db is already Arc internally
 | 
					        // handle this differently as sled::Db is already Arc internally
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,6 +51,7 @@ pub trait StorageBackend: Send + Sync {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    // Metadata
 | 
					    // Metadata
 | 
				
			||||||
    fn is_encrypted(&self) -> bool;
 | 
					    fn is_encrypted(&self) -> bool;
 | 
				
			||||||
 | 
					    fn info(&self) -> Result<Vec<(String, String)>, DBError>;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // Clone to Arc for sharing
 | 
					    // Clone to Arc for sharing
 | 
				
			||||||
    fn clone_arc(&self) -> Arc<dyn StorageBackend>;
 | 
					    fn clone_arc(&self) -> Arc<dyn StorageBackend>;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user