qualia_core_db/sparql_library/
sparql_update.rs1use crate::sparql_ast::*;
6use crate::NQuin;
7
8#[repr(C)]
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub enum UpdateOperation {
12 InsertData { quins: [NQuin; 64], quin_count: u8 },
14 DeleteData { quins: [NQuin; 64], quin_count: u8 },
16 DeleteInsert {
18 delete_pattern: PatternId,
19 insert_pattern: PatternId,
20 where_pattern: PatternId,
21 },
22 Load { uri: u64, graph: u64 },
24 Clear { graph: u64 },
26 Create { graph: u64 },
28 Drop { graph: u64 },
30}
31
32pub struct UpdateExecutor<'a> {
34 pub quins: &'a mut Vec<NQuin>,
35}
36
37impl<'a> UpdateExecutor<'a> {
38 pub fn new(quins: &'a mut Vec<NQuin>) -> Self {
39 Self { quins }
40 }
41
42 pub fn execute(
44 &mut self,
45 operation: &UpdateOperation,
46 ctx: &SparqlQueryContext,
47 ) -> Result<u64, String> {
48 match operation {
49 UpdateOperation::InsertData { quins, quin_count } => {
50 self.execute_insert_data(quins, *quin_count)
51 }
52 UpdateOperation::DeleteData { quins, quin_count } => {
53 self.execute_delete_data(quins, *quin_count)
54 }
55 UpdateOperation::DeleteInsert {
56 delete_pattern,
57 insert_pattern,
58 where_pattern,
59 } => self.execute_delete_insert(*delete_pattern, *insert_pattern, *where_pattern, ctx),
60 UpdateOperation::Load { uri, graph } => self.execute_load(*uri, *graph),
61 UpdateOperation::Clear { graph } => self.execute_clear(*graph),
62 UpdateOperation::Create { graph } => self.execute_create(*graph),
63 UpdateOperation::Drop { graph } => self.execute_drop(*graph),
64 }
65 }
66
67 fn execute_insert_data(&mut self, quins: &[NQuin], quin_count: u8) -> Result<u64, String> {
68 let count = quin_count as usize;
69 if count > quins.len() {
70 return Err("Quin count exceeds array length".to_string());
71 }
72
73 for i in 0..count {
74 self.quins.push(quins[i]);
75 }
76
77 Ok(count as u64)
78 }
79
80 fn execute_delete_data(&mut self, quins: &[NQuin], quin_count: u8) -> Result<u64, String> {
81 let count = quin_count as usize;
82 if count > quins.len() {
83 return Err("Quin count exceeds array length".to_string());
84 }
85
86 let mut deleted = 0;
87 for i in 0..count {
88 let target = quins[i];
89 self.quins.retain(|quin| {
91 quin.subject != target.subject
92 || quin.predicate != target.predicate
93 || quin.object != target.object
94 });
95 deleted += 1;
96 }
97
98 Ok(deleted)
99 }
100
101 fn execute_delete_insert(
102 &mut self,
103 delete_pattern: PatternId,
104 insert_pattern: PatternId,
105 where_pattern: PatternId,
106 ctx: &SparqlQueryContext,
107 ) -> Result<u64, String> {
108 let mut plan = crate::sparql_library::sparql_planner::ExecutionPlan::new();
110 let root_op = crate::sparql_library::sparql_planner::QueryPlanner::plan_pattern(
111 where_pattern,
112 ctx,
113 &mut plan,
114 )?;
115 plan.root_operator = root_op;
116
117 let bindings = {
119 let executor = crate::sparql_library::sparql_executor::QueryExecutor::new(&self.quins);
120 executor.execute(&plan, ctx)?
121 };
122
123 let mut deleted = 0;
124 let mut insert_quins = Vec::new();
125
126 let evaluate_pattern =
128 |pattern_id: PatternId, ctx: &SparqlQueryContext, row: &BindingRow| -> Option<NQuin> {
129 if let Some(pattern) = ctx.patterns.get(pattern_id as usize) {
130 match pattern {
131 Pattern::Triple {
132 subject,
133 predicate,
134 object,
135 } => {
136 let s = if *subject < 0x8000_0000_0000_0000 {
137 row.get(*subject as u8)?
138 } else {
139 *subject
140 };
141 let p = if *predicate < 0x8000_0000_0000_0000 {
142 row.get(*predicate as u8)?
143 } else {
144 *predicate
145 };
146 let o = if *object < 0x8000_0000_0000_0000 {
147 row.get(*object as u8)?
148 } else {
149 *object
150 };
151 Some(NQuin {
152 subject: s,
153 predicate: p,
154 object: o,
155 context: 0,
156 metadata: 0,
157 parity: 0,
158 })
159 }
160 _ => None,
161 }
162 } else {
163 None
164 }
165 };
166
167 for binding in bindings {
168 if let Some(target) = evaluate_pattern(delete_pattern, ctx, &binding) {
169 let initial_len = self.quins.len();
170 self.quins.retain(|q| {
171 q.subject != target.subject
172 || q.predicate != target.predicate
173 || q.object != target.object
174 });
175 deleted += initial_len - self.quins.len();
176 }
177 if let Some(new_quin) = evaluate_pattern(insert_pattern, ctx, &binding) {
178 insert_quins.push(new_quin);
179 }
180 }
181
182 self.quins.extend(insert_quins);
183 Ok(deleted as u64)
184 }
185
186 fn execute_load(&mut self, _uri: u64, _graph: u64) -> Result<u64, String> {
187 Ok(0)
196 }
197
198 fn execute_clear(&mut self, graph: u64) -> Result<u64, String> {
199 let original_len = self.quins.len();
201 self.quins.retain(|quin| quin.context != graph);
202 Ok((original_len - self.quins.len()) as u64)
203 }
204
205 fn execute_create(&mut self, _graph: u64) -> Result<u64, String> {
206 Ok(1)
214 }
215
216 fn execute_drop(&mut self, graph: u64) -> Result<u64, String> {
217 let original_len = self.quins.len();
219 self.quins.retain(|quin| quin.context != graph);
220
221 Ok((original_len - self.quins.len()) as u64)
223 }
224}
225
226#[repr(C)]
228#[derive(Debug, Clone, Copy)]
229pub struct UpdateQuery {
230 pub operation: UpdateOperation,
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236
237 #[test]
238 fn test_insert_data() {
239 let mut quins = vec![];
240 let mut executor = UpdateExecutor::new(&mut quins);
241
242 let test_quin = NQuin {
243 subject: 1,
244 predicate: 2,
245 object: 3,
246 context: 0,
247 metadata: 0,
248 parity: 0,
249 };
250
251 let mut quins_array = [NQuin::default(); 64];
252 quins_array[0] = test_quin;
253
254 let result = executor.execute_insert_data(&quins_array, 1).unwrap();
255 assert_eq!(result, 1);
256 assert_eq!(executor.quins.len(), 1);
257 }
258
259 #[test]
260 fn test_delete_data() {
261 let mut quins = vec![NQuin {
262 subject: 1,
263 predicate: 2,
264 object: 3,
265 context: 0,
266 metadata: 0,
267 parity: 0,
268 }];
269
270 let mut executor = UpdateExecutor::new(&mut quins);
271
272 let test_quin = NQuin {
273 subject: 1,
274 predicate: 2,
275 object: 3,
276 context: 0,
277 metadata: 0,
278 parity: 0,
279 };
280
281 let mut quins_array = [NQuin::default(); 64];
282 quins_array[0] = test_quin;
283
284 let result = executor.execute_delete_data(&quins_array, 1).unwrap();
285 assert_eq!(result, 1);
286 assert_eq!(executor.quins.len(), 0);
287 }
288}