Move query builder into own module
This commit is contained in:
parent
1aa2f22b92
commit
b6aafccc7d
3 changed files with 182 additions and 180 deletions
|
@ -2,8 +2,6 @@ defmodule RDF.Query.BGP do
|
||||||
@enforce_keys [:triple_patterns]
|
@enforce_keys [:triple_patterns]
|
||||||
defstruct [:triple_patterns]
|
defstruct [:triple_patterns]
|
||||||
|
|
||||||
alias RDF.{IRI, BlankNode, Literal, Namespace}
|
|
||||||
import RDF.Utils.Guards
|
|
||||||
|
|
||||||
@type variable :: String.t
|
@type variable :: String.t
|
||||||
@type triple_pattern :: {
|
@type triple_pattern :: {
|
||||||
|
@ -16,148 +14,6 @@ defmodule RDF.Query.BGP do
|
||||||
@type t :: %__MODULE__{triple_patterns: triple_patterns}
|
@type t :: %__MODULE__{triple_patterns: triple_patterns}
|
||||||
|
|
||||||
|
|
||||||
def new(query) do
|
|
||||||
case new!(query) do
|
|
||||||
{:ok, bgp} -> bgp
|
|
||||||
{:error, error} -> raise error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def new!(query) do
|
|
||||||
with {:ok, triple_patterns} <- triple_patterns(query) do
|
|
||||||
{:ok, %__MODULE__{triple_patterns: triple_patterns}}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp triple_patterns(query) when is_list(query) do
|
|
||||||
Enum.reduce_while(query, {:ok, []}, fn
|
|
||||||
triple, {:ok, triple_patterns} ->
|
|
||||||
case triple_pattern(triple) do
|
|
||||||
{:ok, triple_pattern} ->
|
|
||||||
{:cont, {:ok, triple_patterns ++ List.wrap(triple_pattern)}}
|
|
||||||
|
|
||||||
{:error, error} ->
|
|
||||||
{:halt, {:error, error}}
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp triple_patterns(triple_pattern) when is_tuple(triple_pattern),
|
|
||||||
do: triple_patterns([triple_pattern])
|
|
||||||
|
|
||||||
defp triple_pattern({subject, predicate, object})
|
|
||||||
when not is_list(predicate) and not is_list(object) do
|
|
||||||
with {:ok, subject_pattern} <- subject_pattern(subject),
|
|
||||||
{:ok, predicate_pattern} <- predicate_pattern(predicate),
|
|
||||||
{:ok, object_pattern} <- object_pattern(object) do
|
|
||||||
{:ok, {subject_pattern, predicate_pattern, object_pattern}}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp triple_pattern(combined_objects_triple_pattern) when is_tuple(combined_objects_triple_pattern) do
|
|
||||||
[subject | rest] = Tuple.to_list(combined_objects_triple_pattern)
|
|
||||||
|
|
||||||
case rest do
|
|
||||||
[predicate | objects] when not is_list(predicate) ->
|
|
||||||
if Enum.all?(objects, &(not is_list(&1))) do
|
|
||||||
objects
|
|
||||||
|> Enum.map(fn object -> {subject, predicate, object} end)
|
|
||||||
|> triple_patterns()
|
|
||||||
else
|
|
||||||
{:error, %RDF.Query.InvalidError{
|
|
||||||
message: "Invalid use of predicate-object pair brackets"}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
predicate_object_pairs ->
|
|
||||||
if Enum.all?(predicate_object_pairs, &(is_list(&1) and length(&1) > 1)) do
|
|
||||||
predicate_object_pairs
|
|
||||||
|> Enum.flat_map(fn [predicate | objects] ->
|
|
||||||
Enum.map(objects, fn object -> {subject, predicate, object} end)
|
|
||||||
end)
|
|
||||||
|> triple_patterns()
|
|
||||||
else
|
|
||||||
{:error, %RDF.Query.InvalidError{
|
|
||||||
message: "Invalid use of predicate-object pair brackets"}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp subject_pattern(subject) do
|
|
||||||
value = variable(subject) || resource(subject)
|
|
||||||
|
|
||||||
if value do
|
|
||||||
{:ok, value}
|
|
||||||
else
|
|
||||||
{:error, %RDF.Query.InvalidError{
|
|
||||||
message: "Invalid subject term in BGP triple pattern: #{inspect subject}"}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp predicate_pattern(predicate) do
|
|
||||||
value = variable(predicate) || resource(predicate) || property(predicate)
|
|
||||||
|
|
||||||
if value do
|
|
||||||
{:ok, value}
|
|
||||||
else
|
|
||||||
{:error, %RDF.Query.InvalidError{
|
|
||||||
message: "Invalid predicate term in BGP triple pattern: #{inspect predicate}"}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp object_pattern(object) do
|
|
||||||
value = variable(object) || resource(object) || literal(object)
|
|
||||||
|
|
||||||
if value do
|
|
||||||
{:ok, value}
|
|
||||||
else
|
|
||||||
{:error, %RDF.Query.InvalidError{
|
|
||||||
message: "Invalid object term in BGP triple pattern: #{inspect object}"}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp variable(var) when is_atom(var) do
|
|
||||||
var_string = to_string(var)
|
|
||||||
|
|
||||||
if String.ends_with?(var_string, "?") do
|
|
||||||
var_string
|
|
||||||
|> String.slice(0..-2)
|
|
||||||
|> String.to_atom()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp variable(_), do: nil
|
|
||||||
|
|
||||||
defp resource(%IRI{} = iri), do: iri
|
|
||||||
defp resource(%URI{} = uri), do: IRI.new(uri)
|
|
||||||
defp resource(%BlankNode{} = bnode), do: bnode
|
|
||||||
|
|
||||||
defp resource(var) when is_ordinary_atom(var) do
|
|
||||||
case to_string(var) do
|
|
||||||
"_" <> bnode ->
|
|
||||||
BlankNode.new(bnode)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
case Namespace.resolve_term(var) do
|
|
||||||
{:ok, iri} -> iri
|
|
||||||
_ -> nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp resource(_), do: nil
|
|
||||||
|
|
||||||
defp property(:a), do: RDF.type()
|
|
||||||
defp property(_), do: nil
|
|
||||||
|
|
||||||
defp literal(%Literal{} = literal), do: literal
|
|
||||||
defp literal(value), do: Literal.coerce(value)
|
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Return a list of all variables in a BGP.
|
Return a list of all variables in a BGP.
|
||||||
"""
|
"""
|
||||||
|
@ -165,7 +21,7 @@ defmodule RDF.Query.BGP do
|
||||||
|
|
||||||
def variables(triple_patterns) when is_list(triple_patterns) do
|
def variables(triple_patterns) when is_list(triple_patterns) do
|
||||||
triple_patterns
|
triple_patterns
|
||||||
|> Enum.reduce([], fn triple_pattern, vars -> variables(triple_pattern) ++ vars end)
|
|> Enum.flat_map(&variables/1)
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
147
lib/rdf/query/builder.ex
Normal file
147
lib/rdf/query/builder.ex
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
defmodule RDF.Query.Builder do
|
||||||
|
alias RDF.Query.BGP
|
||||||
|
alias RDF.{IRI, BlankNode, Literal, Namespace}
|
||||||
|
import RDF.Utils.Guards
|
||||||
|
|
||||||
|
def bgp(query) do
|
||||||
|
with {:ok, triple_patterns} <- triple_patterns(query) do
|
||||||
|
{:ok, %BGP{triple_patterns: triple_patterns}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def bgp!(query) do
|
||||||
|
case bgp(query) do
|
||||||
|
{:ok, bgp} -> bgp
|
||||||
|
{:error, error} -> raise error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp triple_patterns(query) when is_list(query) do
|
||||||
|
Enum.reduce_while(query, {:ok, []}, fn
|
||||||
|
triple, {:ok, triple_patterns} ->
|
||||||
|
case triple_pattern(triple) do
|
||||||
|
{:ok, triple_pattern} ->
|
||||||
|
{:cont, {:ok, triple_patterns ++ List.wrap(triple_pattern)}}
|
||||||
|
|
||||||
|
{:error, error} ->
|
||||||
|
{:halt, {:error, error}}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp triple_patterns(triple_pattern) when is_tuple(triple_pattern),
|
||||||
|
do: triple_patterns([triple_pattern])
|
||||||
|
|
||||||
|
defp triple_pattern({subject, predicate, object})
|
||||||
|
when not is_list(predicate) and not is_list(object) do
|
||||||
|
with {:ok, subject_pattern} <- subject_pattern(subject),
|
||||||
|
{:ok, predicate_pattern} <- predicate_pattern(predicate),
|
||||||
|
{:ok, object_pattern} <- object_pattern(object) do
|
||||||
|
{:ok, {subject_pattern, predicate_pattern, object_pattern}}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp triple_pattern(combined_objects_triple_pattern) when is_tuple(combined_objects_triple_pattern) do
|
||||||
|
[subject | rest] = Tuple.to_list(combined_objects_triple_pattern)
|
||||||
|
|
||||||
|
case rest do
|
||||||
|
[predicate | objects] when not is_list(predicate) ->
|
||||||
|
if Enum.all?(objects, &(not is_list(&1))) do
|
||||||
|
objects
|
||||||
|
|> Enum.map(fn object -> {subject, predicate, object} end)
|
||||||
|
|> triple_patterns()
|
||||||
|
else
|
||||||
|
{:error, %RDF.Query.InvalidError{
|
||||||
|
message: "Invalid use of predicate-object pair brackets"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
predicate_object_pairs ->
|
||||||
|
if Enum.all?(predicate_object_pairs, &(is_list(&1) and length(&1) > 1)) do
|
||||||
|
predicate_object_pairs
|
||||||
|
|> Enum.flat_map(fn [predicate | objects] ->
|
||||||
|
Enum.map(objects, fn object -> {subject, predicate, object} end)
|
||||||
|
end)
|
||||||
|
|> triple_patterns()
|
||||||
|
else
|
||||||
|
{:error, %RDF.Query.InvalidError{
|
||||||
|
message: "Invalid use of predicate-object pair brackets"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp subject_pattern(subject) do
|
||||||
|
value = variable(subject) || resource(subject)
|
||||||
|
|
||||||
|
if value do
|
||||||
|
{:ok, value}
|
||||||
|
else
|
||||||
|
{:error, %RDF.Query.InvalidError{
|
||||||
|
message: "Invalid subject term in BGP triple pattern: #{inspect subject}"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp predicate_pattern(predicate) do
|
||||||
|
value = variable(predicate) || resource(predicate) || property(predicate)
|
||||||
|
|
||||||
|
if value do
|
||||||
|
{:ok, value}
|
||||||
|
else
|
||||||
|
{:error, %RDF.Query.InvalidError{
|
||||||
|
message: "Invalid predicate term in BGP triple pattern: #{inspect predicate}"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp object_pattern(object) do
|
||||||
|
value = variable(object) || resource(object) || literal(object)
|
||||||
|
|
||||||
|
if value do
|
||||||
|
{:ok, value}
|
||||||
|
else
|
||||||
|
{:error, %RDF.Query.InvalidError{
|
||||||
|
message: "Invalid object term in BGP triple pattern: #{inspect object}"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp variable(var) when is_atom(var) do
|
||||||
|
var_string = to_string(var)
|
||||||
|
|
||||||
|
if String.ends_with?(var_string, "?") do
|
||||||
|
var_string
|
||||||
|
|> String.slice(0..-2)
|
||||||
|
|> String.to_atom()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp variable(_), do: nil
|
||||||
|
|
||||||
|
defp resource(%IRI{} = iri), do: iri
|
||||||
|
defp resource(%URI{} = uri), do: IRI.new(uri)
|
||||||
|
defp resource(%BlankNode{} = bnode), do: bnode
|
||||||
|
|
||||||
|
defp resource(var) when is_ordinary_atom(var) do
|
||||||
|
case to_string(var) do
|
||||||
|
"_" <> bnode ->
|
||||||
|
BlankNode.new(bnode)
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
case Namespace.resolve_term(var) do
|
||||||
|
{:ok, iri} -> iri
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp resource(_), do: nil
|
||||||
|
|
||||||
|
defp property(:a), do: RDF.type()
|
||||||
|
defp property(_), do: nil
|
||||||
|
|
||||||
|
defp literal(%Literal{} = literal), do: literal
|
||||||
|
defp literal(value), do: Literal.coerce(value)
|
||||||
|
|
||||||
|
end
|
|
@ -1,68 +1,68 @@
|
||||||
defmodule RDF.Query.BGPTest do
|
defmodule RDF.Query.BuilderTest do
|
||||||
use RDF.Test.Case
|
use RDF.Test.Case
|
||||||
|
|
||||||
alias RDF.Query.BGP
|
alias RDF.Query.{BGP, Builder}
|
||||||
|
|
||||||
defp bgp(triple_patterns) when is_list(triple_patterns),
|
defp bgp(triple_patterns) when is_list(triple_patterns),
|
||||||
do: %BGP{triple_patterns: triple_patterns}
|
do: {:ok, %BGP{triple_patterns: triple_patterns}}
|
||||||
|
|
||||||
describe "new/1" do
|
describe "new/1" do
|
||||||
test "empty triple pattern" do
|
test "empty triple pattern" do
|
||||||
assert BGP.new([]) == bgp([])
|
assert Builder.bgp([]) == bgp([])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "one triple pattern doesn't require list brackets" do
|
test "one triple pattern doesn't require list brackets" do
|
||||||
assert BGP.new({EX.s, EX.p, EX.o}) ==
|
assert Builder.bgp({EX.s, EX.p, EX.o}) ==
|
||||||
bgp [{EX.s, EX.p, EX.o}]
|
bgp [{EX.s, EX.p, EX.o}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "variables" do
|
test "variables" do
|
||||||
assert BGP.new([{:s?, :p?, :o?}]) == bgp [{:s, :p, :o}]
|
assert Builder.bgp([{:s?, :p?, :o?}]) == bgp [{:s, :p, :o}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "blank nodes" do
|
test "blank nodes" do
|
||||||
assert BGP.new([{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]) ==
|
assert Builder.bgp([{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]) ==
|
||||||
bgp [{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]
|
bgp [{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "blank nodes as atoms" do
|
test "blank nodes as atoms" do
|
||||||
assert BGP.new([{:_s, :_p, :_o}]) ==
|
assert Builder.bgp([{:_s, :_p, :_o}]) ==
|
||||||
bgp [{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]
|
bgp [{RDF.bnode("s"), RDF.bnode("p"), RDF.bnode("o")}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "variable notation has precedence over blank node notation" do
|
test "variable notation has precedence over blank node notation" do
|
||||||
assert BGP.new([{:_s?, :_p?, :_o?}]) == bgp [{:_s, :_p, :_o}]
|
assert Builder.bgp([{:_s?, :_p?, :_o?}]) == bgp [{:_s, :_p, :_o}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "IRIs" do
|
test "IRIs" do
|
||||||
assert BGP.new([{
|
assert Builder.bgp([{
|
||||||
RDF.iri("http://example.com/s"),
|
RDF.iri("http://example.com/s"),
|
||||||
RDF.iri("http://example.com/p"),
|
RDF.iri("http://example.com/p"),
|
||||||
RDF.iri("http://example.com/o")}]
|
RDF.iri("http://example.com/o")}]
|
||||||
) == bgp [{EX.s, EX.p, EX.o}]
|
) == bgp [{EX.s, EX.p, EX.o}]
|
||||||
|
|
||||||
assert BGP.new([{
|
assert Builder.bgp([{
|
||||||
~I<http://example.com/s>,
|
~I<http://example.com/s>,
|
||||||
~I<http://example.com/p>,
|
~I<http://example.com/p>,
|
||||||
~I<http://example.com/o>}]
|
~I<http://example.com/o>}]
|
||||||
) == bgp [{EX.s, EX.p, EX.o}]
|
) == bgp [{EX.s, EX.p, EX.o}]
|
||||||
|
|
||||||
assert BGP.new([{EX.s, EX.p, EX.o}]) ==
|
assert Builder.bgp([{EX.s, EX.p, EX.o}]) ==
|
||||||
bgp [{EX.s, EX.p, EX.o}]
|
bgp [{EX.s, EX.p, EX.o}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "vocabulary term atoms" do
|
test "vocabulary term atoms" do
|
||||||
assert BGP.new([{EX.S, EX.P, EX.O}]) ==
|
assert Builder.bgp([{EX.S, EX.P, EX.O}]) ==
|
||||||
bgp [{RDF.iri(EX.S), RDF.iri(EX.P), RDF.iri(EX.O)}]
|
bgp [{RDF.iri(EX.S), RDF.iri(EX.P), RDF.iri(EX.O)}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "special :a atom for rdf:type" do
|
test "special :a atom for rdf:type" do
|
||||||
assert BGP.new([{EX.S, :a, EX.O}]) ==
|
assert Builder.bgp([{EX.S, :a, EX.O}]) ==
|
||||||
bgp [{RDF.iri(EX.S), RDF.type, RDF.iri(EX.O)}]
|
bgp [{RDF.iri(EX.S), RDF.type, RDF.iri(EX.O)}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "URIs" do
|
test "URIs" do
|
||||||
assert BGP.new([{
|
assert Builder.bgp([{
|
||||||
URI.parse("http://example.com/s"),
|
URI.parse("http://example.com/s"),
|
||||||
URI.parse("http://example.com/p"),
|
URI.parse("http://example.com/p"),
|
||||||
URI.parse("http://example.com/o")}]
|
URI.parse("http://example.com/o")}]
|
||||||
|
@ -70,27 +70,26 @@ defmodule RDF.Query.BGPTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "literals" do
|
test "literals" do
|
||||||
assert BGP.new([{EX.s, EX.p, ~L"foo"}]) ==
|
assert Builder.bgp([{EX.s, EX.p, ~L"foo"}]) ==
|
||||||
bgp [{EX.s, EX.p, ~L"foo"}]
|
bgp [{EX.s, EX.p, ~L"foo"}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "values coercible to literals" do
|
test "values coercible to literals" do
|
||||||
assert BGP.new([{EX.s, EX.p, "foo"}]) ==
|
assert Builder.bgp([{EX.s, EX.p, "foo"}]) ==
|
||||||
bgp [{EX.s, EX.p, ~L"foo"}]
|
bgp [{EX.s, EX.p, ~L"foo"}]
|
||||||
assert BGP.new([{EX.s, EX.p, 42}]) ==
|
assert Builder.bgp([{EX.s, EX.p, 42}]) ==
|
||||||
bgp [{EX.s, EX.p, RDF.literal(42)}]
|
bgp [{EX.s, EX.p, RDF.literal(42)}]
|
||||||
assert BGP.new([{EX.s, EX.p, true}]) ==
|
assert Builder.bgp([{EX.s, EX.p, true}]) ==
|
||||||
bgp [{EX.s, EX.p, XSD.true}]
|
bgp [{EX.s, EX.p, XSD.true}]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "literals on non-object positions" do
|
test "literals on non-object positions" do
|
||||||
assert_raise RDF.Query.InvalidError, fn ->
|
assert {:error, %RDF.Query.InvalidError{}} =
|
||||||
assert BGP.new([{~L"foo", EX.p, ~L"bar"}])
|
Builder.bgp([{~L"foo", EX.p, ~L"bar"}])
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiple triple patterns" do
|
test "multiple triple patterns" do
|
||||||
assert BGP.new([
|
assert Builder.bgp([
|
||||||
{EX.S, EX.p, :o?},
|
{EX.S, EX.p, :o?},
|
||||||
{:o?, EX.p2, 42}
|
{:o?, EX.p2, 42}
|
||||||
]) ==
|
]) ==
|
||||||
|
@ -101,19 +100,19 @@ defmodule RDF.Query.BGPTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiple objects to the same subject-predicate" do
|
test "multiple objects to the same subject-predicate" do
|
||||||
assert BGP.new([{EX.s, EX.p, EX.o1, EX.o2}]) ==
|
assert Builder.bgp([{EX.s, EX.p, EX.o1, EX.o2}]) ==
|
||||||
bgp [
|
bgp [
|
||||||
{EX.s, EX.p, EX.o1},
|
{EX.s, EX.p, EX.o1},
|
||||||
{EX.s, EX.p, EX.o2}
|
{EX.s, EX.p, EX.o2}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert BGP.new({EX.s, EX.p, EX.o1, EX.o2}) ==
|
assert Builder.bgp({EX.s, EX.p, EX.o1, EX.o2}) ==
|
||||||
bgp [
|
bgp [
|
||||||
{EX.s, EX.p, EX.o1},
|
{EX.s, EX.p, EX.o1},
|
||||||
{EX.s, EX.p, EX.o2}
|
{EX.s, EX.p, EX.o2}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert BGP.new({EX.s, EX.p, :o?, false, 42, "foo"}) ==
|
assert Builder.bgp({EX.s, EX.p, :o?, false, 42, "foo"}) ==
|
||||||
bgp [
|
bgp [
|
||||||
{EX.s, EX.p, :o},
|
{EX.s, EX.p, :o},
|
||||||
{EX.s, EX.p, XSD.false},
|
{EX.s, EX.p, XSD.false},
|
||||||
|
@ -123,7 +122,7 @@ defmodule RDF.Query.BGPTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "multiple predicate-object pairs to the same subject" do
|
test "multiple predicate-object pairs to the same subject" do
|
||||||
assert BGP.new([{
|
assert Builder.bgp([{
|
||||||
EX.s,
|
EX.s,
|
||||||
[EX.p1, EX.o1],
|
[EX.p1, EX.o1],
|
||||||
[EX.p2, EX.o2],
|
[EX.p2, EX.o2],
|
||||||
|
@ -133,7 +132,7 @@ defmodule RDF.Query.BGPTest do
|
||||||
{EX.s, EX.p2, EX.o2}
|
{EX.s, EX.p2, EX.o2}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert BGP.new([{
|
assert Builder.bgp([{
|
||||||
EX.s,
|
EX.s,
|
||||||
[:a, :o?],
|
[:a, :o?],
|
||||||
[EX.p1, 42, 3.14],
|
[EX.p1, 42, 3.14],
|
||||||
|
@ -147,7 +146,7 @@ defmodule RDF.Query.BGPTest do
|
||||||
{EX.s, EX.p2, XSD.true}
|
{EX.s, EX.p2, XSD.true}
|
||||||
]
|
]
|
||||||
|
|
||||||
assert BGP.new([{EX.s, [EX.p, EX.o]}]) ==
|
assert Builder.bgp([{EX.s, [EX.p, EX.o]}]) ==
|
||||||
bgp [{EX.s, EX.p, EX.o}]
|
bgp [{EX.s, EX.p, EX.o}]
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue