Skip to content

Commit 903569d

Browse files
committed
Add Solutions#merge based on JOIN semantics.
1 parent 72c0318 commit 903569d

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

lib/rdf/query/solutions.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ def dup
112112
RDF::Query::Solutions.new(self.compact.map(&:dup))
113113
end
114114

115+
##
116+
# Merge solutions in `other` into a new solutions instance. Each solution in `other` is merged into those solutions in `self` that are compatible.
117+
#
118+
# @param [RDF::Query::Solutions] other
119+
# @return [RDF::Query::Solutions]
120+
def merge(other)
121+
other ||= RDF::Query::Solutions()
122+
return other if self.empty?
123+
return self if other.empty?
124+
125+
RDF::Query::Solutions(self.map do |s1|
126+
other.map { |s2| s2.merge(s1) if s2.compatible?(s1) }
127+
end.flatten.compact)
128+
end
129+
115130
##
116131
# Filters this solution sequence by the given `criteria`.
117132
#

spec/query_solutions_spec.rb

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,64 @@
6767
end
6868
end
6969

70+
describe "merge" do
71+
{
72+
"add x dijoint" => [
73+
RDF::Query::Solutions.new.concat([
74+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a")),
75+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b")),
76+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c")),
77+
]),
78+
RDF::Query::Solutions.new.concat([
79+
RDF::Query::Solution.new(x: RDF::URI("http://example.org/x")),
80+
]),
81+
RDF::Query::Solutions.new.concat([
82+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
83+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
84+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
85+
]),
86+
],
87+
"add x shared" => [
88+
RDF::Query::Solutions.new.concat([
89+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
90+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
91+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
92+
]),
93+
RDF::Query::Solutions.new.concat([
94+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), y: RDF::URI("http://example.org/y")),
95+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), y: RDF::URI("http://example.org/y")),
96+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), y: RDF::URI("http://example.org/y")),
97+
]),
98+
RDF::Query::Solutions.new.concat([
99+
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")),
100+
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")),
101+
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")),
102+
]),
103+
],
104+
"add x disjoint" => [
105+
RDF::Query::Solutions.new.concat([
106+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), x: RDF::URI("http://example.org/x")),
107+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/b"), x: RDF::URI("http://example.org/x")),
108+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/c"), x: RDF::URI("http://example.org/x")),
109+
]),
110+
RDF::Query::Solutions.new.concat([
111+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/a"), y: RDF::URI("http://example.org/y")),
112+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/d"), y: RDF::URI("http://example.org/y")),
113+
RDF::Query::Solution.new(animal: RDF::URI("http://example.org/e"), y: RDF::URI("http://example.org/y")),
114+
]),
115+
RDF::Query::Solutions.new.concat([
116+
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")),
117+
]),
118+
],
119+
}.each do |name, (left, right, result)|
120+
it name do
121+
expect(left.merge(right)).to be_a(Enumerable)
122+
expect(left.merge(right)).to be_a(RDF::Query::Solutions)
123+
expect(left.merge(right).to_a).to eq result.to_a
124+
end
125+
end
126+
end
127+
70128
describe "#-" do
71129
{
72130
"subsetByExcl01" => [

0 commit comments

Comments
 (0)