(
&self,
object_type: &str,
id: &str,
name: &str,
payload: &[u8],
labels: Option<&str>,
condition: WriteCondition,
)
| 113 | } |
| 114 | |
| 115 | pub async fn put_if( |
| 116 | &self, |
| 117 | object_type: &str, |
| 118 | id: &str, |
| 119 | name: &str, |
| 120 | payload: &[u8], |
| 121 | labels: Option<&str>, |
| 122 | condition: WriteCondition, |
| 123 | ) -> PersistenceResult<WriteResult> { |
| 124 | let now_ms = current_time_ms(); |
| 125 | |
| 126 | match condition { |
| 127 | WriteCondition::MustCreate => { |
| 128 | // Insert only - fail if object exists |
| 129 | sqlx::query( |
| 130 | r#" |
| 131 | INSERT INTO "objects" ("object_type", "id", "name", "payload", "created_at_ms", "updated_at_ms", "labels", "resource_version") |
| 132 | VALUES (?1, ?2, ?3, ?4, ?5, ?5, ?6, 1) |
| 133 | "#, |
| 134 | ) |
| 135 | .bind(object_type) |
| 136 | .bind(id) |
| 137 | .bind(name) |
| 138 | .bind(payload) |
| 139 | .bind(now_ms) |
| 140 | .bind(labels.unwrap_or("{}")) |
| 141 | .execute(&self.pool) |
| 142 | .await |
| 143 | .map_err(|e| map_db_error(&e))?; |
| 144 | |
| 145 | Ok(WriteResult { |
| 146 | resource_version: 1, |
| 147 | created_at_ms: now_ms, |
| 148 | updated_at_ms: now_ms, |
| 149 | }) |
| 150 | } |
| 151 | WriteCondition::MatchResourceVersion(expected_version) => { |
| 152 | // Update with version check |
| 153 | let result = sqlx::query( |
| 154 | r#" |
| 155 | UPDATE "objects" |
| 156 | SET "payload" = ?4, "labels" = ?5, "updated_at_ms" = ?6, "resource_version" = "resource_version" + 1 |
| 157 | WHERE "object_type" = ?1 AND "id" = ?2 AND "resource_version" = ?3 |
| 158 | "#, |
| 159 | ) |
| 160 | .bind(object_type) |
| 161 | .bind(id) |
| 162 | .bind(i64::try_from(expected_version).unwrap_or(i64::MAX)) |
| 163 | .bind(payload) |
| 164 | .bind(labels.unwrap_or("{}")) |
| 165 | .bind(now_ms) |
| 166 | .execute(&self.pool) |
| 167 | .await |
| 168 | .map_err(|e| map_db_error(&e))?; |
| 169 | |
| 170 | if result.rows_affected() == 0 { |
| 171 | // Check if object exists to distinguish NotFound from Conflict |
| 172 | let existing = self.get(object_type, id).await?; |
nothing calls this directly
no test coverage detected