use serde_json::Value;
use crate::schema::{Registry, Schema};
#[derive(Debug, Clone)]
pub(super) struct Join {
pub(super) rel_name: String,
pub(super) alias: String,
pub(super) model: String,
pub(super) local_col: String,
pub(super) foreign_col: String,
pub(super) one: bool,
pub(super) extra: Option<Value>,
pub(super) parent: Option<usize>,
pub(super) path: Vec<String>,
pub(super) ones: Vec<bool>,
pub(super) child_sort: Option<Value>,
pub(super) child_skip: Option<i64>,
pub(super) child_limit: Option<i64>,
}
pub(super) fn resolve_join(
schema: &Schema,
registry: &Registry,
alias: &str,
from: &str,
) -> Option<Join> {
let make = |name: &str, d: &crate::schema::RelationDef| Join {
rel_name: name.to_string(),
alias: alias.to_string(),
model: d.model.clone(),
local_col: d.local_field.clone(),
foreign_col: d.foreign_field.clone(),
one: d.rel_type == "one",
extra: None,
parent: None,
path: vec![name.to_string()],
ones: vec![d.rel_type == "one"],
child_sort: None,
child_skip: None,
child_limit: None,
};
if let Some((name, d)) = schema.relations.iter().find(|(n, _)| n.as_str() == alias) {
return Some(make(name, d));
}
schema.relations.iter().find_map(|(name, d)| {
let ok = d.model == from
|| registry
.get(&d.model)
.ok()
.map(|s| s.collection == from)
.unwrap_or(false);
if ok {
Some(make(name, d))
} else {
None
}
})
}