Skip to main content

reifydb_sub_server/
binding.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4#[cfg(not(reifydb_single_threaded))]
5use std::fmt::Write;
6
7#[cfg(not(reifydb_single_threaded))]
8use reifydb_core::{actors::server::Operation, metric::ExecutionMetrics};
9#[cfg(not(reifydb_single_threaded))]
10use reifydb_type::{
11	params::Params,
12	value::{frame::frame::Frame, identity::IdentityId},
13};
14
15#[cfg(not(reifydb_single_threaded))]
16use crate::{
17	dispatch::dispatch,
18	execute::ExecuteError,
19	interceptor::{RequestContext, RequestMetadata},
20	state::AppState,
21};
22
23/// Synthesize and dispatch `CALL {ns}::{proc}()` for a binding; parameters are resolved
24/// at execution time from `params` (no `$name` placeholders in the CALL text).
25///
26/// The caller is responsible for:
27/// - Resolving the binding and locating its procedure by `binding.procedure_id`.
28/// - Validating `params` against the procedure's declared parameter list (rejecting unknown keys, missing required,
29///   type-coercion failures) before calling here.
30/// - Building `RequestMetadata` from its transport-specific request.
31///
32/// Returns `(frames, metrics)` from the engine; each transport wraps it into its own
33/// response format based on `binding.format` and reads `metrics.total` / `metrics.fingerprint`
34/// for telemetry headers.
35#[cfg(not(reifydb_single_threaded))]
36pub async fn dispatch_binding(
37	state: &AppState,
38	namespace_path: &str,
39	procedure_name: &str,
40	params: Params,
41	identity: IdentityId,
42	metadata: RequestMetadata,
43) -> Result<(Vec<Frame>, ExecutionMetrics), ExecuteError> {
44	let mut call_text = String::with_capacity(8 + namespace_path.len() + procedure_name.len());
45	write!(&mut call_text, "CALL {}::{}()", namespace_path, procedure_name).unwrap();
46
47	let ctx = RequestContext {
48		identity,
49		operation: Operation::Command,
50		rql: call_text,
51		params,
52		metadata,
53	};
54
55	dispatch(state, ctx).await
56}