Skip to main content

claw_core/schema/
validators.rs

1//! Schema validation helpers for claw-core.
2//!
3//! This module exposes lightweight runtime checks that verify the claw-core
4//! schema is in an expected state after migrations have been applied. Checks
5//! are run on engine startup (when `auto_migrate` is enabled) to guard
6//! against partial migrations or external schema corruption.
7
8use sqlx::SqlitePool;
9
10use crate::error::{ClawError, ClawResult};
11
12/// Verify that all expected claw-core tables are present in the database.
13///
14/// Returns `Ok(())` if every required table exists, or a [`ClawError::Config`]
15/// listing the missing tables.
16///
17/// # Errors
18///
19/// Returns a [`ClawError`] if the introspection query fails or a table is
20/// missing.
21pub async fn validate_schema(pool: &SqlitePool) -> ClawResult<()> {
22    let required_tables = [
23        "active_memory",
24        "session_state",
25        "tool_output",
26        "context",
27        "memories",
28        "sessions",
29    ];
30
31    let rows: Vec<(String,)> =
32        sqlx::query_as("SELECT name FROM sqlite_master WHERE type = 'table'")
33            .fetch_all(pool)
34            .await?;
35
36    let existing: std::collections::HashSet<&str> =
37        rows.iter().map(|(name,)| name.as_str()).collect();
38
39    let missing: Vec<&str> = required_tables
40        .iter()
41        .copied()
42        .filter(|t| !existing.contains(t))
43        .collect();
44
45    if missing.is_empty() {
46        Ok(())
47    } else {
48        Err(ClawError::Config(format!(
49            "schema validation failed — missing tables: {}",
50            missing.join(", ")
51        )))
52    }
53}