1use std::io;
10
11use kevy_store::ScoreBound;
12
13#[cfg(not(target_arch = "wasm32"))]
14use crate::replica_glue::ensure_writable;
15use crate::store::{Store, commit_write, store_err};
16
17#[cfg(target_arch = "wasm32")]
18fn ensure_writable(_s: &Store) -> io::Result<()> { Ok(()) }
19
20impl Store {
21 pub fn sismember(&self, key: &[u8], member: &[u8]) -> io::Result<bool> {
25 self.wshard(key).store.sismember(key, member).map_err(store_err)
26 }
27
28 pub fn spop(&self, key: &[u8], count: usize) -> io::Result<Vec<Vec<u8>>> {
37 ensure_writable(self)?;
38 let mut g = self.wshard(key);
39 let popped = g.store.spop(key, count).map_err(store_err)?;
40 if !popped.is_empty() {
41 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + popped.len());
42 argv.push(b"SREM");
43 argv.push(key);
44 argv.extend(popped.iter().map(Vec::as_slice));
45 commit_write(&mut g, &argv)?;
46 }
47 Ok(popped)
48 }
49
50 pub fn srandmember(&self, key: &[u8], count: usize) -> io::Result<Vec<Vec<u8>>> {
53 self.wshard(key).store.srandmember(key, count).map_err(store_err)
54 }
55
56 pub fn zrank(&self, key: &[u8], member: &[u8]) -> io::Result<Option<usize>> {
61 self.wshard(key).store.zrank(key, member).map_err(store_err)
62 }
63
64 pub fn zcount(&self, key: &[u8], min: f64, max: f64) -> io::Result<usize> {
67 self.wshard(key)
68 .store
69 .zcount(
70 key,
71 ScoreBound { value: min, exclusive: false },
72 ScoreBound { value: max, exclusive: false },
73 )
74 .map_err(store_err)
75 }
76
77 pub fn zpopmin(&self, key: &[u8], count: usize) -> io::Result<Vec<(Vec<u8>, f64)>> {
80 ensure_writable(self)?;
81 let mut g = self.wshard(key);
82 let popped = g.store.zpopmin(key, count).map_err(store_err)?;
83 if !popped.is_empty() {
84 let count_str = format!("{count}");
85 commit_write(&mut g, &[b"ZPOPMIN", key, count_str.as_bytes()])?;
86 }
87 Ok(popped)
88 }
89
90 pub fn zremrangebyrank(
94 &self,
95 key: &[u8],
96 start: i64,
97 stop: i64,
98 ) -> io::Result<usize> {
99 ensure_writable(self)?;
100 let mut g = self.wshard(key);
101 let removed = g.store.zrem_range_by_rank(key, start, stop).map_err(store_err)?;
102 if removed > 0 {
103 let s = format!("{start}");
104 let e = format!("{stop}");
105 commit_write(&mut g, &[b"ZREMRANGEBYRANK", key, s.as_bytes(), e.as_bytes()])?;
106 }
107 Ok(removed)
108 }
109
110 pub fn zremrangebyscore(
113 &self,
114 key: &[u8],
115 min: f64,
116 max: f64,
117 ) -> io::Result<usize> {
118 ensure_writable(self)?;
119 let mut g = self.wshard(key);
120 let removed = g
121 .store
122 .zrem_range_by_score(
123 key,
124 ScoreBound { value: min, exclusive: false },
125 ScoreBound { value: max, exclusive: false },
126 )
127 .map_err(store_err)?;
128 if removed > 0 {
129 let s = format!("{min}");
130 let e = format!("{max}");
131 commit_write(&mut g, &[b"ZREMRANGEBYSCORE", key, s.as_bytes(), e.as_bytes()])?;
132 }
133 Ok(removed)
134 }
135
136 pub fn zrev_range_by_score(
139 &self,
140 key: &[u8],
141 max: f64,
142 min: f64,
143 ) -> io::Result<Vec<(Vec<u8>, f64)>> {
144 self.wshard(key)
145 .store
146 .zrev_range_by_score(
147 key,
148 ScoreBound { value: min, exclusive: false },
149 ScoreBound { value: max, exclusive: false },
150 )
151 .map_err(store_err)
152 }
153
154 pub fn lset(&self, key: &[u8], idx: i64, value: &[u8]) -> io::Result<()> {
160 ensure_writable(self)?;
161 let mut g = self.wshard(key);
162 g.store.lset(key, idx, value).map_err(store_err)?;
163 let i = format!("{idx}");
164 commit_write(&mut g, &[b"LSET", key, i.as_bytes(), value])?;
165 Ok(())
166 }
167
168 pub fn ltrim(&self, key: &[u8], start: i64, stop: i64) -> io::Result<()> {
171 ensure_writable(self)?;
172 let mut g = self.wshard(key);
173 g.store.ltrim(key, start, stop).map_err(store_err)?;
174 let s = format!("{start}");
175 let e = format!("{stop}");
176 commit_write(&mut g, &[b"LTRIM", key, s.as_bytes(), e.as_bytes()])?;
177 Ok(())
178 }
179
180 pub fn rename(&self, src: &[u8], dst: &[u8]) -> io::Result<bool> {
186 ensure_writable(self)?;
187 let mut g = self.wshard(src);
190 let outcome = g.store.rename(src, dst, false);
191 match outcome {
192 kevy_store::RenameOutcome::Renamed => {
193 commit_write(&mut g, &[b"RENAME", src, dst])?;
194 Ok(true)
195 }
196 kevy_store::RenameOutcome::NoSuchSrc => {
197 Err(io::Error::other("no such key"))
198 }
199 kevy_store::RenameOutcome::DstExists => Ok(false),
200 }
201 }
202
203 pub fn renamenx(&self, src: &[u8], dst: &[u8]) -> io::Result<bool> {
206 ensure_writable(self)?;
207 let mut g = self.wshard(src);
208 let outcome = g.store.rename(src, dst, true);
209 match outcome {
210 kevy_store::RenameOutcome::Renamed => {
211 commit_write(&mut g, &[b"RENAMENX", src, dst])?;
212 Ok(true)
213 }
214 kevy_store::RenameOutcome::DstExists => Ok(false),
215 kevy_store::RenameOutcome::NoSuchSrc => {
216 Err(io::Error::other("no such key"))
217 }
218 }
219 }
220}