1use crate::{KevyError, KevyResult};
10
11use kevy_store::ScoreBound;
12
13use crate::store::ensure_writable;
14use crate::store::{Store, commit_write, store_err};
15
16impl Store {
17 pub fn sismember(&self, key: &[u8], member: &[u8]) -> KevyResult<bool> {
21 self.wshard(key).store.sismember(key, member).map_err(store_err)
22 }
23
24 pub fn spop(&self, key: &[u8], count: usize) -> KevyResult<Vec<Vec<u8>>> {
33 ensure_writable(self)?;
34 let mut g = self.wshard(key);
35 let popped = g.store.spop(key, count).map_err(store_err)?;
36 if !popped.is_empty() {
37 let mut argv: Vec<&[u8]> = Vec::with_capacity(2 + popped.len());
38 argv.push(b"SREM");
39 argv.push(key);
40 argv.extend(popped.iter().map(Vec::as_slice));
41 commit_write(&mut g, &argv)?;
42 }
43 Ok(popped)
44 }
45
46 pub fn srandmember(&self, key: &[u8], count: usize) -> KevyResult<Vec<Vec<u8>>> {
49 self.wshard(key).store.srandmember(key, count).map_err(store_err)
50 }
51
52 pub fn zrank(&self, key: &[u8], member: &[u8]) -> KevyResult<Option<usize>> {
57 self.wshard(key).store.zrank(key, member).map_err(store_err)
58 }
59
60 pub fn zcount(&self, key: &[u8], min: f64, max: f64) -> KevyResult<usize> {
63 self.wshard(key)
64 .store
65 .zcount(
66 key,
67 ScoreBound { value: min, exclusive: false },
68 ScoreBound { value: max, exclusive: false },
69 )
70 .map_err(store_err)
71 }
72
73 pub fn zpopmin(&self, key: &[u8], count: usize) -> KevyResult<Vec<(Vec<u8>, f64)>> {
76 ensure_writable(self)?;
77 let mut g = self.wshard(key);
78 let popped = g.store.zpopmin(key, count).map_err(store_err)?;
79 if !popped.is_empty() {
80 let count_str = format!("{count}");
81 commit_write(&mut g, &[b"ZPOPMIN", key, count_str.as_bytes()])?;
82 }
83 Ok(popped)
84 }
85
86 pub fn zremrangebyrank(&self, key: &[u8], start: i64, stop: i64) -> KevyResult<usize> {
90 ensure_writable(self)?;
91 let mut g = self.wshard(key);
92 let removed = g.store.zrem_range_by_rank(key, start, stop).map_err(store_err)?;
93 if removed > 0 {
94 let s = format!("{start}");
95 let e = format!("{stop}");
96 commit_write(&mut g, &[b"ZREMRANGEBYRANK", key, s.as_bytes(), e.as_bytes()])?;
97 }
98 Ok(removed)
99 }
100
101 pub fn zremrangebyscore(&self, key: &[u8], min: f64, max: f64) -> KevyResult<usize> {
104 ensure_writable(self)?;
105 let mut g = self.wshard(key);
106 let removed = g
107 .store
108 .zrem_range_by_score(
109 key,
110 ScoreBound { value: min, exclusive: false },
111 ScoreBound { value: max, exclusive: false },
112 )
113 .map_err(store_err)?;
114 if removed > 0 {
115 let s = format!("{min}");
116 let e = format!("{max}");
117 commit_write(&mut g, &[b"ZREMRANGEBYSCORE", key, s.as_bytes(), e.as_bytes()])?;
118 }
119 Ok(removed)
120 }
121
122 pub fn zrev_range_by_score(
125 &self,
126 key: &[u8],
127 max: f64,
128 min: f64,
129 ) -> KevyResult<Vec<(Vec<u8>, f64)>> {
130 self.wshard(key)
131 .store
132 .zrev_range_by_score(
133 key,
134 ScoreBound { value: min, exclusive: false },
135 ScoreBound { value: max, exclusive: false },
136 )
137 .map_err(store_err)
138 }
139
140 pub fn lset(&self, key: &[u8], idx: i64, value: &[u8]) -> KevyResult<()> {
146 ensure_writable(self)?;
147 let mut g = self.wshard(key);
148 g.store.lset(key, idx, value).map_err(store_err)?;
149 let i = format!("{idx}");
150 commit_write(&mut g, &[b"LSET", key, i.as_bytes(), value])?;
151 Ok(())
152 }
153
154 pub fn ltrim(&self, key: &[u8], start: i64, stop: i64) -> KevyResult<()> {
157 ensure_writable(self)?;
158 let mut g = self.wshard(key);
159 g.store.ltrim(key, start, stop).map_err(store_err)?;
160 let s = format!("{start}");
161 let e = format!("{stop}");
162 commit_write(&mut g, &[b"LTRIM", key, s.as_bytes(), e.as_bytes()])?;
163 Ok(())
164 }
165
166 pub fn rename(&self, src: &[u8], dst: &[u8]) -> KevyResult<bool> {
172 ensure_writable(self)?;
173 let mut g = self.wshard(src);
176 let outcome = g.store.rename(src, dst, false);
177 match outcome {
178 kevy_store::RenameOutcome::Renamed => {
179 commit_write(&mut g, &[b"RENAME", src, dst])?;
180 Ok(true)
181 }
182 kevy_store::RenameOutcome::NoSuchSrc => {
183 Err(KevyError::Store(kevy_store::StoreError::NoSuchKey))
184 }
185 kevy_store::RenameOutcome::DstExists => Ok(false),
186 }
187 }
188
189 pub fn renamenx(&self, src: &[u8], dst: &[u8]) -> KevyResult<bool> {
192 ensure_writable(self)?;
193 let mut g = self.wshard(src);
194 let outcome = g.store.rename(src, dst, true);
195 match outcome {
196 kevy_store::RenameOutcome::Renamed => {
197 commit_write(&mut g, &[b"RENAMENX", src, dst])?;
198 Ok(true)
199 }
200 kevy_store::RenameOutcome::DstExists => Ok(false),
201 kevy_store::RenameOutcome::NoSuchSrc => {
202 Err(KevyError::Store(kevy_store::StoreError::NoSuchKey))
203 }
204 }
205 }
206}