added setup strict mode

This commit is contained in:
2026-04-03 00:29:44 -04:00
parent 5c1779651c
commit 776a442374
5 changed files with 53 additions and 32 deletions

View File

@ -38,7 +38,7 @@ pub struct Database {
}
impl Database {
pub fn new(val: &serde_json::Value) -> Result<Self, crate::drop::Drop> {
pub fn new(val: &serde_json::Value) -> (Self, crate::drop::Drop) {
let mut db = Self {
enums: HashMap::new(),
types: HashMap::new(),
@ -151,10 +151,12 @@ impl Database {
}
db.compile(&mut errors);
if !errors.is_empty() {
return Err(crate::drop::Drop::with_errors(errors));
}
Ok(db)
let drop = if errors.is_empty() {
crate::drop::Drop::success()
} else {
crate::drop::Drop::with_errors(errors)
};
(db, drop)
}
/// Override the default executor for unit testing

View File

@ -588,6 +588,8 @@ impl Schema {
prop_name,
Some(&keys_for_ambiguity),
is_array,
self.id.as_deref(),
&format!("/{}", prop_name),
errors,
) {
schema_edges.insert(
@ -617,6 +619,8 @@ pub(crate) fn resolve_relation<'a>(
prop_name: &str,
relative_keys: Option<&Vec<String>>,
is_array: bool,
schema_id: Option<&str>,
path: &str,
errors: &mut Vec<crate::drop::Error>,
) -> Option<(&'a crate::database::relation::Relation, bool)> {
// Enforce graph locality by ensuring we don't accidentally crawl to pure structural entity boundaries
@ -661,13 +665,21 @@ pub(crate) fn resolve_relation<'a>(
// Abort relation discovery early if no hierarchical inheritance match was found
if matching_rels.is_empty() {
let mut details = crate::drop::ErrorDetails {
path: path.to_string(),
..Default::default()
};
if let Some(sid) = schema_id {
details.schema = Some(sid.to_string());
}
errors.push(crate::drop::Error {
code: "EDGE_MISSING".to_string(),
message: format!(
"No database relation exists between '{}' and '{}' for property '{}'",
parent_type, child_type, prop_name
),
details: crate::drop::ErrorDetails::default(),
details,
});
return None;
}
@ -752,13 +764,21 @@ pub(crate) fn resolve_relation<'a>(
// we must abort rather than silently guessing. Returning None prevents arbitrary SQL generation
// and forces a clean structural error for the architect.
if !resolved {
let mut details = crate::drop::ErrorDetails {
path: path.to_string(),
..Default::default()
};
if let Some(sid) = schema_id {
details.schema = Some(sid.to_string());
}
errors.push(crate::drop::Error {
code: "AMBIGUOUS_TYPE_RELATIONS".to_string(),
message: format!(
"Ambiguous database relation between '{}' and '{}' for property '{}'",
parent_type, child_type, prop_name
),
details: crate::drop::ErrorDetails::default(),
details,
});
return None;
}

View File

@ -12,18 +12,21 @@ pub struct Jspg {
}
impl Jspg {
pub fn new(database_val: &serde_json::Value) -> Result<Self, crate::drop::Drop> {
let database_instance = Database::new(database_val)?;
pub fn new(database_val: &serde_json::Value) -> (Self, crate::drop::Drop) {
let (database_instance, drop) = Database::new(database_val);
let database = Arc::new(database_instance);
let validator = Validator::new(database.clone());
let queryer = Queryer::new(database.clone());
let merger = Merger::new(database.clone());
Ok(Self {
database,
validator,
queryer,
merger,
})
(
Self {
database,
validator,
queryer,
merger,
},
drop,
)
}
}

View File

@ -42,21 +42,16 @@ fn jspg_failure() -> JsonB {
#[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);
let (new_jspg, drop) = 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();
JsonB(serde_json::to_value(drop).unwrap())
}
Err(drop) => JsonB(serde_json::to_value(drop).unwrap()),
// 3. ATOMIC SWAP
{
let mut lock = GLOBAL_JSPG.write().unwrap();
*lock = Some(new_arc);
}
JsonB(serde_json::to_value(drop).unwrap())
}
#[cfg_attr(not(test), pg_extern)]

View File

@ -42,10 +42,11 @@ fn get_cached_file(path: &str) -> CompiledSuite {
let mut compiled_suites = Vec::new();
for suite in suites {
let db_result = crate::database::Database::new(&suite.database);
let compiled_db = match db_result {
Ok(db) => Ok(Arc::new(db)),
Err(drop) => Err(drop),
let (db, drop) = crate::database::Database::new(&suite.database);
let compiled_db = if drop.errors.is_empty() {
Ok(Arc::new(db))
} else {
Err(drop)
};
compiled_suites.push((suite, Arc::new(compiled_db)));
}