1use crate::convert::*;
3use crate::error::Result;
4use kstone_core::Item;
5use kstone_proto::{self as proto, keystone_db_client::KeystoneDbClient};
6use tonic::transport::Channel;
7use std::collections::HashMap;
8
9pub struct RemoteUpdate {
11 partition_key: Vec<u8>,
12 sort_key: Option<Vec<u8>>,
13 update_expression: String,
14 condition_expression: Option<String>,
15 expression_values: HashMap<String, kstone_core::Value>,
16}
17
18impl RemoteUpdate {
19 pub fn new(pk: &[u8]) -> Self {
21 Self {
22 partition_key: pk.to_vec(),
23 sort_key: None,
24 update_expression: String::new(),
25 condition_expression: None,
26 expression_values: HashMap::new(),
27 }
28 }
29
30 pub fn with_sk(pk: &[u8], sk: &[u8]) -> Self {
32 Self {
33 partition_key: pk.to_vec(),
34 sort_key: Some(sk.to_vec()),
35 update_expression: String::new(),
36 condition_expression: None,
37 expression_values: HashMap::new(),
38 }
39 }
40
41 pub fn expression(mut self, expr: impl Into<String>) -> Self {
43 self.update_expression = expr.into();
44 self
45 }
46
47 pub fn condition(mut self, condition: impl Into<String>) -> Self {
49 self.condition_expression = Some(condition.into());
50 self
51 }
52
53 pub fn value(mut self, placeholder: impl Into<String>, value: kstone_core::Value) -> Self {
55 self.expression_values.insert(placeholder.into(), value);
56 self
57 }
58
59 pub async fn execute(self, client: &mut KeystoneDbClient<Channel>) -> Result<RemoteUpdateResponse> {
61 let proto_values: HashMap<String, proto::Value> = self
63 .expression_values
64 .iter()
65 .map(|(k, v)| (k.clone(), ks_value_to_proto(v)))
66 .collect();
67
68 let request = proto::UpdateRequest {
69 partition_key: self.partition_key,
70 sort_key: self.sort_key,
71 update_expression: self.update_expression,
72 condition_expression: self.condition_expression,
73 expression_values: proto_values,
74 };
75
76 let response = client
77 .update(request)
78 .await?
79 .into_inner();
80
81 let item = proto_item_to_ks(
82 response.item.expect("Server should return updated item")
83 )?;
84
85 Ok(RemoteUpdateResponse { item })
86 }
87}
88
89pub struct RemoteUpdateResponse {
91 pub item: Item,
93}