Add RDF.Graph.base_iri field and functions to handle it

This commit is contained in:
Marcel Otto 2019-08-03 00:10:47 +02:00
parent eae2196777
commit b28e5e4744
5 changed files with 104 additions and 12 deletions

View file

@ -5,6 +5,20 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
[Keep a CHANGELOG](http://keepachangelog.com).
## Unreleased
### Added
- field `base_iri` on `RDF.Graph` structure which can be set via new `base_iri`
option on `RDF.Graph.new` or the the new functions `RDF.Graph.set_base_iri/2`
and `RDF.Graph.clear_base_iri/1`
- `RDF.Graph.clear_metadata/1` which clears the base IRI and the prefixes
[Compare v0.6.1...HEAD](https://github.com/marcelotto/rdf-ex/compare/v0.6.1...HEAD)
## 0.6.1 - 2019-07-15
### Added

View file

@ -788,16 +788,16 @@ defmodule RDF.Dataset do
def equal?(dataset1, dataset2)
def equal?(%RDF.Dataset{} = dataset1, %RDF.Dataset{} = dataset2) do
clear_prefixes(dataset1) == clear_prefixes(dataset2)
clear_metadata(dataset1) == clear_metadata(dataset2)
end
def equal?(_, _), do: false
defp clear_prefixes(%RDF.Dataset{graphs: graphs} = dataset) do
defp clear_metadata(%RDF.Dataset{graphs: graphs} = dataset) do
%RDF.Dataset{dataset |
graphs:
Map.new(graphs, fn {name, graph} ->
{name, RDF.Graph.clear_prefixes(graph)}
{name, RDF.Graph.clear_metadata(graph)}
end)
}
end

View file

@ -11,7 +11,7 @@ defmodule RDF.Graph do
"""
defstruct name: nil, descriptions: %{}, prefixes: nil
defstruct name: nil, descriptions: %{}, prefixes: nil, base_iri: nil
@behaviour Access
@ -68,6 +68,8 @@ defmodule RDF.Graph do
- `name`: the name of the graph to be created
- `prefixes`: some prefix mappings which should be stored alongside the graph
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
## Examples
@ -77,6 +79,7 @@ defmodule RDF.Graph do
RDF.Graph.new([{EX.S1, EX.p1, EX.O1}, {EX.S2, EX.p2, EX.O2}])
RDF.Graph.new(RDF.Description.new(EX.S, EX.P, EX.O))
RDF.Graph.new([graph, description, triple])
RDF.Graph.new({EX.S, EX.p, EX.O}, name: EX.GraphName, base_iri: EX.base)
"""
def new(data, options)
@ -84,6 +87,7 @@ defmodule RDF.Graph do
def new(%RDF.Graph{} = graph, options) do
%RDF.Graph{graph | name: options |> Keyword.get(:name) |> coerce_graph_name()}
|> add_prefixes(Keyword.get(options, :prefixes))
|> set_base_iri(Keyword.get(options, :base_iri))
end
def new(data, options) do
@ -692,7 +696,7 @@ defmodule RDF.Graph do
def equal?(graph1, graph2)
def equal?(%RDF.Graph{} = graph1, %RDF.Graph{} = graph2) do
clear_prefixes(graph1) == clear_prefixes(graph2)
clear_metadata(graph1) == clear_metadata(graph2)
end
def equal?(_, _), do: false
@ -747,6 +751,35 @@ defmodule RDF.Graph do
%RDF.Graph{graph | prefixes: nil}
end
@doc """
Sets the base IRI of the given `graph`.
"""
def set_base_iri(graph, base_iri)
def set_base_iri(%RDF.Graph{} = graph, nil) do
%RDF.Graph{graph | base_iri: nil}
end
def set_base_iri(%RDF.Graph{} = graph, base_iri) do
%RDF.Graph{graph | base_iri: RDF.IRI.new(base_iri)}
end
@doc """
Clears the base IRI of the given `graph`.
"""
def clear_base_iri(%RDF.Graph{} = graph) do
%RDF.Graph{graph | base_iri: nil}
end
@doc """
Clears the base IRI and all prefixes of the given `graph`.
"""
def clear_metadata(%RDF.Graph{} = graph) do
graph
|> clear_base_iri()
|> clear_prefixes()
end
defimpl Enumerable do
def member?(graph, triple), do: {:ok, RDF.Graph.include?(graph, triple)}
@ -765,10 +798,8 @@ defmodule RDF.Graph do
def reduce(%RDF.Graph{} = graph, {:suspend, acc}, fun) do
{:suspended, acc, &reduce(graph, &1, fun)}
end
end
defimpl Collectable do
def into(original) do
collector_fun = fn
@ -782,6 +813,4 @@ defmodule RDF.Graph do
{original, collector_fun}
end
end
end

View file

@ -748,6 +748,10 @@ defmodule RDF.DatasetTest do
Dataset.new(Graph.new(triple, name: EX.Graph1, prefixes: %{ex: EX})),
Dataset.new(Graph.new(triple, name: EX.Graph1, prefixes: %{ex: RDF}))
)
assert Dataset.equal?(
Dataset.new(Graph.new(triple, name: EX.Graph1, base_iri: EX.base)),
Dataset.new(Graph.new(triple, name: EX.Graph1, base_iri: EX.other_base))
)
refute Dataset.equal?(Dataset.new(triple), Dataset.new({EX.S, EX.p, EX.O2}))
refute Dataset.equal?(Dataset.new(triple, name: EX.Dataset1),
Dataset.new(triple, name: EX.Dataset2))

View file

@ -120,6 +120,16 @@ defmodule RDF.GraphTest do
%Graph{Graph.new({EX.Subject, EX.predicate, EX.Object}) | prefixes: PrefixMap.new(ex: EX)}
end
test "with base_iri" do
assert Graph.new(base_iri: EX.base) ==
%Graph{base_iri: EX.base}
assert Graph.new(prefixes: %{ex: EX}, base_iri: EX.base) ==
%Graph{prefixes: PrefixMap.new(ex: EX), base_iri: EX.base}
assert Graph.new({EX.Subject, EX.predicate, EX.Object}, base_iri: EX.base) ==
%Graph{Graph.new({EX.Subject, EX.predicate, EX.Object}) | base_iri: EX.base}
end
test "creating a graph from another graph takes the prefixes from the other graph, but overwrites if necessary" do
prefix_map = PrefixMap.new(ex: EX)
g = Graph.new(Graph.new(prefixes: prefix_map))
@ -227,7 +237,13 @@ defmodule RDF.GraphTest do
assert graph.prefixes == PrefixMap.new(ex: EX)
end
test "preserves the name and prefixes on when the data provided is not a graph" do
test "preserves the base_iri" do
graph = Graph.new()
|> Graph.add(Graph.new({EX.Subject, EX.predicate, EX.Object}, base_iri: EX.base))
assert graph.base_iri == Graph.new.base_iri
end
test "preserves the name and prefixes when the data provided is not a graph" do
graph = Graph.new(name: EX.GraphName, prefixes: %{ex: EX})
|> Graph.add(EX.Subject, EX.predicate, EX.Object)
assert graph.name == RDF.iri(EX.GraphName)
@ -302,11 +318,12 @@ defmodule RDF.GraphTest do
assert graph.prefixes == PrefixMap.new(ex: EX)
end
test "preserves the name and prefixes" do
graph = Graph.new(name: EX.GraphName, prefixes: %{ex: EX})
test "preserves the name, base_iri and prefixes" do
graph = Graph.new(name: EX.GraphName, prefixes: %{ex: EX}, base_iri: EX.base)
|> Graph.put(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
@ -469,6 +486,8 @@ defmodule RDF.GraphTest do
|> Graph.equal?(Graph.new({EX.S, EX.p, EX.O}, name: EX.Graph1))
assert Graph.new({EX.S, EX.p, EX.O}, prefixes: %{ex: EX})
|> Graph.equal?(Graph.new({EX.S, EX.p, EX.O}, prefixes: %{xsd: XSD}))
assert Graph.new({EX.S, EX.p, EX.O}, base_iri: EX.base)
|> Graph.equal?(Graph.new({EX.S, EX.p, EX.O}, base_iri: EX.other_base))
refute Graph.new({EX.S, EX.p, EX.O}) |> Graph.equal?(Graph.new({EX.S, EX.p, EX.O2}))
refute Graph.new({EX.S, EX.p, EX.O}, name: EX.Graph1)
@ -519,6 +538,32 @@ defmodule RDF.GraphTest do
assert Graph.clear_prefixes(Graph.new(prefixes: %{ex: EX})) == Graph.new
end
describe "set_base_iri/1" do
test "when given an IRI" do
graph = Graph.new() |> Graph.set_base_iri(~I<http://example.com/>)
assert graph.base_iri == ~I<http://example.com/>
end
test "when given a vocabulary namespace atom" do
graph = Graph.new() |> Graph.set_base_iri(EX.Base)
assert graph.base_iri == RDF.iri(EX.Base)
end
test "when given nil" do
graph = Graph.new() |> Graph.set_base_iri(nil)
assert graph.base_iri == nil
end
end
test "clear_base_iri/1" do
assert Graph.clear_base_iri(Graph.new(base_iri: EX.base)) == Graph.new
end
test "clear_metadata/1" do
assert Graph.clear_metadata(Graph.new(base_iri: EX.base, prefixes: %{ex: EX})) ==
Graph.new
end
describe "Enumerable protocol" do
test "Enum.count" do
assert Enum.count(Graph.new(name: EX.foo)) == 0