Write support
See original GitHub issueThis is a proposal for adding write-support to LDflex.
It requires three new handles:
- AdditionHandler: binds to
add
andaddAll
. - DeletionHandler: binds to
delete
anddeleteAll
. - UpdateHandler (optional): binds to
update
andupdateAll
.
Addition
This requires a straightforward handler that intercepts the add
and addAll
functions
that take one mandatory argument.
Adding a single value:
await user.friends.add('https://rubensworks.solid.community/profile/card#me')
SPARQL:
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <https://rubensworks.solid.community/profile/card#me>.
}
Adding the first of multiple values:
await user.friends.add(user.friends.friends)
SPARQL:
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows
<http://example.org/A>.
}
Adding multiple values:
for await (const addedFriend of user.friends.add(user.friends.friends)) {
console.log(addedFriend)
}
SPARQL:
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/A>.
}
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/B>.
}
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/C>.
}
Adding multiple values in bulk:
await user.friends.addAll(user.friends.friends)
SPARQL:
INSERT DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows
<http://example.org/A>,
<http://example.org/B>,
<http://example.org/C>.
}
Note: We can not trap =
via the proxy (set
), as this requires a synchronous operation, and you can not play around with return values.
Deletion
This requires a handler that intercepts the delete
and deleteAll
functions
that take one optional argument.
Deleting a single value:
await user.friends.delete('https://rubensworks.solid.community/profile/card#me')
SPARQL:
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <https://rubensworks.solid.community/profile/card#me>.
}
Deleting the first of a list of values:
await user.friends.delete(user.friends.friends)
SPARQL:
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows
<http://example.org/A>.
}
(maybe this can be done with a DELETE WHERE
?)
Deleting a list of values:
for await (const deletedFriend of user.friends.add(user.friends.friends)) {
console.log(deletedFriend)
}
SPARQL:
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/A>,
}
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/B>,
}
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows <http://example.org/C>,
}
Deleting a list of values in bulk:
await user.friends.deleteAll(user.friends.friends)
SPARQL:
DELETE DATA
{
<https://rubensworks.solid.community/profile/card#me> foaf:knows
<http://example.org/A>,
<http://example.org/B>,
<http://example.org/C>.
}
Deleting first or all possible values:
await user.friends.delete()
await user.friends.deleteAll()
Internally, this corresponds to await user.friends.delete(user.friends)
or await user.friends.deleteAll(user.friends)
, because SPARQL DELETE does not allow blank nodes or variables
Note: We can not trap the delete
operator via the proxy (deleteProperty
), as this requires a synchronous operation, and you can not play around with return values.
Update
This corresponds to a delete followed by an insert.
This is merely convenience functionality that combines deletion and addition (optimizable with a combined SPARQL query: https://www.w3.org/TR/2013/REC-sparql11-update-20130321/#deleteInsert).
This requires a handler for set
and setAll
that take one mandatory argument.
Updating a single value:
await user.name.set('Ruben')
Translation:
await user.name.delete() # Delete a single value
await user.name.add('Ruben') # Add a single value
Updating the first of multiple value:
await user.name.set(user.friends.name)
Translation:
await user.name.delete()
await user.name.add(user.friends.name)
Updating multiple values:
for await (const newName of user.name.set(user.friends.name)) {
console.log(newName)
}
SPARQL:
await user.name.deleteAll()
await user.name.add(name0) # add calls are separated by for-await iterations.
await user.name.add(name1)
await user.name.add(name2)
...
Updating multiple values in bulk:
await user.name.setAll(user.friends.name)
SPARQL:
await user.name.deleteAll()
await user.name.addAll(user.friends.name)
Issue Analytics
- State:
- Created 5 years ago
- Reactions:2
- Comments:10 (3 by maintainers)
Top GitHub Comments
I’ve written everything down in a separate gist that I will update once we decide new things: https://gist.github.com/rubensworks/1123742b048bd2e82624c713a024dcab
I think we agree on everything already, except for perhaps the syntactical sugar and batching. But those build on top of the previous ones, so I can already go ahead an start implementing those.
Ok, I see there is https://github.com/RubenVerborgh/LDflex/issues/10 already 😃