use redb::{ReadableTable}; use crate::error::DBError; use super::*; impl Storage { // ✅ ENCRYPTION APPLIED: Elements are encrypted before storage pub fn lpush(&self, key: &str, elements: Vec) -> Result { let write_txn = self.db.begin_write()?; let mut _length = 0i64; { let mut types_table = write_txn.open_table(TYPES_TABLE)?; let mut lists_table = write_txn.open_table(LISTS_TABLE)?; // Set the type to list types_table.insert(key, "list")?; // Get current list or create empty one let mut list: Vec = match lists_table.get(key)? { Some(data) => { let decrypted = self.decrypt_if_needed(data.value())?; serde_json::from_slice(&decrypted)? } None => Vec::new(), }; // Add elements to the front (left) for element in elements.into_iter() { list.insert(0, element); } _length = list.len() as i64; // Encrypt and store the updated list let serialized = serde_json::to_vec(&list)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } write_txn.commit()?; Ok(_length) } // ✅ ENCRYPTION APPLIED: Elements are encrypted before storage pub fn rpush(&self, key: &str, elements: Vec) -> Result { let write_txn = self.db.begin_write()?; let mut _length = 0i64; { let mut types_table = write_txn.open_table(TYPES_TABLE)?; let mut lists_table = write_txn.open_table(LISTS_TABLE)?; // Set the type to list types_table.insert(key, "list")?; // Get current list or create empty one let mut list: Vec = match lists_table.get(key)? { Some(data) => { let decrypted = self.decrypt_if_needed(data.value())?; serde_json::from_slice(&decrypted)? } None => Vec::new(), }; // Add elements to the end (right) list.extend(elements); _length = list.len() as i64; // Encrypt and store the updated list let serialized = serde_json::to_vec(&list)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } write_txn.commit()?; Ok(_length) } // ✅ ENCRYPTION APPLIED: Elements are decrypted after retrieval and encrypted before storage pub fn lpop(&self, key: &str, count: u64) -> Result, DBError> { let write_txn = self.db.begin_write()?; let mut result = Vec::new(); // First check if key exists and is a list, and get the data let list_data = { let types_table = write_txn.open_table(TYPES_TABLE)?; let lists_table = write_txn.open_table(LISTS_TABLE)?; let result = match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { if let Some(data) = lists_table.get(key)? { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; Some(list) } else { None } } _ => None, }; result }; if let Some(mut list) = list_data { let pop_count = std::cmp::min(count as usize, list.len()); for _ in 0..pop_count { if !list.is_empty() { result.push(list.remove(0)); } } let mut lists_table = write_txn.open_table(LISTS_TABLE)?; if list.is_empty() { // Remove the key if list is empty lists_table.remove(key)?; let mut types_table = write_txn.open_table(TYPES_TABLE)?; types_table.remove(key)?; } else { // Encrypt and store the updated list let serialized = serde_json::to_vec(&list)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } } write_txn.commit()?; Ok(result) } // ✅ ENCRYPTION APPLIED: Elements are decrypted after retrieval and encrypted before storage pub fn rpop(&self, key: &str, count: u64) -> Result, DBError> { let write_txn = self.db.begin_write()?; let mut result = Vec::new(); // First check if key exists and is a list, and get the data let list_data = { let types_table = write_txn.open_table(TYPES_TABLE)?; let lists_table = write_txn.open_table(LISTS_TABLE)?; let result = match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { if let Some(data) = lists_table.get(key)? { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; Some(list) } else { None } } _ => None, }; result }; if let Some(mut list) = list_data { let pop_count = std::cmp::min(count as usize, list.len()); for _ in 0..pop_count { if !list.is_empty() { result.push(list.pop().unwrap()); } } let mut lists_table = write_txn.open_table(LISTS_TABLE)?; if list.is_empty() { // Remove the key if list is empty lists_table.remove(key)?; let mut types_table = write_txn.open_table(TYPES_TABLE)?; types_table.remove(key)?; } else { // Encrypt and store the updated list let serialized = serde_json::to_vec(&list)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } } write_txn.commit()?; Ok(result) } pub fn llen(&self, key: &str) -> Result { let read_txn = self.db.begin_read()?; let types_table = read_txn.open_table(TYPES_TABLE)?; match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { let lists_table = read_txn.open_table(LISTS_TABLE)?; match lists_table.get(key)? { Some(data) => { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; Ok(list.len() as i64) } None => Ok(0), } } _ => Ok(0), } } // ✅ ENCRYPTION APPLIED: Element is decrypted after retrieval pub fn lindex(&self, key: &str, index: i64) -> Result, DBError> { let read_txn = self.db.begin_read()?; let types_table = read_txn.open_table(TYPES_TABLE)?; match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { let lists_table = read_txn.open_table(LISTS_TABLE)?; match lists_table.get(key)? { Some(data) => { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; let actual_index = if index < 0 { list.len() as i64 + index } else { index }; if actual_index >= 0 && (actual_index as usize) < list.len() { Ok(Some(list[actual_index as usize].clone())) } else { Ok(None) } } None => Ok(None), } } _ => Ok(None), } } // ✅ ENCRYPTION APPLIED: Elements are decrypted after retrieval pub fn lrange(&self, key: &str, start: i64, stop: i64) -> Result, DBError> { let read_txn = self.db.begin_read()?; let types_table = read_txn.open_table(TYPES_TABLE)?; match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { let lists_table = read_txn.open_table(LISTS_TABLE)?; match lists_table.get(key)? { Some(data) => { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; if list.is_empty() { return Ok(Vec::new()); } let len = list.len() as i64; let start_idx = if start < 0 { std::cmp::max(0, len + start) } else { std::cmp::min(start, len) }; let stop_idx = if stop < 0 { std::cmp::max(-1, len + stop) } else { std::cmp::min(stop, len - 1) }; if start_idx > stop_idx || start_idx >= len { return Ok(Vec::new()); } let start_usize = start_idx as usize; let stop_usize = (stop_idx + 1) as usize; Ok(list[start_usize..std::cmp::min(stop_usize, list.len())].to_vec()) } None => Ok(Vec::new()), } } _ => Ok(Vec::new()), } } // ✅ ENCRYPTION APPLIED: Elements are decrypted after retrieval and encrypted before storage pub fn ltrim(&self, key: &str, start: i64, stop: i64) -> Result<(), DBError> { let write_txn = self.db.begin_write()?; // First check if key exists and is a list, and get the data let list_data = { let types_table = write_txn.open_table(TYPES_TABLE)?; let lists_table = write_txn.open_table(LISTS_TABLE)?; let result = match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { if let Some(data) = lists_table.get(key)? { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; Some(list) } else { None } } _ => None, }; result }; if let Some(list) = list_data { if list.is_empty() { write_txn.commit()?; return Ok(()); } let len = list.len() as i64; let start_idx = if start < 0 { std::cmp::max(0, len + start) } else { std::cmp::min(start, len) }; let stop_idx = if stop < 0 { std::cmp::max(-1, len + stop) } else { std::cmp::min(stop, len - 1) }; let mut lists_table = write_txn.open_table(LISTS_TABLE)?; if start_idx > stop_idx || start_idx >= len { // Remove the entire list lists_table.remove(key)?; let mut types_table = write_txn.open_table(TYPES_TABLE)?; types_table.remove(key)?; } else { let start_usize = start_idx as usize; let stop_usize = (stop_idx + 1) as usize; let trimmed = list[start_usize..std::cmp::min(stop_usize, list.len())].to_vec(); if trimmed.is_empty() { lists_table.remove(key)?; let mut types_table = write_txn.open_table(TYPES_TABLE)?; types_table.remove(key)?; } else { // Encrypt and store the trimmed list let serialized = serde_json::to_vec(&trimmed)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } } } write_txn.commit()?; Ok(()) } // ✅ ENCRYPTION APPLIED: Elements are decrypted after retrieval and encrypted before storage pub fn lrem(&self, key: &str, count: i64, element: &str) -> Result { let write_txn = self.db.begin_write()?; let mut removed = 0i64; // First check if key exists and is a list, and get the data let list_data = { let types_table = write_txn.open_table(TYPES_TABLE)?; let lists_table = write_txn.open_table(LISTS_TABLE)?; let result = match types_table.get(key)? { Some(type_val) if type_val.value() == "list" => { if let Some(data) = lists_table.get(key)? { let decrypted = self.decrypt_if_needed(data.value())?; let list: Vec = serde_json::from_slice(&decrypted)?; Some(list) } else { None } } _ => None, }; result }; if let Some(mut list) = list_data { if count == 0 { // Remove all occurrences let original_len = list.len(); list.retain(|x| x != element); removed = (original_len - list.len()) as i64; } else if count > 0 { // Remove first count occurrences let mut to_remove = count as usize; list.retain(|x| { if x == element && to_remove > 0 { to_remove -= 1; removed += 1; false } else { true } }); } else { // Remove last |count| occurrences let mut to_remove = (-count) as usize; for i in (0..list.len()).rev() { if list[i] == element && to_remove > 0 { list.remove(i); to_remove -= 1; removed += 1; } } } let mut lists_table = write_txn.open_table(LISTS_TABLE)?; if list.is_empty() { lists_table.remove(key)?; let mut types_table = write_txn.open_table(TYPES_TABLE)?; types_table.remove(key)?; } else { // Encrypt and store the updated list let serialized = serde_json::to_vec(&list)?; let encrypted = self.encrypt_if_needed(&serialized)?; lists_table.insert(key, encrypted.as_slice())?; } } write_txn.commit()?; Ok(removed) } }