Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion sdk/cosmos/azure_data_cosmos/examples/cosmos/patch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ impl PatchCommand {
.iter()
.map(|op| serde_json::from_str(op).expect("Invalid JSON patch operation"))
.collect();
let patch = PatchDocument { operations };
let patch = PatchDocument {
condition: None,
operations,
};

let response = container_client
.patch_item(pk, &self.item_id, patch, None)
Expand Down
47 changes: 47 additions & 0 deletions sdk/cosmos/azure_data_cosmos/src/models/patch_operations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use serde::{Deserialize, Serialize};
/// .with_add("/color", "silver")?
/// .with_move("/from", "/to")?;
/// # assert_eq!(patch, PatchDocument {
/// # condition: None,
/// # operations: vec![
/// # PatchOperation::Add {
/// # path: "/color".into(),
Expand All @@ -39,10 +40,20 @@ use serde::{Deserialize, Serialize};
/// ```
#[derive(Default, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct PatchDocument {
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<Cow<'static, str>>,
pub operations: Vec<PatchOperation>,
}

impl PatchDocument {
/// Adds a condition, which determines whether or not the patch should be applied.
///
/// The value is an SQL-like filter predicate as a string. For example, `from c where c.taskNum = 3`.
pub fn with_condition(mut self, condition: impl Into<Cow<'static, str>>) -> Self {
self.condition = Some(condition.into());
self
}

/// Adds a new "add" operation to the patch document.
///
/// See the [type documentation](PatchDocument) for more information on patch operations.
Expand Down Expand Up @@ -255,6 +266,18 @@ mod tests {
Ok(())
}

#[test]
pub fn serialize_condition() -> Result<(), Box<dyn std::error::Error>> {
let patch_document = PatchDocument::default().with_condition("from c where c.value = 0");

let serialized = serde_json::to_string(&patch_document).unwrap();
assert_eq!(
serialized,
"{\"condition\":\"from c where c.value = 0\",\"operations\":[]}"
);
Ok(())
}

#[test]
pub fn serialize_add() -> Result<(), Box<dyn std::error::Error>> {
let patch_document = PatchDocument::default().with_add(
Expand Down Expand Up @@ -380,6 +403,30 @@ mod tests {
Ok(())
}

#[test]
pub fn cosmos_docs_conditional_patch_example() -> Result<(), Box<dyn std::error::Error>> {
const TEST_DOC: &str = r#"{
"condition": "from c where c.Address.ZipCode = '98101'",
"operations": [
{
"op":"replace",
"path":"/Address/ZipCode",
"value":98107
}
]
}"#;

let doc: PatchDocument = serde_json::from_str(TEST_DOC)?;

assert_eq!(
doc,
PatchDocument::default()
.with_condition("from c where c.Address.ZipCode = '98101'")
.with_replace("/Address/ZipCode", 98107)?
);
Ok(())
}

#[test]
pub fn to_json_number_f64() -> Result<(), Box<dyn std::error::Error>> {
assert_eq!(
Expand Down