From d1b81f689b1c43a86137df65a2270b3b4ebdd70f Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Mon, 11 Sep 2023 11:52:45 +0300 Subject: [PATCH] Add exists command --- src/connection_manager/command_handler.rs | 20 +++++++++++++++++++- src/connection_manager/commands.rs | 8 ++++++++ src/store/db.rs | 5 +++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/connection_manager/command_handler.rs b/src/connection_manager/command_handler.rs index 26b02bf..cff4132 100644 --- a/src/connection_manager/command_handler.rs +++ b/src/connection_manager/command_handler.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use super::{ - commands::{handle_echo, handle_get, handle_ping, handle_set, ignore_command}, + commands::{handle_echo, handle_exists, handle_get, handle_ping, handle_set, ignore_command}, utils::serialize_error, }; use crate::{deserialize, resp::deserialize::RespResponse, store::db::Cache}; @@ -21,6 +21,7 @@ pub fn handle_command(human_readable: Cow<'_, str>, cache: &Cache) -> String { "echo" => handle_echo(args), "set" => handle_set(args, cache), "get" => handle_get(args, cache), + "exists" => handle_exists(args, cache), unknown_command => { let message = "-unknown command '".to_owned() + unknown_command + "'"; serialize_error(message.as_str()) @@ -152,4 +153,21 @@ mod tests { handle_command(set_input, &cache) ); } + + #[test] + fn should_return_existing_values() { + let cache = Cache::new(); + cache.set("name".to_string(), "name_val".to_string()); + cache.set("name1".to_string(), "name_val_1".to_string()); + cache.set("name2".to_string(), "name_val_2".to_string()); + let input = Cow::Borrowed("*4\r\n$6\r\nexists\r\n$4\r\nname\r\n$5\r\nname1\r\n$5\r\nname2\r\n"); + assert_eq!(serialize(InputVariants::NumberVariant(3)), handle_command(input, &cache)) + } + + #[test] + fn should_return_zero_if_not_exists() { + let cache = Cache::new(); + let input = Cow::Borrowed("*2\r\n$6\r\nexists\r\n$4\r\nname\r\n"); + assert_eq!(serialize(InputVariants::NumberVariant(0)), handle_command(input, &cache)) + } } diff --git a/src/connection_manager/commands.rs b/src/connection_manager/commands.rs index 3822c5a..568d41b 100644 --- a/src/connection_manager/commands.rs +++ b/src/connection_manager/commands.rs @@ -88,3 +88,11 @@ fn handle_set_with_expiration(args: &[String], cache: &Cache, time: Duration) -> serialize_error("-invalid SET arguments") } } + +pub fn handle_exists(args: &[String], cache: &Cache) -> String { + let count = args.iter().filter(|key| cache.exists(key)).count(); + match i32::try_from(count) { + Ok(count_i32) => serialize(InputVariants::NumberVariant(count_i32)), + Err(_) => serialize_error("-something went wrong during exists"), + } +} diff --git a/src/store/db.rs b/src/store/db.rs index 49cbf00..260cd93 100644 --- a/src/store/db.rs +++ b/src/store/db.rs @@ -48,6 +48,11 @@ impl Cache { let data = self.data.read().unwrap(); data.get(key).cloned() } + + pub fn exists(&self, key: &str) -> bool { + let data = self.data.read().unwrap(); + data.contains_key(key) + } } #[cfg(test)]