1use std::io;
9
10use kevy_store::ScoreBound;
11
12#[cfg(not(target_arch = "wasm32"))]
13use crate::replica_glue::ensure_writable;
14use crate::store::{Store, commit_write, store_err};
15
16#[cfg(target_arch = "wasm32")]
17fn ensure_writable(_s: &Store) -> io::Result<()> { Ok(()) }
18
19impl Store {
20 pub fn hgetall(&self, key: &[u8]) -> io::Result<Vec<(Vec<u8>, Vec<u8>)>> {
25 let flat = self.wshard(key).store.hgetall(key).map_err(store_err)?;
26 let mut out = Vec::with_capacity(flat.len() / 2);
28 let mut it = flat.into_iter();
29 while let (Some(f), Some(v)) = (it.next(), it.next()) {
30 out.push((f, v));
31 }
32 Ok(out)
33 }
34
35 pub fn hexists(&self, key: &[u8], field: &[u8]) -> io::Result<bool> {
37 self.wshard(key).store.hexists(key, field).map_err(store_err)
38 }
39
40 pub fn hlen(&self, key: &[u8]) -> io::Result<usize> {
42 self.wshard(key).store.hlen(key).map_err(store_err)
43 }
44
45 pub fn hkeys(&self, key: &[u8]) -> io::Result<Vec<Vec<u8>>> {
47 self.wshard(key).store.hkeys(key).map_err(store_err)
48 }
49
50 pub fn hvals(&self, key: &[u8]) -> io::Result<Vec<Vec<u8>>> {
52 self.wshard(key).store.hvals(key).map_err(store_err)
53 }
54
55 pub fn hmget(&self, key: &[u8], fields: &[&[u8]]) -> io::Result<Vec<Option<Vec<u8>>>> {
58 let owned: Vec<Vec<u8>> = fields.iter().map(|f| f.to_vec()).collect();
59 self.wshard(key).store.hmget(key, &owned).map_err(store_err)
60 }
61
62 pub fn hincrby(&self, key: &[u8], field: &[u8], delta: i64) -> io::Result<i64> {
65 ensure_writable(self)?;
66 let mut g = self.wshard(key);
67 let new_val = g.store.hincrby(key, field, delta).map_err(store_err)?;
68 let delta_str = format!("{delta}");
69 commit_write(&mut g, &[b"HINCRBY", key, field, delta_str.as_bytes()])?;
70 Ok(new_val)
71 }
72
73 pub fn zrange(&self, key: &[u8], start: i64, stop: i64) -> io::Result<Vec<(Vec<u8>, f64)>> {
80 self.wshard(key).store.zrange(key, start, stop).map_err(store_err)
81 }
82
83 pub fn zrevrange(
87 &self,
88 key: &[u8],
89 start: i64,
90 stop: i64,
91 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
92 let mut all = self
93 .wshard(key)
94 .store
95 .zrange(key, 0, -1)
96 .map_err(store_err)?;
97 all.reverse();
98 let n = all.len() as i64;
99 if n == 0 {
100 return Ok(Vec::new());
101 }
102 let clamp = |x: i64| -> usize {
103 let v = if x < 0 { (n + x).max(0) } else { x.min(n - 1) };
104 v as usize
105 };
106 let s = clamp(start);
107 let e = clamp(stop);
108 if s > e {
109 return Ok(Vec::new());
110 }
111 Ok(all.into_iter().skip(s).take(e - s + 1).collect())
112 }
113
114 pub fn zrange_by_score(
120 &self,
121 key: &[u8],
122 min: f64,
123 max: f64,
124 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
125 self.wshard(key)
126 .store
127 .zrange_by_score(
128 key,
129 ScoreBound { value: min, exclusive: false },
130 ScoreBound { value: max, exclusive: false },
131 )
132 .map_err(store_err)
133 }
134
135 pub fn zrange_by_score_excl(
139 &self,
140 key: &[u8],
141 min: ScoreBound,
142 max: ScoreBound,
143 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
144 self.wshard(key)
145 .store
146 .zrange_by_score(key, min, max)
147 .map_err(store_err)
148 }
149
150 pub fn zrange_by_score_limit(
154 &self,
155 key: &[u8],
156 min: f64,
157 max: f64,
158 offset: usize,
159 count: usize,
160 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
161 let all = self.zrange_by_score(key, min, max)?;
162 Ok(all.into_iter().skip(offset).take(count).collect())
163 }
164
165 pub fn zrevrange_by_score_limit(
168 &self,
169 key: &[u8],
170 max: f64,
171 min: f64,
172 offset: usize,
173 count: usize,
174 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
175 let mut all = self.zrange_by_score(key, min, max)?;
176 all.reverse();
177 Ok(all.into_iter().skip(offset).take(count).collect())
178 }
179
180 pub fn zpopmin_below(
184 &self,
185 key: &[u8],
186 below: f64,
187 count: usize,
188 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
189 ensure_writable(self)?;
190 let mut g = self.wshard(key);
191 let items = g.store.zpopmin_below(key, below, count).map_err(store_err)?;
192 if !items.is_empty() {
193 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + items.len());
194 argv.push(b"ZREM");
195 argv.push(key);
196 argv.extend(items.iter().map(|(m, _)| m.as_slice()));
197 commit_write(&mut g, &argv)?;
198 }
199 Ok(items)
200 }
201
202 pub fn zincrby(&self, key: &[u8], delta: f64, member: &[u8]) -> io::Result<f64> {
205 ensure_writable(self)?;
206 let mut g = self.wshard(key);
207 let new_score = g.store.zincrby(key, delta, member).map_err(store_err)?;
208 let delta_str = format!("{delta}");
209 commit_write(&mut g, &[b"ZINCRBY", key, delta_str.as_bytes(), member])?;
210 Ok(new_score)
211 }
212
213 pub fn lrange(&self, key: &[u8], start: i64, stop: i64) -> io::Result<Vec<Vec<u8>>> {
218 self.wshard(key).store.lrange(key, start, stop).map_err(store_err)
219 }
220
221 pub fn lindex(&self, key: &[u8], idx: i64) -> io::Result<Option<Vec<u8>>> {
223 self.wshard(key).store.lindex(key, idx).map_err(store_err)
224 }
225
226 pub fn lrem(&self, key: &[u8], count: i64, value: &[u8]) -> io::Result<usize> {
230 ensure_writable(self)?;
231 let mut g = self.wshard(key);
232 let removed = g.store.lrem(key, count, value).map_err(store_err)?;
233 if removed > 0 {
234 let count_str = format!("{count}");
235 commit_write(&mut g, &[b"LREM", key, count_str.as_bytes(), value])?;
236 }
237 Ok(removed)
238 }
239
240 pub fn getset(&self, key: &[u8], new: &[u8]) -> io::Result<Option<Vec<u8>>> {
245 ensure_writable(self)?;
246 let mut g = self.wshard(key);
247 let prev = g.store.getset(key, new.to_vec()).map_err(store_err)?;
248 commit_write(&mut g, &[b"SET", key, new])?;
249 Ok(prev)
250 }
251
252 pub fn getdel(&self, key: &[u8]) -> io::Result<Option<Vec<u8>>> {
255 ensure_writable(self)?;
256 let mut g = self.wshard(key);
257 let prev = g.store.getdel(key).map_err(store_err)?;
258 if prev.is_some() {
259 commit_write(&mut g, &[b"DEL", key])?;
260 }
261 Ok(prev)
262 }
263}