The AllegroGraph RDF server can be scripted using, apart from Common Lisp, the JavaScript language. The easiest way to get started with this is to open a repository in WebView and select the 'Script' page from the navigation bar.
This document describes the programming interface available to JavaScript programs running in an AllegroGraph server.
Overview
The simplest way to run scripts (and this is what the WebView interface uses), is the /eval
HTTP service, using a text/javascript
content-type for your request. This will cause the body of the request to evaluated as JavaScript. If an error is raised, it will be returned as an HTTP error. If not, the result of evaluating the code is returned. Usually, you'll want to specify that you accept application/json
responses, and receive the result in that form. If your code returns a cursor, you can also specify one of the formats suitable for that kind of cursor (like application/trix
for triple cursors, or application/sparql-results+xml
for SPARQL SELECT cursors).
It is also possible to define custom HTTP services using JavaScript. Here, you'll probably want to put your code in a server-side script file, with a .js
extension, and use the x-scripts
header to ensure your service is available. See the server.defineService
API function described below.
Note that, unless you are using a session, each /eval
request will run in its own environment, and thus not see variables and state created by previous requests.
Parts and Triples
The Part
function, when given a string, tries to parse it using N-Triples syntax, and returns a part value. This constructor has the following properties, used for constructing parts in other ways:
literal(string [, language])
- Create a literal.
literalTyped(string, type)
- Create a typed literal.
resource(string [, namespace])
- Create a resource. If namespace is given, it is looked up (see namespaces) and prepended to the resource name.
fromInt(int)
,fromUnsignedInt(int)
,fromLong(long)
,fromUnsignedLong(long)
- Create an encoded part from an integer value.
fromFloat(float)
,fromDouble(double)
- Create an encoded part from a floating-point value.
fromSeconds(seconds)
- When given an amount of seconds relative to 1900, encodes the time as a part.
fromDate(milliseconds)
- Like
fromSeconds
, but divides its argument by 1000, and uses 1970 as reference point. This can be used to convert JavaScriptDate
objects to parts, since those (when converted to number, which this function implicitly does) will return an amount of milliseconds since 1970.
Part values themselves have the following properties:
toString()
- Returns an N-Triples representation of the part.
value
- The main value of the part. For resources, this is the URI, for literals, the string, for encoded values, usually a number.
type
- A string, such as
"literal"
or"resource"
, which identifies the type of the part. language
- The language of a literal, or
null
if no language is specified. datatype
- The datatype of a literal, or
null
if no language is specified.
Triple
objects, as returned by, for example, store.getTriples
, have object
, predicate
, subject
, and graph
properties, which will return parts, and an id
property, which will return an integer.
The Triple Store
The top-level store
variable provides an interface to the current triple store (as determined by the URL from which the request is made). It is an instance of the the Store
type, and has the following properties:
name
- The name of the store.
getTriples(subject, predicate, object, graph)
- Returns a triple cursor containing the triples in the store that match the given query. Each of the arguments can be left as null (or not given) to specify a wildcard.
getTriplesArray(subject, predicate, object, graph [, limit])
- Like getTriples, but returns an array instead of a cursor. If
limit
is given, it provides a maximum length for the returned array. deleteTriples(subject, predicate, object, graph)
- Deletes all matching triples. Again, null and undefined count as wildcards.
addTriple(subject, predicate, object [, graph])
- Adds a new triple. Graph is optional.
size
- The amount of triples in the store.
commit()
,rollback()
- Commit or roll back the store.
newBlankNode()
- Returns a newly allocated blank node.
runSparql(query)
- Evaluates the given SPARQL query, and returns, depending on the type of query, a boolean, a triple cursor, or a row cursor. SPARQL/Update is supported (when the user has write access).
runProlog(query)
- Evaluates the given Prolog query. Will typically return an array of arrays of parts, but the exact format returned depends on the form of the query.
textIndices
- A list of names, corresponding to the full text indices present in the store.
createTextIndex(name [, options])
- Create a text index.
options
, if given, is an object containing options for the store. The propertiespredicates
,indexFields
,indexResources
,indexLitrals
,minimumWordSize
,stopWords
, andwordFilters
are supported, and accept values similar to those in the Lisp API. dropTextIndex(name)
- Drop a text index.
textSearch(query [, index])
- Search the given text index (or all of them, when
index
is left off) for the given query string. Returns a triple cursor. indices
- A list of indices present in the store.
addIndex(type)
- Add a new index. Type must be a
posgi
-style specifier. dropIndex(type)
- Delete an index.
Cursors
Cursors have the following properties:
next()
- Returns the next value from the cursor, or
null
if the cursor is exhausted. For triple cursors, this will return a triple. For row cursors, you get an array of parts. close()
- Closes the cursor, freeing any resources it holds. Note that all cursors are closed automatically after a script runs, so you only need this when you expect to be creating a large amount of cursors.
forEach(func)
- Calls
func
on each row in the cursor. collect([limit])
- Returns an array holding all the rows in the cursor. If
limit
is given, it limits the amount of rows that are collected. count()
- Counts the amount of rows in the cursor (and exhausts it).
names
- Only available for row cursor. Returns an array of strings, the names of the rows.
Namespace Management
There is a toplevel namespaces
object with these methods:
collect()
- Returns an array of
{name, uri}
objects representing the namespaces. register(name, uri)
- Register a new namespace.
unregister(name)
- Remove a namespace.
clear()
- Remove all namespaces.
reset()
- Go back to the standard namespaces.
lookup(name)
- Return the URI associated with the given name, or
null
if the namespace is not defined.
Geospatial Part Encoding
The GeoType
constructor provides an interface to geospatial encodings. Instances are created through these methods:
cartesian(store, xmin, xmax, ymin, ymax, strip-width)
- Defines a cartesian geospatial system for the given store.
spherical(store, strip-width [, unit])
- Defines a spherical system.
unit
can be one of degree, radian, km, or mile, and defaults to degree.
GeoType
instances have these properties:
datatype
- The RDF datatype associated with this type.
encode(x, y)
- Encode a geospatial part in this system. For spherical systems,
x
takes the longitude, andy
the latitude.
Graph/Network Operations
All graph operations are modeled around 'generators', which, conceptually, are functions that take a node, and produce a set of 'neighbors', by some definition of neighbor. The Generator
constructor can be called in two ways. In both, it takes a store as its first argument. When its second argument is a function, it wraps that function as a generator. The function should take a single part as an argument, and return an array of parts. When the second argument is not a function, the signature of the constructor is (store, objects, subjects, undirected)
, where each of the last tree arguments can be null
, a predicate part, or an array of predicates. The set of predicates indicated by the objects
parameter causes relations with those predicates to be followed from the starting node to any objects. The subjects
parameter does the reverse—it follows relations from object to subject. Finally, the undirected
parameter causes both of these to happen for the given predicates.
Generator instances have the following methods:
asMatrix(group, maxdepth)
- Converting a generator to a matrix returns a new generator which is a pre-computed version of the original generator. The
group
parameter should be an array of parts, andmaxdepth
an integer, indicating how many 'jumps' (starting from this group) should be pre-computed. The return value is again an instance ofGenerator
, and supports all the methods listed below. breadthFirstPath(from, to [, maxdepth])
depthFirstPath(from, to [, maxdepth])
bidirectionalPath(from, to [, maxdepth])
- These three methods try to compute and return a path between two parts, giving up after
maxdepth
jumps (or not giving up if no maximum depth is given). The return value will be an array of parts, ornull
if no path was found. breadthFirstPaths(from, to [, maxdepth])
bidirectionalPaths(from, to [, maxdepth])
- These work just like the methods described above, but will return an array containing all the shortest paths found, or the empty array if no path was found.
neighbors(node [, maxdepth])
- Returns an array containing all the parts that can be reached within
maxdepth
jumps fromnode
. If not given,maxdepth
defaults to 1. cliques(node [, minsize [, maxsize]])
- Finds and returns any cliques (completely connected subgraphs) that
node
is part of.minsize
defaults to 3. isClique(nodes)
- Given an array of parts, returns a boolean that indicates whether this group is a clique.
UPI Hash Tables
Hash tables specialized for UPIs are exposed through the UPIHash
constructor. These are much faster than using regular JavaScript objects to keep a mapping on triple parts. The constructor takes an optional size argument. Instances have the following methods:
set(key, value)
- Store
value
under the part given askey
. get(key)
- Retrieve the value stored under this key.
del(key)
- Remove the given key from the table.
keys()
- Returns an array holding all the keys in the table.
forEach(func)
- Calls
func
with(key, value)
arguments for every entry in the table.
Custom Service Definitions
The server
variable exposes a method defineService(method, name, func)
which can be used to define a JavaScript custom service. Its first argument should be a string (one of "get"
, "post"
, "put"
, and "delete"
), or an array of such strings. name
is a string that will name the service (for example, "magic"
will create a service under /repositories/[x]/custom/magic
), and finally, func
should be a JavaScript function of one argument.
When the service is called, this function will be applied to a request object, and its return value will be returned to the user, using the same content-negotiation process that was used for /eval
(as described before).
The request object can be used to get information about the request. It has the following properties:
url
- The URL to which this request was made.
method
- The method used for the request, as a lower-case string.
param(name)
- Retrieves the value of a parameter. This includes url-query ('get') parameters, and parameters found in the request body if it has a content-type of
application/x-www-form-urlencoded
. Returnsnull
if the parameter was not given. paramArray(name)
- Works like
param
, but returns an array, allowing you to see whether a parameter has been given multiple times. params
- An object with the parameter names as property names, their values as property values.
body
- The body of the request, as a string, or
null
if no body was given. header(name)
- Retrieves the value of a request header.