diff --git a/CHANGELOG.md b/CHANGELOG.md index 5df6956..bbea104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a CHANGELOG](http://keepachangelog.com). +## Unreleased + +### Added + +- `RDF.Graph.new/2` and `RDF.Graph.add/2` support the addition of `RDF.Dataset`s + + +[Compare v0.11.0...HEAD](https://github.com/rdf-elixir/rdf-ex/compare/v0.11.0...HEAD) + + + ## 0.10.0 - 2022-03-22 ### Added diff --git a/VERSION b/VERSION index d9df1bb..aa871ec 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.11.0 +0.11.1-pre diff --git a/lib/rdf/graph.ex b/lib/rdf/graph.ex index 3885d5b..c31e86f 100644 --- a/lib/rdf/graph.ex +++ b/lib/rdf/graph.ex @@ -94,6 +94,7 @@ defmodule RDF.Graph do - a nested subject-predicate-object map - a `RDF.Description` - a `RDF.Graph` + - a `RDF.Dataset` - or a list with any combination of the former Available options: @@ -224,6 +225,15 @@ defmodule RDF.Graph do end end + def add(graph, %RDF.Dataset{} = dataset, opts) do + # normalize the annotations here, so we don't have to do this repeatedly + opts = RDF.Star.Graph.normalize_annotation_opts(opts) + + dataset + |> RDF.Dataset.graphs() + |> Enum.reduce(graph, &add(&2, &1, opts)) + end + def add(graph, input, opts) when is_list(input) or (is_map(input) and not is_struct(input)) do Enum.reduce(input, graph, &add(&2, &1, opts)) end @@ -298,6 +308,10 @@ defmodule RDF.Graph do |> RDF.Star.Graph.handle_addition_annotations(input, opts) end + def put(%__MODULE__{}, %RDF.Dataset{}, _opts) do + raise ArgumentError, "RDF.Graph.put/3 does not support RDF.Datasets" + end + def put(%__MODULE__{} = graph, input, opts) do put(graph, new() |> add(input, RDF.Star.Graph.clear_annotation_opts(opts)), opts) end @@ -361,6 +375,10 @@ defmodule RDF.Graph do |> RDF.Star.Graph.handle_addition_annotations(input, opts) end + def put_properties(%__MODULE__{}, %RDF.Dataset{}, _opts) do + raise ArgumentError, "RDF.Graph.put_properties/3 does not support RDF.Datasets" + end + def put_properties(%__MODULE__{} = graph, input, opts) do put_properties(graph, new() |> add(input, RDF.Star.Graph.clear_annotation_opts(opts)), opts) end diff --git a/test/unit/graph_test.exs b/test/unit/graph_test.exs index 9467f6d..7c00748 100644 --- a/test/unit/graph_test.exs +++ b/test/unit/graph_test.exs @@ -123,6 +123,42 @@ defmodule RDF.GraphTest do assert graph_includes_statement?(g, {EX.Subject, EX.predicate(), EX.Object}) end + test "creating an graph from a dataset" do + g = + Dataset.new([ + {EX.Subject1, EX.predicate1(), EX.Object1, nil}, + {EX.Subject2, EX.predicate2(), EX.Object2, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph2}, + {EX.Subject4, EX.predicate4(), EX.Object4, EX.Graph2} + ]) + |> Graph.new() + + assert unnamed_graph?(g) + assert Graph.triple_count(g) == 4 + assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1}) + assert graph_includes_statement?(g, {EX.Subject2, EX.predicate2(), EX.Object2}) + assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3(), EX.Object3}) + assert graph_includes_statement?(g, {EX.Subject4, EX.predicate4(), EX.Object4}) + + g = + Dataset.new([ + {EX.Subject1, EX.predicate1(), EX.Object1, nil}, + {EX.Subject2, EX.predicate2(), EX.Object2, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph2}, + {EX.Subject4, EX.predicate4(), EX.Object4, EX.Graph2} + ]) + |> Graph.new(name: EX.GraphName) + + assert named_graph?(g, iri(EX.GraphName)) + assert Graph.triple_count(g) == 4 + assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1}) + assert graph_includes_statement?(g, {EX.Subject2, EX.predicate2(), EX.Object2}) + assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3(), EX.Object3}) + assert graph_includes_statement?(g, {EX.Subject4, EX.predicate4(), EX.Object4}) + end + test "with a context" do g = Graph.new( @@ -423,6 +459,26 @@ defmodule RDF.GraphTest do assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3(), EX.Object3}) end + test "a dataset" do + g = + Graph.add( + graph(), + Dataset.new([ + {EX.Subject1, EX.predicate1(), EX.Object1, nil}, + {EX.Subject2, EX.predicate2(), EX.Object2, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph1}, + {EX.Subject3, EX.predicate3(), EX.Object3, EX.Graph2}, + {EX.Subject4, EX.predicate4(), EX.Object4, EX.Graph2} + ]) + ) + + assert Graph.triple_count(g) == 4 + assert graph_includes_statement?(g, {EX.Subject1, EX.predicate1(), EX.Object1}) + assert graph_includes_statement?(g, {EX.Subject2, EX.predicate2(), EX.Object2}) + assert graph_includes_statement?(g, {EX.Subject3, EX.predicate3(), EX.Object3}) + assert graph_includes_statement?(g, {EX.Subject4, EX.predicate4(), EX.Object4}) + end + test "merges the prefixes of another graph" do graph = Graph.new(prefixes: %{xsd: XSD}) @@ -543,7 +599,7 @@ defmodule RDF.GraphTest do end assert_raise FunctionClauseError, fn -> - Graph.add(graph(), RDF.dataset()) + Graph.add(graph(), RDF.bnode()) end end end @@ -735,13 +791,19 @@ defmodule RDF.GraphTest do assert graph_includes_statement?(g, {EX.S3, EX.p3(), EX.O3}) end + test "RDF.Datasets are causing an error" do + assert_raise ArgumentError, fn -> + Graph.put(graph(), RDF.dataset()) + end + end + test "structs are causing an error" do assert_raise FunctionClauseError, fn -> Graph.put(graph(), Date.utc_today()) end assert_raise FunctionClauseError, fn -> - Graph.put(graph(), RDF.dataset()) + Graph.put(graph(), RDF.bnode()) end end end @@ -943,13 +1005,19 @@ defmodule RDF.GraphTest do assert graph_includes_statement?(g, {EX.S3, EX.p3(), EX.O3}) end + test "RDF.Datasets are causing an error" do + assert_raise ArgumentError, fn -> + Graph.put_properties(graph(), RDF.dataset()) + end + end + test "structs are causing an error" do assert_raise FunctionClauseError, fn -> Graph.put_properties(graph(), Date.utc_today()) end assert_raise FunctionClauseError, fn -> - Graph.put_properties(graph(), RDF.dataset()) + Graph.put_properties(graph(), RDF.bnode()) end end end