Extension Functions
On this page
SPARQL allows non-standard, custom extension functions to be used within queries. In order to provide an implementation to these extension functions, Comunica allows developers to plug them in via the context.
Dictionary-based extension functions
The easiest way to plug in extension functions to Comunica is by using
the extensionFunctions
context entry
in a JavaScript application:
import {DataFactory} from "rdf-data-factory"; const DF = new DataFactory(); const bindingsStream = await myEngine.queryBindings(` PREFIX func: <http://example.org/functions#> SELECT ?caps WHERE { ?s ?p ?o. BIND (func:to-upper-case(?o) AS ?caps) } `, { sources: ['https://www.rubensworks.net/'], extensionFunctions: { 'http://example.org/functions#to-upper-case'(args: RDF.Term[]) { const arg = args[0]; if (arg.termType === 'Literal' && arg.datatype.value === 'http://www.w3.org/2001/XMLSchema#string') { return DF.literal(arg.value.toUpperCase(), arg.datatype); } return arg; }, }, });
Within this extensionFunctions
dictionary, you can provide any number of extension functions.
These functions may even be async
.
Callback-based extension functions
If function names are not known beforehand,
or the dictionary-based format is not usable for whatever reason,
then the callback-based extensionFunctionCreator
entry may be used:
import {DataFactory} from "rdf-data-factory"; const DF = new DataFactory(); const bindingsStream = await myEngine.queryBindings(` PREFIX func: <http://example.org/functions#> SELECT ?caps WHERE { ?s ?p ?o. BIND (func:to-upper-case(?o) AS ?caps) } `, { sources: ['https://www.rubensworks.net/'], extensionFunctionCreator: (funcTerm: RDF.NamedNode) => { if (funcTerm.value === 'http://example.org/functions#to-upper-case') { return (args: RDF.Term[]) => { const arg = args[0]; if (arg.termType === 'Literal' && arg.datatype.value === 'http://www.w3.org/2001/XMLSchema#string') { return DF.literal(arg.value.toUpperCase(), arg.datatype); } return arg; }; } }, });
The extensionFunctionCreator
is invoked upon any occurrence of an extension function,
and is called with the extension function name, wrapped within an RDF/JS named node.
The return type of this function is expected to be a function with the same signature
as the values of the extensionFunction
dictionary, or undefined
.