1use crate::model::*;
7use serde::{Deserialize, Serialize};
8use std::collections::HashMap;
9use std::fmt;
10
11pub use crate::model::pattern::TriplePattern;
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
16pub enum PropertyPath {
17 Predicate(NamedNode),
19 Inverse(Box<PropertyPath>),
21 Sequence(Box<PropertyPath>, Box<PropertyPath>),
23 Alternative(Box<PropertyPath>, Box<PropertyPath>),
25 ZeroOrMore(Box<PropertyPath>),
27 OneOrMore(Box<PropertyPath>),
29 ZeroOrOne(Box<PropertyPath>),
31 NegatedPropertySet(Vec<NamedNode>),
33}
34
35impl fmt::Display for PropertyPath {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self {
38 PropertyPath::Predicate(p) => write!(f, "{p}"),
39 PropertyPath::Inverse(p) => write!(f, "^{p}"),
40 PropertyPath::Sequence(a, b) => write!(f, "({a} / {b})"),
41 PropertyPath::Alternative(a, b) => write!(f, "({a} | {b})"),
42 PropertyPath::ZeroOrMore(p) => write!(f, "({p})*"),
43 PropertyPath::OneOrMore(p) => write!(f, "({p})+"),
44 PropertyPath::ZeroOrOne(p) => write!(f, "({p})?"),
45 PropertyPath::NegatedPropertySet(ps) => {
46 write!(f, "!(")?;
47 for (i, p) in ps.iter().enumerate() {
48 if i > 0 {
49 write!(f, " | ")?;
50 }
51 write!(f, "{p}")?;
52 }
53 write!(f, ")")
54 }
55 }
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub enum Expression {
62 Term(Term),
64 Variable(Variable),
66 And(Box<Expression>, Box<Expression>),
68 Or(Box<Expression>, Box<Expression>),
70 Not(Box<Expression>),
72 Equal(Box<Expression>, Box<Expression>),
74 NotEqual(Box<Expression>, Box<Expression>),
76 Less(Box<Expression>, Box<Expression>),
78 LessOrEqual(Box<Expression>, Box<Expression>),
80 Greater(Box<Expression>, Box<Expression>),
82 GreaterOrEqual(Box<Expression>, Box<Expression>),
84 Add(Box<Expression>, Box<Expression>),
86 Subtract(Box<Expression>, Box<Expression>),
88 Multiply(Box<Expression>, Box<Expression>),
90 Divide(Box<Expression>, Box<Expression>),
92 UnaryPlus(Box<Expression>),
94 UnaryMinus(Box<Expression>),
96 In(Box<Expression>, Vec<Expression>),
98 NotIn(Box<Expression>, Vec<Expression>),
100 Exists(Box<GraphPattern>),
102 NotExists(Box<GraphPattern>),
104 FunctionCall(Function, Vec<Expression>),
106 Bound(Variable),
108 If(Box<Expression>, Box<Expression>, Box<Expression>),
110 Coalesce(Vec<Expression>),
112 Literal(crate::model::Literal),
114 IsIri(Box<Expression>),
116 IsBlank(Box<Expression>),
118 IsLiteral(Box<Expression>),
120 IsNumeric(Box<Expression>),
122 Str(Box<Expression>),
124 Regex(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
130pub enum Function {
131 Str,
133 Lang,
134 LangMatches,
135 Datatype,
136 Iri,
137 Bnode,
138 StrDt,
139 StrLang,
140 StrLen,
141 SubStr,
142 UCase,
143 LCase,
144 StrStarts,
145 StrEnds,
146 Contains,
147 StrBefore,
148 StrAfter,
149 Encode,
150 Concat,
151 Replace,
152 Regex,
153
154 Abs,
156 Round,
157 Ceil,
158 Floor,
159 Rand,
160
161 Now,
163 Year,
164 Month,
165 Day,
166 Hours,
167 Minutes,
168 Seconds,
169 Timezone,
170 Tz,
171
172 Md5,
174 Sha1,
175 Sha256,
176 Sha384,
177 Sha512,
178
179 IsIri,
181 IsBlank,
182 IsLiteral,
183 IsNumeric,
184
185 Custom(NamedNode),
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
191pub struct AlgebraTriplePattern {
192 pub subject: TermPattern,
193 pub predicate: TermPattern,
194 pub object: TermPattern,
195}
196
197impl AlgebraTriplePattern {
198 pub fn new(subject: TermPattern, predicate: TermPattern, object: TermPattern) -> Self {
200 Self {
201 subject,
202 predicate,
203 object,
204 }
205 }
206
207 pub fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
209 f.write_str("(triple ")?;
210 self.subject.fmt_sse(f)?;
211 f.write_str(" ")?;
212 self.predicate.fmt_sse(f)?;
213 f.write_str(" ")?;
214 self.object.fmt_sse(f)?;
215 f.write_str(")")
216 }
217}
218
219impl fmt::Display for AlgebraTriplePattern {
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 write!(f, "{} {} {}", self.subject, self.predicate, self.object)
222 }
223}
224
225impl From<crate::model::pattern::TriplePattern> for Option<AlgebraTriplePattern> {
226 fn from(pattern: crate::model::pattern::TriplePattern) -> Self {
227 use crate::model::pattern::{ObjectPattern, PredicatePattern, SubjectPattern};
228
229 let subject = match pattern.subject? {
230 SubjectPattern::NamedNode(n) => TermPattern::NamedNode(n),
231 SubjectPattern::BlankNode(b) => TermPattern::BlankNode(b),
232 SubjectPattern::Variable(v) => TermPattern::Variable(v),
233 SubjectPattern::QuotedTriple(qt) => TermPattern::QuotedTriple(qt),
234 };
235
236 let predicate = match pattern.predicate? {
237 PredicatePattern::NamedNode(n) => TermPattern::NamedNode(n),
238 PredicatePattern::Variable(v) => TermPattern::Variable(v),
239 };
240
241 let object = match pattern.object? {
242 ObjectPattern::NamedNode(n) => TermPattern::NamedNode(n),
243 ObjectPattern::BlankNode(b) => TermPattern::BlankNode(b),
244 ObjectPattern::Literal(l) => TermPattern::Literal(l),
245 ObjectPattern::Variable(v) => TermPattern::Variable(v),
246 ObjectPattern::QuotedTriple(qt) => TermPattern::QuotedTriple(qt),
247 };
248
249 Some(AlgebraTriplePattern::new(subject, predicate, object))
250 }
251}
252
253#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
255pub enum TermPattern {
256 NamedNode(NamedNode),
257 BlankNode(BlankNode),
258 Literal(Literal),
259 Variable(Variable),
260 QuotedTriple(Box<AlgebraTriplePattern>),
262}
263
264impl From<Variable> for TermPattern {
265 fn from(v: Variable) -> Self {
266 TermPattern::Variable(v)
267 }
268}
269
270impl From<NamedNode> for TermPattern {
271 fn from(n: NamedNode) -> Self {
272 TermPattern::NamedNode(n)
273 }
274}
275
276impl From<BlankNode> for TermPattern {
277 fn from(b: BlankNode) -> Self {
278 TermPattern::BlankNode(b)
279 }
280}
281
282impl From<Literal> for TermPattern {
283 fn from(l: Literal) -> Self {
284 TermPattern::Literal(l)
285 }
286}
287
288impl TermPattern {
289 pub fn is_variable(&self) -> bool {
291 matches!(self, TermPattern::Variable(_))
292 }
293
294 pub fn fmt_sse(&self, f: &mut impl fmt::Write) -> fmt::Result {
296 match self {
297 TermPattern::NamedNode(node) => write!(f, "{node}"),
298 TermPattern::BlankNode(node) => write!(f, "{node}"),
299 TermPattern::Literal(literal) => write!(f, "{literal}"),
300 TermPattern::Variable(var) => write!(f, "{var}"),
301 TermPattern::QuotedTriple(triple) => {
302 write!(f, "<<")?;
303 triple.subject.fmt_sse(f)?;
304 write!(f, " ")?;
305 triple.predicate.fmt_sse(f)?;
306 write!(f, " ")?;
307 triple.object.fmt_sse(f)?;
308 write!(f, ">>")
309 }
310 }
311 }
312}
313
314impl fmt::Display for TermPattern {
315 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316 match self {
317 TermPattern::NamedNode(n) => write!(f, "{n}"),
318 TermPattern::BlankNode(b) => write!(f, "{b}"),
319 TermPattern::Literal(l) => write!(f, "{l}"),
320 TermPattern::Variable(v) => write!(f, "{v}"),
321 TermPattern::QuotedTriple(triple) => {
322 write!(
323 f,
324 "<<{} {} {}>>",
325 triple.subject, triple.predicate, triple.object
326 )
327 }
328 }
329 }
330}
331
332#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
334pub enum GraphPattern {
335 Bgp(Vec<AlgebraTriplePattern>),
337 Path {
339 subject: TermPattern,
340 path: PropertyPath,
341 object: TermPattern,
342 },
343 Join(Box<GraphPattern>, Box<GraphPattern>),
345 LeftJoin {
347 left: Box<GraphPattern>,
348 right: Box<GraphPattern>,
349 condition: Option<Expression>,
350 },
351 Filter {
353 expr: Expression,
354 inner: Box<GraphPattern>,
355 },
356 Union(Box<GraphPattern>, Box<GraphPattern>),
358 Graph {
360 graph_name: TermPattern,
361 inner: Box<GraphPattern>,
362 },
363 Service {
365 service: TermPattern,
366 inner: Box<GraphPattern>,
367 silent: bool,
368 },
369 Group {
371 inner: Box<GraphPattern>,
372 variables: Vec<Variable>,
373 aggregates: Vec<(Variable, AggregateExpression)>,
374 },
375 Extend {
377 inner: Box<GraphPattern>,
378 variable: Variable,
379 expression: Expression,
380 },
381 Minus(Box<GraphPattern>, Box<GraphPattern>),
383 Values {
385 variables: Vec<Variable>,
386 bindings: Vec<Vec<Option<Term>>>,
387 },
388 OrderBy {
390 inner: Box<GraphPattern>,
391 order_by: Vec<OrderExpression>,
392 },
393 Project {
395 inner: Box<GraphPattern>,
396 variables: Vec<Variable>,
397 },
398 Distinct(Box<GraphPattern>),
400 Reduced(Box<GraphPattern>),
402 Slice {
404 inner: Box<GraphPattern>,
405 offset: usize,
406 limit: Option<usize>,
407 },
408}
409
410#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
412pub enum AggregateExpression {
413 Count {
414 expr: Option<Box<Expression>>,
415 distinct: bool,
416 },
417 Sum {
418 expr: Box<Expression>,
419 distinct: bool,
420 },
421 Avg {
422 expr: Box<Expression>,
423 distinct: bool,
424 },
425 Min {
426 expr: Box<Expression>,
427 distinct: bool,
428 },
429 Max {
430 expr: Box<Expression>,
431 distinct: bool,
432 },
433 GroupConcat {
434 expr: Box<Expression>,
435 distinct: bool,
436 separator: Option<String>,
437 },
438 Sample {
439 expr: Box<Expression>,
440 distinct: bool,
441 },
442}
443
444#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
446pub enum OrderExpression {
447 Asc(Expression),
448 Desc(Expression),
449}
450
451#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
453pub enum QueryForm {
454 Select {
456 variables: SelectVariables,
458 where_clause: GraphPattern,
460 distinct: bool,
462 reduced: bool,
463 order_by: Vec<OrderExpression>,
464 offset: usize,
465 limit: Option<usize>,
466 },
467 Construct {
469 template: Vec<AlgebraTriplePattern>,
471 where_clause: GraphPattern,
473 order_by: Vec<OrderExpression>,
475 offset: usize,
476 limit: Option<usize>,
477 },
478 Describe {
480 resources: Vec<TermPattern>,
482 where_clause: Option<GraphPattern>,
484 order_by: Vec<OrderExpression>,
486 offset: usize,
487 limit: Option<usize>,
488 },
489 Ask {
491 where_clause: GraphPattern,
493 },
494}
495
496#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
498pub enum SelectVariables {
499 All,
501 Specific(Vec<Variable>),
503}
504
505#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
507pub struct Query {
508 pub base: Option<NamedNode>,
510 pub prefixes: HashMap<String, NamedNode>,
512 pub form: QueryForm,
514 pub dataset: Dataset,
516}
517
518#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
520pub struct Dataset {
521 pub default: Vec<NamedNode>,
523 pub named: Vec<NamedNode>,
525}
526
527#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
529pub enum UpdateOperation {
530 InsertData { data: Vec<Quad> },
532 DeleteData { data: Vec<Quad> },
534 DeleteWhere { pattern: Vec<QuadPattern> },
536 Modify {
538 delete: Option<Vec<QuadPattern>>,
539 insert: Option<Vec<QuadPattern>>,
540 where_clause: Box<GraphPattern>,
541 using: Dataset,
542 },
543 Load {
545 source: NamedNode,
546 destination: Option<NamedNode>,
547 silent: bool,
548 },
549 Clear { graph: GraphTarget, silent: bool },
551 Create { graph: NamedNode, silent: bool },
553 Drop { graph: GraphTarget, silent: bool },
555 Copy {
557 source: GraphTarget,
558 destination: GraphTarget,
559 silent: bool,
560 },
561 Move {
563 source: GraphTarget,
564 destination: GraphTarget,
565 silent: bool,
566 },
567 Add {
569 source: GraphTarget,
570 destination: GraphTarget,
571 silent: bool,
572 },
573}
574
575#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
577pub enum GraphTarget {
578 Default,
579 Named(NamedNode),
580 All,
581}
582
583#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
585pub struct QuadPattern {
586 pub subject: TermPattern,
587 pub predicate: TermPattern,
588 pub object: TermPattern,
589 pub graph: Option<TermPattern>,
590}
591
592#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
594pub struct Update {
595 pub base: Option<NamedNode>,
597 pub prefixes: HashMap<String, NamedNode>,
599 pub operations: Vec<UpdateOperation>,
601}