core: delete statements from a Description

This commit is contained in:
Marcel Otto 2017-05-23 02:03:41 +02:00
parent ef5b5985dd
commit 5a911a9cce
2 changed files with 130 additions and 0 deletions

View file

@ -183,6 +183,65 @@ defmodule RDF.Description do
end
@doc """
Deletes statements from a `RDF.Description`.
"""
def delete(description, predicate, objects)
def delete(description, predicate, objects) when is_list(objects) do
Enum.reduce objects, description, fn (object, description) ->
delete(description, predicate, object)
end
end
def delete(%RDF.Description{subject: subject, predications: predications} = descr, predicate, object) do
with triple_predicate = convert_predicate(predicate),
triple_object = convert_object(object) do
if (objects = predications[triple_predicate]) && Map.has_key?(objects, triple_object) do
%RDF.Description{
subject: subject,
predications:
if map_size(objects) == 1 do
Map.delete(predications, triple_predicate)
else
Map.update!(predications, triple_predicate, fn objects ->
Map.delete(objects, triple_object)
end)
end
}
else
descr
end
end
end
@doc """
Deletes statements from a `RDF.Description`.
"""
def delete(description, statements)
def delete(desc = %RDF.Description{}, {predicate, object}),
do: delete(desc, predicate, object)
def delete(description = %RDF.Description{}, {subject, predicate, object}) do
if convert_subject(subject) == description.subject,
do: delete(description, predicate, object),
else: description
end
def delete(description, statements) when is_list(statements) do
Enum.reduce statements, description, fn (statement, description) ->
delete(description, statement)
end
end
def delete(description = %RDF.Description{}, predications = %{}) do
Enum.reduce predications, description, fn ({predicate, objects}, description) ->
delete(description, predicate, objects)
end
end
@doc """
Fetches the objects for the given predicate of a Description.

View file

@ -200,6 +200,77 @@ defmodule RDF.DescriptionTest do
end
end
describe "delete" do
setup do
{:ok,
empty_description: Description.new(EX.S),
description1: Description.new(EX.S, EX.p, EX.O),
description2: Description.new(EX.S, EX.p, [EX.O1, EX.O2]),
description3: Description.new(EX.S, [
{EX.p1, [EX.O1, EX.O2]},
{EX.p2, EX.O3},
{EX.p3, [~B<foo>, ~L"bar"]},
])
}
end
test "a single statement as a predicate object",
%{empty_description: empty_description, description1: description1, description2: description2} do
assert Description.delete(empty_description, EX.p, EX.O) == empty_description
assert Description.delete(description1, EX.p, EX.O) == empty_description
assert Description.delete(description2, EX.p, EX.O1) == Description.new(EX.S, EX.p, EX.O2)
end
test "a single statement as a predicate-object tuple",
%{empty_description: empty_description, description1: description1, description2: description2} do
assert Description.delete(empty_description, {EX.p, EX.O}) == empty_description
assert Description.delete(description1, {EX.p, EX.O}) == empty_description
assert Description.delete(description2, {EX.p, EX.O2}) == Description.new(EX.S, EX.p, EX.O1)
end
test "a single statement as a subject-predicate-object tuple and the proper description subject",
%{empty_description: empty_description, description1: description1, description2: description2} do
assert Description.delete(empty_description, {EX.S, EX.p, EX.O}) == empty_description
assert Description.delete(description1, {EX.S, EX.p, EX.O}) == empty_description
assert Description.delete(description2, {EX.S, EX.p, EX.O2}) == Description.new(EX.S, EX.p, EX.O1)
end
test "a single statement as a subject-predicate-object tuple and another description subject",
%{empty_description: empty_description, description1: description1, description2: description2} do
assert Description.delete(empty_description, {EX.Other, EX.p, EX.O}) == empty_description
assert Description.delete(description1, {EX.Other, EX.p, EX.O}) == description1
assert Description.delete(description2, {EX.Other, EX.p, EX.O2}) == description2
end
test "multiple statements via predicate-objects tuple",
%{empty_description: empty_description, description1: description1, description2: description2} do
assert Description.delete(empty_description, {EX.p, [EX.O1, EX.O2]}) == empty_description
assert Description.delete(description1, {EX.p, [EX.O, EX.O2]}) == empty_description
assert Description.delete(description2, {EX.p, [EX.O1, EX.O2]}) == empty_description
end
test "multiple statements with a list",
%{empty_description: empty_description, description3: description3} do
assert Description.delete(empty_description, [{EX.p, [EX.O1, EX.O2]}]) == empty_description
assert Description.delete(description3, [
{EX.p1, EX.O1},
{EX.p2, [EX.O2, EX.O3]},
{EX.S, EX.p3, [~B<foo>, ~L"bar"]},
]) == Description.new(EX.S, EX.p1, EX.O2)
end
test "multiple statements with a map of predications",
%{empty_description: empty_description, description3: description3} do
assert Description.delete(empty_description, [{EX.p, [EX.O1, EX.O2]}]) == empty_description
assert Description.delete(description3, %{
EX.p1 => EX.O1,
EX.p2 => [EX.O2, EX.O3],
EX.p3 => [~B<foo>, ~L"bar"],
}) == Description.new(EX.S, EX.p1, EX.O2)
end
end
test "pop" do
assert Description.pop(Description.new(EX.S)) == {nil, Description.new(EX.S)}