Add RDF.Description.update/4
This commit is contained in:
parent
2cfa89125f
commit
623577b35e
3 changed files with 80 additions and 6 deletions
|
@ -9,6 +9,8 @@ This project adheres to [Semantic Versioning](http://semver.org/) and
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- `RDF.Description.update/4` updates the objects of a predicate in a description
|
||||||
|
with a custom update function
|
||||||
- `RDF.Description.take/2` creates a description from another one by limiting
|
- `RDF.Description.take/2` creates a description from another one by limiting
|
||||||
its statements to a set of predicates
|
its statements to a set of predicates
|
||||||
- `RDF.Graph.take/3` creates a graph from another one by limiting
|
- `RDF.Graph.take/3` creates a graph from another one by limiting
|
||||||
|
|
|
@ -367,13 +367,49 @@ defmodule RDF.Description do
|
||||||
|> List.first
|
|> List.first
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Updates the objects of the `predicate` in `description` with the given function.
|
||||||
|
|
||||||
# def update(description = %RDF.Description{}, predicate, initial \\ [], fun) do
|
If `predicate` is present in `description` with `objects` as value,
|
||||||
# triple_predicate = coerce_predicate(predicate)
|
`fun` is invoked with argument `objects` and its result is used as the new
|
||||||
# description.predicates
|
list of objects of `predicate`. If `predicate` is not present in `description`,
|
||||||
# |> Map.update(triple_predicate, initial, fn objects ->
|
`initial` is inserted as the `objects` of `predicate`. The initial value will
|
||||||
# end)
|
not be passed through the update function.
|
||||||
# end
|
|
||||||
|
The initial value and the returned objects by the update function will automatically
|
||||||
|
coerced to proper RDF object values before added.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> RDF.Description.new({EX.S, EX.p, EX.O}) |>
|
||||||
|
...> RDF.Description.update(EX.p, fn objects -> [EX.O2 | objects] end)
|
||||||
|
RDF.Description.new([{EX.S, EX.p, EX.O}, {EX.S, EX.p, EX.O2}])
|
||||||
|
iex> RDF.Description.new(EX.S) |>
|
||||||
|
...> RDF.Description.update(EX.p, EX.O, fn _ -> EX.O2 end)
|
||||||
|
RDF.Description.new({EX.S, EX.p, EX.O})
|
||||||
|
|
||||||
|
"""
|
||||||
|
def update(description = %RDF.Description{}, predicate, initial \\ nil, fun) do
|
||||||
|
predicate = coerce_predicate(predicate)
|
||||||
|
|
||||||
|
case get(description, predicate) do
|
||||||
|
nil ->
|
||||||
|
if initial do
|
||||||
|
put(description, predicate, initial)
|
||||||
|
else
|
||||||
|
description
|
||||||
|
end
|
||||||
|
|
||||||
|
objects ->
|
||||||
|
objects
|
||||||
|
|> fun.()
|
||||||
|
|> List.wrap()
|
||||||
|
|> case do
|
||||||
|
[] -> delete_predicates(description, predicate)
|
||||||
|
objects -> put(description, predicate, objects)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -317,6 +317,42 @@ defmodule RDF.DescriptionTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "update/4" do
|
||||||
|
test "list values returned from the update function become new coerced objects of the predicate" do
|
||||||
|
assert Description.new(EX.S, EX.P, [EX.O1, EX.O2])
|
||||||
|
|> Description.update(EX.P,
|
||||||
|
fn [_object | other] -> [EX.O3 | other] end) ==
|
||||||
|
Description.new(EX.S, EX.P, [EX.O3, EX.O2])
|
||||||
|
end
|
||||||
|
|
||||||
|
test "single values returned from the update function becomes new object of the predicate" do
|
||||||
|
assert Description.new(EX.S, EX.P, [EX.O1, EX.O2])
|
||||||
|
|> Description.update(EX.P, fn _ -> EX.O3 end) ==
|
||||||
|
Description.new(EX.S, EX.P, EX.O3)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returning an empty list or nil from the update function causes a removal of the predications" do
|
||||||
|
description = EX.S
|
||||||
|
|> EX.p(EX.O1, EX.O2)
|
||||||
|
assert description
|
||||||
|
|> Description.update(EX.p, fn _ -> [] end) ==
|
||||||
|
Description.new(EX.S, {EX.p, []})
|
||||||
|
assert description
|
||||||
|
|> Description.update(EX.p, fn _ -> nil end) ==
|
||||||
|
Description.new(EX.S, {EX.p, []})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "when the property is not present the initial object value is added for the predicate and the update function not called" do
|
||||||
|
fun = fn _ -> raise "should not be called" end
|
||||||
|
assert Description.new(EX.S)
|
||||||
|
|> Description.update(EX.P, EX.O, fun) ==
|
||||||
|
Description.new(EX.S, EX.P, EX.O)
|
||||||
|
|
||||||
|
assert Description.new(EX.S)
|
||||||
|
|> Description.update(EX.P, fun) ==
|
||||||
|
Description.new(EX.S)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "pop" do
|
test "pop" do
|
||||||
assert Description.pop(Description.new(EX.S)) == {nil, Description.new(EX.S)}
|
assert Description.pop(Description.new(EX.S)) == {nil, Description.new(EX.S)}
|
||||||
|
|
Loading…
Reference in a new issue