Add describes?/1 to RDF.Data protocol and all RDF data structures
This commit is contained in:
parent
a6db9723ca
commit
dc7dce7dbc
6 changed files with 118 additions and 10 deletions
|
@ -10,8 +10,10 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
|||
### Added
|
||||
|
||||
- Turtle decoder
|
||||
- `describes?/1` on `RDF.Data` protocol and all RDF data structures which check
|
||||
if statements about a given resource exist
|
||||
- `RDF.Data.descriptions/1` which returns all descriptions within a RDF data structure
|
||||
- `RDF.Description.first/2` which returns a single object a predicate of a `RDF.Description`
|
||||
- `RDF.Description.first/2` which returns a single object to a predicate of a `RDF.Description`
|
||||
- `RDF.Description.objects/2` with custom filter function
|
||||
- `RDF.bnode?/1` which checks if the given value is a blank node
|
||||
|
||||
|
|
|
@ -37,9 +37,9 @@ defprotocol RDF.Data do
|
|||
def include?(data, statements)
|
||||
|
||||
@doc """
|
||||
Returns the list of all statements of a RDF data structure.
|
||||
Checks if a RDF data structure contains statements about the given resource.
|
||||
"""
|
||||
def statements(data)
|
||||
def describes?(data, subject)
|
||||
|
||||
@doc """
|
||||
Returns a `RDF.Description` of the given subject.
|
||||
|
@ -57,6 +57,11 @@ defprotocol RDF.Data do
|
|||
"""
|
||||
def descriptions(data)
|
||||
|
||||
@doc """
|
||||
Returns the list of all statements of a RDF data structure.
|
||||
"""
|
||||
def statements(data)
|
||||
|
||||
@doc """
|
||||
Returns the set of all resources which are subject of the statements of a RDF data structure.
|
||||
"""
|
||||
|
@ -129,7 +134,8 @@ defimpl RDF.Data, for: RDF.Description do
|
|||
def include?(description, statements),
|
||||
do: RDF.Description.include?(description, statements)
|
||||
|
||||
def statements(description), do: RDF.Description.statements(description)
|
||||
def describes?(description, subject),
|
||||
do: RDF.Description.describes?(description, subject)
|
||||
|
||||
def description(%RDF.Description{subject: subject} = description, s) do
|
||||
with ^subject <- RDF.Statement.convert_subject(s) do
|
||||
|
@ -141,6 +147,8 @@ defimpl RDF.Data, for: RDF.Description do
|
|||
|
||||
def descriptions(description), do: [description]
|
||||
|
||||
def statements(description), do: RDF.Description.statements(description)
|
||||
|
||||
def subjects(%RDF.Description{subject: subject}), do: MapSet.new([subject])
|
||||
def predicates(description), do: RDF.Description.predicates(description)
|
||||
def objects(description), do: RDF.Description.objects(description)
|
||||
|
@ -193,13 +201,16 @@ defimpl RDF.Data, for: RDF.Graph do
|
|||
|
||||
def include?(graph, statements), do: RDF.Graph.include?(graph, statements)
|
||||
|
||||
def statements(graph), do: RDF.Graph.statements(graph)
|
||||
def describes?(graph, subject),
|
||||
do: RDF.Graph.describes?(graph, subject)
|
||||
|
||||
def description(graph, subject),
|
||||
do: RDF.Graph.description(graph, subject) || RDF.Description.new(subject)
|
||||
|
||||
def descriptions(graph), do: RDF.Graph.descriptions(graph)
|
||||
|
||||
def statements(graph), do: RDF.Graph.statements(graph)
|
||||
|
||||
def subjects(graph), do: RDF.Graph.subjects(graph)
|
||||
def predicates(graph), do: RDF.Graph.predicates(graph)
|
||||
def objects(graph), do: RDF.Graph.objects(graph)
|
||||
|
@ -231,7 +242,8 @@ defimpl RDF.Data, for: RDF.Dataset do
|
|||
|
||||
def include?(dataset, statements), do: RDF.Dataset.include?(dataset, statements)
|
||||
|
||||
def statements(dataset), do: RDF.Dataset.statements(dataset)
|
||||
def describes?(dataset, subject),
|
||||
do: RDF.Dataset.who_describes(dataset, subject) != []
|
||||
|
||||
def description(dataset, subject) do
|
||||
with subject = RDF.Statement.convert_subject(subject) do
|
||||
|
@ -250,6 +262,8 @@ defimpl RDF.Data, for: RDF.Dataset do
|
|||
|> Enum.map(&(description(dataset, &1)))
|
||||
end
|
||||
|
||||
def statements(dataset), do: RDF.Dataset.statements(dataset)
|
||||
|
||||
def subjects(dataset), do: RDF.Dataset.subjects(dataset)
|
||||
def predicates(dataset), do: RDF.Dataset.predicates(dataset)
|
||||
def objects(dataset), do: RDF.Dataset.objects(dataset)
|
||||
|
|
|
@ -683,6 +683,47 @@ defmodule RDF.Dataset do
|
|||
do: include?(dataset, {subject, predicate, object}, graph_context)
|
||||
|
||||
|
||||
@doc """
|
||||
Checks if a graph of a `RDF.Dataset` contains statements about the given resource.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.Dataset.new([{EX.S1, EX.p1, EX.O1}]) |> RDF.Dataset.describes?(EX.S1)
|
||||
true
|
||||
iex> RDF.Dataset.new([{EX.S1, EX.p1, EX.O1}]) |> RDF.Dataset.describes?(EX.S2)
|
||||
false
|
||||
"""
|
||||
def describes?(%RDF.Dataset{graphs: graphs}, subject, graph_context \\ nil) do
|
||||
with graph_context = convert_graph_name(graph_context) do
|
||||
if graph = graphs[graph_context] do
|
||||
Graph.describes?(graph, subject)
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the names of all graphs of a `RDF.Dataset` containing statements about the given subject.
|
||||
|
||||
## Examples
|
||||
iex> dataset = RDF.Dataset.new([
|
||||
...> {EX.S1, EX.p, EX.O},
|
||||
...> {EX.S2, EX.p, EX.O},
|
||||
...> {EX.S1, EX.p, EX.O, EX.Graph1},
|
||||
...> {EX.S2, EX.p, EX.O, EX.Graph2}])
|
||||
...> RDF.Dataset.who_describes(dataset, EX.S1)
|
||||
[nil, RDF.uri(EX.Graph1)]
|
||||
"""
|
||||
def who_describes(%RDF.Dataset{graphs: graphs}, subject) do
|
||||
with subject = convert_subject(subject) do
|
||||
graphs
|
||||
|> Map.values
|
||||
|> Stream.filter(&Graph.describes?(&1, subject))
|
||||
|> Enum.map(&(&1.name))
|
||||
end
|
||||
end
|
||||
|
||||
defimpl Enumerable do
|
||||
def member?(graph, statement), do: {:ok, RDF.Dataset.include?(graph, statement)}
|
||||
def count(graph), do: {:ok, RDF.Dataset.statement_count(graph)}
|
||||
|
|
|
@ -552,6 +552,23 @@ defmodule RDF.Description do
|
|||
def include?(%RDF.Description{}, _), do: false
|
||||
|
||||
|
||||
@doc """
|
||||
Checks if a `RDF.Description` has the given resource as subject.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.Description.new(EX.S1, EX.p1, EX.O1) |> RDF.Description.describes?(EX.S1)
|
||||
true
|
||||
iex> RDF.Description.new(EX.S1, EX.p1, EX.O1) |> RDF.Description.describes?(EX.S2)
|
||||
false
|
||||
"""
|
||||
def describes?(%RDF.Description{subject: subject}, other_subject) do
|
||||
with other_subject = convert_subject(other_subject) do
|
||||
subject == other_subject
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defimpl Enumerable do
|
||||
def member?(desc, triple), do: {:ok, RDF.Description.include?(desc, triple)}
|
||||
def count(desc), do: {:ok, RDF.Description.count(desc)}
|
||||
|
|
|
@ -582,6 +582,22 @@ defmodule RDF.Graph do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if a `RDF.Graph` contains statements about the given resource.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> RDF.Graph.new([{EX.S1, EX.p1, EX.O1}]) |> RDF.Graph.describes?(EX.S1)
|
||||
true
|
||||
iex> RDF.Graph.new([{EX.S1, EX.p1, EX.O1}]) |> RDF.Graph.describes?(EX.S2)
|
||||
false
|
||||
"""
|
||||
def describes?(%RDF.Graph{descriptions: descriptions}, subject) do
|
||||
with subject = convert_subject(subject) do
|
||||
Map.has_key?(descriptions, subject)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
defimpl Enumerable do
|
||||
def member?(desc, triple), do: {:ok, RDF.Graph.include?(desc, triple)}
|
||||
|
|
|
@ -91,8 +91,9 @@ defmodule RDF.DataTest do
|
|||
refute RDF.Data.include?(description, {EX.Other, EX.p1, EX.O2})
|
||||
end
|
||||
|
||||
test "statements", %{description: description} do
|
||||
assert RDF.Data.statements(description) == Description.statements(description)
|
||||
test "describes?", %{description: description} do
|
||||
assert RDF.Data.describes?(description, EX.S)
|
||||
refute RDF.Data.describes?(description, EX.Other)
|
||||
end
|
||||
|
||||
test "description when the requested subject matches the Description.subject",
|
||||
|
@ -111,6 +112,10 @@ defmodule RDF.DataTest do
|
|||
assert RDF.Data.descriptions(description) == [description]
|
||||
end
|
||||
|
||||
test "statements", %{description: description} do
|
||||
assert RDF.Data.statements(description) == Description.statements(description)
|
||||
end
|
||||
|
||||
test "subjects", %{description: description} do
|
||||
assert RDF.Data.subjects(description) == MapSet.new([uri(EX.S)])
|
||||
end
|
||||
|
@ -215,8 +220,10 @@ defmodule RDF.DataTest do
|
|||
refute RDF.Data.include?(graph, {EX.Other, EX.p1, EX.O2})
|
||||
end
|
||||
|
||||
test "statements", %{graph: graph} do
|
||||
assert RDF.Data.statements(graph) == Graph.statements(graph)
|
||||
test "describes?", %{graph: graph} do
|
||||
assert RDF.Data.describes?(graph, EX.S)
|
||||
assert RDF.Data.describes?(graph, EX.S2)
|
||||
refute RDF.Data.describes?(graph, EX.Other)
|
||||
end
|
||||
|
||||
test "description when a description is present",
|
||||
|
@ -234,6 +241,10 @@ defmodule RDF.DataTest do
|
|||
[description, EX.S2 |> EX.p2(EX.O3, EX.O4)]
|
||||
end
|
||||
|
||||
test "statements", %{graph: graph} do
|
||||
assert RDF.Data.statements(graph) == Graph.statements(graph)
|
||||
end
|
||||
|
||||
test "subjects", %{graph: graph} do
|
||||
assert RDF.Data.subjects(graph) == MapSet.new([uri(EX.S), uri(EX.S2)])
|
||||
end
|
||||
|
@ -321,6 +332,13 @@ defmodule RDF.DataTest do
|
|||
refute RDF.Data.include?(dataset, {EX.Other, EX.p1, EX.O2})
|
||||
end
|
||||
|
||||
test "describes?", %{dataset: dataset} do
|
||||
assert RDF.Data.describes?(dataset, EX.S)
|
||||
assert RDF.Data.describes?(dataset, EX.S2)
|
||||
assert RDF.Data.describes?(dataset, EX.S3)
|
||||
refute RDF.Data.describes?(dataset, EX.Other)
|
||||
end
|
||||
|
||||
test "description when a description is present",
|
||||
%{dataset: dataset, description: description} do
|
||||
description_aggregate = Description.add(description, {EX.S, EX.p3, EX.O5})
|
||||
|
|
Loading…
Reference in a new issue