Skip to content

Commit

Permalink
Add Solutions#merge based on JOIN semantics.
Browse files Browse the repository at this point in the history
  • Loading branch information
gkellogg committed Feb 4, 2019
1 parent 72c0318 commit 903569d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
15 changes: 15 additions & 0 deletions lib/rdf/query/solutions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,21 @@ def dup
RDF::Query::Solutions.new(self.compact.map(&:dup))
end

##
# Merge solutions in `other` into a new solutions instance. Each solution in `other` is merged into those solutions in `self` that are compatible.
#
# @param [RDF::Query::Solutions] other
# @return [RDF::Query::Solutions]
def merge(other)
other ||= RDF::Query::Solutions()
return other if self.empty?
return self if other.empty?

RDF::Query::Solutions(self.map do |s1|
other.map { |s2| s2.merge(s1) if s2.compatible?(s1) }
end.flatten.compact)
end

##
# Filters this solution sequence by the given `criteria`.
#
Expand Down
58 changes: 58 additions & 0 deletions spec/query_solutions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,64 @@
end
end

describe "merge" do
{
"add x dijoint" => [
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(x: RDF::URI("http://example.org/x")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
]),
],
"add x shared" => [
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), y: RDF::URI("http://example.org/y")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x"), y: RDF::URI("http://example.org/y")),
]),
],
"add x disjoint" => [
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/d"), y: RDF::URI("http://example.org/y")),
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/e"), y: RDF::URI("http://example.org/y")),
]),
RDF::Query::Solutions.new.concat([
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x"), y: RDF::URI("http://example.org/y")),
]),
],
}.each do |name, (left, right, result)|
it name do
expect(left.merge(right)).to be_a(Enumerable)
expect(left.merge(right)).to be_a(RDF::Query::Solutions)
expect(left.merge(right).to_a).to eq result.to_a
end
end
end

describe "#-" do
{
"subsetByExcl01" => [
Expand Down

0 comments on commit 903569d

Please sign in to comment.