chore: JSPG Engine tuple decoupling and core routing optimizations
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
use crate::database::schema::Schema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::sync::OnceLock;
|
||||
use crate::database::schema::Schema;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Case {
|
||||
@ -19,9 +19,6 @@ pub struct Case {
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct SchemaObject {
|
||||
// Core Schema Keywords
|
||||
#[serde(rename = "$id")]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub id: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub description: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
@ -176,7 +173,7 @@ pub struct SchemaObject {
|
||||
#[serde(skip_deserializing)]
|
||||
#[serde(skip_serializing_if = "crate::database::object::is_once_lock_map_empty")]
|
||||
#[serde(serialize_with = "crate::database::object::serialize_once_lock")]
|
||||
pub compiled_options: OnceLock<BTreeMap<String, String>>,
|
||||
pub compiled_options: OnceLock<BTreeMap<String, (Option<usize>, Option<String>)>>,
|
||||
|
||||
#[serde(rename = "compiledEdges")]
|
||||
#[serde(skip_deserializing)]
|
||||
@ -275,93 +272,49 @@ pub fn is_primitive_type(t: &str) -> bool {
|
||||
}
|
||||
|
||||
impl SchemaObject {
|
||||
pub fn identifier(&self) -> Option<String> {
|
||||
if let Some(id) = &self.id {
|
||||
return Some(id.split('.').next_back().unwrap_or("").to_string());
|
||||
}
|
||||
if let Some(SchemaTypeOrArray::Single(t)) = &self.type_ {
|
||||
if !is_primitive_type(t) {
|
||||
return Some(t.split('.').next_back().unwrap_or("").to_string());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_discriminator_value(&self, dim: &str) -> Option<String> {
|
||||
pub fn get_discriminator_value(&self, dim: &str, schema_id: &str) -> Option<String> {
|
||||
let is_split = self
|
||||
.compiled_properties
|
||||
.get()
|
||||
.map_or(false, |p| p.contains_key("kind"));
|
||||
if let Some(id) = &self.id {
|
||||
if id.contains("light.person") || id.contains("light.organization") {
|
||||
println!(
|
||||
"[DEBUG SPLIT] ID: {}, dim: {}, is_split: {:?}, props: {:?}",
|
||||
id,
|
||||
dim,
|
||||
is_split,
|
||||
self
|
||||
.compiled_properties
|
||||
.get()
|
||||
.map(|p| p.keys().cloned().collect::<Vec<_>>())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(props) = self.compiled_properties.get() {
|
||||
if let Some(prop_schema) = props.get(dim) {
|
||||
if let Some(c) = &prop_schema.obj.const_ {
|
||||
if let Some(s) = c.as_str() {
|
||||
return Some(s.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(e) = &prop_schema.obj.enum_ {
|
||||
if e.len() == 1 {
|
||||
if let Some(s) = e[0].as_str() {
|
||||
return Some(s.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if dim == "kind" {
|
||||
if let Some(id) = &self.id {
|
||||
let base = id.split('/').last().unwrap_or(id);
|
||||
if let Some(idx) = base.rfind('.') {
|
||||
return Some(base[..idx].to_string());
|
||||
}
|
||||
}
|
||||
if let Some(SchemaTypeOrArray::Single(t)) = &self.type_ {
|
||||
if !is_primitive_type(t) {
|
||||
let base = t.split('/').last().unwrap_or(t);
|
||||
if let Some(idx) = base.rfind('.') {
|
||||
return Some(base[..idx].to_string());
|
||||
}
|
||||
}
|
||||
let base = schema_id.split('/').last().unwrap_or(schema_id);
|
||||
if let Some(idx) = base.rfind('.') {
|
||||
return Some(base[..idx].to_string());
|
||||
}
|
||||
}
|
||||
|
||||
if dim == "type" {
|
||||
if let Some(id) = &self.id {
|
||||
let base = id.split('/').last().unwrap_or(id);
|
||||
if is_split {
|
||||
return Some(base.split('.').next_back().unwrap_or(base).to_string());
|
||||
} else {
|
||||
return Some(base.to_string());
|
||||
}
|
||||
}
|
||||
if let Some(SchemaTypeOrArray::Single(t)) = &self.type_ {
|
||||
if !is_primitive_type(t) {
|
||||
let base = t.split('/').last().unwrap_or(t);
|
||||
if is_split {
|
||||
return Some(base.split('.').next_back().unwrap_or(base).to_string());
|
||||
} else {
|
||||
return Some(base.to_string());
|
||||
}
|
||||
}
|
||||
let base = schema_id.split('/').last().unwrap_or(schema_id);
|
||||
if is_split {
|
||||
return Some(base.split('.').next_back().unwrap_or(base).to_string());
|
||||
} else {
|
||||
return Some(base.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn requires_uuid_path(&self, db: &crate::database::Database) -> bool {
|
||||
// 1. Explicitly defines "id" either directly or via inheritance/extension?
|
||||
if self
|
||||
.compiled_properties
|
||||
.get()
|
||||
.map_or(false, |p| p.contains_key("id"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. Implicit table-backed rule: Does its $family boundary map directly to the global database catalog?
|
||||
if let Some(family) = &self.family {
|
||||
let base = family.split('.').next_back().unwrap_or(family);
|
||||
if db.types.contains_key(base) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user