Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 473b087d97 | |||
| 6d6745d95d | |||
| 146efaa2d9 | |||
| d0294eec3f |
30
src/lib.rs
30
src/lib.rs
@ -5,7 +5,7 @@ use pgrx::*;
|
|||||||
pg_module_magic!();
|
pg_module_magic!();
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub struct JsonB(pub serde_json::Value);
|
pub struct Json(pub serde_json::Value);
|
||||||
|
|
||||||
pub mod database;
|
pub mod database;
|
||||||
pub mod drop;
|
pub mod drop;
|
||||||
@ -25,7 +25,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() -> JsonB {
|
fn jspg_failure() -> Json {
|
||||||
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,11 +37,11 @@ fn jspg_failure() -> JsonB {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), pg_extern(strict))]
|
#[cfg_attr(not(test), pg_extern(strict))]
|
||||||
pub fn jspg_setup(database: JsonB) -> JsonB {
|
pub fn jspg_setup(database: Json) -> Json {
|
||||||
let (new_jspg, drop) = crate::jspg::Jspg::new(&database.0);
|
let (new_jspg, drop) = crate::jspg::Jspg::new(&database.0);
|
||||||
let new_arc = Arc::new(new_jspg);
|
let new_arc = Arc::new(new_jspg);
|
||||||
|
|
||||||
@ -51,11 +51,11 @@ pub fn jspg_setup(database: JsonB) -> JsonB {
|
|||||||
*lock = Some(new_arc);
|
*lock = Some(new_arc);
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), pg_extern)]
|
#[cfg_attr(not(test), pg_extern)]
|
||||||
pub fn jspg_merge(schema_id: &str, data: JsonB) -> JsonB {
|
pub fn jspg_merge(schema_id: &str, data: Json) -> Json {
|
||||||
// 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();
|
||||||
@ -65,14 +65,14 @@ pub fn jspg_merge(schema_id: &str, data: JsonB) -> JsonB {
|
|||||||
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);
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
None => jspg_failure(),
|
None => jspg_failure(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), pg_extern)]
|
#[cfg_attr(not(test), pg_extern)]
|
||||||
pub fn jspg_query(schema_id: &str, filter: Option<JsonB>) -> JsonB {
|
pub fn jspg_query(schema_id: &str, filter: Option<Json>) -> Json {
|
||||||
let engine_opt = {
|
let engine_opt = {
|
||||||
let lock = GLOBAL_JSPG.read().unwrap();
|
let lock = GLOBAL_JSPG.read().unwrap();
|
||||||
lock.clone()
|
lock.clone()
|
||||||
@ -83,7 +83,7 @@ pub fn jspg_query(schema_id: &str, filter: Option<JsonB>) -> JsonB {
|
|||||||
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));
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
None => jspg_failure(),
|
None => jspg_failure(),
|
||||||
}
|
}
|
||||||
@ -92,7 +92,7 @@ pub fn jspg_query(schema_id: &str, filter: Option<JsonB>) -> JsonB {
|
|||||||
// `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: JsonB) -> JsonB {
|
pub fn jspg_validate(schema_id: &str, instance: Json) -> Json {
|
||||||
// 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,14 +102,14 @@ pub fn jspg_validate(schema_id: &str, instance: JsonB) -> JsonB {
|
|||||||
// 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);
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
} else {
|
} else {
|
||||||
jspg_failure()
|
jspg_failure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), pg_extern)]
|
#[cfg_attr(not(test), pg_extern)]
|
||||||
pub fn jspg_database() -> JsonB {
|
pub fn jspg_database() -> Json {
|
||||||
let engine_opt = {
|
let engine_opt = {
|
||||||
let lock = GLOBAL_JSPG.read().unwrap();
|
let lock = GLOBAL_JSPG.read().unwrap();
|
||||||
lock.clone()
|
lock.clone()
|
||||||
@ -120,18 +120,18 @@ pub fn jspg_database() -> JsonB {
|
|||||||
let database_json = serde_json::to_value(&engine.database)
|
let database_json = serde_json::to_value(&engine.database)
|
||||||
.unwrap_or(serde_json::Value::Object(serde_json::Map::new()));
|
.unwrap_or(serde_json::Value::Object(serde_json::Map::new()));
|
||||||
let drop = crate::drop::Drop::success_with_val(database_json);
|
let drop = crate::drop::Drop::success_with_val(database_json);
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
None => jspg_failure(),
|
None => jspg_failure(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(test), pg_extern(strict))]
|
#[cfg_attr(not(test), pg_extern(strict))]
|
||||||
pub fn jspg_teardown() -> JsonB {
|
pub fn jspg_teardown() -> Json {
|
||||||
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();
|
||||||
JsonB(serde_json::to_value(drop).unwrap())
|
Json(serde_json::to_value(drop).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@ -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", JsonB(json!({})));
|
let uninitialized_drop = jspg_validate("source_schema", Json(json!({})));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
uninitialized_drop.0,
|
uninitialized_drop.0,
|
||||||
json!({
|
json!({
|
||||||
@ -73,7 +73,7 @@ fn test_library_api() {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
let cache_drop = jspg_setup(JsonB(db_json));
|
let cache_drop = jspg_setup(Json(db_json));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
cache_drop.0,
|
cache_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", JsonB(json!({"type": "source_schema", "name": "Neo"})));
|
let happy_drop = jspg_validate("source_schema", Json(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", JsonB(json!({"type": "source_schema", "wrong": "data"})));
|
let unhappy_drop = jspg_validate("source_schema", Json(json!({"type": "source_schema", "wrong": "data"})));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unhappy_drop.0,
|
unhappy_drop.0,
|
||||||
json!({
|
json!({
|
||||||
|
|||||||
Reference in New Issue
Block a user