core: add RDF.Dataset.delete

This commit is contained in:
Marcel Otto 2017-06-04 03:58:30 +02:00
parent 3f403d6f64
commit 25a2d963f6
2 changed files with 164 additions and 0 deletions

View file

@ -255,6 +255,68 @@ defmodule RDF.Dataset do
do: put(dataset, {subject, graph_context}, predications, graph_context)
@doc """
Deletes statements from a `RDF.Dataset`.
The optional third argument `graph_context` defaulting to `nil` for the default
graph, specifies the graph to which the statements are added.
Note that this also applies when deleting a named graph. Its name is ignored over
`graph_context` and its default value.
Note: When the statements to be deleted are given as another `RDF.Dataset`,
the dataset name must not match dataset name of the dataset from which the statements
are deleted. If you want to delete only datasets with matching names, you can
use `RDF.Data.delete/2`.
"""
def delete(dataset, statements, graph_context \\ nil)
def delete(%RDF.Dataset{} = dataset, statements, graph_context) when is_list(statements) do
with graph_context = convert_graph_name(graph_context) do
Enum.reduce statements, dataset, fn (statement, dataset) ->
delete(dataset, statement, graph_context)
end
end
end
def delete(%RDF.Dataset{} = dataset, {_, _, _} = statement, graph_context),
do: do_delete(dataset, graph_context, statement)
def delete(%RDF.Dataset{} = dataset, {subject, predicate, objects, graph_context}, _),
do: do_delete(dataset, graph_context, {subject, predicate, objects})
def delete(%RDF.Dataset{} = dataset, %Description{} = description, graph_context),
do: do_delete(dataset, graph_context, description)
def delete(%RDF.Dataset{} = dataset, %RDF.Graph{} = graph, graph_context),
do: do_delete(dataset, graph_context, graph)
def delete(%RDF.Dataset{} = dataset, %RDF.Dataset{graphs: graphs}, _) do
Enum.reduce graphs, dataset, fn ({_, graph}, dataset) ->
delete(dataset, graph)
end
end
defp do_delete(%RDF.Dataset{name: name, graphs: graphs} = dataset,
graph_context, statements) do
with graph_context = convert_graph_name(graph_context),
graph when not is_nil(graph) <- graphs[graph_context],
new_graph = Graph.delete(graph, statements)
do
%RDF.Dataset{name: name,
graphs:
if Enum.empty?(new_graph) do
Map.delete(graphs, graph_context)
else
Map.put(graphs, graph_context, new_graph)
end
}
else
nil -> dataset
end
end
@doc """
Deletes the given graph.
"""

View file

@ -389,6 +389,108 @@ defmodule RDF.DatasetTest do
end
describe "delete" do
setup do
{:ok,
dataset1: Dataset.new({EX.S1, EX.p1, EX.O1}),
dataset2: Dataset.new([
{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, EX.O2, EX.Graph},
]),
dataset3: Dataset.new([
{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, [EX.O1, EX.O2], EX.Graph1},
{EX.S3, EX.p3, [~B<foo>, ~L"bar"], EX.Graph2},
]),
}
end
test "a single statement",
%{dataset1: dataset1, dataset2: dataset2, dataset3: dataset3} do
assert Dataset.delete(Dataset.new, {EX.S, EX.p, EX.O}) == Dataset.new
assert Dataset.delete(dataset1, {EX.S1, EX.p1, EX.O1}) == Dataset.new
assert Dataset.delete(dataset2, {EX.S2, EX.p2, EX.O2, EX.Graph}) == dataset1
assert Dataset.delete(dataset2, {EX.S1, EX.p1, EX.O1}) ==
Dataset.new({EX.S2, EX.p2, EX.O2, EX.Graph})
assert Dataset.delete(dataset3, {EX.S2, EX.p2, EX.O1, EX.Graph1}) ==
Dataset.new [
{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, EX.O2, EX.Graph1},
{EX.S3, EX.p3, [~B<foo>, ~L"bar"], EX.Graph2},
]
assert Dataset.delete(dataset3, {EX.S2, EX.p2, [EX.O1, EX.O2], EX.Graph1}) ==
Dataset.new [
{EX.S1, EX.p1, EX.O1},
{EX.S3, EX.p3, [~B<foo>, ~L"bar"], EX.Graph2},
]
assert Dataset.delete(dataset3, {EX.S2, EX.p2, [EX.O1, EX.O2]}, EX.Graph1) ==
Dataset.new [
{EX.S1, EX.p1, EX.O1},
{EX.S3, EX.p3, [~B<foo>, ~L"bar"], EX.Graph2},
]
end
test "multiple statements with a list of triples",
%{dataset1: dataset1, dataset2: dataset2, dataset3: dataset3} do
assert Dataset.delete(dataset1, [{EX.S1, EX.p1, EX.O1},
{EX.S1, EX.p1, EX.O2}]) == Dataset.new
assert Dataset.delete(dataset2, [{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, EX.O2, EX.Graph}]) == Dataset.new
assert Dataset.delete(dataset3, [
{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, [EX.O1, EX.O2, EX.O3], EX.Graph1},
{EX.S3, EX.p3, ~B<foo>, EX.Graph2}]) == Dataset.new({EX.S3, EX.p3, ~L"bar", EX.Graph2})
end
test "multiple statements with a Description",
%{dataset1: dataset1, dataset2: dataset2} do
assert Dataset.delete(dataset1, Description.new(EX.S1, EX.p1, EX.O1)) == Dataset.new
assert Dataset.delete(dataset1, Description.new(EX.S1, EX.p1, EX.O1), EX.Graph) == dataset1
assert Dataset.delete(dataset2, Description.new(EX.S2, EX.p2, EX.O2), EX.Graph) == dataset1
assert Dataset.delete(dataset2, Description.new(EX.S1, EX.p1, EX.O1)) ==
Dataset.new({EX.S2, EX.p2, EX.O2, EX.Graph})
end
test "multiple statements with a Graph",
%{dataset1: dataset1, dataset2: dataset2, dataset3: dataset3} do
assert Dataset.delete(dataset1, Graph.new({EX.S1, EX.p1, EX.O1})) == Dataset.new
assert Dataset.delete(dataset2, Graph.new({EX.S1, EX.p1, EX.O1})) ==
Dataset.new({EX.S2, EX.p2, EX.O2, EX.Graph})
assert Dataset.delete(dataset2, Graph.new({EX.S2, EX.p2, EX.O2}), EX.Graph) == dataset1
assert Dataset.delete(dataset2, Graph.new({EX.S2, EX.p2, EX.O2}), EX.Graph) == dataset1
assert Dataset.delete(dataset3, Graph.new([
{EX.S1, EX.p1, [EX.O1, EX.O2]},
{EX.S2, EX.p2, EX.O3},
{EX.S3, EX.p3, ~B<foo>},
])) == Dataset.new([
{EX.S2, EX.p2, [EX.O1, EX.O2], EX.Graph1},
{EX.S3, EX.p3, [~B<foo>, ~L"bar"], EX.Graph2},
])
assert Dataset.delete(dataset3, Graph.new({EX.S3, EX.p3, ~B<foo>}), EX.Graph2) ==
Dataset.new([
{EX.S1, EX.p1, EX.O1},
{EX.S2, EX.p2, [EX.O1, EX.O2], EX.Graph1},
{EX.S3, EX.p3, ~L"bar", EX.Graph2},
])
end
test "the name of a graph is ignored",
%{dataset1: dataset1, dataset2: dataset2} do
assert Dataset.delete(dataset1, Graph.new(EX.Graph, {EX.S1, EX.p1, EX.O1})) == Dataset.new
assert Dataset.delete(dataset2, Graph.new(EX.Graph, {EX.S1, EX.p1, EX.O1})) ==
Dataset.new({EX.S2, EX.p2, EX.O2, EX.Graph})
assert Dataset.delete(dataset2, Graph.new(EX.Graph, {EX.S2, EX.p2, EX.O2})) == dataset2
end
test "multiple statements with a Dataset",
%{dataset1: dataset1, dataset2: dataset2} do
assert Dataset.delete(dataset1, dataset1) == Dataset.new
assert Dataset.delete(dataset1, dataset2) == Dataset.new
assert Dataset.delete(dataset2, dataset1) == Dataset.new({EX.S2, EX.p2, EX.O2, EX.Graph})
end
end
describe "delete_graph" do
setup do
{:ok,