diff --git a/src/key.rs b/src/key.rs index b2aaa938..e2d2e77c 100644 --- a/src/key.rs +++ b/src/key.rs @@ -14,6 +14,7 @@ use crate::redismodule::REDIS_OK; use crate::RedisError; use crate::RedisResult; use crate::RedisString; +use std::collections::HashMap; /// `RedisKey` is an abstraction over a Redis key that allows readonly /// operations. @@ -81,13 +82,12 @@ impl RedisKey { Ok(val) } - pub fn hash_get(&self, field: &str) -> Result, RedisError> { - let val = if self.is_null() { - None - } else { - hash_get_key(self.ctx, self.key_inner, field) - }; - Ok(val) + pub fn hash_get(&self, fields: &[&str]) -> Result, RedisError> { + if self.is_null() { + return Ok(HashMap::new()); + } + let res = raw::hash_get_multi(self.ctx, self.key_inner, fields); + Ok(res) } } diff --git a/src/raw.rs b/src/raw.rs index 67a58547..bbfeac71 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -17,6 +17,7 @@ use std::slice; pub use crate::redisraw::bindings::*; use crate::RedisBuffer; use crate::RedisString; +use std::collections::HashMap; bitflags! { pub struct KeyMode: c_int { @@ -246,6 +247,47 @@ pub fn hash_get(key: *mut RedisModuleKey, field: &str) -> *mut RedisModuleString res } +pub fn hash_get_multi( + ctx: *mut RedisModuleCtx, + key: *mut RedisModuleKey, + fields: &[&str], +) -> HashMap { + // let res: *mut RedisModuleString = ptr::null_mut(); + let values = vec![ptr::null_mut::(); fields.len()]; + + match fields { + &[f0] => unsafe { + RedisModule_HashGet.unwrap()( + key, + REDISMODULE_HASH_CFIELDS as i32, + CString::new(f0).unwrap().as_ptr(), + &values[0], + ptr::null::(), + ); + }, + &[f0, f1] => unsafe { + RedisModule_HashGet.unwrap()( + key, + REDISMODULE_HASH_CFIELDS as i32, + CString::new(f0).unwrap().as_ptr(), + &values[0], + CString::new(f1).unwrap().as_ptr(), + &values[1], + ptr::null::(), + ); + }, + // Repeat for more fields using a macro + &[] => { /* TODO: Return empty result? */ } + &[_, ..] => { /* TODO: Panic? */ } + } + + fields + .iter() + .zip(values.iter()) + .map(|(&k, &v)| (k.to_string(), RedisString::new(ctx, v))) + .collect() +} + pub fn hash_set(key: *mut RedisModuleKey, field: &str, value: *mut RedisModuleString) -> Status { unsafe { RedisModule_HashSet.unwrap()(