Skip to content

Commit

Permalink
Fixed issue: Query selecting resources using .Uri does not return res…
Browse files Browse the repository at this point in the history
…ources with Stardog.
  • Loading branch information
faubulous committed May 17, 2018
1 parent 2b9bd91 commit 65367dd
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
6 changes: 6 additions & 0 deletions Trinity/Query/Linq/ISparqlVariableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ internal interface ISparqlVariableGenerator

void AddVariableMapping(Expression expression, string alias);

bool HasSubjectVariable(Expression expression);

bool HasPredicateVariable(Expression expression);

bool HasObjectVariable(Expression expression);

SparqlVariable TryGetSubjectVariable(Expression expression);

SparqlVariable TryGetPredicateVariable(Expression expression);
Expand Down
32 changes: 20 additions & 12 deletions Trinity/Query/Linq/SparqlQueryGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,12 @@

using Remotion.Linq;
using Remotion.Linq.Clauses;
using Remotion.Linq.Clauses.Expressions;
using Remotion.Linq.Clauses.ResultOperators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Xml;
using VDS.RDF;
using VDS.RDF.Query;
using VDS.RDF.Query.Builder;
using VDS.RDF.Query.Builder.Expressions;
Expand Down Expand Up @@ -203,8 +200,15 @@ private SparqlVariable BuildMemberAccess(MemberExpression memberExpression, IGra

if(member.IsUriType())
{
// We access the .Uri member of a resource. We do not need a property mapping and return the subject.
// When we access the .Uri member of a resource we do not need a property mapping and return the subject as the bound variable.

// We create a triple pattern describing the resource in the local scope just in case it has not been described yet.
// Todo: Improve. Check if triples actually need to be asserted.
SparqlVariable s = VariableGenerator.TryGetSubjectVariable(memberExpression) ?? SubjectVariable;
SparqlVariable p = VariableGenerator.CreatePredicateVariable();
SparqlVariable o = VariableGenerator.CreateObjectVariable(memberExpression);

patternBuilder.Where(t => t.Subject(s).Predicate(p).Object(o));

VariableGenerator.SetSubjectVariable(memberExpression, s);

Expand All @@ -224,7 +228,7 @@ private SparqlVariable BuildMemberAccess(MemberExpression memberExpression, IGra
}

// Invoke the final user-handled member access triple builder callback.
patternBuilder.Where(t => t.Subject(s.Name).PredicateUri(p.MappedUri).Object(o));
patternBuilder.Where(t => t.Subject(s).PredicateUri(p.MappedUri).Object(o));

return o;
}
Expand Down Expand Up @@ -358,10 +362,12 @@ public void WhereEqual(MemberExpression expression, ConstantExpression c)
if (c.Value == null)
{
// If we want to filter for non-bound values we need to mark the properties as optional.
SparqlVariable o = BuildMemberAccessOptional(expression);
SparqlVariable so = BuildMemberAccessOptional(expression);

// TODO: If we filter a resource, make sure it has been described with variables in the local scope.

// Comparing with null means the variable is not bound.
PatternBuilder.Filter(e => !e.Bound(o.Name));
PatternBuilder.Filter(e => !e.Bound(so.Name));
}
else if(c.Type.IsValueType || c.Type == typeof(string))
{
Expand Down Expand Up @@ -403,9 +409,11 @@ public void WhereEqual(MemberExpression expression, ConstantExpression c)
else
{
// We are comparing reference types / resources against a bound value here.
SparqlVariable o = BuildMemberAccess(expression);
SparqlVariable so = BuildMemberAccess(expression);

// TODO: If we filter a resource, make sure it has been described with variables in the local scope.

PatternBuilder.Filter(e => e.Variable(o.Name) == c.AsIriExpression());
PatternBuilder.Filter(e => e.Variable(so.Name) == c.AsIriExpression());
}
}

Expand Down Expand Up @@ -582,14 +590,14 @@ public void FilterRegex(MemberExpression expression, string pattern, bool ignore

public void WhereResource(SparqlVariable s, SparqlVariable p, SparqlVariable o)
{
PatternBuilder.Where(t => t.Subject(s.Name).Predicate(p.Name).Object(o.Name));
PatternBuilder.Where(t => t.Subject(s).Predicate(p).Object(o));
}

public void WhereResource(Expression expression, SparqlVariable p, SparqlVariable o)
{
SparqlVariable s = VariableGenerator.TryGetSubjectVariable(expression) ?? SubjectVariable;

PatternBuilder.Where(t => t.Subject(s.Name).Predicate(p.Name).Object(o.Name));
PatternBuilder.Where(t => t.Subject(s).Predicate(p).Object(o));
}

public void WhereResourceOfType(Expression expression, Type type)
Expand All @@ -607,7 +615,7 @@ public void WhereResourceOfType(SparqlVariable s, Type type)
{
Uri a = new Uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");

PatternBuilder.Where(e => e.Subject(s.Name).PredicateUri(a).Object(t.MappedUri));
PatternBuilder.Where(e => e.Subject(s).PredicateUri(a).Object(t.MappedUri));
}
}

Expand Down
15 changes: 15 additions & 0 deletions Trinity/Query/Linq/SparqlVariableGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,21 @@ public void AddVariableMapping(Expression expression, string alias)
}
}

public bool HasSubjectVariable(Expression expression)
{
return TryGetSubjectVariable(expression) != null;
}

public bool HasPredicateVariable(Expression expression)
{
return TryGetPredicateVariable(expression) != null;
}

public bool HasObjectVariable(Expression expression)
{
return TryGetObjectVariable(expression) != null;
}

private SparqlVariable TryGetVariable(Dictionary<string, SparqlVariable> source, params Expression[] expressions)
{
foreach(Expression expression in expressions)
Expand Down

0 comments on commit 65367dd

Please sign in to comment.