Skip to content

Commit 72db89a

Browse files
authored
Merge pull request #123 from kinode-dao/bp/kvgetas
kv: functions for several value types in db
2 parents 75d3f10 + d97e012 commit 72db89a

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

src/kv.rs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,43 @@ where
101101
}
102102
}
103103

104+
/// Get a value as a different type T
105+
pub fn get_as<T>(&self, key: &K) -> anyhow::Result<T>
106+
where
107+
T: DeserializeOwned,
108+
{
109+
let key = serde_json::to_vec(key)?;
110+
let res = Request::new()
111+
.target(("our", "kv", "distro", "sys"))
112+
.body(serde_json::to_vec(&KvRequest {
113+
package_id: self.package_id.clone(),
114+
db: self.db.clone(),
115+
action: KvAction::Get { key },
116+
})?)
117+
.send_and_await_response(self.timeout)?;
118+
119+
match res {
120+
Ok(Message::Response { body, .. }) => {
121+
let response = serde_json::from_slice::<KvResponse>(&body)?;
122+
123+
match response {
124+
KvResponse::Get { .. } => {
125+
let bytes = match get_blob() {
126+
Some(bytes) => bytes.bytes,
127+
None => return Err(anyhow::anyhow!("kv: no blob")),
128+
};
129+
let value = serde_json::from_slice::<T>(&bytes)
130+
.map_err(|e| anyhow::anyhow!("Failed to deserialize value: {}", e))?;
131+
Ok(value)
132+
}
133+
KvResponse::Err { error } => Err(error.into()),
134+
_ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)),
135+
}
136+
}
137+
_ => Err(anyhow::anyhow!("kv: unexpected message: {:?}", res)),
138+
}
139+
}
140+
104141
/// Set a value, optionally in a transaction.
105142
pub fn set(&self, key: &K, value: &V, tx_id: Option<u64>) -> anyhow::Result<()> {
106143
let key = serde_json::to_vec(key)?;
@@ -130,6 +167,38 @@ where
130167
}
131168
}
132169

170+
/// Set a value as a different type T
171+
pub fn set_as<T>(&self, key: &K, value: &T, tx_id: Option<u64>) -> anyhow::Result<()>
172+
where
173+
T: Serialize,
174+
{
175+
let key = serde_json::to_vec(key)?;
176+
let value = serde_json::to_vec(value)?;
177+
178+
let res = Request::new()
179+
.target(("our", "kv", "distro", "sys"))
180+
.body(serde_json::to_vec(&KvRequest {
181+
package_id: self.package_id.clone(),
182+
db: self.db.clone(),
183+
action: KvAction::Set { key, tx_id },
184+
})?)
185+
.blob_bytes(value)
186+
.send_and_await_response(self.timeout)?;
187+
188+
match res {
189+
Ok(Message::Response { body, .. }) => {
190+
let response = serde_json::from_slice::<KvResponse>(&body)?;
191+
192+
match response {
193+
KvResponse::Ok => Ok(()),
194+
KvResponse::Err { error } => Err(error.into()),
195+
_ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)),
196+
}
197+
}
198+
_ => Err(anyhow::anyhow!("kv: unexpected message: {:?}", res)),
199+
}
200+
}
201+
133202
/// Delete a value, optionally in a transaction.
134203
pub fn delete(&self, key: &K, tx_id: Option<u64>) -> anyhow::Result<()> {
135204
let key = serde_json::to_vec(key)?;
@@ -156,6 +225,36 @@ where
156225
}
157226
}
158227

228+
/// Delete a value with a different key type
229+
pub fn delete_as<T>(&self, key: &T, tx_id: Option<u64>) -> anyhow::Result<()>
230+
where
231+
T: Serialize,
232+
{
233+
let key = serde_json::to_vec(key)?;
234+
235+
let res = Request::new()
236+
.target(("our", "kv", "distro", "sys"))
237+
.body(serde_json::to_vec(&KvRequest {
238+
package_id: self.package_id.clone(),
239+
db: self.db.clone(),
240+
action: KvAction::Delete { key, tx_id },
241+
})?)
242+
.send_and_await_response(self.timeout)?;
243+
244+
match res {
245+
Ok(Message::Response { body, .. }) => {
246+
let response = serde_json::from_slice::<KvResponse>(&body)?;
247+
248+
match response {
249+
KvResponse::Ok => Ok(()),
250+
KvResponse::Err { error } => Err(error.into()),
251+
_ => Err(anyhow::anyhow!("kv: unexpected response {:?}", response)),
252+
}
253+
}
254+
_ => Err(anyhow::anyhow!("kv: unexpected message: {:?}", res)),
255+
}
256+
}
257+
159258
/// Begin a transaction.
160259
pub fn begin_tx(&self) -> anyhow::Result<u64> {
161260
let res = Request::new()

0 commit comments

Comments
 (0)