claw_core/index.rs
1//! Lightweight FTS and B-tree index helpers for claw-core.
2//!
3//! This module exposes helpers that create and query SQLite FTS5 full-text
4//! search virtual tables and ordinary B-tree indexes on the claw-core schema
5//! tables. Index creation is idempotent (`CREATE INDEX IF NOT EXISTS`).
6
7use sqlx::SqlitePool;
8
9use crate::error::ClawResult;
10
11/// Helpers for managing lightweight indexes on claw-core tables.
12///
13/// All methods are idempotent and safe to call multiple times (they use
14/// `IF NOT EXISTS` guards internally).
15pub struct IndexManager<'a> {
16 pool: &'a SqlitePool,
17}
18
19impl<'a> IndexManager<'a> {
20 /// Create a new [`IndexManager`] bound to `pool`.
21 pub fn new(pool: &'a SqlitePool) -> Self {
22 IndexManager { pool }
23 }
24
25 /// Create a B-tree index on `active_memory(agent_id)` if it does not
26 /// already exist.
27 ///
28 /// # Errors
29 ///
30 /// Returns a [`crate::error::ClawError`] if the SQL execution fails.
31 pub async fn ensure_active_memory_agent_index(&self) -> ClawResult<()> {
32 sqlx::query(
33 "CREATE INDEX IF NOT EXISTS idx_active_memory_agent_id \
34 ON active_memory (agent_id)",
35 )
36 .execute(self.pool)
37 .await?;
38 Ok(())
39 }
40
41 /// Create a B-tree index on `session_state(session_id)` if it does not
42 /// already exist.
43 ///
44 /// # Errors
45 ///
46 /// Returns a [`crate::error::ClawError`] if the SQL execution fails.
47 pub async fn ensure_session_index(&self) -> ClawResult<()> {
48 sqlx::query(
49 "CREATE INDEX IF NOT EXISTS idx_session_state_session_id \
50 ON session_state (session_id)",
51 )
52 .execute(self.pool)
53 .await?;
54 Ok(())
55 }
56
57 /// Create a B-tree index on `tool_output(tool_name, created_at)` if it
58 /// does not already exist.
59 ///
60 /// # Errors
61 ///
62 /// Returns a [`crate::error::ClawError`] if the SQL execution fails.
63 pub async fn ensure_tool_output_index(&self) -> ClawResult<()> {
64 sqlx::query(
65 "CREATE INDEX IF NOT EXISTS idx_tool_output_tool_name_created_at \
66 ON tool_output (tool_name, created_at)",
67 )
68 .execute(self.pool)
69 .await?;
70 Ok(())
71 }
72}
73
74impl<'a> std::fmt::Debug for IndexManager<'a> {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 f.debug_struct("IndexManager").finish_non_exhaustive()
77 }
78}