properly handling patch updates
Some checks failed
CI / Clippy (push) Failing after 3m6s
CI / Rustfmt (push) Failing after 3m9s
CI / Cargo Audit & Deny (push) Successful in 5m2s
CI / Tests (push) Successful in 8m15s
CI / Security Blocking Checks (push) Successful in 10s
CI / Web Advisory Checks (push) Successful in 1m4s
CI / Web Blocking Checks (push) Failing after 4m52s
Publish Images And Chart / Resolve Publish Metadata (push) Successful in 2s
CI / Security Advisory Checks (push) Successful in 1m31s
Publish Images And Chart / Publish init-user (push) Failing after 30s
Publish Images And Chart / Publish init-packs (push) Failing after 1m41s
Publish Images And Chart / Publish migrations (push) Failing after 10s
Publish Images And Chart / Publish web (push) Failing after 11s
Publish Images And Chart / Publish sensor (push) Failing after 32s
Publish Images And Chart / Publish worker (push) Failing after 11s
Publish Images And Chart / Publish executor (push) Failing after 11s
Publish Images And Chart / Publish notifier (push) Failing after 9s
Publish Images And Chart / Publish api (push) Failing after 31s
Publish Images And Chart / Publish Helm Chart (push) Has been skipped
Some checks failed
CI / Clippy (push) Failing after 3m6s
CI / Rustfmt (push) Failing after 3m9s
CI / Cargo Audit & Deny (push) Successful in 5m2s
CI / Tests (push) Successful in 8m15s
CI / Security Blocking Checks (push) Successful in 10s
CI / Web Advisory Checks (push) Successful in 1m4s
CI / Web Blocking Checks (push) Failing after 4m52s
Publish Images And Chart / Resolve Publish Metadata (push) Successful in 2s
CI / Security Advisory Checks (push) Successful in 1m31s
Publish Images And Chart / Publish init-user (push) Failing after 30s
Publish Images And Chart / Publish init-packs (push) Failing after 1m41s
Publish Images And Chart / Publish migrations (push) Failing after 10s
Publish Images And Chart / Publish web (push) Failing after 11s
Publish Images And Chart / Publish sensor (push) Failing after 32s
Publish Images And Chart / Publish worker (push) Failing after 11s
Publish Images And Chart / Publish executor (push) Failing after 11s
Publish Images And Chart / Publish notifier (push) Failing after 9s
Publish Images And Chart / Publish api (push) Failing after 31s
Publish Images And Chart / Publish Helm Chart (push) Has been skipped
This commit is contained in:
@@ -6,7 +6,7 @@ use crate::models::{action::*, enums::PolicyMethod, Id, JsonSchema};
|
||||
use crate::{Error, Result};
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Repository, Update};
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Patch, Repository, Update};
|
||||
|
||||
/// Columns selected in all Action queries. Must match the `Action` model's `FromRow` fields.
|
||||
pub const ACTION_COLUMNS: &str = "id, ref, pack, pack_ref, label, description, entrypoint, \
|
||||
@@ -67,7 +67,7 @@ pub struct UpdateActionInput {
|
||||
pub description: Option<String>,
|
||||
pub entrypoint: Option<String>,
|
||||
pub runtime: Option<Id>,
|
||||
pub runtime_version_constraint: Option<Option<String>>,
|
||||
pub runtime_version_constraint: Option<Patch<String>>,
|
||||
pub param_schema: Option<JsonSchema>,
|
||||
pub out_schema: Option<JsonSchema>,
|
||||
pub parameter_delivery: Option<String>,
|
||||
@@ -237,7 +237,10 @@ impl Update for ActionRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("runtime_version_constraint = ");
|
||||
query.push_bind(runtime_version_constraint);
|
||||
match runtime_version_constraint {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::models::{
|
||||
use crate::Result;
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Repository, Update};
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Patch, Repository, Update};
|
||||
|
||||
// ============================================================================
|
||||
// ArtifactRepository
|
||||
@@ -48,12 +48,12 @@ pub struct UpdateArtifactInput {
|
||||
pub visibility: Option<ArtifactVisibility>,
|
||||
pub retention_policy: Option<RetentionPolicyType>,
|
||||
pub retention_limit: Option<i32>,
|
||||
pub name: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub content_type: Option<String>,
|
||||
pub name: Option<Patch<String>>,
|
||||
pub description: Option<Patch<String>>,
|
||||
pub content_type: Option<Patch<String>>,
|
||||
pub size_bytes: Option<i64>,
|
||||
pub execution: Option<Option<i64>>,
|
||||
pub data: Option<serde_json::Value>,
|
||||
pub execution: Option<Patch<i64>>,
|
||||
pub data: Option<Patch<serde_json::Value>>,
|
||||
}
|
||||
|
||||
/// Filters for searching artifacts
|
||||
@@ -186,20 +186,62 @@ impl Update for ArtifactRepository {
|
||||
push_field!(input.visibility, "visibility");
|
||||
push_field!(input.retention_policy, "retention_policy");
|
||||
push_field!(input.retention_limit, "retention_limit");
|
||||
push_field!(&input.name, "name");
|
||||
push_field!(&input.description, "description");
|
||||
push_field!(&input.content_type, "content_type");
|
||||
if let Some(name) = &input.name {
|
||||
if has_updates {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("name = ");
|
||||
match name {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
if let Some(description) = &input.description {
|
||||
if has_updates {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("description = ");
|
||||
match description {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
if let Some(content_type) = &input.content_type {
|
||||
if has_updates {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("content_type = ");
|
||||
match content_type {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
push_field!(input.size_bytes, "size_bytes");
|
||||
// execution is Option<Option<i64>> — outer Option = "was field provided?",
|
||||
// inner Option = nullable column value
|
||||
if let Some(exec_val) = input.execution {
|
||||
if has_updates {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("execution = ").push_bind(exec_val);
|
||||
query.push("execution = ");
|
||||
match exec_val {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<i64>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
if let Some(data) = &input.data {
|
||||
if has_updates {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("data = ");
|
||||
match data {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<serde_json::Value>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
push_field!(&input.data, "data");
|
||||
|
||||
if !has_updates {
|
||||
return Self::get_by_id(executor, id).await;
|
||||
|
||||
@@ -66,6 +66,14 @@ pub use runtime_version::RuntimeVersionRepository;
|
||||
pub use trigger::{SensorRepository, TriggerRepository};
|
||||
pub use workflow::{WorkflowDefinitionRepository, WorkflowExecutionRepository};
|
||||
|
||||
/// Explicit patch operation for update inputs where callers must distinguish
|
||||
/// between "leave unchanged", "set value", and "clear to NULL".
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Patch<T> {
|
||||
Set(T),
|
||||
Clear,
|
||||
}
|
||||
|
||||
/// Type alias for database connection/transaction
|
||||
pub type DbConnection<'c> = &'c mut Transaction<'c, Postgres>;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::models::{pack::Pack, JsonDict, JsonSchema};
|
||||
use crate::{Error, Result};
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Pagination, Repository, Update};
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Pagination, Patch, Repository, Update};
|
||||
|
||||
/// Repository for Pack operations
|
||||
pub struct PackRepository;
|
||||
@@ -40,7 +40,7 @@ pub struct CreatePackInput {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct UpdatePackInput {
|
||||
pub label: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub description: Option<Patch<String>>,
|
||||
pub version: Option<String>,
|
||||
pub conf_schema: Option<JsonSchema>,
|
||||
pub config: Option<JsonDict>,
|
||||
@@ -186,7 +186,10 @@ impl Update for PackRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("description = ");
|
||||
query.push_bind(description);
|
||||
match description {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::models::{
|
||||
use crate::Result;
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Repository, Update};
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Patch, Repository, Update};
|
||||
|
||||
/// Repository for Runtime operations
|
||||
pub struct RuntimeRepository;
|
||||
@@ -39,10 +39,10 @@ pub struct CreateRuntimeInput {
|
||||
/// Input for updating a runtime
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct UpdateRuntimeInput {
|
||||
pub description: Option<String>,
|
||||
pub description: Option<Patch<String>>,
|
||||
pub name: Option<String>,
|
||||
pub distributions: Option<JsonDict>,
|
||||
pub installation: Option<JsonDict>,
|
||||
pub installation: Option<Patch<JsonDict>>,
|
||||
pub execution_config: Option<JsonDict>,
|
||||
}
|
||||
|
||||
@@ -163,7 +163,10 @@ impl Update for RuntimeRepository {
|
||||
|
||||
if let Some(description) = &input.description {
|
||||
query.push("description = ");
|
||||
query.push_bind(description);
|
||||
match description {
|
||||
Patch::Set(description) => query.push_bind(description),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -190,7 +193,10 @@ impl Update for RuntimeRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("installation = ");
|
||||
query.push_bind(installation);
|
||||
match installation {
|
||||
Patch::Set(installation) => query.push_bind(installation),
|
||||
Patch::Clear => query.push_bind(Option::<JsonDict>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::models::{Id, RuntimeVersion};
|
||||
use crate::repositories::{Create, Delete, FindById, List, Repository, Update};
|
||||
use crate::repositories::{Create, Delete, FindById, List, Patch, Repository, Update};
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
/// Repository for runtime version database operations
|
||||
@@ -39,14 +39,14 @@ pub struct CreateRuntimeVersionInput {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct UpdateRuntimeVersionInput {
|
||||
pub version: Option<String>,
|
||||
pub version_major: Option<Option<i32>>,
|
||||
pub version_minor: Option<Option<i32>>,
|
||||
pub version_patch: Option<Option<i32>>,
|
||||
pub version_major: Option<Patch<i32>>,
|
||||
pub version_minor: Option<Patch<i32>>,
|
||||
pub version_patch: Option<Patch<i32>>,
|
||||
pub execution_config: Option<serde_json::Value>,
|
||||
pub distributions: Option<serde_json::Value>,
|
||||
pub is_default: Option<bool>,
|
||||
pub available: Option<bool>,
|
||||
pub verified_at: Option<Option<chrono::DateTime<chrono::Utc>>>,
|
||||
pub verified_at: Option<Patch<chrono::DateTime<chrono::Utc>>>,
|
||||
pub meta: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
@@ -154,7 +154,10 @@ impl Update for RuntimeVersionRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("version_major = ");
|
||||
query.push_bind(*version_major);
|
||||
match version_major {
|
||||
Patch::Set(value) => query.push_bind(*value),
|
||||
Patch::Clear => query.push_bind(Option::<i32>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -163,7 +166,10 @@ impl Update for RuntimeVersionRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("version_minor = ");
|
||||
query.push_bind(*version_minor);
|
||||
match version_minor {
|
||||
Patch::Set(value) => query.push_bind(*value),
|
||||
Patch::Clear => query.push_bind(Option::<i32>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -172,7 +178,10 @@ impl Update for RuntimeVersionRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("version_patch = ");
|
||||
query.push_bind(*version_patch);
|
||||
match version_patch {
|
||||
Patch::Set(value) => query.push_bind(*value),
|
||||
Patch::Clear => query.push_bind(Option::<i32>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -217,7 +226,10 @@ impl Update for RuntimeVersionRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("verified_at = ");
|
||||
query.push_bind(*verified_at);
|
||||
match verified_at {
|
||||
Patch::Set(value) => query.push_bind(*value),
|
||||
Patch::Clear => query.push_bind(Option::<chrono::DateTime<chrono::Utc>>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use crate::Result;
|
||||
use serde_json::Value as JsonValue;
|
||||
use sqlx::{Executor, Postgres, QueryBuilder};
|
||||
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Repository, Update};
|
||||
use super::{Create, Delete, FindById, FindByRef, List, Patch, Repository, Update};
|
||||
|
||||
// ============================================================================
|
||||
// Trigger Search
|
||||
@@ -88,10 +88,10 @@ pub struct CreateTriggerInput {
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct UpdateTriggerInput {
|
||||
pub label: Option<String>,
|
||||
pub description: Option<String>,
|
||||
pub description: Option<Patch<String>>,
|
||||
pub enabled: Option<bool>,
|
||||
pub param_schema: Option<JsonSchema>,
|
||||
pub out_schema: Option<JsonSchema>,
|
||||
pub param_schema: Option<Patch<JsonSchema>>,
|
||||
pub out_schema: Option<Patch<JsonSchema>>,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
@@ -229,7 +229,10 @@ impl Update for TriggerRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("description = ");
|
||||
query.push_bind(description);
|
||||
match description {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -247,7 +250,10 @@ impl Update for TriggerRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("param_schema = ");
|
||||
query.push_bind(param_schema);
|
||||
match param_schema {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<JsonSchema>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -256,7 +262,10 @@ impl Update for TriggerRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("out_schema = ");
|
||||
query.push_bind(out_schema);
|
||||
match out_schema {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<JsonSchema>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -676,11 +685,11 @@ pub struct UpdateSensorInput {
|
||||
pub entrypoint: Option<String>,
|
||||
pub runtime: Option<Id>,
|
||||
pub runtime_ref: Option<String>,
|
||||
pub runtime_version_constraint: Option<Option<String>>,
|
||||
pub runtime_version_constraint: Option<Patch<String>>,
|
||||
pub trigger: Option<Id>,
|
||||
pub trigger_ref: Option<String>,
|
||||
pub enabled: Option<bool>,
|
||||
pub param_schema: Option<JsonSchema>,
|
||||
pub param_schema: Option<Patch<JsonSchema>>,
|
||||
pub config: Option<JsonValue>,
|
||||
}
|
||||
|
||||
@@ -866,7 +875,10 @@ impl Update for SensorRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("runtime_version_constraint = ");
|
||||
query.push_bind(runtime_version_constraint);
|
||||
match runtime_version_constraint {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<String>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
@@ -893,7 +905,10 @@ impl Update for SensorRepository {
|
||||
query.push(", ");
|
||||
}
|
||||
query.push("param_schema = ");
|
||||
query.push_bind(param_schema);
|
||||
match param_schema {
|
||||
Patch::Set(value) => query.push_bind(value),
|
||||
Patch::Clear => query.push_bind(Option::<JsonSchema>::None),
|
||||
};
|
||||
has_updates = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user