1use crate::KevyResult;
9
10use kevy_store::ScoreBound;
11
12use crate::store::ensure_writable;
13use crate::store::{Store, commit_write, store_err};
14
15impl Store {
16 pub fn hgetall(&self, key: &[u8]) -> KevyResult<Vec<(Vec<u8>, Vec<u8>)>> {
21 let flat = self.wshard(key).store.hgetall(key).map_err(store_err)?;
22 let mut out = Vec::with_capacity(flat.len() / 2);
24 let mut it = flat.into_iter();
25 while let (Some(f), Some(v)) = (it.next(), it.next()) {
26 out.push((f, v));
27 }
28 Ok(out)
29 }
30
31 pub fn hexists(&self, key: &[u8], field: &[u8]) -> KevyResult<bool> {
33 self.wshard(key).store.hexists(key, field).map_err(store_err)
34 }
35
36 pub fn hlen(&self, key: &[u8]) -> KevyResult<usize> {
38 self.wshard(key).store.hlen(key).map_err(store_err)
39 }
40
41 pub fn hkeys(&self, key: &[u8]) -> KevyResult<Vec<Vec<u8>>> {
43 self.wshard(key).store.hkeys(key).map_err(store_err)
44 }
45
46 pub fn hvals(&self, key: &[u8]) -> KevyResult<Vec<Vec<u8>>> {
48 self.wshard(key).store.hvals(key).map_err(store_err)
49 }
50
51 pub fn hmget(&self, key: &[u8], fields: &[&[u8]]) -> KevyResult<Vec<Option<Vec<u8>>>> {
54 self.wshard(key).store.hmget(key, fields).map_err(store_err)
55 }
56
57 pub fn hincrby(&self, key: &[u8], field: &[u8], delta: i64) -> KevyResult<i64> {
60 ensure_writable(self)?;
61 let mut g = self.wshard(key);
62 let new_val = g.store.hincrby(key, field, delta).map_err(store_err)?;
63 let delta_str = format!("{delta}");
64 commit_write(&mut g, &[b"HINCRBY", key, field, delta_str.as_bytes()])?;
65 Ok(new_val)
66 }
67
68 pub fn zrange(&self, key: &[u8], start: i64, stop: i64) -> KevyResult<Vec<(Vec<u8>, f64)>> {
75 self.wshard(key).store.zrange(key, start, stop).map_err(store_err)
76 }
77
78 pub fn zrevrange(
82 &self,
83 key: &[u8],
84 start: i64,
85 stop: i64,
86 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
87 let mut all = self
88 .wshard(key)
89 .store
90 .zrange(key, 0, -1)
91 .map_err(store_err)?;
92 all.reverse();
93 let n = all.len() as i64;
94 if n == 0 {
95 return Ok(Vec::new());
96 }
97 let clamp = |x: i64| -> usize {
98 let v = if x < 0 { (n + x).max(0) } else { x.min(n - 1) };
99 v as usize
100 };
101 let s = clamp(start);
102 let e = clamp(stop);
103 if s > e {
104 return Ok(Vec::new());
105 }
106 Ok(all.into_iter().skip(s).take(e - s + 1).collect())
107 }
108
109 pub fn zrange_by_score(
115 &self,
116 key: &[u8],
117 min: f64,
118 max: f64,
119 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
120 self.wshard(key)
121 .store
122 .zrange_by_score(
123 key,
124 ScoreBound { value: min, exclusive: false },
125 ScoreBound { value: max, exclusive: false },
126 )
127 .map_err(store_err)
128 }
129
130 pub fn zrange_by_score_excl(
134 &self,
135 key: &[u8],
136 min: ScoreBound,
137 max: ScoreBound,
138 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
139 self.wshard(key)
140 .store
141 .zrange_by_score(key, min, max)
142 .map_err(store_err)
143 }
144
145 pub fn zrange_by_score_limit(
149 &self,
150 key: &[u8],
151 min: f64,
152 max: f64,
153 offset: usize,
154 count: usize,
155 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
156 let all = self.zrange_by_score(key, min, max)?;
157 Ok(all.into_iter().skip(offset).take(count).collect())
158 }
159
160 pub fn zrevrange_by_score_limit(
163 &self,
164 key: &[u8],
165 max: f64,
166 min: f64,
167 offset: usize,
168 count: usize,
169 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
170 let mut all = self.zrange_by_score(key, min, max)?;
171 all.reverse();
172 Ok(all.into_iter().skip(offset).take(count).collect())
173 }
174
175 pub fn zpopmin_below(
179 &self,
180 key: &[u8],
181 below: f64,
182 count: usize,
183 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
184 ensure_writable(self)?;
185 let mut g = self.wshard(key);
186 let items = g.store.zpopmin_below(key, below, count).map_err(store_err)?;
187 if !items.is_empty() {
188 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + items.len());
189 argv.push(b"ZREM");
190 argv.push(key);
191 argv.extend(items.iter().map(|(m, _)| m.as_slice()));
192 commit_write(&mut g, &argv)?;
193 }
194 Ok(items)
195 }
196
197 pub fn zincrby(&self, key: &[u8], delta: f64, member: &[u8]) -> KevyResult<f64> {
200 ensure_writable(self)?;
201 let mut g = self.wshard(key);
202 let new_score = g.store.zincrby(key, delta, member).map_err(store_err)?;
203 let delta_str = format!("{delta}");
204 commit_write(&mut g, &[b"ZINCRBY", key, delta_str.as_bytes(), member])?;
205 Ok(new_score)
206 }
207
208 pub fn lrange(&self, key: &[u8], start: i64, stop: i64) -> KevyResult<Vec<Vec<u8>>> {
213 self.wshard(key).store.lrange(key, start, stop).map_err(store_err)
214 }
215
216 pub fn lindex(&self, key: &[u8], idx: i64) -> KevyResult<Option<Vec<u8>>> {
218 self.wshard(key).store.lindex(key, idx).map_err(store_err)
219 }
220
221 pub fn lrem(&self, key: &[u8], count: i64, value: &[u8]) -> KevyResult<usize> {
225 ensure_writable(self)?;
226 let mut g = self.wshard(key);
227 let removed = g.store.lrem(key, count, value).map_err(store_err)?;
228 if removed > 0 {
229 let count_str = format!("{count}");
230 commit_write(&mut g, &[b"LREM", key, count_str.as_bytes(), value])?;
231 }
232 Ok(removed)
233 }
234
235 pub fn getset(&self, key: &[u8], new: &[u8]) -> KevyResult<Option<Vec<u8>>> {
240 ensure_writable(self)?;
241 let mut g = self.wshard(key);
242 let prev = g.store.getset(key, new.to_vec()).map_err(store_err)?;
243 commit_write(&mut g, &[b"SET", key, new])?;
244 Ok(prev)
245 }
246
247 pub fn getdel(&self, key: &[u8]) -> KevyResult<Option<Vec<u8>>> {
250 ensure_writable(self)?;
251 let mut g = self.wshard(key);
252 let prev = g.store.getdel(key).map_err(store_err)?;
253 if prev.is_some() {
254 commit_write(&mut g, &[b"DEL", key])?;
255 }
256 Ok(prev)
257 }
258}