use serde_json::Value;
use crate::computes::{
process_node, run_async_fns, select_async_fns, strip_dep_injected, FnRegistry, InjectInfo,
};
use crate::permission::Context;
use crate::pipeline::Ast;
use crate::schema::Registry;
fn postprocess_ast(postprocess: &Value) -> Result<Ast, String> {
let ast_v = postprocess
.get("ast")
.ok_or_else(|| "postprocess 缺少 ast".to_string())?;
Ast::from_value(ast_v)
}
pub fn prepare_query(
postprocess: &Value,
items: &mut [Value],
registry: &Registry,
fn_registry: Option<&dyn FnRegistry>,
ctx: Option<&Context>,
) -> Result<Vec<String>, String> {
if postprocess.is_null() {
return Ok(Vec::new());
}
let mut ast = postprocess_ast(postprocess)?;
let schema = registry.get(&ast.model)?;
for item in items.iter_mut() {
process_node(
item,
&mut ast.fields,
&mut ast.relations,
schema,
ctx,
registry,
fn_registry,
)?;
}
Ok(select_async_fns(schema, ctx)
.into_iter()
.map(|e| e.fn_ref)
.collect())
}
pub fn strip_query(postprocess: &Value, items: &mut [Value]) {
if postprocess.is_null() {
return;
}
if let Some(inj_v) = postprocess.get("inject") {
if !inj_v.is_null() {
let info = InjectInfo::from_value(inj_v);
strip_dep_injected(items, &info);
}
}
}
pub fn finalize_query(
postprocess: &Value,
items: &mut [Value],
registry: &Registry,
fn_registry: Option<&dyn FnRegistry>,
ctx: Option<&Context>,
) -> Result<(), String> {
if postprocess.is_null() {
return Ok(());
}
prepare_query(postprocess, items, registry, fn_registry, ctx)?;
let ast = postprocess_ast(postprocess)?;
let schema = registry.get(&ast.model)?;
run_async_fns(items, schema, ctx, fn_registry)?;
strip_query(postprocess, items);
Ok(())
}