Add :init option to RDF.Graph.new/2 and RDF.Dataset.new/2

This commit is contained in:
Marcel Otto 2020-10-07 16:08:22 +02:00
parent 8325ba9988
commit 71292b721c
5 changed files with 125 additions and 11 deletions

View file

@ -48,10 +48,12 @@ defmodule RDF.Dataset do
## Examples
RDF.Dataset.new({EX.S, EX.p, EX.O})
RDF.Dataset.new(name: EX.GraphName)
RDF.Dataset.new(init: {EX.S, EX.p, EX.O})
RDF.Dataset.new({EX.S, EX.p, EX.O})
"""
@spec new(input | keyword) :: t
def new(data_or_options)
@ -59,7 +61,8 @@ defmodule RDF.Dataset do
def new(data_or_options)
when is_list(data_or_options) and length(data_or_options) != 0 do
if Keyword.keyword?(data_or_options) do
new([], data_or_options)
{data, options} = Keyword.pop(data_or_options, :init)
new(data, options)
else
new(data_or_options, [])
end
@ -75,6 +78,9 @@ defmodule RDF.Dataset do
Available options:
- `name`: the name of the dataset to be created
- `init`: some data with which the dataset should be initialized; the data can be
provided in any form accepted by `add/3` and above that also with a function returning
the initialization data in any of these forms
"""
@spec new(input, keyword) :: t
@ -87,9 +93,13 @@ defmodule RDF.Dataset do
def new(data, options) do
%__MODULE__{}
|> new(options)
|> add(data)
|> init(data)
end
defp init(dataset, nil), do: dataset
defp init(dataset, fun) when is_function(fun), do: add(dataset, fun.())
defp init(dataset, data), do: add(dataset, data)
@doc """
Returns the dataset name IRI of `dataset`.
"""

View file

@ -35,7 +35,7 @@ defmodule RDF.Diff do
defp coerce_graph(%Description{} = description),
do: if(Enum.empty?(description), do: Graph.new(), else: Graph.new(description))
defp coerce_graph(data), do: Graph.new(data)
defp coerce_graph(data), do: Graph.new(init: data)
@doc """
Computes a diff between two `RDF.Graph`s or `RDF.Description`s.

View file

@ -56,17 +56,19 @@ defmodule RDF.Graph do
@doc """
Creates an `RDF.Graph`.
If a keyword list is given an empty graph is created.
If a keyword list with options is given an empty graph is created.
Otherwise an unnamed graph initialized with the given data is created.
See `new/2` for available arguments and the different ways to provide data.
## Examples
RDF.Graph.new({EX.S, EX.p, EX.O})
RDF.Graph.new(name: EX.GraphName)
RDF.Graph.new(init: {EX.S, EX.p, EX.O})
RDF.Graph.new({EX.S, EX.p, EX.O})
"""
@spec new(input | keyword) :: t
def new(data_or_options)
@ -74,7 +76,8 @@ defmodule RDF.Graph do
def new(data_or_options)
when is_list(data_or_options) and length(data_or_options) != 0 do
if Keyword.keyword?(data_or_options) do
new([], data_or_options)
{data, options} = Keyword.pop(data_or_options, :init)
new(data, options)
else
new(data_or_options, [])
end
@ -99,6 +102,9 @@ defmodule RDF.Graph do
and will be used for example when serializing in a format with prefix support
- `base_iri`: a base IRI which should be stored alongside the graph
and will be used for example when serializing in a format with base IRI support
- `init`: some data with which the graph should be initialized; the data can be
provided in any form accepted by `add/3` and above that also with a function returning
the initialization data in any of these forms
## Examples
@ -121,11 +127,15 @@ defmodule RDF.Graph do
end
def new(data, options) do
%__MODULE__{}
new()
|> new(options)
|> add(data)
|> init(data)
end
defp init(graph, nil), do: graph
defp init(graph, fun) when is_function(fun), do: add(graph, fun.())
defp init(graph, data), do: add(graph, data)
@doc """
Removes all triples from `graph`.

View file

@ -150,6 +150,53 @@ defmodule RDF.DatasetTest do
{EX.Subject, EX.predicate(), EX.Object, EX.GraphName}
)
end
@tag skip: "This case is currently not supported, since it's indistinguishable from Keywords"
test "creating a dataset with a list of subject-predications pairs" do
ds =
Dataset.new([
{EX.S1,
[
{EX.P1, EX.O1},
%{EX.P2 => [EX.O2]}
]}
])
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O2})
end
test "with init data" do
ds =
Dataset.new(
init: [
{EX.S1,
[
{EX.P1, EX.O1},
%{EX.P2 => [EX.O2]}
]}
]
)
assert unnamed_dataset?(ds)
assert dataset_includes_statement?(ds, {EX.S1, EX.P1, EX.O1})
assert dataset_includes_statement?(ds, {EX.S1, EX.P2, EX.O2})
ds =
Dataset.new(
name: EX.Dataset,
init: {EX.S, EX.p(), EX.O}
)
assert named_dataset?(ds, RDF.iri(EX.Dataset))
assert dataset_includes_statement?(ds, {EX.S, EX.p(), EX.O})
end
test "with an initializer function" do
ds = Dataset.new(init: fn -> {EX.S, EX.p(), EX.O} end)
assert unnamed_dataset?(ds)
assert dataset_includes_statement?(ds, {EX.S, EX.p(), EX.O})
end
end
test "name/1" do

View file

@ -156,6 +156,53 @@ defmodule RDF.GraphTest do
g = Graph.new(Graph.new(prefixes: %{ex: XSD, rdfs: RDFS}), prefixes: prefix_map)
assert g.prefixes == PrefixMap.new(ex: EX, rdfs: RDFS)
end
@tag skip: "This case is currently not supported, since it's indistinguishable from Keywords"
test "creating a graph with a list of subject-predications pairs" do
g =
Graph.new([
{EX.S1,
[
{EX.P1, EX.O1},
%{EX.P2 => [EX.O2]}
]}
])
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P2, EX.O2})
end
test "with init data" do
g =
Graph.new(
init: [
{EX.S1,
[
{EX.P1, EX.O1},
%{EX.P2 => [EX.O2]}
]}
]
)
assert unnamed_graph?(g)
assert graph_includes_statement?(g, {EX.S1, EX.P1, EX.O1})
assert graph_includes_statement?(g, {EX.S1, EX.P2, EX.O2})
g =
Graph.new(
name: EX.Graph,
init: {EX.S, EX.p(), EX.O}
)
assert named_graph?(g, RDF.iri(EX.Graph))
assert graph_includes_statement?(g, {EX.S, EX.p(), EX.O})
end
test "with an initializer function" do
g = Graph.new(init: fn -> {EX.S, EX.p(), EX.O} end)
assert unnamed_graph?(g)
assert graph_includes_statement?(g, {EX.S, EX.p(), EX.O})
end
end
test "clear/1" do