more ordering fixes

This commit is contained in:
2026-05-14 17:35:31 -04:00
parent 473b087d97
commit 5b2feb5ea7
2 changed files with 33 additions and 14 deletions

View File

@ -4,6 +4,9 @@ use pgrx::*;
#[cfg(not(test))] #[cfg(not(test))]
pg_module_magic!(); pg_module_magic!();
#[cfg(test)]
pub struct JsonB(pub serde_json::Value);
#[cfg(test)] #[cfg(test)]
pub struct Json(pub serde_json::Value); pub struct Json(pub serde_json::Value);
@ -25,7 +28,7 @@ lazy_static::lazy_static! {
static ref GLOBAL_JSPG: RwLock<Option<Arc<jspg::Jspg>>> = RwLock::new(None); static ref GLOBAL_JSPG: RwLock<Option<Arc<jspg::Jspg>>> = RwLock::new(None);
} }
fn jspg_failure() -> Json { fn jspg_failure() -> JsonB {
let error = crate::drop::Error { let error = crate::drop::Error {
code: "ENGINE_NOT_INITIALIZED".to_string(), code: "ENGINE_NOT_INITIALIZED".to_string(),
message: "JSPG extension has not been initialized via jspg_setup".to_string(), message: "JSPG extension has not been initialized via jspg_setup".to_string(),
@ -37,7 +40,7 @@ fn jspg_failure() -> Json {
}, },
}; };
let drop = crate::drop::Drop::with_errors(vec![error]); let drop = crate::drop::Drop::with_errors(vec![error]);
Json(serde_json::to_value(drop).unwrap()) JsonB(serde_json::to_value(drop).unwrap())
} }
#[cfg_attr(not(test), pg_extern(strict))] #[cfg_attr(not(test), pg_extern(strict))]
@ -55,24 +58,40 @@ pub fn jspg_setup(database: Json) -> Json {
} }
#[cfg_attr(not(test), pg_extern)] #[cfg_attr(not(test), pg_extern)]
pub fn jspg_merge(schema_id: &str, data: Json) -> Json { pub fn jspg_merge(schema_id: &str, data: JsonB) -> JsonB {
// Try to acquire a read lock to get a clone of the Engine Arc // Try to acquire a read lock to get a clone of the Engine Arc
let engine_opt = { let engine_opt = {
let lock = GLOBAL_JSPG.read().unwrap(); let lock = GLOBAL_JSPG.read().unwrap();
lock.clone() lock.clone()
}; };
match engine_opt {
Some(engine) => {
let drop = engine.merger.merge(schema_id, data.0);
JsonB(serde_json::to_value(drop).unwrap())
}
None => jspg_failure(),
}
}
#[cfg_attr(not(test), pg_extern)]
pub fn jspg_merge_ordered(schema_id: &str, data: Json) -> Json {
let engine_opt = {
let lock = GLOBAL_JSPG.read().unwrap();
lock.clone()
};
match engine_opt { match engine_opt {
Some(engine) => { Some(engine) => {
let drop = engine.merger.merge(schema_id, data.0); let drop = engine.merger.merge(schema_id, data.0);
Json(serde_json::to_value(drop).unwrap()) Json(serde_json::to_value(drop).unwrap())
} }
None => jspg_failure(), None => Json(jspg_failure().0),
} }
} }
#[cfg_attr(not(test), pg_extern)] #[cfg_attr(not(test), pg_extern)]
pub fn jspg_query(schema_id: &str, filter: Option<Json>) -> Json { pub fn jspg_query(schema_id: &str, filter: Option<JsonB>) -> JsonB {
let engine_opt = { let engine_opt = {
let lock = GLOBAL_JSPG.read().unwrap(); let lock = GLOBAL_JSPG.read().unwrap();
lock.clone() lock.clone()
@ -83,7 +102,7 @@ pub fn jspg_query(schema_id: &str, filter: Option<Json>) -> Json {
let drop = engine let drop = engine
.queryer .queryer
.query(schema_id, filter.as_ref().map(|f| &f.0)); .query(schema_id, filter.as_ref().map(|f| &f.0));
Json(serde_json::to_value(drop).unwrap()) JsonB(serde_json::to_value(drop).unwrap())
} }
None => jspg_failure(), None => jspg_failure(),
} }
@ -92,7 +111,7 @@ pub fn jspg_query(schema_id: &str, filter: Option<Json>) -> Json {
// `mask_json_schema` has been removed as the mask architecture is fully replaced by Spi string queries during DB interactions. // `mask_json_schema` has been removed as the mask architecture is fully replaced by Spi string queries during DB interactions.
#[cfg_attr(not(test), pg_extern(strict, parallel_safe))] #[cfg_attr(not(test), pg_extern(strict, parallel_safe))]
pub fn jspg_validate(schema_id: &str, instance: Json) -> Json { pub fn jspg_validate(schema_id: &str, instance: JsonB) -> JsonB {
// 1. Acquire Snapshot // 1. Acquire Snapshot
let jspg_arc = { let jspg_arc = {
let lock = GLOBAL_JSPG.read().unwrap(); let lock = GLOBAL_JSPG.read().unwrap();
@ -102,7 +121,7 @@ pub fn jspg_validate(schema_id: &str, instance: Json) -> Json {
// 2. Validate (Lock-Free) // 2. Validate (Lock-Free)
if let Some(engine) = jspg_arc { if let Some(engine) = jspg_arc {
let drop = engine.validator.validate(schema_id, &instance.0); let drop = engine.validator.validate(schema_id, &instance.0);
Json(serde_json::to_value(drop).unwrap()) JsonB(serde_json::to_value(drop).unwrap())
} else { } else {
jspg_failure() jspg_failure()
} }
@ -122,16 +141,16 @@ pub fn jspg_database() -> Json {
let drop = crate::drop::Drop::success_with_val(database_json); let drop = crate::drop::Drop::success_with_val(database_json);
Json(serde_json::to_value(drop).unwrap()) Json(serde_json::to_value(drop).unwrap())
} }
None => jspg_failure(), None => Json(jspg_failure().0),
} }
} }
#[cfg_attr(not(test), pg_extern(strict))] #[cfg_attr(not(test), pg_extern(strict))]
pub fn jspg_teardown() -> Json { pub fn jspg_teardown() -> JsonB {
let mut lock = GLOBAL_JSPG.write().unwrap(); let mut lock = GLOBAL_JSPG.write().unwrap();
*lock = None; *lock = None;
let drop = crate::drop::Drop::success(); let drop = crate::drop::Drop::success();
Json(serde_json::to_value(drop).unwrap()) JsonB(serde_json::to_value(drop).unwrap())
} }
#[cfg(test)] #[cfg(test)]

View File

@ -11,7 +11,7 @@ fn test_library_api() {
// 1. Initially, schemas are not cached. // 1. Initially, schemas are not cached.
// Expected uninitialized drop format: errors + null response // Expected uninitialized drop format: errors + null response
let uninitialized_drop = jspg_validate("source_schema", Json(json!({}))); let uninitialized_drop = jspg_validate("source_schema", JsonB(json!({})));
assert_eq!( assert_eq!(
uninitialized_drop.0, uninitialized_drop.0,
json!({ json!({
@ -226,7 +226,7 @@ fn test_library_api() {
); );
// 4. Validate Happy Path // 4. Validate Happy Path
let happy_drop = jspg_validate("source_schema", Json(json!({"type": "source_schema", "name": "Neo"}))); let happy_drop = jspg_validate("source_schema", JsonB(json!({"type": "source_schema", "name": "Neo"})));
assert_eq!( assert_eq!(
happy_drop.0, happy_drop.0,
json!({ json!({
@ -236,7 +236,7 @@ fn test_library_api() {
); );
// 5. Validate Unhappy Path // 5. Validate Unhappy Path
let unhappy_drop = jspg_validate("source_schema", Json(json!({"type": "source_schema", "wrong": "data"}))); let unhappy_drop = jspg_validate("source_schema", JsonB(json!({"type": "source_schema", "wrong": "data"})));
assert_eq!( assert_eq!(
unhappy_drop.0, unhappy_drop.0,
json!({ json!({