tensorlogic_adapters/database/
sql.rs1use super::SchemaDatabase;
4use crate::AdapterError;
5
6pub struct SchemaDatabaseSQL;
12
13impl SchemaDatabaseSQL {
14 pub fn create_tables_sql() -> Vec<String> {
16 vec![
17 r#"
19 CREATE TABLE IF NOT EXISTS schemas (
20 id INTEGER PRIMARY KEY AUTOINCREMENT,
21 name TEXT NOT NULL,
22 version INTEGER NOT NULL DEFAULT 1,
23 created_at INTEGER NOT NULL,
24 updated_at INTEGER NOT NULL,
25 description TEXT,
26 UNIQUE(name, version)
27 )
28 "#
29 .to_string(),
30 r#"
32 CREATE TABLE IF NOT EXISTS domains (
33 id INTEGER PRIMARY KEY AUTOINCREMENT,
34 schema_id INTEGER NOT NULL,
35 name TEXT NOT NULL,
36 cardinality INTEGER NOT NULL,
37 description TEXT,
38 metadata TEXT,
39 FOREIGN KEY (schema_id) REFERENCES schemas(id) ON DELETE CASCADE,
40 UNIQUE(schema_id, name)
41 )
42 "#
43 .to_string(),
44 r#"
46 CREATE TABLE IF NOT EXISTS predicates (
47 id INTEGER PRIMARY KEY AUTOINCREMENT,
48 schema_id INTEGER NOT NULL,
49 name TEXT NOT NULL,
50 arity INTEGER NOT NULL,
51 description TEXT,
52 constraints TEXT,
53 metadata TEXT,
54 FOREIGN KEY (schema_id) REFERENCES schemas(id) ON DELETE CASCADE,
55 UNIQUE(schema_id, name)
56 )
57 "#
58 .to_string(),
59 r#"
61 CREATE TABLE IF NOT EXISTS predicate_arguments (
62 id INTEGER PRIMARY KEY AUTOINCREMENT,
63 predicate_id INTEGER NOT NULL,
64 position INTEGER NOT NULL,
65 domain_name TEXT NOT NULL,
66 FOREIGN KEY (predicate_id) REFERENCES predicates(id) ON DELETE CASCADE,
67 UNIQUE(predicate_id, position)
68 )
69 "#
70 .to_string(),
71 r#"
73 CREATE TABLE IF NOT EXISTS variables (
74 id INTEGER PRIMARY KEY AUTOINCREMENT,
75 schema_id INTEGER NOT NULL,
76 name TEXT NOT NULL,
77 domain_name TEXT NOT NULL,
78 FOREIGN KEY (schema_id) REFERENCES schemas(id) ON DELETE CASCADE,
79 UNIQUE(schema_id, name)
80 )
81 "#
82 .to_string(),
83 "CREATE INDEX IF NOT EXISTS idx_schemas_name ON schemas(name)".to_string(),
85 "CREATE INDEX IF NOT EXISTS idx_domains_schema ON domains(schema_id)".to_string(),
86 "CREATE INDEX IF NOT EXISTS idx_predicates_schema ON predicates(schema_id)".to_string(),
87 ]
88 }
89
90 pub fn insert_domain_sql() -> &'static str {
92 r#"
93 INSERT INTO domains (schema_id, name, cardinality, description, metadata)
94 VALUES (?, ?, ?, ?, ?)
95 "#
96 }
97
98 pub fn insert_predicate_sql() -> &'static str {
100 r#"
101 INSERT INTO predicates (schema_id, name, arity, description, constraints, metadata)
102 VALUES (?, ?, ?, ?, ?, ?)
103 "#
104 }
105
106 pub fn insert_predicate_arg_sql() -> &'static str {
108 r#"
109 INSERT INTO predicate_arguments (predicate_id, position, domain_name)
110 VALUES (?, ?, ?)
111 "#
112 }
113
114 pub fn insert_variable_sql() -> &'static str {
116 r#"
117 INSERT INTO variables (schema_id, name, domain_name)
118 VALUES (?, ?, ?)
119 "#
120 }
121
122 pub fn select_schema_sql() -> &'static str {
124 "SELECT id, name, version, created_at, updated_at, description FROM schemas WHERE id = ?"
125 }
126
127 pub fn select_domains_sql() -> &'static str {
129 "SELECT name, cardinality, description, metadata FROM domains WHERE schema_id = ?"
130 }
131
132 pub fn select_predicates_sql() -> &'static str {
134 "SELECT id, name, arity, description, constraints, metadata FROM predicates WHERE schema_id = ?"
135 }
136
137 pub fn select_predicate_args_sql() -> &'static str {
139 "SELECT position, domain_name FROM predicate_arguments WHERE predicate_id = ? ORDER BY position"
140 }
141}
142
143#[derive(Clone, Debug)]
145pub struct DatabaseStats {
146 pub total_schemas: usize,
148 pub total_domains: usize,
150 pub total_predicates: usize,
152 pub size_bytes: Option<usize>,
154}
155
156impl DatabaseStats {
157 pub fn new() -> Self {
159 Self {
160 total_schemas: 0,
161 total_domains: 0,
162 total_predicates: 0,
163 size_bytes: None,
164 }
165 }
166
167 pub fn from_database<D: SchemaDatabase>(db: &D) -> Result<Self, AdapterError> {
169 let schemas = db.list_schemas()?;
170 let total_schemas = schemas.len();
171 let total_domains: usize = schemas.iter().map(|s| s.num_domains).sum();
172 let total_predicates: usize = schemas.iter().map(|s| s.num_predicates).sum();
173
174 Ok(Self {
175 total_schemas,
176 total_domains,
177 total_predicates,
178 size_bytes: None,
179 })
180 }
181
182 pub fn avg_domains_per_schema(&self) -> f64 {
184 if self.total_schemas == 0 {
185 0.0
186 } else {
187 self.total_domains as f64 / self.total_schemas as f64
188 }
189 }
190
191 pub fn avg_predicates_per_schema(&self) -> f64 {
193 if self.total_schemas == 0 {
194 0.0
195 } else {
196 self.total_predicates as f64 / self.total_schemas as f64
197 }
198 }
199}
200
201impl Default for DatabaseStats {
202 fn default() -> Self {
203 Self::new()
204 }
205}