fixed more filtering issues and promoted enum condition generation
This commit is contained in:
87
src/database/compile/condition.rs
Normal file
87
src/database/compile/condition.rs
Normal file
@ -0,0 +1,87 @@
|
||||
use crate::database::object::{SchemaObject, SchemaTypeOrArray};
|
||||
use crate::database::schema::Schema;
|
||||
use crate::database::r#enum::Enum;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
impl Enum {
|
||||
pub fn compile_condition(&self) -> Schema {
|
||||
let mut props = BTreeMap::new();
|
||||
let enum_name = &self.name;
|
||||
|
||||
let mut eq_obj = SchemaObject::default();
|
||||
eq_obj.type_ = Some(SchemaTypeOrArray::Multiple(vec![
|
||||
enum_name.clone(),
|
||||
"null".to_string(),
|
||||
]));
|
||||
props.insert(
|
||||
"$eq".to_string(),
|
||||
Arc::new(Schema {
|
||||
obj: eq_obj,
|
||||
always_fail: false,
|
||||
}),
|
||||
);
|
||||
|
||||
let mut ne_obj = SchemaObject::default();
|
||||
ne_obj.type_ = Some(SchemaTypeOrArray::Multiple(vec![
|
||||
enum_name.clone(),
|
||||
"null".to_string(),
|
||||
]));
|
||||
props.insert(
|
||||
"$ne".to_string(),
|
||||
Arc::new(Schema {
|
||||
obj: ne_obj,
|
||||
always_fail: false,
|
||||
}),
|
||||
);
|
||||
|
||||
let mut of_obj = SchemaObject::default();
|
||||
of_obj.type_ = Some(SchemaTypeOrArray::Multiple(vec![
|
||||
"array".to_string(),
|
||||
"null".to_string(),
|
||||
]));
|
||||
of_obj.items = Some(Arc::new(Schema {
|
||||
obj: SchemaObject {
|
||||
type_: Some(SchemaTypeOrArray::Single(enum_name.clone())),
|
||||
..Default::default()
|
||||
},
|
||||
always_fail: false,
|
||||
}));
|
||||
props.insert(
|
||||
"$of".to_string(),
|
||||
Arc::new(Schema {
|
||||
obj: of_obj,
|
||||
always_fail: false,
|
||||
}),
|
||||
);
|
||||
|
||||
let mut nof_obj = SchemaObject::default();
|
||||
nof_obj.type_ = Some(SchemaTypeOrArray::Multiple(vec![
|
||||
"array".to_string(),
|
||||
"null".to_string(),
|
||||
]));
|
||||
nof_obj.items = Some(Arc::new(Schema {
|
||||
obj: SchemaObject {
|
||||
type_: Some(SchemaTypeOrArray::Single(enum_name.clone())),
|
||||
..Default::default()
|
||||
},
|
||||
always_fail: false,
|
||||
}));
|
||||
props.insert(
|
||||
"$nof".to_string(),
|
||||
Arc::new(Schema {
|
||||
obj: nof_obj,
|
||||
always_fail: false,
|
||||
}),
|
||||
);
|
||||
|
||||
let mut cond_obj = SchemaObject::default();
|
||||
cond_obj.type_ = Some(SchemaTypeOrArray::Single("condition".to_string()));
|
||||
cond_obj.properties = Some(props);
|
||||
|
||||
Schema {
|
||||
obj: cond_obj,
|
||||
always_fail: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,7 +42,7 @@ impl Schema {
|
||||
key.clone(),
|
||||
Arc::new(inline_schema),
|
||||
);
|
||||
} else if let Some(mut filter_type) = Self::resolve_filter_type(child) {
|
||||
} else if let Some(mut filter_type) = Self::resolve_filter_type(child, _db) {
|
||||
filter_type.push("null".to_string());
|
||||
|
||||
let mut child_obj = SchemaObject::default();
|
||||
@ -117,16 +117,16 @@ impl Schema {
|
||||
None
|
||||
}
|
||||
|
||||
fn resolve_filter_type(schema: &Arc<Schema>) -> Option<Vec<String>> {
|
||||
fn resolve_filter_type(schema: &Arc<Schema>, db: &Database) -> Option<Vec<String>> {
|
||||
if let Some(type_) = &schema.obj.type_ {
|
||||
match type_ {
|
||||
SchemaTypeOrArray::Single(t) => {
|
||||
return Self::map_filter_string(t, schema);
|
||||
return Self::map_filter_string(t, schema, db);
|
||||
}
|
||||
SchemaTypeOrArray::Multiple(types) => {
|
||||
for t in types {
|
||||
if t != "null" {
|
||||
return Self::map_filter_string(t, schema);
|
||||
return Self::map_filter_string(t, schema, db);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,7 +135,7 @@ impl Schema {
|
||||
None
|
||||
}
|
||||
|
||||
fn map_filter_string(t: &str, schema: &Arc<Schema>) -> Option<Vec<String>> {
|
||||
fn map_filter_string(t: &str, schema: &Arc<Schema>, db: &Database) -> Option<Vec<String>> {
|
||||
match t {
|
||||
"string" => {
|
||||
if let Some(fmt) = &schema.obj.format {
|
||||
@ -151,14 +151,18 @@ impl Schema {
|
||||
"object" => None, // Inline structures are ignored in Composed References
|
||||
"array" => {
|
||||
if let Some(items) = &schema.obj.items {
|
||||
return Self::resolve_filter_type(items);
|
||||
return Self::resolve_filter_type(items, db);
|
||||
}
|
||||
None
|
||||
},
|
||||
"null" => None,
|
||||
custom => {
|
||||
// Assume anything else is a Relational cross-boundary that already has its own .filter dynamically built
|
||||
Some(vec![format!("{}.filter", custom)])
|
||||
if db.enums.contains_key(custom) {
|
||||
Some(vec![format!("{}.condition", custom)])
|
||||
} else {
|
||||
// Assume anything else is a Relational cross-boundary that already has its own .filter dynamically built
|
||||
Some(vec![format!("{}.filter", custom)])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
pub mod collection;
|
||||
pub mod condition;
|
||||
pub mod edges;
|
||||
pub mod filter;
|
||||
pub mod polymorphism;
|
||||
|
||||
@ -191,9 +191,10 @@ impl Database {
|
||||
}
|
||||
|
||||
pub fn compile(&mut self, errors: &mut Vec<crate::drop::Error>) {
|
||||
// Phase 1: Registration
|
||||
self.collect_schemas(errors);
|
||||
|
||||
// Formally evaluate properties with strict 3-pass Ordered Graph execution natively
|
||||
// Phase 2: Formally evaluate properties with strict 3-pass Ordered Graph execution natively
|
||||
for (_, enum_def) in &self.enums {
|
||||
for (schema_id, schema_arc) in &enum_def.schemas {
|
||||
let root_id = schema_id.split('/').next().unwrap_or(schema_id);
|
||||
@ -219,7 +220,25 @@ impl Database {
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 2: Synthesize Composed Filter References
|
||||
// Phase 3: Synthesize Virtual Boundaries
|
||||
let mut compile_ids = self.compile_filters(errors);
|
||||
let mut condition_ids = self.compile_conditions();
|
||||
compile_ids.append(&mut condition_ids);
|
||||
|
||||
// Phase 4: Compile Virtual Boundaries
|
||||
// Now actively compile the newly injected schemas to lock all nested compose references natively
|
||||
for (_, id) in compile_ids {
|
||||
if let Some(schema_arc) = self.schemas.get(&id).cloned() {
|
||||
let root_id = id.split('/').next().unwrap_or(&id);
|
||||
schema_arc
|
||||
.as_ref()
|
||||
.compile(self, root_id, id.clone(), errors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Synthesizes Composed Filter References for all table-backed boundaries.
|
||||
fn compile_filters(&mut self, errors: &mut Vec<crate::drop::Error>) -> Vec<(String, String)> {
|
||||
let mut filter_schemas = Vec::new();
|
||||
for (type_name, type_def) in &self.types {
|
||||
for (id, schema_arc) in &type_def.schemas {
|
||||
@ -246,21 +265,30 @@ impl Database {
|
||||
t.schemas.insert(id, filter_arc);
|
||||
}
|
||||
}
|
||||
filter_ids
|
||||
}
|
||||
|
||||
// Now actively compile the newly injected filters to lock all nested compose references natively
|
||||
for (type_name, id) in filter_ids {
|
||||
if let Some(filter_arc) = self
|
||||
.types
|
||||
.get(&type_name)
|
||||
.and_then(|t| t.schemas.get(&id))
|
||||
.cloned()
|
||||
{
|
||||
let root_id = id.split('/').next().unwrap_or(&id);
|
||||
filter_arc
|
||||
.as_ref()
|
||||
.compile(self, root_id, id.clone(), errors);
|
||||
/// Synthesizes strong Enum Conditions mirroring the string.condition capabilities.
|
||||
fn compile_conditions(&mut self) -> Vec<(String, String)> {
|
||||
let mut enum_conditions = Vec::new();
|
||||
for (enum_name, enum_def) in &self.enums {
|
||||
let cond_schema = enum_def.compile_condition();
|
||||
enum_conditions.push((
|
||||
enum_name.clone(),
|
||||
format!("{}.condition", enum_name),
|
||||
Arc::new(cond_schema),
|
||||
));
|
||||
}
|
||||
|
||||
let mut condition_ids = Vec::new();
|
||||
for (enum_name, id, cond_arc) in enum_conditions {
|
||||
condition_ids.push((enum_name.clone(), id.clone()));
|
||||
self.schemas.insert(id.clone(), cond_arc.clone());
|
||||
if let Some(e) = self.enums.get_mut(&enum_name) {
|
||||
e.schemas.insert(id.clone(), cond_arc.clone());
|
||||
}
|
||||
}
|
||||
condition_ids
|
||||
}
|
||||
|
||||
fn collect_schemas(&mut self, errors: &mut Vec<crate::drop::Error>) {
|
||||
|
||||
Reference in New Issue
Block a user