hash.rs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. use crate::{
  2. check_arg, connection::Connection, error::Error, value::bytes_to_number, value::Value,
  3. };
  4. use bytes::Bytes;
  5. use rand::Rng;
  6. use std::{
  7. collections::{BTreeMap, HashMap},
  8. convert::TryFrom,
  9. ops::AddAssign,
  10. str::FromStr,
  11. };
  12. pub fn hdel(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  13. conn.db().get_map(
  14. &args[1],
  15. |v| match v {
  16. Value::Hash(h) => {
  17. let mut h = h.write();
  18. let mut total: i64 = 0;
  19. for key in (&args[2..]).iter() {
  20. if h.remove(key).is_some() {
  21. total += 1;
  22. }
  23. }
  24. Ok(total.into())
  25. }
  26. _ => Err(Error::WrongType),
  27. },
  28. || Ok(0_i64.into()),
  29. )
  30. }
  31. pub fn hexists(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  32. match conn.db().get(&args[1]) {
  33. Value::Hash(h) => Ok(if h.read().get(&args[2]).is_some() {
  34. 1_i64.into()
  35. } else {
  36. 0_i64.into()
  37. }),
  38. Value::Null => Ok(0_i64.into()),
  39. _ => Err(Error::WrongType),
  40. }
  41. }
  42. pub fn hget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  43. match conn.db().get(&args[1]) {
  44. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  45. Value::Blob(v.clone())
  46. } else {
  47. Value::Null
  48. }),
  49. Value::Null => Ok(Value::Null),
  50. _ => Err(Error::WrongType),
  51. }
  52. }
  53. pub fn hgetall(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  54. match conn.db().get(&args[1]) {
  55. Value::Hash(h) => {
  56. let mut ret = vec![];
  57. for (key, value) in h.read().iter() {
  58. ret.push(Value::Blob(key.clone()));
  59. ret.push(Value::Blob(value.clone()));
  60. }
  61. Ok(ret.into())
  62. }
  63. Value::Null => Ok(Value::Array(vec![])),
  64. _ => Err(Error::WrongType),
  65. }
  66. }
  67. pub fn hincrby<
  68. T: ToString + FromStr + AddAssign + for<'a> TryFrom<&'a Value, Error = Error> + Into<Value> + Copy,
  69. >(
  70. conn: &Connection,
  71. args: &[Bytes],
  72. ) -> Result<Value, Error> {
  73. conn.db().get_map(
  74. &args[1],
  75. |v| match v {
  76. Value::Hash(h) => {
  77. let mut incr_by: T = bytes_to_number(&args[3])?;
  78. let mut h = h.write();
  79. if let Some(n) = h.get(&args[2]) {
  80. incr_by += bytes_to_number(n)?;
  81. }
  82. h.insert(args[2].clone(), incr_by.to_string().into());
  83. Ok(incr_by.into())
  84. }
  85. _ => Err(Error::WrongType),
  86. },
  87. || {
  88. let incr_by: T = bytes_to_number(&args[3])?;
  89. #[allow(clippy::mutable_key_type)]
  90. let mut h = HashMap::new();
  91. h.insert(args[2].clone(), incr_by.to_string().into());
  92. conn.db().set(&args[1], h.into(), None);
  93. Ok(incr_by.into())
  94. },
  95. )
  96. }
  97. pub fn hkeys(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  98. match conn.db().get(&args[1]) {
  99. Value::Hash(h) => {
  100. let mut ret = vec![];
  101. for key in h.read().keys() {
  102. ret.push(Value::Blob(key.clone()));
  103. }
  104. Ok(ret.into())
  105. }
  106. Value::Null => Ok(Value::Array(vec![])),
  107. _ => Err(Error::WrongType),
  108. }
  109. }
  110. pub fn hlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  111. match conn.db().get(&args[1]) {
  112. Value::Hash(h) => Ok((h.read().len() as i64).into()),
  113. Value::Null => Ok(0_i64.into()),
  114. _ => Err(Error::WrongType),
  115. }
  116. }
  117. pub fn hmget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  118. match conn.db().get(&args[1]) {
  119. Value::Hash(h) => {
  120. let h = h.read();
  121. Ok((&args[2..])
  122. .iter()
  123. .map(|key| {
  124. if let Some(value) = h.get(key) {
  125. Value::Blob(value.clone())
  126. } else {
  127. Value::Null
  128. }
  129. })
  130. .collect::<Vec<Value>>()
  131. .into())
  132. }
  133. Value::Null => Ok(Value::Array(vec![])),
  134. _ => Err(Error::WrongType),
  135. }
  136. }
  137. pub fn hrandfield(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  138. let (count, with_values) = match args.len() {
  139. 2 => (None, false),
  140. 3 => (Some(bytes_to_number::<i64>(&args[2])?), false),
  141. 4 => {
  142. if !(check_arg!(args, 3, "WITHVALUES")) {
  143. return Err(Error::Syntax);
  144. }
  145. (Some(bytes_to_number::<i64>(&args[2])?), true)
  146. }
  147. _ => return Err(Error::InvalidArgsCount("hrandfield".to_owned())),
  148. };
  149. let (count, single, repeat) = if let Some(count) = count {
  150. if count > 0 {
  151. (count, false, 1)
  152. } else {
  153. (count.abs(), false, count.abs())
  154. }
  155. } else {
  156. (1, true, 1)
  157. };
  158. match conn.db().get(&args[1]) {
  159. Value::Hash(h) => {
  160. let mut ret = vec![];
  161. let mut i = 0;
  162. let mut rand_sorted = BTreeMap::new();
  163. let mut rng = rand::thread_rng();
  164. let h = h.read();
  165. for _ in 0..repeat {
  166. for (key, value) in h.iter() {
  167. let rand = rng.gen::<u64>();
  168. rand_sorted.insert((rand, i), (key, value));
  169. i += 1;
  170. }
  171. }
  172. i = 0;
  173. for val in rand_sorted.values() {
  174. if single {
  175. return Ok(Value::Blob(val.0.clone()));
  176. }
  177. if i == count {
  178. break;
  179. }
  180. ret.push(Value::Blob(val.0.clone()));
  181. if with_values {
  182. ret.push(Value::Blob(val.1.clone()));
  183. }
  184. i += 1;
  185. }
  186. Ok(ret.into())
  187. }
  188. Value::Null => Ok(Value::Array(vec![])),
  189. _ => Err(Error::WrongType),
  190. }
  191. }
  192. pub fn hset(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  193. if args.len() % 2 == 1 {
  194. return Err(Error::InvalidArgsCount("hset".to_owned()));
  195. }
  196. conn.db().get_map(
  197. &args[1],
  198. |v| match v {
  199. Value::Hash(h) => {
  200. let mut h = h.write();
  201. let mut e: i64 = 0;
  202. for i in (2..args.len()).step_by(2) {
  203. if h.insert(args[i].clone(), args[i + 1].clone()).is_none() {
  204. e += 1;
  205. }
  206. }
  207. Ok(e.into())
  208. }
  209. _ => Err(Error::WrongType),
  210. },
  211. || {
  212. #[allow(clippy::mutable_key_type)]
  213. let mut h = HashMap::new();
  214. for i in (2..args.len()).step_by(2) {
  215. h.insert(args[i].clone(), args[i + 1].clone());
  216. }
  217. let len = h.len() as i64;
  218. conn.db().set(&args[1], h.into(), None);
  219. Ok(len.into())
  220. },
  221. )
  222. }
  223. pub fn hsetnx(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  224. conn.db().get_map(
  225. &args[1],
  226. |v| match v {
  227. Value::Hash(h) => {
  228. let mut h = h.write();
  229. if h.get(&args[2]).is_some() {
  230. Ok(0_i64.into())
  231. } else {
  232. h.insert(args[2].clone(), args[3].clone());
  233. Ok(1_i64.into())
  234. }
  235. }
  236. _ => Err(Error::WrongType),
  237. },
  238. || {
  239. #[allow(clippy::mutable_key_type)]
  240. let mut h = HashMap::new();
  241. for i in (2..args.len()).step_by(2) {
  242. h.insert(args[i].clone(), args[i + 1].clone());
  243. }
  244. let len = h.len() as i64;
  245. conn.db().set(&args[1], h.into(), None);
  246. Ok(len.into())
  247. },
  248. )
  249. }
  250. pub fn hstrlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  251. match conn.db().get(&args[1]) {
  252. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  253. (v.len() as i64).into()
  254. } else {
  255. 0_i64.into()
  256. }),
  257. Value::Null => Ok(0_i64.into()),
  258. _ => Err(Error::WrongType),
  259. }
  260. }
  261. pub fn hvals(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  262. match conn.db().get(&args[1]) {
  263. Value::Hash(h) => {
  264. let mut ret = vec![];
  265. for value in h.read().values() {
  266. ret.push(Value::Blob(value.clone()));
  267. }
  268. Ok(ret.into())
  269. }
  270. Value::Null => Ok(Value::Array(vec![])),
  271. _ => Err(Error::WrongType),
  272. }
  273. }