From 2dfb4e68e4ed90f1631c58d1ad1f1a8a8f921d8b Mon Sep 17 00:00:00 2001 From: Alex Groleau Date: Mon, 3 Aug 2026 15:00:03 -0400 Subject: [PATCH] fixed immutability effects in merger --- src/merger/mod.rs | 81 +++++++++++++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 27 deletions(-) diff --git a/src/merger/mod.rs b/src/merger/mod.rs index 7631795..d1bb73e 100644 --- a/src/merger/mod.rs +++ b/src/merger/mod.rs @@ -6,8 +6,8 @@ pub mod cache; use crate::database::Database; use crate::database::r#type::Type; use crate::drop::{Drop, Error, ErrorDetails}; -use serde_json::Value; use indexmap::IndexMap; +use serde_json::Value; use std::sync::Arc; pub struct Merger { @@ -31,9 +31,10 @@ impl Merger { None => { return Drop::with_errors(vec![Error { code: "SCHEMA_NOT_FOUND".to_string(), - values: Some(IndexMap::from([ - ("schema".to_string(), schema_id.to_string()), - ])), + values: Some(IndexMap::from([( + "schema".to_string(), + schema_id.to_string(), + )])), details: ErrorDetails { path: None, cause: None, @@ -56,9 +57,7 @@ impl Merger { if let Err(e) = self.db.execute(¬ify_sql, None) { return Drop::with_errors(vec![Error { code: "MERGE_FAILED".to_string(), - values: Some(IndexMap::from([ - ("error".to_string(), e.clone()), - ])), + values: Some(IndexMap::from([("error".to_string(), e.clone())])), details: ErrorDetails { path: None, cause: Some(e), @@ -121,9 +120,15 @@ impl Merger { } else { return Err(Error { code: "TARGET_SCHEMA_NOT_FOUND".to_string(), - values: Some(IndexMap::from([("target_id".to_string(), target_id.clone())])), + values: Some(IndexMap::from([( + "target_id".to_string(), + target_id.clone(), + )])), details: ErrorDetails { - cause: Some(format!("Polymorphic mapped target '{}' not found in database registry", target_id)), + cause: Some(format!( + "Polymorphic mapped target '{}' not found in database registry", + target_id + )), ..Default::default() }, }); @@ -141,7 +146,10 @@ impl Merger { code: "ONE_OF_INDEX_NOT_FOUND".to_string(), values: Some(IndexMap::from([("index".to_string(), idx.to_string())])), details: ErrorDetails { - cause: Some(format!("Polymorphic index target '{}' not found in local oneOf array", idx)), + cause: Some(format!( + "Polymorphic index target '{}' not found in local oneOf array", + idx + )), ..Default::default() }, }); @@ -164,7 +172,10 @@ impl Merger { ("value".to_string(), v.to_string()), ])), details: ErrorDetails { - cause: Some(format!("Polymorphic discriminator {}='{}' matched no compiled options", disc, v)), + cause: Some(format!( + "Polymorphic discriminator {}='{}' matched no compiled options", + disc, v + )), ..Default::default() }, }); @@ -172,9 +183,15 @@ impl Merger { } else { return Err(Error { code: "MISSING_DISCRIMINATOR".to_string(), - values: Some(IndexMap::from([("discriminator".to_string(), disc.to_string())])), + values: Some(IndexMap::from([( + "discriminator".to_string(), + disc.to_string(), + )])), details: ErrorDetails { - cause: Some(format!("Polymorphic merging failed: missing required discriminator '{}'", disc)), + cause: Some(format!( + "Polymorphic merging failed: missing required discriminator '{}'", + disc + )), ..Default::default() }, }); @@ -281,8 +298,6 @@ impl Merger { let mut entity_objects = std::collections::BTreeMap::new(); let mut entity_arrays = std::collections::BTreeMap::new(); - let is_external = self.db.executor.punc_external().unwrap_or(false); - for (k, v) in obj { // Always retain system and unmapped core fields natively implicitly mapped to the Postgres tables if k == "id" || k == "type" || k == "created" { @@ -291,12 +306,6 @@ impl Merger { } if let Some(prop_schema) = compiled_props.get(&k) { - if prop_schema.is_immutable(is_external) { - continue; - } - - - let mut is_edge = false; if let Some(edges) = schema.obj.compiled_edges.get() { if edges.contains_key(&k) { @@ -373,7 +382,10 @@ impl Merger { if let Some(deps) = &schema.obj.dependencies { if let Some(crate::database::object::Dependency::Props(req_props)) = deps.get("created") { for req in req_props { - if !entity_fields.contains_key(req) && !entity_objects.contains_key(req) && !entity_arrays.contains_key(req) { + if !entity_fields.contains_key(req) + && !entity_objects.contains_key(req) + && !entity_arrays.contains_key(req) + { return Err(Error { code: "REQUIRED_FIELD_MISSING".to_string(), values: Some(IndexMap::from([ @@ -382,7 +394,10 @@ impl Merger { ])), details: ErrorDetails { path: Some(req.to_string()), - cause: Some(format!("Missing required creation field '{}' for entity {}", req, type_name)), + cause: Some(format!( + "Missing required creation field '{}' for entity {}", + req, type_name + )), ..Default::default() }, }); @@ -829,9 +844,15 @@ impl Merger { if table.len() > 1 { Err(Error { code: "TOO_MANY_LOOKUP_ROWS".to_string(), - values: Some(IndexMap::from([("entity_type".to_string(), entity_type_name.to_string())])), + values: Some(IndexMap::from([( + "entity_type".to_string(), + entity_type_name.to_string(), + )])), details: ErrorDetails { - cause: Some(format!("Lookup for {} found too many existing rows", entity_type_name)), + cause: Some(format!( + "Lookup for {} found too many existing rows", + entity_type_name + )), ..Default::default() }, }) @@ -904,9 +925,15 @@ impl Merger { _ => { return Err(Error { code: "MISSING_GROUPED_FIELDS".to_string(), - values: Some(IndexMap::from([("type".to_string(), entity_type_name.to_string())])), + values: Some(IndexMap::from([( + "type".to_string(), + entity_type_name.to_string(), + )])), details: ErrorDetails { - cause: Some(format!("Grouped fields missing for type {}", entity_type_name)), + cause: Some(format!( + "Grouped fields missing for type {}", + entity_type_name + )), ..Default::default() }, });