jspg stabilized again
This commit is contained in:
@ -28,21 +28,12 @@ impl Schema {
|
||||
db: &crate::database::Database,
|
||||
root_id: &str,
|
||||
path: String,
|
||||
visited: &mut std::collections::HashSet<String>,
|
||||
errors: &mut Vec<crate::drop::Error>,
|
||||
) {
|
||||
if self.obj.compiled_properties.get().is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
if !visited.insert(t.clone()) {
|
||||
return; // Break cyclical resolution
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(format_str) = &self.obj.format {
|
||||
if let Some(fmt) = crate::database::formats::FORMATS.get(format_str.as_str()) {
|
||||
let _ = self
|
||||
@ -79,7 +70,7 @@ impl Schema {
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
if let Some(parent) = db.schemas.get(t) {
|
||||
parent.as_ref().compile(db, t, t.clone(), visited, errors);
|
||||
parent.as_ref().compile(db, t, t.clone(), errors);
|
||||
if let Some(p_props) = parent.obj.compiled_properties.get() {
|
||||
props.extend(p_props.clone());
|
||||
}
|
||||
@ -113,7 +104,7 @@ impl Schema {
|
||||
for t in types {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
if let Some(parent) = db.schemas.get(t) {
|
||||
parent.as_ref().compile(db, t, t.clone(), visited, errors);
|
||||
parent.as_ref().compile(db, t, t.clone(), errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -133,21 +124,21 @@ impl Schema {
|
||||
let _ = self.obj.compiled_property_names.set(names);
|
||||
|
||||
// 4. Compute Edges natively
|
||||
let schema_edges = self.compile_edges(db, root_id, &path, visited, &props, errors);
|
||||
let schema_edges = self.compile_edges(db, root_id, &path, &props, errors);
|
||||
let _ = self.obj.compiled_edges.set(schema_edges);
|
||||
|
||||
// 5. Build our inline children properties recursively NOW! (Depth-first search)
|
||||
if let Some(local_props) = &self.obj.properties {
|
||||
for (k, child) in local_props {
|
||||
child.compile(db, root_id, format!("{}/{}", path, k), visited, errors);
|
||||
child.compile(db, root_id, format!("{}/{}", path, k), errors);
|
||||
}
|
||||
}
|
||||
if let Some(items) = &self.obj.items {
|
||||
items.compile(db, root_id, format!("{}/items", path), visited, errors);
|
||||
items.compile(db, root_id, format!("{}/items", path), errors);
|
||||
}
|
||||
if let Some(pattern_props) = &self.obj.pattern_properties {
|
||||
for (k, child) in pattern_props {
|
||||
child.compile(db, root_id, format!("{}/{}", path, k), visited, errors);
|
||||
child.compile(db, root_id, format!("{}/{}", path, k), errors);
|
||||
}
|
||||
}
|
||||
if let Some(additional_props) = &self.obj.additional_properties {
|
||||
@ -155,7 +146,6 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/additionalProperties", path),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
@ -165,7 +155,6 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/oneOf/{}", path, i),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
@ -176,16 +165,15 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/prefixItems/{}", path, i),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(child) = &self.obj.not {
|
||||
child.compile(db, root_id, format!("{}/not", path), visited, errors);
|
||||
child.compile(db, root_id, format!("{}/not", path), errors);
|
||||
}
|
||||
if let Some(child) = &self.obj.contains {
|
||||
child.compile(db, root_id, format!("{}/contains", path), visited, errors);
|
||||
child.compile(db, root_id, format!("{}/contains", path), errors);
|
||||
}
|
||||
if let Some(cases) = &self.obj.cases {
|
||||
for (i, c) in cases.iter().enumerate() {
|
||||
@ -194,7 +182,6 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/cases/{}/when", path, i),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
@ -203,7 +190,6 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/cases/{}/then", path, i),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
@ -212,7 +198,6 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/cases/{}/else", path, i),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
}
|
||||
@ -220,12 +205,6 @@ impl Schema {
|
||||
}
|
||||
|
||||
self.compile_polymorphism(db, root_id, &path, errors);
|
||||
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
visited.remove(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Dynamically infers and compiles all structural database relationships between this Schema
|
||||
@ -237,7 +216,6 @@ impl Schema {
|
||||
db: &crate::database::Database,
|
||||
root_id: &str,
|
||||
path: &str,
|
||||
visited: &mut std::collections::HashSet<String>,
|
||||
props: &std::collections::BTreeMap<String, std::sync::Arc<Schema>>,
|
||||
errors: &mut Vec<crate::drop::Error>,
|
||||
) -> std::collections::BTreeMap<String, crate::database::edge::Edge> {
|
||||
@ -263,31 +241,11 @@ impl Schema {
|
||||
}
|
||||
}
|
||||
|
||||
if parent_type_name.is_none() {
|
||||
// 3. Absolute fallback for anonymous inline structures
|
||||
let base_type_name = root_id
|
||||
.split('.')
|
||||
.next_back()
|
||||
.unwrap_or(root_id)
|
||||
.to_string();
|
||||
if db.types.contains_key(&base_type_name) {
|
||||
parent_type_name = Some(base_type_name);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(p_type) = parent_type_name {
|
||||
// Proceed only if the resolved table physically exists within the Postgres Type hierarchy
|
||||
if let Some(type_def) = db.types.get(&p_type) {
|
||||
// Iterate over all discovered schema boundaries mapped inside the object
|
||||
for (prop_name, prop_schema) in props {
|
||||
if let Some(field_types_map) = type_def.field_types.as_ref().and_then(|v| v.as_object()) {
|
||||
if let Some(pg_type) = field_types_map.get(prop_name).and_then(|v| v.as_str()) {
|
||||
if pg_type == "json" || pg_type == "jsonb" {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut child_type_name = None;
|
||||
let mut target_schema = prop_schema.clone();
|
||||
let mut is_array = false;
|
||||
@ -325,6 +283,16 @@ impl Schema {
|
||||
}
|
||||
|
||||
if let Some(c_type) = child_type_name {
|
||||
// Skip edge compilation for JSONB columns — they store data inline, not relationally.
|
||||
// The physical column type from field_types is the single source of truth.
|
||||
if let Some(ft) = type_def.field_types.as_ref()
|
||||
.and_then(|v| v.get(prop_name.as_str()))
|
||||
.and_then(|v| v.as_str())
|
||||
{
|
||||
if ft == "jsonb" {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if db.types.contains_key(&c_type) {
|
||||
// Ensure the child Schema's AST has accurately compiled its own physical property keys so we can
|
||||
// inject them securely for Many-to-Many Twin Deduction disambiguation matching.
|
||||
@ -332,9 +300,9 @@ impl Schema {
|
||||
db,
|
||||
root_id,
|
||||
format!("{}/{}", path, prop_name),
|
||||
visited,
|
||||
errors,
|
||||
);
|
||||
|
||||
if let Some(compiled_target_props) = target_schema.obj.compiled_properties.get() {
|
||||
let keys_for_ambiguity: Vec<String> =
|
||||
compiled_target_props.keys().cloned().collect();
|
||||
|
||||
Reference in New Issue
Block a user