Make RDF.Data.merge/3 implementations commutative
This commit is contained in:
parent
768bc9ae09
commit
af5cc26d7f
4 changed files with 77 additions and 2 deletions
|
@ -9,6 +9,10 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
|
||||
### Changed
|
||||
|
||||
- `RDF.Data.merge/3` is now commutative, i.e. structs which implement the
|
||||
`RDF.Data` protocol can be given also as the second argument
|
||||
(previously custom structs with `RDF.Data` protocol implementations always
|
||||
had to be given as the first argument)
|
||||
- several performance improvements
|
||||
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@ defprotocol RDF.Data do
|
|||
An abstraction over the different data structures for collections of RDF statements.
|
||||
"""
|
||||
|
||||
@type t :: RDF.Description.t() | RDF.Graph.t() | RDF.Dataset.t()
|
||||
|
||||
@doc """
|
||||
Adds statements to a RDF data structure.
|
||||
|
||||
|
@ -166,6 +164,14 @@ defimpl RDF.Data, for: RDF.Description do
|
|||
def merge(description, %Dataset{} = dataset, opts),
|
||||
do: RDF.Data.merge(dataset, description, opts)
|
||||
|
||||
def merge(description, %_{} = other, opts) do
|
||||
if RDF.Data.impl_for(other) do
|
||||
RDF.Data.merge(other, description, opts)
|
||||
else
|
||||
raise ArgumentError, "no RDF.Data implementation found for #{inspect(other)}"
|
||||
end
|
||||
end
|
||||
|
||||
def delete(description, input, opts \\ [])
|
||||
|
||||
def delete(
|
||||
|
@ -272,6 +278,14 @@ defimpl RDF.Data, for: RDF.Graph do
|
|||
def merge(graph, %Dataset{} = dataset, opts),
|
||||
do: RDF.Data.merge(dataset, graph, opts)
|
||||
|
||||
def merge(graph, %_{} = other, opts) do
|
||||
if RDF.Data.impl_for(other) do
|
||||
RDF.Data.merge(other, graph, opts)
|
||||
else
|
||||
raise ArgumentError, "no RDF.Data implementation found for #{inspect(other)}"
|
||||
end
|
||||
end
|
||||
|
||||
def delete(graph, input, opts \\ [])
|
||||
|
||||
def delete(%Graph{name: name} = graph, %Graph{name: other_name}, _opts)
|
||||
|
@ -340,6 +354,14 @@ defimpl RDF.Data, for: RDF.Dataset do
|
|||
def merge(dataset, %Dataset{} = other_dataset, opts),
|
||||
do: Dataset.add(dataset, other_dataset, opts)
|
||||
|
||||
def merge(dataset, %_{} = other, opts) do
|
||||
if RDF.Data.impl_for(other) do
|
||||
RDF.Data.merge(other, dataset, opts)
|
||||
else
|
||||
raise ArgumentError, "no RDF.Data implementation found for #{inspect(other)}"
|
||||
end
|
||||
end
|
||||
|
||||
def delete(dataset, input, opts \\ [])
|
||||
|
||||
def delete(%Dataset{name: name} = dataset, %Dataset{name: other_name}, _opts)
|
||||
|
|
32
test/support/external_data_impl.ex
Normal file
32
test/support/external_data_impl.ex
Normal file
|
@ -0,0 +1,32 @@
|
|||
defmodule External do
|
||||
defstruct []
|
||||
|
||||
import RDF.Sigils
|
||||
def data, do: RDF.triple(~I<http://example.com/S>, ~I<http://example.com/p>, 42)
|
||||
|
||||
defimpl RDF.Data do
|
||||
def merge(%External{}, data, opts) do
|
||||
RDF.Data.merge(data, External.data(), opts)
|
||||
end
|
||||
|
||||
def delete(_external, _, _opts), do: nil
|
||||
def pop(_external), do: nil
|
||||
def empty?(_external), do: false
|
||||
def include?(_external, _, _opts \\ []), do: false
|
||||
def describes?(_external, _), do: false
|
||||
def description(_external, _), do: nil
|
||||
def descriptions(_external), do: []
|
||||
def statements(_external), do: []
|
||||
def subjects(_external), do: []
|
||||
def predicates(_external), do: []
|
||||
def objects(_external), do: []
|
||||
def resources(_external), do: []
|
||||
def subject_count(_external), do: 0
|
||||
def statement_count(_external), do: 0
|
||||
|
||||
def values(_external, _opts \\ []), do: nil
|
||||
def map(_external, _fun), do: nil
|
||||
|
||||
def equal?(_, _), do: false
|
||||
end
|
||||
end
|
|
@ -625,4 +625,21 @@ defmodule RDF.DataTest do
|
|||
refute RDF.Data.equal?(dataset, graph)
|
||||
end
|
||||
end
|
||||
|
||||
test "external RDF.Data protocol implementations" do
|
||||
description = EX.S |> EX.p(EX.O2)
|
||||
|
||||
assert RDF.Data.merge(description, %External{}) ==
|
||||
Description.add(description, External.data())
|
||||
|
||||
graph = RDF.graph({EX.S, EX.p(), EX.O2})
|
||||
|
||||
assert RDF.Data.merge(graph, %External{}) ==
|
||||
Graph.add(graph, External.data())
|
||||
|
||||
dataset = RDF.dataset({EX.S, EX.p(), EX.O2})
|
||||
|
||||
assert RDF.Data.merge(dataset, %External{}) ==
|
||||
Dataset.add(dataset, External.data())
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue