Change behaviour of put and add put_properties on RDF.Graph and Dataset

This commit is contained in:
Marcel Otto 2020-10-04 16:31:41 +02:00
parent 4408a04103
commit 1a7ffe58c4
5 changed files with 641 additions and 84 deletions

View file

@ -33,10 +33,23 @@ are specified.
### Changed
- the format for the specification of BGP queries with `RDF.Graph.query/2`,
`RDF.Graph.query_stream/2` and `RDF.Query.bgp/1` has been changed to be consistent with
the supported formats for input data in the rest of the library
`RDF.Graph.query_stream/2` and `RDF.Query.bgp/1` has been changed to be consistent
with the supported formats for input data in the rest of the library
- `RDF.Description.new` now requires the `subject` to be passed always as first argument;
if you want to add some initial data this must be done with the `:init` option
- The `put/3` functions on `RDF.Graph` and `RDF.Dataset` now overwrite all
statements with same subject. Previously only statements with the same subject
AND predicate were overwritten, which was probably not the expected behaviour,
since it's not inline with the common `put` semantics in Elixir.
- **CAUTION: This means the `RDF.Graph.put/2` and `RDF.Dataset.put/2` function have become more destructive now when not specified otherwise.**
- Note: Although one could argue, that following this route `RDF.Dataset.put/3`
would consequently have to overwrite whole graphs, this was not implemented
for practical reasons. It's probably not what's wanted in most cases.
- The `Access` protocol implementation of `get_and_update/3` on `RDF.Graph` and
`RDF.Dataset` previously relied on the `put/2` functions with the old behaviour
of overwriting only statements with the same subject and predicate, which was
almost never the expected behaviour. This is fixed now by relying on the new
`put/2` behaviour.
- for consistency reasons the internal `:id` struct field of `RDF.BlankNode` was renamed
to `:value`

View file

@ -169,7 +169,7 @@ defmodule RDF.Dataset do
end
@doc """
Adds statements to a `RDF.Dataset` and overwrites all existing statements with the same subjects and predicates in the specified graph context.
Adds statements to a `RDF.Dataset` overwriting existing statements with the subjects given in the `input` data.
The `graph` option allows to set a different destination graph to which the
statements should be added, ignoring the graph context of given quads or the
@ -182,13 +182,10 @@ defmodule RDF.Dataset do
## Examples
iex> dataset = RDF.Dataset.new({EX.S, EX.P1, EX.O1})
...> RDF.Dataset.put(dataset, {EX.S, EX.P1, EX.O2})
RDF.Dataset.new({EX.S, EX.P1, EX.O2})
iex> RDF.Dataset.put(dataset, {EX.S, EX.P2, EX.O2})
RDF.Dataset.new([{EX.S, EX.P1, EX.O1}, {EX.S, EX.P2, EX.O2}])
iex> RDF.Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Dataset.put([{EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
RDF.Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
...> RDF.Dataset.put(dataset, {EX.S, EX.P2, EX.O2})
RDF.Dataset.new({EX.S, EX.P2, EX.O2})
iex> RDF.Dataset.put(dataset, {EX.S2, EX.P2, EX.O2})
RDF.Dataset.new([{EX.S, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
"""
@spec put(t, input, keyword) :: t
@ -217,6 +214,55 @@ defmodule RDF.Dataset do
put(dataset, new() |> add(input, opts), opts)
end
@doc """
Adds statements to a `RDF.Dataset` and overwrites all existing statements with the same subject-predicate combinations given in the `input` data.
The `graph` option allows to set a different destination graph to which the
statements should be added, ignoring the graph context of given quads or the
name of given graphs in `input`.
Note: When the statements to be added are given as another `RDF.Dataset` and
a destination graph is set with the `graph` option, the descriptions of the
subjects in the different graphs are aggregated.
## Examples
iex> dataset = RDF.Dataset.new({EX.S, EX.P1, EX.O1})
...> RDF.Dataset.put_properties(dataset, {EX.S, EX.P1, EX.O2})
RDF.Dataset.new({EX.S, EX.P1, EX.O2})
iex> RDF.Dataset.put_properties(dataset, {EX.S, EX.P2, EX.O2})
RDF.Dataset.new([{EX.S, EX.P1, EX.O1}, {EX.S, EX.P2, EX.O2}])
iex> RDF.Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Dataset.put_properties([{EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
RDF.Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S1, EX.P2, EX.O3}, {EX.S2, EX.P2, EX.O3}])
"""
@spec put_properties(t, input, keyword) :: t
def put_properties(dataset, input, opts \\ [])
def put_properties(%__MODULE__{} = dataset, %__MODULE__{} = input, opts) do
%__MODULE__{
dataset
| graphs:
Enum.reduce(
input.graphs,
dataset.graphs,
fn {graph_name, graph}, graphs ->
Map.update(
graphs,
graph_name,
graph,
fn current -> Graph.put_properties(current, graph, opts) end
)
end
)
}
end
def put_properties(%__MODULE__{} = dataset, input, opts) do
put_properties(dataset, new() |> add(input, opts), opts)
end
@doc """
Deletes statements from a `RDF.Dataset`.

View file

@ -224,7 +224,7 @@ defmodule RDF.Graph do
end
@doc """
Adds statements to a `RDF.Graph` and overwrites all existing statements with the same subjects and predicates.
Adds statements to a `RDF.Graph` overwriting existing statements with the subjects given in the `input` data.
When the statements to be added are given as another `RDF.Graph`, the prefixes
of this graph will be added. In case of conflicting prefix mappings the
@ -233,14 +233,55 @@ defmodule RDF.Graph do
## 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}])
...> |> RDF.Graph.put([{EX.S1, EX.P3, EX.O3}])
RDF.Graph.new([{EX.S1, EX.P3, EX.O3}, {EX.S2, EX.P2, EX.O2}])
"""
@spec put(t, input, keyword) :: t
def put(graph, input, opts \\ [])
def put(%__MODULE__{} = graph, %__MODULE__{} = input, opts) do
def put(%__MODULE__{} = graph, %__MODULE__{} = input, _opts) do
graph = %__MODULE__{
graph
| descriptions:
Enum.reduce(
input.descriptions,
graph.descriptions,
fn {subject, description}, descriptions ->
Map.put(descriptions, subject, description)
end
)
}
if input.prefixes do
add_prefixes(graph, input.prefixes, :ignore)
else
graph
end
end
def put(%__MODULE__{} = graph, input, opts) do
put(graph, new() |> add(input, opts), opts)
end
@doc """
Adds statements to a `RDF.Graph` and overwrites all existing statements with the same subject-predicate combinations given in the `input` data.
When the statements to be added are given as another `RDF.Graph`, the prefixes
of this graph will be added. In case of conflicting prefix mappings the
original prefix from `graph` will be kept.
## Examples
iex> RDF.Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
...> |> RDF.Graph.put_properties([{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}])
"""
@spec put_properties(t, input, keyword) :: t
def put_properties(graph, input, opts \\ [])
def put_properties(%__MODULE__{} = graph, %__MODULE__{} = input, opts) do
graph = %__MODULE__{
graph
| descriptions:
@ -265,8 +306,8 @@ defmodule RDF.Graph do
end
end
def put(%__MODULE__{} = graph, input, opts) do
put(graph, new() |> add(input, opts), opts)
def put_properties(%__MODULE__{} = graph, input, opts) do
put_properties(graph, new() |> add(input, opts), opts)
end
@doc """

View file

@ -693,7 +693,7 @@ defmodule RDF.DatasetTest do
test "a list of graphs" do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> RDF.Dataset.add([
|> Dataset.add([
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S1, EX.P2, bnode(:foo)}]),
Graph.new({EX.S1, EX.P2, EX.O3}),
Graph.new([{EX.S1, EX.P2, EX.O2}, {EX.S2, EX.P2, EX.O2}], name: EX.Graph)
@ -711,7 +711,7 @@ defmodule RDF.DatasetTest do
test "lists of descriptions, graphs and datasets without an overwriting graph context" do
ds =
Dataset.new([{EX.S1, EX.p(), EX.O}, {EX.S2, EX.p(), EX.O, EX.Graph}])
|> RDF.Dataset.add([
|> Dataset.add([
EX.S1 |> EX.p(bnode(:foo)),
%{EX.S1 => {EX.p(), EX.O1}},
EX.S2 |> EX.p(EX.O3) |> RDF.graph(),
@ -732,7 +732,7 @@ defmodule RDF.DatasetTest do
test "lists of descriptions, graphs and datasets with an overwriting graph context" do
ds =
Dataset.new([{EX.S1, EX.p(), EX.O}, {EX.S2, EX.p(), EX.O, EX.Graph}])
|> RDF.Dataset.add(
|> Dataset.add(
[
EX.S1 |> EX.p(bnode(:foo)),
%{EX.S1 => {EX.p(), EX.O1}},
@ -780,10 +780,295 @@ defmodule RDF.DatasetTest do
end
describe "put/3" do
test "a list of statements without an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S2, EX.P2, EX.O2, EX.Graph},
{EX.S3, EX.P3, EX.O3, EX.Graph}
])
|> Dataset.put([
{EX.S1, EX.P2, bnode(:foo), nil},
{EX.S1, EX.P2, EX.O3, EX.Graph},
{EX.S2, EX.P3, EX.O3, EX.Graph},
{EX.S3, EX.P3, EX.O3}
])
assert Dataset.statement_count(ds) == 5
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo)})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O3, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S2, EX.P3, EX.O3, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S3, EX.P3, EX.O3})
assert dataset_includes_statement?(ds, {EX.S3, EX.P3, EX.O3, EX.Graph})
end
test "a list of statements with an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S2, EX.P2, EX.O2},
{EX.S3, EX.P3, EX.O3, EX.Graph}
])
|> Dataset.put(
[
{EX.S1, EX.P2, bnode(:foo), nil},
{EX.S1, EX.P2, EX.O3, EX.Graph},
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P3, EX.O3},
{EX.S3, EX.P4, EX.O4, EX.Graph}
],
graph: nil
)
assert Dataset.statement_count(ds) == 6
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo)})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O3})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3})
assert dataset_includes_statement?(ds, {EX.S2, EX.P3, EX.O3})
assert dataset_includes_statement?(ds, {EX.S3, EX.P4, EX.O4})
assert dataset_includes_statement?(ds, {EX.S3, EX.P3, EX.O3, EX.Graph})
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S2, EX.P2, EX.O2},
{EX.S3, EX.P3, EX.O3, EX.Graph}
])
|> Dataset.put(
[
{EX.S1, EX.P2, bnode(:foo), nil},
{EX.S1, EX.P2, EX.O3, EX.Graph},
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P3, EX.O3},
{EX.S3, EX.P4, EX.O4, EX.Graph}
],
graph: EX.Graph2
)
assert Dataset.statement_count(ds) == 8
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, EX.O2})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo), EX.Graph2})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O3, EX.Graph2})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3, EX.Graph2})
assert dataset_includes_statement?(ds, {EX.S2, EX.P3, EX.O3, EX.Graph2})
assert dataset_includes_statement?(ds, {EX.S3, EX.P4, EX.O4, EX.Graph2})
assert dataset_includes_statement?(ds, {EX.S3, EX.P3, EX.O3, EX.Graph})
end
test "lists of subject-predications pairs" do
ds =
Dataset.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}])
|> Dataset.put([
{EX.S1, [{EX.p2(), EX.O2}]},
{EX.S3, %{EX.p3() => EX.O3}}
])
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.p2(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S3, EX.p3(), EX.O3})
end
test "maps" do
ds =
Dataset.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}])
|> Dataset.put(%{
EX.S1 => [{EX.p2(), EX.O2}],
EX.S2 => %{EX.p1() => EX.O2},
EX.S3 => %{EX.p3() => EX.O3}
})
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.p2(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p1(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S3, EX.p3(), EX.O3})
end
test "descriptions" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P2, EX.O2}
])
|> Dataset.put(
Description.new(EX.S1)
|> Description.add([{EX.P3, EX.O4}, {EX.P2, bnode(:foo)}])
)
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O4})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo)})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, EX.O2})
end
test "an unnamed graph without an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P2, EX.O2},
{EX.S2, EX.P2, EX.O2}
])
|> Dataset.put(
Graph.new([
{EX.S1, EX.P3, EX.O4},
{EX.S1, EX.P2, bnode(:foo)}
])
)
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O4})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo)})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, EX.O2})
end
test "an unnamed graph with an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P2, EX.O2},
{EX.S2, EX.P2, EX.O2}
])
|> Dataset.put(
Graph.new([
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P2, bnode(:foo)}
]),
graph: nil
)
assert Dataset.statement_count(ds) == 2
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, bnode(:foo)})
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S2, EX.P2, EX.O2, EX.Graph}
])
|> Dataset.put(
Graph.new([
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P2, bnode(:foo)}
]),
graph: EX.Graph
)
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, bnode(:foo), EX.Graph})
end
test "a named graph without an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P2, EX.O2, EX.Graph},
{EX.S2, EX.P2, EX.O2, EX.Graph}
])
|> Dataset.put(
Graph.new(
[
{EX.S1, EX.P3, EX.O4},
{EX.S1, EX.P2, bnode(:foo)}
],
name: EX.Graph
)
)
assert Dataset.statement_count(ds) == 4
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O4, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, bnode(:foo), EX.Graph})
assert dataset_includes_statement?(ds, {EX.S2, EX.P2, EX.O2, EX.Graph})
end
test "a named graph with an overwriting graph context" do
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P2, EX.O2, EX.Graph},
{EX.S2, EX.P2, EX.O2}
])
|> Dataset.put(
Graph.new(
[
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P3, bnode(:foo)}
],
name: EX.Graph
),
graph: nil
)
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O2, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3})
assert dataset_includes_statement?(ds, {EX.S2, EX.P3, bnode(:foo)})
ds =
Dataset.new([
{EX.S1, EX.P1, EX.O1},
{EX.S2, EX.P2, EX.O2, EX.Graph}
])
|> Dataset.put(
Graph.new(
[
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P3, bnode(:foo)}
],
name: EX.Graph2
),
graph: EX.Graph
)
assert Dataset.statement_count(ds) == 3
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S1, EX.P3, EX.O3, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S2, EX.P3, bnode(:foo), EX.Graph})
end
test "lists of descriptions, graphs and datasets" do
ds =
Dataset.new([{EX.S1, EX.p(), EX.O}, {EX.S2, EX.p(), EX.O, EX.Graph}])
|> Dataset.put([
EX.S1 |> EX.p2(bnode(:foo)),
EX.S1 |> EX.p2("bar"),
%{EX.S1 => {EX.p2(), EX.O1}},
EX.S2 |> EX.p2(EX.O3) |> RDF.graph(),
EX.S2 |> EX.p2(EX.O4) |> RDF.graph(name: EX.Graph),
EX.S2 |> EX.p2(EX.O5) |> RDF.dataset()
])
assert Dataset.statement_count(ds) == 6
assert dataset_includes_statement?(ds, {EX.S1, EX.p2(), bnode(:foo)})
assert dataset_includes_statement?(ds, {EX.S1, EX.p2(), ~L"bar"})
assert dataset_includes_statement?(ds, {EX.S1, EX.p2(), EX.O1})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O3})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O4, EX.Graph})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O5})
end
test "simultaneous use of the different forms to address the default context" do
ds =
Dataset.put(dataset(), [
{EX.S, EX.P, EX.O1},
{EX.S, EX.P, EX.O2, nil}
])
assert Dataset.statement_count(ds) == 2
assert dataset_includes_statement?(ds, {EX.S, EX.P, EX.O1})
assert dataset_includes_statement?(ds, {EX.S, EX.P, EX.O2})
end
end
describe "put_properties/3" do
test "a list of statements without an overwriting graph context" do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2, EX.Graph}])
|> RDF.Dataset.put([
|> Dataset.put_properties([
{EX.S1, EX.P2, EX.O3, EX.Graph},
{EX.S1, EX.P2, bnode(:foo), nil},
{EX.S2, EX.P2, EX.O3, EX.Graph},
@ -801,7 +1086,7 @@ defmodule RDF.DatasetTest do
test "a list of statements with an overwriting graph context" do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2, EX.Graph}])
|> RDF.Dataset.put(
|> Dataset.put_properties(
[
{EX.S1, EX.P1, EX.O3, EX.Graph},
{EX.S1, EX.P2, bnode(:foo), nil},
@ -820,7 +1105,7 @@ defmodule RDF.DatasetTest do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2, EX.Graph}])
|> RDF.Dataset.put(
|> Dataset.put_properties(
[
{EX.S1, EX.P1, EX.O3},
{EX.S1, EX.P1, EX.O4, EX.Graph},
@ -843,12 +1128,13 @@ defmodule RDF.DatasetTest do
test "lists of subject-predications pairs" do
ds =
Dataset.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}])
|> Dataset.put([
|> Dataset.put_properties([
{EX.S1, [{EX.p1(), EX.O2}]},
{EX.S2, %{EX.p1() => EX.O2}},
{EX.S3, %{EX.p3() => EX.O3}}
])
assert Dataset.statement_count(ds) == 4
assert dataset_includes_statement?(ds, {EX.S1, EX.p1(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p1(), EX.O2})
@ -858,12 +1144,13 @@ defmodule RDF.DatasetTest do
test "maps" do
ds =
Dataset.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}])
|> Dataset.put(%{
|> Dataset.put_properties(%{
EX.S1 => [{EX.p1(), EX.O2}],
EX.S2 => %{EX.p1() => EX.O2},
EX.S3 => %{EX.p3() => EX.O3}
})
assert Dataset.statement_count(ds) == 4
assert dataset_includes_statement?(ds, {EX.S1, EX.p1(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p2(), EX.O2})
assert dataset_includes_statement?(ds, {EX.S2, EX.p1(), EX.O2})
@ -873,7 +1160,7 @@ defmodule RDF.DatasetTest do
test "descriptions" do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}, {EX.S1, EX.P3, EX.O3}])
|> RDF.Dataset.put(
|> Dataset.put_properties(
Description.new(EX.S1)
|> Description.add([{EX.P3, EX.O4}, {EX.P2, bnode(:foo)}])
)
@ -888,7 +1175,7 @@ defmodule RDF.DatasetTest do
test "an unnamed graph" do
ds =
Dataset.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}, {EX.S1, EX.P3, EX.O3}])
|> RDF.Dataset.put(Graph.new([{EX.S1, EX.P3, EX.O4}, {EX.S1, EX.P2, bnode(:foo)}]))
|> Dataset.put_properties(Graph.new([{EX.S1, EX.P3, EX.O4}, {EX.S1, EX.P2, bnode(:foo)}]))
assert Dataset.statement_count(ds) == 4
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
@ -904,7 +1191,7 @@ defmodule RDF.DatasetTest do
name: EX.GraphName
)
)
|> RDF.Dataset.put(
|> Dataset.put_properties(
Graph.new([{EX.S1, EX.P3, EX.O4}, {EX.S1, EX.P2, bnode(:foo)}]),
graph: EX.GraphName
)
@ -919,7 +1206,7 @@ defmodule RDF.DatasetTest do
test "lists of descriptions, graphs and datasets" do
ds =
Dataset.new([{EX.S1, EX.p(), EX.O}, {EX.S2, EX.p(), EX.O, EX.Graph}])
|> RDF.Dataset.put([
|> Dataset.put_properties([
EX.S1 |> EX.p(bnode(:foo)),
EX.S1 |> EX.p("bar"),
%{EX.S1 => {EX.p(), EX.O1}},
@ -939,7 +1226,7 @@ defmodule RDF.DatasetTest do
test "simultaneous use of the different forms to address the default context" do
ds =
RDF.Dataset.put(dataset(), [
Dataset.put_properties(dataset(), [
{EX.S, EX.P, EX.O1},
{EX.S, EX.P, EX.O2, nil}
])

View file

@ -210,7 +210,7 @@ defmodule RDF.GraphTest do
test "a list of subject-predications pairs" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> RDF.Graph.add([
|> Graph.add([
{EX.S1,
[
{EX.P1, EX.O3},
@ -228,7 +228,7 @@ defmodule RDF.GraphTest do
test "a mixed list" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|> RDF.Graph.add([
|> Graph.add([
%{EX.S1 => {EX.p1(), EX.O41}},
%{
EX.S1 => %{EX.p1() => EX.O42},
@ -389,79 +389,75 @@ defmodule RDF.GraphTest do
describe "put/3" do
test "a list of triples" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> RDF.Graph.put([
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}, {EX.S3, EX.P3, EX.O3}])
|> 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}
{EX.S2, EX.P3, EX.O3}
])
assert Graph.triple_count(g) == 5
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert Graph.triple_count(g) == 4
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})
assert graph_includes_statement?(g, {EX.S2, EX.P3, EX.O3})
assert graph_includes_statement?(g, {EX.S3, EX.P3, EX.O3})
end
test "quads" do
g =
Graph.new([{EX.S1, EX.P1, EX.O}, {EX.S2, EX.P2, EX.O}])
|> RDF.Graph.put([
{EX.S2, EX.P2, bnode(:foo), EX.Graph1},
{EX.S2, EX.P2, EX.O1, EX.Graph2},
{EX.S2, EX.P2, EX.O2, nil},
{EX.S2, EX.P2, EX.O3}
|> Graph.put([
{EX.S1, EX.P3, bnode(:foo), EX.Graph1},
{EX.S2, EX.P3, EX.O1, EX.Graph2},
{EX.S2, EX.P3, EX.O2, nil},
{EX.S2, EX.P3, EX.O3}
])
assert Graph.triple_count(g) == 5
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O})
assert graph_includes_statement?(g, {EX.S2, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O1})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O3})
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.P3, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P3, EX.O1})
assert graph_includes_statement?(g, {EX.S2, EX.P3, EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.P3, EX.O3})
end
test "a list of subject-predications pairs" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> RDF.Graph.put([
|> Graph.put([
{EX.S1,
[
{EX.P1, EX.O3},
%{EX.P2 => [EX.O4]}
{EX.P3, EX.O3},
%{EX.P4 => [EX.O4]}
]}
])
assert Graph.triple_count(g) == 3
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.P2, EX.O4})
assert graph_includes_statement?(g, {EX.S1, EX.P3, EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.P4, EX.O4})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
end
test "a mixed list" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|> RDF.Graph.put([
|> Graph.put([
%{EX.S1 => {EX.p1(), EX.O41}},
%{
EX.S1 => %{EX.p1() => EX.O42},
EX.S2 => %{EX.p2() => EX.O42}
EX.S2 => %{EX.p3() => EX.O42}
},
{EX.S2, {EX.p2(), EX.O43}},
[{EX.S2, {EX.p2(), EX.O44}}],
EX.p2(EX.S2, EX.O45)
{EX.S2, {EX.p3(), EX.O43}},
[{EX.S2, {EX.p3(), EX.O44}}],
EX.p2(EX.S3, EX.O45)
])
assert Graph.triple_count(g) == 7
assert graph_includes_statement?(g, {EX.S1, EX.p3(), EX.O3})
assert Graph.triple_count(g) == 6
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O41})
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O43})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O44})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O45})
assert graph_includes_statement?(g, {EX.S2, EX.p3(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p3(), EX.O43})
assert graph_includes_statement?(g, {EX.S2, EX.p3(), EX.O44})
assert graph_includes_statement?(g, {EX.S3, EX.p2(), EX.O45})
end
test "a map" do
@ -473,9 +469,8 @@ defmodule RDF.GraphTest do
EX.S3 => %{EX.p3() => EX.O3}
})
assert Graph.triple_count(g) == 4
assert Graph.triple_count(g) == 3
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.p1(), EX.O2})
assert graph_includes_statement?(g, {EX.S3, EX.p3(), EX.O3})
end
@ -483,13 +478,12 @@ defmodule RDF.GraphTest do
test "a description" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}, {EX.S1, EX.P3, EX.O3}])
|> RDF.Graph.put(
|> Graph.put(
Description.new(EX.S1)
|> Description.add([{EX.P3, EX.O4}, {EX.P2, bnode(:foo)}])
)
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert Graph.triple_count(g) == 3
assert graph_includes_statement?(g, {EX.S1, EX.P3, EX.O4})
assert graph_includes_statement?(g, {EX.S1, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
@ -502,16 +496,16 @@ defmodule RDF.GraphTest do
test "a list of descriptions" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|> RDF.Graph.put([
EX.p1(EX.S1, EX.O41),
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S3, EX.p3(), EX.O3}])
|> Graph.put([
EX.p2(EX.S1, EX.O41),
EX.p2(EX.S2, EX.O42),
EX.p2(EX.S2, EX.O43)
])
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.p3(), EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O41})
assert graph_includes_statement?(g, {EX.S3, EX.p3(), EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.p2(), EX.O41})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O43})
end
@ -520,21 +514,18 @@ defmodule RDF.GraphTest do
g =
Graph.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P2, EX.O2}
])
|> RDF.Graph.put(
|> Graph.put(
Graph.new([
{EX.S1, EX.P3, EX.O4},
{EX.S2, EX.P2, bnode(:foo)},
{EX.S1, EX.P12, EX.O12},
{EX.S3, EX.P3, EX.O3}
])
)
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P3, EX.O4})
assert graph_includes_statement?(g, {EX.S2, EX.P2, bnode(:foo)})
assert Graph.triple_count(g) == 3
assert graph_includes_statement?(g, {EX.S1, EX.P12, EX.O12})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
assert graph_includes_statement?(g, {EX.S3, EX.P3, EX.O3})
end
@ -565,6 +556,185 @@ defmodule RDF.GraphTest do
end
end
describe "put_properties/3" do
test "a list of triples" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> Graph.put_properties([
{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 "quads" do
g =
Graph.new([{EX.S1, EX.P1, EX.O}, {EX.S2, EX.P2, EX.O}])
|> Graph.put_properties([
{EX.S2, EX.P2, bnode(:foo), EX.Graph1},
{EX.S2, EX.P2, EX.O1, EX.Graph2},
{EX.S2, EX.P2, EX.O2, nil},
{EX.S2, EX.P2, EX.O3}
])
assert Graph.triple_count(g) == 5
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O})
assert graph_includes_statement?(g, {EX.S2, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O1})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O3})
end
test "a list of subject-predications pairs" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}])
|> Graph.put_properties([
{EX.S1,
[
{EX.P1, EX.O3},
%{EX.P2 => [EX.O4]}
]}
])
assert Graph.triple_count(g) == 3
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.P2, EX.O4})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
end
test "a mixed list" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|> Graph.put_properties([
%{EX.S1 => {EX.p1(), EX.O41}},
%{
EX.S1 => %{EX.p1() => EX.O42},
EX.S2 => %{EX.p2() => EX.O42}
},
{EX.S2, {EX.p2(), EX.O43}},
[{EX.S2, {EX.p2(), EX.O44}}],
EX.p2(EX.S2, EX.O45)
])
assert Graph.triple_count(g) == 7
assert graph_includes_statement?(g, {EX.S1, EX.p3(), EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O41})
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O43})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O44})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O45})
end
test "a map" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}])
|> Graph.put_properties(%{
EX.S1 => [{EX.p1(), EX.O2}],
EX.S2 => %{EX.p1() => EX.O2},
EX.S3 => %{EX.p3() => EX.O3}
})
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O2})
assert graph_includes_statement?(g, {EX.S2, EX.p1(), EX.O2})
assert graph_includes_statement?(g, {EX.S3, EX.p3(), EX.O3})
end
test "a description" do
g =
Graph.new([{EX.S1, EX.P1, EX.O1}, {EX.S2, EX.P2, EX.O2}, {EX.S1, EX.P3, EX.O3}])
|> Graph.put_properties(
Description.new(EX.S1)
|> Description.add([{EX.P3, EX.O4}, {EX.P2, bnode(:foo)}])
)
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P3, EX.O4})
assert graph_includes_statement?(g, {EX.S1, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S2, EX.P2, EX.O2})
end
test "an empty description is ignored" do
g = Graph.new() |> Graph.put_properties(Description.new(EX.Subject))
assert empty_graph?(g)
end
test "a list of descriptions" do
g =
Graph.new([{EX.S1, EX.p1(), EX.O1}, {EX.S2, EX.p2(), EX.O2}, {EX.S1, EX.p3(), EX.O3}])
|> Graph.put_properties([
EX.p1(EX.S1, EX.O41),
EX.p2(EX.S2, EX.O42),
EX.p2(EX.S2, EX.O43)
])
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.p3(), EX.O3})
assert graph_includes_statement?(g, {EX.S1, EX.p1(), EX.O41})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O42})
assert graph_includes_statement?(g, {EX.S2, EX.p2(), EX.O43})
end
test "a graph" do
g =
Graph.new([
{EX.S1, EX.P1, EX.O1},
{EX.S1, EX.P3, EX.O3},
{EX.S2, EX.P2, EX.O2}
])
|> Graph.put_properties(
Graph.new([
{EX.S1, EX.P3, EX.O4},
{EX.S2, EX.P2, bnode(:foo)},
{EX.S3, EX.P3, EX.O3}
])
)
assert Graph.triple_count(g) == 4
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P3, EX.O4})
assert graph_includes_statement?(g, {EX.S2, EX.P2, bnode(:foo)})
assert graph_includes_statement?(g, {EX.S3, EX.P3, EX.O3})
end
test "merges the prefixes of another graph" do
graph =
Graph.new(prefixes: %{xsd: XSD})
|> Graph.put_properties(Graph.new(prefixes: %{rdfs: RDFS}))
assert graph.prefixes == PrefixMap.new(xsd: XSD, rdfs: RDFS)
end
test "merges the prefixes of another graph and keeps the original mapping in case of conflicts" do
graph =
Graph.new(prefixes: %{ex: EX})
|> Graph.put_properties(Graph.new(prefixes: %{ex: XSD}))
assert graph.prefixes == PrefixMap.new(ex: EX)
end
test "preserves the name, base_iri and prefixes" do
graph =
Graph.new(name: EX.GraphName, prefixes: %{ex: EX}, base_iri: EX.base())
|> Graph.put_properties({EX.Subject, EX.predicate(), EX.Object})
assert graph.name == RDF.iri(EX.GraphName)
assert graph.prefixes == PrefixMap.new(ex: EX)
assert graph.base_iri == EX.base()
end
end
describe "delete/2" do
setup do
{:ok,