hash.rs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  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_or(
  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.into()),
  29. )
  30. }
  31. pub fn hexists(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  32. conn.db().get_map_or(
  33. &args[1],
  34. |v| match v {
  35. Value::Hash(h) => Ok(if h.read().get(&args[2]).is_some() {
  36. 1.into()
  37. } else {
  38. 0.into()
  39. }),
  40. _ => Err(Error::WrongType),
  41. },
  42. || Ok(0.into()),
  43. )
  44. }
  45. pub fn hget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  46. conn.db().get_map_or(
  47. &args[1],
  48. |v| match v {
  49. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  50. Value::Blob(v.clone())
  51. } else {
  52. Value::Null
  53. }),
  54. _ => Err(Error::WrongType),
  55. },
  56. || Ok(Value::Null),
  57. )
  58. }
  59. pub fn hgetall(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  60. conn.db().get_map_or(
  61. &args[1],
  62. |v| match v {
  63. Value::Hash(h) => {
  64. let mut ret = vec![];
  65. for (key, value) in h.read().iter() {
  66. ret.push(Value::Blob(key.clone()));
  67. ret.push(Value::Blob(value.clone()));
  68. }
  69. Ok(ret.into())
  70. }
  71. _ => Err(Error::WrongType),
  72. },
  73. || Ok(Value::Array(vec![])),
  74. )
  75. }
  76. pub fn hincrby<
  77. T: ToString + FromStr + AddAssign + for<'a> TryFrom<&'a Value, Error = Error> + Into<Value> + Copy,
  78. >(
  79. conn: &Connection,
  80. args: &[Bytes],
  81. ) -> Result<Value, Error> {
  82. conn.db().get_map_or(
  83. &args[1],
  84. |v| match v {
  85. Value::Hash(h) => {
  86. let mut incr_by: T = bytes_to_number(&args[3])?;
  87. let mut h = h.write();
  88. if let Some(n) = h.get(&args[2]) {
  89. incr_by += bytes_to_number(n)?;
  90. }
  91. h.insert(args[2].clone(), incr_by.to_string().into());
  92. Ok(incr_by.into())
  93. }
  94. _ => Err(Error::WrongType),
  95. },
  96. || {
  97. let incr_by: T = bytes_to_number(&args[3])?;
  98. #[allow(clippy::mutable_key_type)]
  99. let mut h = HashMap::new();
  100. h.insert(args[2].clone(), incr_by.to_string().into());
  101. conn.db().set(&args[1], h.into(), None);
  102. Ok(incr_by.into())
  103. },
  104. )
  105. }
  106. pub fn hkeys(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  107. conn.db().get_map_or(
  108. &args[1],
  109. |v| match v {
  110. Value::Hash(h) => {
  111. let mut ret = vec![];
  112. for key in h.read().keys() {
  113. ret.push(Value::Blob(key.clone()));
  114. }
  115. Ok(ret.into())
  116. }
  117. _ => Err(Error::WrongType),
  118. },
  119. || Ok(Value::Array(vec![])),
  120. )
  121. }
  122. pub fn hlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  123. conn.db().get_map_or(
  124. &args[1],
  125. |v| match v {
  126. Value::Hash(h) => Ok((h.read().len() as i64).into()),
  127. _ => Err(Error::WrongType),
  128. },
  129. || Ok(0.into()),
  130. )
  131. }
  132. pub fn hmget(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  133. conn.db().get_map_or(
  134. &args[1],
  135. |v| match v {
  136. Value::Hash(h) => {
  137. let h = h.read();
  138. Ok((&args[2..])
  139. .iter()
  140. .map(|key| {
  141. if let Some(value) = h.get(key) {
  142. Value::Blob(value.clone())
  143. } else {
  144. Value::Null
  145. }
  146. })
  147. .collect::<Vec<Value>>()
  148. .into())
  149. }
  150. _ => Err(Error::WrongType),
  151. },
  152. || Ok(Value::Array(vec![])),
  153. )
  154. }
  155. pub fn hrandfield(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  156. let (count, with_values) = match args.len() {
  157. 2 => (None, false),
  158. 3 => (Some(bytes_to_number::<i64>(&args[2])?), false),
  159. 4 => {
  160. if !(check_arg!(args, 3, "WITHVALUES")) {
  161. return Err(Error::Syntax);
  162. }
  163. (Some(bytes_to_number::<i64>(&args[2])?), true)
  164. }
  165. _ => return Err(Error::InvalidArgsCount("hrandfield".to_owned())),
  166. };
  167. let (count, single, repeat) = if let Some(count) = count {
  168. if count > 0 {
  169. (count, false, 1)
  170. } else {
  171. (count.abs(), false, count.abs())
  172. }
  173. } else {
  174. (1, true, 1)
  175. };
  176. conn.db().get_map_or(
  177. &args[1],
  178. |v| match v {
  179. Value::Hash(h) => {
  180. let mut ret = vec![];
  181. let mut i = 0;
  182. let mut rand_sorted = BTreeMap::new();
  183. let mut rng = rand::thread_rng();
  184. let h = h.read();
  185. for _ in 0..repeat {
  186. for (key, value) in h.iter() {
  187. let rand = rng.gen::<u64>();
  188. rand_sorted.insert((rand, i), (key, value));
  189. i += 1;
  190. }
  191. }
  192. i = 0;
  193. for val in rand_sorted.values() {
  194. if single {
  195. return Ok(Value::Blob(val.0.clone()));
  196. }
  197. if i == count {
  198. break;
  199. }
  200. ret.push(Value::Blob(val.0.clone()));
  201. if with_values {
  202. ret.push(Value::Blob(val.1.clone()));
  203. }
  204. i += 1;
  205. }
  206. Ok(ret.into())
  207. }
  208. _ => Err(Error::WrongType),
  209. },
  210. || Ok(Value::Array(vec![])),
  211. )
  212. }
  213. pub fn hset(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  214. if args.len() % 2 == 1 {
  215. return Err(Error::InvalidArgsCount("hset".to_owned()));
  216. }
  217. conn.db().get_map_or(
  218. &args[1],
  219. |v| match v {
  220. Value::Hash(h) => {
  221. let mut h = h.write();
  222. let mut e: i64 = 0;
  223. for i in (2..args.len()).step_by(2) {
  224. if h.insert(args[i].clone(), args[i + 1].clone()).is_none() {
  225. e += 1;
  226. }
  227. }
  228. Ok(e.into())
  229. }
  230. _ => Err(Error::WrongType),
  231. },
  232. || {
  233. #[allow(clippy::mutable_key_type)]
  234. let mut h = HashMap::new();
  235. for i in (2..args.len()).step_by(2) {
  236. h.insert(args[i].clone(), args[i + 1].clone());
  237. }
  238. let len = h.len() as i64;
  239. conn.db().set(&args[1], h.into(), None);
  240. Ok(len.into())
  241. },
  242. )
  243. }
  244. pub fn hsetnx(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  245. conn.db().get_map_or(
  246. &args[1],
  247. |v| match v {
  248. Value::Hash(h) => {
  249. let mut h = h.write();
  250. if h.get(&args[2]).is_some() {
  251. Ok(0.into())
  252. } else {
  253. h.insert(args[2].clone(), args[3].clone());
  254. Ok(1.into())
  255. }
  256. }
  257. _ => Err(Error::WrongType),
  258. },
  259. || {
  260. #[allow(clippy::mutable_key_type)]
  261. let mut h = HashMap::new();
  262. for i in (2..args.len()).step_by(2) {
  263. h.insert(args[i].clone(), args[i + 1].clone());
  264. }
  265. let len = h.len() as i64;
  266. conn.db().set(&args[1], h.into(), None);
  267. Ok(len.into())
  268. },
  269. )
  270. }
  271. pub fn hstrlen(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  272. conn.db().get_map_or(
  273. &args[1],
  274. |v| match v {
  275. Value::Hash(h) => Ok(if let Some(v) = h.read().get(&args[2]) {
  276. (v.len() as i64).into()
  277. } else {
  278. 0.into()
  279. }),
  280. _ => Err(Error::WrongType),
  281. },
  282. || Ok(0.into()),
  283. )
  284. }
  285. pub fn hvals(conn: &Connection, args: &[Bytes]) -> Result<Value, Error> {
  286. conn.db().get_map_or(
  287. &args[1],
  288. |v| match v {
  289. Value::Hash(h) => {
  290. let mut ret = vec![];
  291. for value in h.read().values() {
  292. ret.push(Value::Blob(value.clone()));
  293. }
  294. Ok(ret.into())
  295. }
  296. _ => Err(Error::WrongType),
  297. },
  298. || Ok(Value::Array(vec![])),
  299. )
  300. }
  301. #[cfg(test)]
  302. mod test {
  303. use crate::{
  304. cmd::test::{create_connection, run_command},
  305. value::Value,
  306. };
  307. #[test]
  308. fn hget() {
  309. let c = create_connection();
  310. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  311. assert_eq!(Ok(Value::Integer(3)), r);
  312. let r = run_command(&c, &["hget", "foo", "f1"]);
  313. assert_eq!(Ok(Value::Blob("1".into())), r);
  314. }
  315. #[test]
  316. fn hgetall() {
  317. let c = create_connection();
  318. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  319. assert_eq!(Ok(Value::Integer(3)), r);
  320. let r = run_command(&c, &["hgetall", "foo"]);
  321. match r {
  322. Ok(Value::Array(x)) => {
  323. assert_eq!(6, x.len());
  324. assert!(
  325. x[0] == Value::Blob("f1".into())
  326. || x[0] == Value::Blob("f2".into())
  327. || x[0] == Value::Blob("f3".into())
  328. )
  329. }
  330. _ => assert!(false),
  331. };
  332. }
  333. #[test]
  334. fn hrandfield() {
  335. let c = create_connection();
  336. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  337. assert_eq!(Ok(Value::Integer(3)), r);
  338. let r = run_command(&c, &["hrandfield", "foo"]);
  339. match r {
  340. Ok(Value::Blob(x)) => {
  341. let x = unsafe { std::str::from_utf8_unchecked(&x) };
  342. assert!(x == "f1".to_owned() || x == "f2".to_owned() || x == "f3".to_owned());
  343. }
  344. _ => assert!(false),
  345. };
  346. }
  347. #[test]
  348. fn hmget() {
  349. let c = create_connection();
  350. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  351. assert_eq!(Ok(Value::Integer(3)), r);
  352. let r = run_command(&c, &["hmget", "foo", "f1", "f2"]);
  353. assert_eq!(
  354. Ok(Value::Array(vec![
  355. Value::Blob("1".into()),
  356. Value::Blob("2".into()),
  357. ])),
  358. r
  359. );
  360. }
  361. #[test]
  362. fn hexists() {
  363. let c = create_connection();
  364. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  365. assert_eq!(Ok(Value::Integer(3)), r);
  366. assert_eq!(
  367. Ok(Value::Integer(1)),
  368. run_command(&c, &["hexists", "foo", "f1"])
  369. );
  370. assert_eq!(
  371. Ok(Value::Integer(1)),
  372. run_command(&c, &["hexists", "foo", "f3"])
  373. );
  374. assert_eq!(
  375. Ok(Value::Integer(0)),
  376. run_command(&c, &["hexists", "foo", "f4"])
  377. );
  378. }
  379. #[test]
  380. fn hstrlen() {
  381. let c = create_connection();
  382. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  383. assert_eq!(Ok(Value::Integer(3)), r);
  384. let r = run_command(&c, &["hstrlen", "foo", "f1"]);
  385. assert_eq!(Ok(Value::Integer(1)), r);
  386. }
  387. #[test]
  388. fn hlen() {
  389. let c = create_connection();
  390. let r = run_command(&c, &["hset", "foo", "f1", "1", "f2", "2", "f3", "3"]);
  391. assert_eq!(Ok(Value::Integer(3)), r);
  392. let r = run_command(&c, &["hset", "foo", "f1", "2", "f4", "2", "f5", "3"]);
  393. assert_eq!(Ok(Value::Integer(2)), r);
  394. let r = run_command(&c, &["hlen", "foo"]);
  395. assert_eq!(Ok(Value::Integer(5)), r);
  396. }
  397. #[test]
  398. fn hkeys() {
  399. let c = create_connection();
  400. let r = run_command(&c, &["hset", "foo", "f1", "1"]);
  401. assert_eq!(Ok(Value::Integer(1)), r);
  402. let r = run_command(&c, &["hkeys", "foo"]);
  403. assert_eq!(Ok(Value::Array(vec![Value::Blob("f1".into()),])), r);
  404. }
  405. #[test]
  406. fn hvals() {
  407. let c = create_connection();
  408. let r = run_command(&c, &["hset", "foo", "f1", "1"]);
  409. assert_eq!(Ok(Value::Integer(1)), r);
  410. let r = run_command(&c, &["hvals", "foo"]);
  411. assert_eq!(Ok(Value::Array(vec![Value::Blob("1".into()),])), r);
  412. }
  413. }