Skip to main content

uni_db/api/
hooks.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2024-2026 Dragonscale Team
3
4//! Session hooks — before/after interception for queries and commits.
5//!
6//! Hooks allow cross-cutting concerns (audit logging, authorization, metrics)
7//! to be injected into the query and commit lifecycle without modifying
8//! individual query call sites.
9
10use std::collections::HashMap;
11
12use uni_common::{Result, Value};
13use uni_query::QueryMetrics;
14
15use crate::api::transaction::CommitResult;
16
17/// The type of query being executed.
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum QueryType {
20    /// A Cypher query (read or write).
21    Cypher,
22    /// A Locy program evaluation.
23    Locy,
24    /// An execute (mutation) statement.
25    Execute,
26}
27
28/// Context passed to query hooks.
29#[derive(Debug, Clone)]
30pub struct HookContext {
31    /// The session ID that initiated the query.
32    pub session_id: String,
33    /// The query text (Cypher or Locy program).
34    pub query_text: String,
35    /// The type of query.
36    pub query_type: QueryType,
37    /// Parameters bound to the query.
38    pub params: HashMap<String, Value>,
39}
40
41/// Context passed to commit hooks.
42#[derive(Debug, Clone)]
43pub struct CommitHookContext {
44    /// The session ID that owns the transaction.
45    pub session_id: String,
46    /// The transaction ID being committed.
47    pub tx_id: String,
48    /// Number of mutations in the transaction.
49    pub mutation_count: usize,
50}
51
52/// Trait for session lifecycle hooks.
53///
54/// Implement this trait to intercept queries and commits at the session level.
55/// Hooks are stored as `Arc<dyn SessionHook>` and can be shared across sessions
56/// and templates.
57///
58/// # Failure Semantics
59///
60/// - `before_query`: Returning `Err` aborts the query with `HookRejected`.
61/// - `after_query`: Infallible — panics are caught and logged.
62/// - `before_commit`: Returning `Err` aborts the commit with `HookRejected`.
63/// - `after_commit`: Infallible — panics are caught and logged.
64pub trait SessionHook: Send + Sync {
65    /// Called before a query is executed. Return `Err` to reject the query.
66    fn before_query(&self, _ctx: &HookContext) -> Result<()> {
67        Ok(())
68    }
69
70    /// Called after a query completes. Panics are caught and logged.
71    fn after_query(&self, _ctx: &HookContext, _metrics: &QueryMetrics) {}
72
73    /// Called before a transaction is committed. Return `Err` to reject the commit.
74    fn before_commit(&self, _ctx: &CommitHookContext) -> Result<()> {
75        Ok(())
76    }
77
78    /// Called after a transaction is successfully committed. Panics are caught and logged.
79    fn after_commit(&self, _ctx: &CommitHookContext, _result: &CommitResult) {}
80}