queryer merger test progress
This commit is contained in:
183
src/lib.rs
183
src/lib.rs
@ -1,7 +1,12 @@
|
||||
#[cfg(not(test))]
|
||||
use pgrx::*;
|
||||
|
||||
#[cfg(not(test))]
|
||||
pg_module_magic!();
|
||||
|
||||
#[cfg(test)]
|
||||
pub struct JsonB(pub serde_json::Value);
|
||||
|
||||
pub mod database;
|
||||
pub mod drop;
|
||||
pub mod jspg;
|
||||
@ -20,22 +25,38 @@ lazy_static::lazy_static! {
|
||||
static ref GLOBAL_JSPG: RwLock<Option<Arc<jspg::Jspg>>> = RwLock::new(None);
|
||||
}
|
||||
|
||||
#[pg_extern(strict)]
|
||||
pub fn jspg_setup(database: JsonB) -> JsonB {
|
||||
let new_jspg = crate::jspg::Jspg::new(&database.0);
|
||||
let new_arc = Arc::new(new_jspg);
|
||||
|
||||
// 3. ATOMIC SWAP
|
||||
{
|
||||
let mut lock = GLOBAL_JSPG.write().unwrap();
|
||||
*lock = Some(new_arc);
|
||||
}
|
||||
|
||||
let drop = crate::drop::Drop::success();
|
||||
fn jspg_failure() -> JsonB {
|
||||
let error = crate::drop::Error {
|
||||
code: "ENGINE_NOT_INITIALIZED".to_string(),
|
||||
message: "JSPG extension has not been initialized via jspg_setup".to_string(),
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: "".to_string(),
|
||||
},
|
||||
};
|
||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
|
||||
#[pg_extern]
|
||||
#[cfg_attr(not(test), pg_extern(strict))]
|
||||
pub fn jspg_setup(database: JsonB) -> JsonB {
|
||||
match crate::jspg::Jspg::new(&database.0) {
|
||||
Ok(new_jspg) => {
|
||||
let new_arc = Arc::new(new_jspg);
|
||||
|
||||
// 3. ATOMIC SWAP
|
||||
{
|
||||
let mut lock = GLOBAL_JSPG.write().unwrap();
|
||||
*lock = Some(new_arc);
|
||||
}
|
||||
|
||||
let drop = crate::drop::Drop::success();
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
Err(drop) => JsonB(serde_json::to_value(drop).unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(not(test), pg_extern)]
|
||||
pub fn jspg_merge(data: JsonB) -> JsonB {
|
||||
// Try to acquire a read lock to get a clone of the Engine Arc
|
||||
let engine_opt = {
|
||||
@ -44,35 +65,15 @@ pub fn jspg_merge(data: JsonB) -> JsonB {
|
||||
};
|
||||
|
||||
match engine_opt {
|
||||
Some(engine) => match engine.merger.merge(data.0) {
|
||||
Ok(result) => JsonB(result),
|
||||
Err(e) => {
|
||||
let error = crate::drop::Error {
|
||||
code: "MERGE_FAILED".to_string(),
|
||||
message: e,
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: "".to_string(),
|
||||
},
|
||||
};
|
||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let error = crate::drop::Error {
|
||||
code: "VALIDATOR_NOT_INITIALIZED".to_string(),
|
||||
message: "The JSPG database has not been cached yet. Run jspg_setup()".to_string(),
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: "".to_string(),
|
||||
},
|
||||
};
|
||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||
Some(engine) => {
|
||||
let drop = engine.merger.merge(data.0);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
None => jspg_failure(),
|
||||
}
|
||||
}
|
||||
|
||||
#[pg_extern]
|
||||
#[cfg_attr(not(test), pg_extern)]
|
||||
pub fn jspg_query(schema_id: &str, stem: Option<&str>, filters: Option<JsonB>) -> JsonB {
|
||||
let engine_opt = {
|
||||
let lock = GLOBAL_JSPG.read().unwrap();
|
||||
@ -80,38 +81,19 @@ pub fn jspg_query(schema_id: &str, stem: Option<&str>, filters: Option<JsonB>) -
|
||||
};
|
||||
|
||||
match engine_opt {
|
||||
Some(engine) => match engine
|
||||
.queryer
|
||||
.query(schema_id, stem, filters.as_ref().map(|f| &f.0))
|
||||
{
|
||||
Ok(res) => JsonB(res),
|
||||
Err(e) => {
|
||||
let error = crate::drop::Error {
|
||||
code: "QUERY_FAILED".to_string(),
|
||||
message: e,
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: schema_id.to_string(),
|
||||
},
|
||||
};
|
||||
JsonB(serde_json::to_value(crate::drop::Drop::with_errors(vec![error])).unwrap())
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let error = crate::drop::Error {
|
||||
code: "ENGINE_NOT_INITIALIZED".to_string(),
|
||||
message: "JSPG extension has not been initialized via jspg_setup".to_string(),
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: "".to_string(),
|
||||
},
|
||||
};
|
||||
JsonB(serde_json::to_value(crate::drop::Drop::with_errors(vec![error])).unwrap())
|
||||
Some(engine) => {
|
||||
let drop = engine
|
||||
.queryer
|
||||
.query(schema_id, stem, filters.as_ref().map(|f| &f.0));
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
None => jspg_failure(),
|
||||
}
|
||||
}
|
||||
|
||||
// `mask_json_schema` has been removed as the mask architecture is fully replaced by Spi string queries during DB interactions.
|
||||
|
||||
#[pg_extern(strict, parallel_safe)]
|
||||
#[cfg_attr(not(test), pg_extern(strict, parallel_safe))]
|
||||
pub fn jspg_validate(schema_id: &str, instance: JsonB) -> JsonB {
|
||||
// 1. Acquire Snapshot
|
||||
let jspg_arc = {
|
||||
@ -121,50 +103,17 @@ pub fn jspg_validate(schema_id: &str, instance: JsonB) -> JsonB {
|
||||
|
||||
// 2. Validate (Lock-Free)
|
||||
if let Some(engine) = jspg_arc {
|
||||
match engine.validator.validate(schema_id, &instance.0) {
|
||||
Ok(result) => {
|
||||
if result.is_valid() {
|
||||
let drop = crate::drop::Drop::success();
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
} else {
|
||||
let errors: Vec<crate::drop::Error> = result
|
||||
.errors
|
||||
.into_iter()
|
||||
.map(|e| crate::drop::Error {
|
||||
code: e.code,
|
||||
message: e.message,
|
||||
details: crate::drop::ErrorDetails { path: e.path },
|
||||
})
|
||||
.collect();
|
||||
let drop = crate::drop::Drop::with_errors(errors);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
let error = crate::drop::Error {
|
||||
code: e.code,
|
||||
message: e.message,
|
||||
details: crate::drop::ErrorDetails { path: e.path },
|
||||
};
|
||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let error = crate::drop::Error {
|
||||
code: "VALIDATOR_NOT_INITIALIZED".to_string(),
|
||||
message: "The JSPG database has not been cached yet. Run jspg_setup()".to_string(),
|
||||
details: crate::drop::ErrorDetails {
|
||||
path: "".to_string(),
|
||||
},
|
||||
};
|
||||
let drop = crate::drop::Drop::with_errors(vec![error]);
|
||||
let drop = engine.validator.validate(schema_id, &instance.0);
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
} else {
|
||||
jspg_failure()
|
||||
}
|
||||
}
|
||||
|
||||
#[pg_extern]
|
||||
pub fn jspg_get_punc_stems(punc_name: &str) -> JsonB {
|
||||
#[cfg_attr(not(test), pg_extern)]
|
||||
pub fn jspg_stems() -> JsonB {
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
let engine_opt = {
|
||||
let lock = GLOBAL_JSPG.read().unwrap();
|
||||
lock.clone()
|
||||
@ -172,17 +121,13 @@ pub fn jspg_get_punc_stems(punc_name: &str) -> JsonB {
|
||||
|
||||
match engine_opt {
|
||||
Some(engine) => {
|
||||
if let Some(punc) = engine.database.puncs.get(punc_name) {
|
||||
JsonB(serde_json::to_value(&punc.stems).unwrap_or(serde_json::Value::Array(vec![])))
|
||||
} else {
|
||||
JsonB(serde_json::Value::Array(vec![]))
|
||||
}
|
||||
JsonB(serde_json::to_value(&engine.database.stems).unwrap_or(Value::Object(Map::new())))
|
||||
}
|
||||
None => JsonB(serde_json::Value::Array(vec![])),
|
||||
None => JsonB(Value::Object(Map::new())),
|
||||
}
|
||||
}
|
||||
|
||||
#[pg_extern(strict)]
|
||||
#[cfg_attr(not(test), pg_extern(strict))]
|
||||
pub fn jspg_teardown() -> JsonB {
|
||||
let mut lock = GLOBAL_JSPG.write().unwrap();
|
||||
*lock = None;
|
||||
@ -190,21 +135,5 @@ pub fn jspg_teardown() -> JsonB {
|
||||
JsonB(serde_json::to_value(drop).unwrap())
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "pg_test"))]
|
||||
#[pg_schema]
|
||||
mod tests {
|
||||
use pgrx::prelude::*;
|
||||
include!("tests/fixtures.rs");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub mod pg_test {
|
||||
pub fn setup(_options: Vec<&str>) {
|
||||
// perform any initialization common to all tests
|
||||
}
|
||||
|
||||
pub fn postgresql_conf_options() -> Vec<&'static str> {
|
||||
// return any postgresql.conf settings that are required for your tests
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
pub mod tests;
|
||||
|
||||
Reference in New Issue
Block a user