Skip to main content

uqa_storage/sqlite/catalog/
analyzers.rs

1//
2// Unified Query Algebra
3//
4// Copyright (c) 2023-2026 Cognica, Inc.
5//
6
7//! Named and per-field analyzer configuration.
8
9use super::{params, Catalog, Result};
10
11impl Catalog {
12    // -- Named analyzers ---------------------------------------------------
13
14    /// Persist a named analyzer configuration.
15    pub fn save_analyzer(&self, name: &str, config_json: &str) -> Result<()> {
16        self.conn.with(|c| {
17            c.execute(
18                "INSERT OR REPLACE INTO _analyzers (name, config_json) VALUES (?1, ?2)",
19                params![name, config_json],
20            )?;
21            Ok(())
22        })
23    }
24
25    pub fn drop_analyzer(&self, name: &str) -> Result<()> {
26        self.conn.with(|c| {
27            c.execute("DELETE FROM _analyzers WHERE name = ?1", params![name])?;
28            Ok(())
29        })
30    }
31
32    pub fn load_analyzers(&self) -> Result<Vec<(String, String)>> {
33        self.conn.with(|c| {
34            let mut stmt = c.prepare("SELECT name, config_json FROM _analyzers ORDER BY name")?;
35            let rows =
36                stmt.query_map([], |r| Ok((r.get::<_, String>(0)?, r.get::<_, String>(1)?)))?;
37            let mut out = Vec::new();
38            for row in rows {
39                out.push(row?);
40            }
41            Ok(out)
42        })
43    }
44
45    // -- Per-field analyzer overrides --------------------------------------
46
47    /// Persist a `(table, field, phase) -> analyzer_name` mapping.
48    pub fn save_table_field_analyzer(
49        &self,
50        table_name: &str,
51        field: &str,
52        phase: &str,
53        analyzer_name: &str,
54    ) -> Result<()> {
55        self.conn.with(|c| {
56            c.execute(
57                "INSERT OR REPLACE INTO _table_field_analyzers \
58                    (table_name, field, phase, analyzer_name) \
59                 VALUES (?1, ?2, ?3, ?4)",
60                params![table_name, field, phase, analyzer_name],
61            )?;
62            Ok(())
63        })
64    }
65
66    pub fn drop_table_field_analyzers(&self, table_name: &str) -> Result<()> {
67        self.conn.with(|c| {
68            c.execute(
69                "DELETE FROM _table_field_analyzers WHERE table_name = ?1",
70                params![table_name],
71            )?;
72            Ok(())
73        })
74    }
75
76    pub fn replace_table_field_analyzer(
77        &self,
78        table_name: &str,
79        field: &str,
80        phase: &str,
81        analyzer_name: &str,
82    ) -> Result<()> {
83        self.conn.with_mut(|c| {
84            let tx = c.savepoint()?;
85            tx.execute(
86                "DELETE FROM _table_field_analyzers
87                  WHERE table_name = ?1 AND field = ?2",
88                params![table_name, field],
89            )?;
90            tx.execute(
91                "INSERT INTO _table_field_analyzers
92                    (table_name, field, phase, analyzer_name)
93                 VALUES (?1, ?2, ?3, ?4)",
94                params![table_name, field, phase, analyzer_name],
95            )?;
96            tx.commit()?;
97            Ok(())
98        })
99    }
100
101    pub fn drop_table_field_analyzer_field(&self, table_name: &str, field: &str) -> Result<()> {
102        self.conn.with(|c| {
103            c.execute(
104                "DELETE FROM _table_field_analyzers
105                  WHERE table_name = ?1 AND field = ?2",
106                params![table_name, field],
107            )?;
108            Ok(())
109        })
110    }
111
112    /// Every `(table_name, field, phase, analyzer_name)` row sorted by
113    /// `(table_name, field, phase)`.
114    pub fn load_table_field_analyzers(&self) -> Result<Vec<(String, String, String, String)>> {
115        self.conn.with(|c| {
116            let mut stmt = c.prepare(
117                "SELECT table_name, field, phase, analyzer_name FROM _table_field_analyzers \
118                  ORDER BY table_name, field, phase",
119            )?;
120            let rows = stmt.query_map([], |r| {
121                Ok((
122                    r.get::<_, String>(0)?,
123                    r.get::<_, String>(1)?,
124                    r.get::<_, String>(2)?,
125                    r.get::<_, String>(3)?,
126                ))
127            })?;
128            let mut out = Vec::new();
129            for row in rows {
130                out.push(row?);
131            }
132            Ok(out)
133        })
134    }
135}