core: Description.put

This commit is contained in:
Marcel Otto 2016-11-26 23:45:41 +01:00
parent 012daff14d
commit ebd751827f
3 changed files with 79 additions and 4 deletions

View file

@ -29,6 +29,8 @@ defmodule RDF.Description do
do: %RDF.Description{subject: Triple.convert_subject(subject)}
def new(subject, predicate, objects),
do: new(subject) |> add(predicate, objects)
def new(subject, statements) when is_list(statements),
do: new(subject) |> add(statements)
def new(subject, description = %RDF.Description{}),
do: new(subject) |> add(description)
def new(subject, predications = %{}),
@ -58,7 +60,8 @@ defmodule RDF.Description do
triple_object = Triple.convert_object(object),
new_predications = Map.update(predications,
triple_predicate, %{triple_object => nil}, fn objects ->
Map.put_new(objects, triple_object, nil) end) do
Map.put_new(objects, triple_object, nil)
end) do
%RDF.Description{subject: subject, predications: new_predications}
end
end
@ -119,8 +122,8 @@ defmodule RDF.Description do
predications: Map.put(predications, triple_predicate, triple_objects)}
end
def put(desc = %RDF.Description{}, predicate, objects),
do: put(desc, predicate, [objects])
def put(desc = %RDF.Description{}, predicate, object),
do: put(desc, predicate, [object])
@doc """
Adds statements to a `RDF.Description` and overwrites all existing statements with already used predicates.

View file

@ -97,6 +97,65 @@ defmodule RDF.Graph do
end
end
@doc """
Puts statements to a `RDF.Graph`, overwriting all statements with the same subject and predicate.
# Examples
iex> RDF.Graph.new(EX.S, EX.P, EX.O1) |> RDF.Graph.put(EX.S, EX.P, EX.O2)
RDF.Graph.new(EX.S, EX.P, EX.O2)
iex> RDF.Graph.new(EX.S, EX.P1, EX.O1) |> RDF.Graph.put(EX.S, EX.P2, EX.O2)
RDF.Graph.new([{EX.S, EX.P1, EX.O1}, {EX.S, EX.P2, EX.O2}])
"""
def put(%RDF.Graph{name: name, descriptions: descriptions},
subject, predicate, objects) do
with triple_subject = Triple.convert_subject(subject) do
new_description = case descriptions[triple_subject] do
desc = %Description{} -> Description.put(desc, predicate, objects)
nil -> Description.new(triple_subject, predicate, objects)
end
%RDF.Graph{name: name,
descriptions: Map.put(descriptions, triple_subject, new_description)}
end
end
@doc """
Adds statements to a `RDF.Graph` and overwrites all existing statements with the same subjects and predicates.
# Examples
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}]) |>
...> RDF.Graph.put([{EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
"""
def put(graph, statements)
def put(graph = %RDF.Graph{}, {subject, predicate, object}),
do: put(graph, subject, predicate, object)
def put(graph = %RDF.Graph{}, statements) when is_map(statements) do
Enum.reduce statements, graph, fn ({subject, predications}, graph) ->
put(graph, subject, predications)
end
end
def put(graph = %RDF.Graph{}, statements) when is_list(statements) do
put(graph, Enum.group_by(statements, &(elem(&1, 0)), fn {_, p, o} -> {p, o} end))
end
def put(%RDF.Graph{name: name, descriptions: descriptions}, subject, predications)
when is_list(predications) do
with triple_subject = Triple.convert_subject(subject),
description = Map.get(descriptions, triple_subject)
|| Description.new(triple_subject) do
new_descriptions = descriptions
|> Map.put(triple_subject, Description.put(description, predications))
%RDF.Graph{name: name, descriptions: new_descriptions}
end
end
def subject_count(graph), do: Enum.count(graph.descriptions)
def triple_count(%RDF.Graph{descriptions: descriptions}) do

View file

@ -7,7 +7,7 @@ defmodule RDF.GraphTest do
doctest RDF.Graph
alias RDF.{Graph, Description}
import RDF, only: [uri: 1]
import RDF, only: [uri: 1, literal: 1, bnode: 1]
def graph, do: unnamed_graph
@ -138,6 +138,19 @@ defmodule RDF.GraphTest do
end
end
test "putting triples" do
g = Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> RDF.Graph.put([{EX.S1, EX.P2, EX.O3}, {EX.S1, EX.P2, bnode(:foo)},
{EX.S2, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O4}])
assert Graph.triple_count(g) == 5
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P2, EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O3})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O4})
end
test "subject_count" do
g = Graph.add(graph, [
{EX.Subject1, EX.predicate1, EX.Object1},