Skip to content

Commit

Permalink
feat(cognitarium): implements building triple pattern query node
Browse files Browse the repository at this point in the history
  • Loading branch information
amimart committed Jun 5, 2023
1 parent 6a8d7b9 commit 7f32451
Showing 1 changed file with 98 additions and 0 deletions.
98 changes: 98 additions & 0 deletions contracts/okp4-cognitarium/src/querier/plan_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,104 @@ impl<'a> PlanBuilder<'a> {

pub fn build_plan(&mut self, where_clause: WhereClause) -> StdResult<QueryPlan> {
Err(StdError::generic_err("not implemented"))

fn build_triple_pattern(
&mut self,
pattern: &TriplePattern,
) -> StdResult<QueryNode::TriplePattern> {
Ok(QueryNode::TriplePattern {
subject: self.build_subject_pattern(pattern.subject.clone())?,
predicate: self.build_predicate_pattern(pattern.predicate.clone())?,
object: self.build_object_pattern(pattern.object.clone())?,
})
}

fn build_subject_pattern(&mut self, value: VarOrNode) -> StdResult<PatternValue<Subject>> {
Ok(match value {
VarOrNode::Variable(v) => PatternValue::Variable(self.resolve_variable(v)),
VarOrNode::Node(n) => match n {
Node::NamedNode(iri) => {
PatternValue::Constant(Subject::Named(self.build_named_node(iri)?))
}
Node::BlankNode(blank) => PatternValue::Constant(Subject::Blank(blank)),
},
})
}

fn build_predicate_pattern(&mut self, value: VarOrNode) -> StdResult<PatternValue<Predicate>> {
Ok(match value {
VarOrNode::Variable(v) => PatternValue::Variable(self.resolve_variable(v)),
VarOrNode::Node(n) => match n {
Node::NamedNode(iri) => PatternValue::Constant(self.build_named_node(iri)?),
Node::BlankNode(_) => (),
},
})
}

fn build_object_pattern(
&mut self,
value: VarOrNodeOrLiteral,
) -> StdResult<PatternValue<Object>> {
Ok(match value {
VarOrNodeOrLiteral::Variable(v) => PatternValue::Variable(self.resolve_variable(v)),
VarOrNodeOrLiteral::Node(n) => match n {
Node::NamedNode(iri) => {
PatternValue::Constant(Object::Named(self.build_named_node(iri)?))
}
Node::BlankNode(blank) => PatternValue::Constant(Object::Blank(blank)),
},
VarOrNodeOrLiteral::Literal(l) => PatternValue::Constant(Object::Literal(match l {
Literal::Simple(value) => state::Literal::Simple { value },
Literal::LanguageTaggedString { value, language } => {
state::Literal::I18NString { value, language }
}
Literal::TypedValue { value, datatype } => state::Literal::Typed {
value,
datatype: self.build_named_node(datatype)?,
},
})),
})
}

fn build_named_node(&mut self, value: IRI) -> StdResult<state::Node> {
match value {
IRI::Prefixed(prefixed) => prefixed
.rfind(b':')
.map(Ok)
.unwrap_or(Err(StdError::generic_err(
"Malformed prefixed IRI: no prefix delimiter found",
)))
.and_then(|index| {
self.prefixes
.get(&prefixed.as_str()[..index + 1])
.map(|resolved_prefix| {
[resolved_prefix, &prefixed.as_str()[index + 1..]].join("")
})
.map(Ok)
.unwrap_or(Err(StdError::generic_err(
"Malformed prefixed IRI: prefix not found",
)))
}),
IRI::Full(full) => Ok(full),
}
.and_then(rdf::explode_iri)
.and_then(|(ns_key, v)| {
namespaces()
.load(self.storage, ns_key)
.map(|ns| state::Node {
namespace: ns.key,
value: v,
})
})
}

fn resolve_variable(&mut self, v: String) -> usize {
if let Some(index) = self.variables.iter().position(|&name| name == v) {
return index;
}

self.variables.push(v);
self.variables.len() - 1
}

fn make_prefixes(as_list: Vec<Prefix>) -> HashMap<String, String> {
Expand Down

0 comments on commit 7f32451

Please sign in to comment.