Store = function (arg1, arg2) { var callback = null; var params = null; if(arguments.length == 0) { params ={}; } else if(arguments.length == 1) { params = {}; callback = arg1; } else if(arguments.length > 1) { params = arg1; callback = arg2; } else { throw("An optional argument map and a callback must be provided"); } if(params['treeOrder'] == null) { params['treeOrder'] = 15; } var Lexicon = InMemoryLexicon; var QuadBackend = InMemoryQuadBackend; if(params['persistent'] === true){ Lexicon = PersistentLexicon; QuadBackend = PersistentBackend; } this.functionMap = {}; var that = this; this.customFns = {}; new Lexicon(function(lexicon){ var createQuadBackend = function() { new QuadBackend(params, function (backend) { var createEngine = function() { params.backend = backend; params.lexicon = lexicon; that.engine = new QueryEngine(params); callback(null, that); }; if(params['overwrite']) { backend.clear(createEngine) } else { createEngine(); } }); }; if(params['overwrite'] === true) { // delete lexicon values lexicon.clear(createQuadBackend); } else { createQuadBackend(); } },params['name']); }
...
// alt 1
rdfstore.create(function(err, store) {
// the new store is ready
});
// alt 2
new rdfstore.Store(function(err, store) {
// the new store is ready
});
```
###Query execution
```javascript
...
connect = function () { var callback; if(arguments.length == 1) { callback = arguments[0]; } else if(arguments.length == 2) { callback = arguments[1]; } else { callback = arguments[2]; } callback(new Error("Store#connect is not supported in the 0.9.X series of the library")); }
n/a
create = function (){ if(arguments.length == 1) { return new Store(arguments[0]); } else if(arguments.length == 2) { return new Store(arguments[0], arguments[1]); } else { return new Store(); }; }
...
## Introduction
rdfstore-js is a pure Javascript implementation of a RDF graph store with support for the SPARQL query and data manipulation language
.
```javascript
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
...
Store = function (arg1, arg2) { var callback = null; var params = null; if(arguments.length == 0) { params ={}; } else if(arguments.length == 1) { params = {}; callback = arg1; } else if(arguments.length > 1) { params = arg1; callback = arg2; } else { throw("An optional argument map and a callback must be provided"); } if(params['treeOrder'] == null) { params['treeOrder'] = 15; } var Lexicon = InMemoryLexicon; var QuadBackend = InMemoryQuadBackend; if(params['persistent'] === true){ Lexicon = PersistentLexicon; QuadBackend = PersistentBackend; } this.functionMap = {}; var that = this; this.customFns = {}; new Lexicon(function(lexicon){ var createQuadBackend = function() { new QuadBackend(params, function (backend) { var createEngine = function() { params.backend = backend; params.lexicon = lexicon; that.engine = new QueryEngine(params); callback(null, that); }; if(params['overwrite']) { backend.clear(createEngine) } else { createEngine(); } }); }; if(params['overwrite'] === true) { // delete lexicon values lexicon.clear(createQuadBackend); } else { createQuadBackend(); } },params['name']); }
...
// alt 1
rdfstore.create(function(err, store) {
// the new store is ready
});
// alt 2
new rdfstore.Store(function(err, store) {
// the new store is ready
});
```
###Query execution
```javascript
...
yieldFrequency = function (val) { _.yieldFrequency(val); }
...
###Controlling the frequency of function yielding
Performance of the store can be improved by reducing the frequency the 'nexTick' mechanism is used to cancel the the calls
stack.
You can reduce this frequency by invoking the `yieldFrequency` function on the Store object and passing a bigger number:
``` javascript
var rdfstore = require('rdfstore')
rdfstore.Store.yieldFrequency(200); // will only yield after 200 invocations of nextTick
```
If the number is too big a number can produce stack overflow errors during execution. If you find this problem, reduce the value
provided for `yieldFrequency`.
##Dependencies
The library include dependencies to two semantic-web libraries for
...
_nodeToQuery = function (term) { if(term.interfaceName === 'NamedNode') { var resolvedUri = this.rdf.resolve(term.valueOf()); if(resolvedUri != null) { return "<" + resolvedUri + ">"; } else { return "<" + term.valueOf() + ">"; } } else { return term.toString(); } }
...
} else {
throw("The triples to insert, an optional graph and callback must be provided");
}
var query = "";
var that = this;
triples.forEach(function(triple) {
query = query + that._nodeToQuery(triple.subject) + that._nodeToQuery(triple.predicate
) + that._nodeToQuery(triple.object) + ".";
});
if(graph != null) {
query = "INSERT DATA { GRAPH " + this._nodeToQuery(graph) +" { "+ query + " } }";
} else {
query = "INSERT DATA { "+ query + " }";
}
...
clear = function () { var graph; var callback; if(arguments.length === 0) { graph = this.rdf.createNamedNode(this.engine.lexicon.defaultGraphUri); var callback= function(){}; } else if(arguments.length === 1) { graph = this.rdf.createNamedNode(this.engine.lexicon.defaultGraphUri); callback= arguments[0] || function(){}; } else if(arguments.length === 2) { graph = this.rdf.createNamedNode(arguments[0]); callback= arguments[1] || function(){}; } else { throw("The optional graph and a callback must be provided"); } var query = "CLEAR GRAPH " + this._nodeToQuery(graph); this.engine.execute(query, callback); }
...
store.delete(graph, graphUri, function(err){});
/* clearing a graph */
// clears the default graph
store.clear(function(err){});
// clears a named graph
store.clear(graphUri, function(err){});
/* Parsing and loading a graph */
...
close = function (cb) { if(cb == null) cb = function(){}; if(this.engine.close) this.engine.close(cb); else cb(); }
...
* Clean-up function releasing all temporary resources held by the
* store instance.
*/
Store.prototype.close = function(cb) {
if(cb == null)
cb = function(){};
if(this.engine.close)
this.engine.close(cb);
else
cb();
};
/**
* Version of the store
*/
...
delete = function () { var graph; var triples; var callback; if(arguments.length === 1) { triples = arguments[0]; callback= function(){}; } else if(arguments.length === 2) { triples = arguments[0]; callback= arguments[1] || function(){}; } else if(arguments.length === 3) { triples = arguments[0]; graph = this.rdf.createNamedNode(arguments[1]); callback= arguments[2] || function(){}; } else { throw("The triples to delete, an optional graph and callback must be provided"); } var query = ""; var that = this; triples.forEach(function(triple) { query = query + that._nodeToQuery(triple.subject) + that._nodeToQuery(triple.predicate) + that._nodeToQuery(triple.object) + "."; }); if(graph != null) { query = "DELETE DATA { GRAPH " + this._nodeToQuery(graph) +" { "+ query + " } }"; } else { query = "DELETE DATA { "+ query + " }"; } this.engine.execute(query, callback); }
...
store.insert(graph, graphUri, function(err) {}) ;
/* deleting a JS Interface API graph object into the store */
// deleted from the default graph
store.delete(graph, function(err){});
// deleted from graphUri
store.delete(graph, graphUri, function(err){});
/* clearing a graph */
...
execute = function () { if(arguments.length === 3) { this.executeWithEnvironment(arguments[0], arguments[1], arguments[2]); } else if(arguments.length === 4) { this.executeWithEnvironment(arguments[0], arguments[1], arguments[2], arguments[3]); } else { var queryString; var callback; if(arguments.length === 1) { queryString = arguments[0]; var callback = function(){}; } else if(arguments.length === 2) { queryString = arguments[0]; callback = arguments [1]; } this.engine.execute(queryString, callback); } }
...
## Introduction
rdfstore-js is a pure Javascript implementation of a RDF graph store with support for the SPARQL query and data manipulation language
.
```javascript
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO
GRAPH <http://example.org/people>', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
...
executeWithEnvironment = function () { var queryString, defaultGraphs, namedGraphs; if(arguments.length === 3) { queryString = arguments[0]; // JSDoc fails if this is pushed outside var callback = function(){}; defaultGraphs = arguments[1]; namedGraphs = arguments[2]; } else if(arguments.length === 4) { queryString = arguments[0]; var callback = arguments [3]; defaultGraphs = arguments[1]; namedGraphs = arguments[2]; } defaultGraphs = _.map(defaultGraphs, function(graph){ return {'token':'uri','value':graph}; }); namedGraphs = _.map(namedGraphs, function(graph){ return {'token':'uri','value':graph}; }); this.engine.execute(queryString, callback, defaultGraphs, namedGraphs); }
...
});
// execution with an explicit default and named graph
var defaultGraph = [{'token':'uri', 'value': graph1}, {'token':'uri', 'value
': graph2}, ...];
var namedGraphs = [{'token':'uri', 'value': graph3}, {'token':'uri', 'value
': graph4}, ...];
store.executeWithEnvironment("SELECT * { ?s ?p ?o }",defaultGraph,
namedGraphs, function(err, results) {
if(err) {
// process results
}
});
```
...
getNetworkTransport = function () { return NetworkTransport; }
n/a
graph = function () { var graphUri = null; var callback = null; if(arguments.length === 1) { callback = arguments[0] || function(){}; graphUri = this.engine.lexicon.defaultGraphUri; } else if(arguments.length === 2) { callback = arguments[1] || function(){}; graphUri = arguments[0]; } else { throw("An optional graph URI and a callback function must be provided"); } if(this.rdf.resolve(graphUri) != null) { graphUri = this.rdf.resolve(graphUri); } this.engine.execute("CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <" + graphUri + "> { ?s ?p ?o } }", callback); }
...
###High level interface
The following interface is a convenience API to work with Javascript code instead of using SPARQL query strings. It is built on
top of the RDF Interfaces W3C API.
```javascript
/* retrieving a whole graph as JS Interafce API graph object */
store.graph(graphUri, function(err, graph){
// process graph
});
/* Exporting a graph to N3 (this function is not part of W3C's API)*/
store.graph(graphUri, function(err, graph){
var serialized = graph.toNT();
...
insert = function () { var graph; var triples; var callback; if(arguments.length === 1) { triples = arguments[0]; callback= function(){}; } else if(arguments.length === 2) { triples = arguments[0]; callback= arguments[1] || function(){}; } else if(arguments.length === 3) { triples = arguments[0]; graph = this.rdf.createNamedNode(arguments[1]); callback= arguments[2] || function(){}; } else { throw("The triples to insert, an optional graph and callback must be provided"); } var query = ""; var that = this; triples.forEach(function(triple) { query = query + that._nodeToQuery(triple.subject) + that._nodeToQuery(triple.predicate) + that._nodeToQuery(triple.object) + "."; }); if(graph != null) { query = "INSERT DATA { GRAPH " + this._nodeToQuery(graph) +" { "+ query + " } }"; } else { query = "INSERT DATA { "+ query + " }"; } this.engine.execute(query, callback); }
...
});
/* inserting a JS Interface API graph object into the store */
// inserted in the default graph
store.insert(graph, function(err) {}) ;
// inserted in graphUri
store.insert(graph, graphUri, function(err) {}) ;
/* deleting a JS Interface API graph object into the store */
...
load = function (){ var mediaType; var data; var graph; var callback; var options = {}; if(arguments.length === 3) { graph = this.rdf.createNamedNode(this.engine.lexicon.defaultGraphUri); mediaType = arguments[0]; data = arguments[1]; callback= arguments[2] || function(){}; } else if(arguments.length === 4) { mediaType = arguments[0]; data = arguments[1]; options = arguments[2]; if(typeof(options) === 'string') { graph = this.rdf.createNamedNode(options); options = {}; } else { graph = this.rdf.createNamedNode(options.graph || this.engine.lexicon.defaultGraphUri); delete options['graph']; } callback= arguments[3] || function(){}; } else if(arguments.length === 2) { throw("The mediaType of the parser, the data a callback and an optional graph must be provided"); } if(mediaType === 'remote') { data = this.rdf.createNamedNode(data); var query = "LOAD <"+data.valueOf()+"> INTO GRAPH <"+graph.valueOf()+">"; this.engine.execute(query, callback); } else { var that = this; var parser = this.engine.rdfLoader.parsers[mediaType]; if (!parser) return callback(new Error("Cannot find parser for the provided media type:"+mediaType)); var cb = function(err, quads) { if(err) { callback(err, quads); } else { that.engine.batchLoad(quads,function(success){ if(success != null){ callback(null,success); } else { callback(new Error("Erro batch-loading triples.")); } }); } }; var args = [parser, {'token':'uri', 'value':graph.valueOf()}, data, options, cb]; if(data && typeof(data)==='string' && data.indexOf('file://')=== 0) { this.engine.rdfLoader.loadFromFile.apply(null, args); } else { this.engine.rdfLoader.tryToParse.apply(null, args); } } }
...
store.clear(graphUri, function(err){});
/* Parsing and loading a graph */
// loading local data
store.load("text/turtle", turtleString, function(err, results) {});
// loading remote data
store.load('remote', remoteGraphUri, function(err, results) {});
/* Registering a parser for a new media type */
...
node = function () { var graphUri = null; var callback = null; var nodeUri = null; if(arguments.length === 2) { nodeUri = arguments[0]; callback = arguments[1] || function(){}; graphUri = this.engine.lexicon.defaultGraphUri; } else if(arguments.length === 3) { nodeUri = arguments[0]; graphUri = arguments[1]; callback = arguments[2] || function(){}; } else { throw("An optional graph URI, node URI and a callback function must be provided"); } if(this.rdf.resolve(graphUri) != null) { graphUri = this.rdf.resolve(graphUri); } if(this.rdf.resolve(nodeUri) != null) { nodeUri = this.rdf.resolve(nodeUri); } this.engine.execute("CONSTRUCT { <" + nodeUri + "> ?p ?o } WHERE { GRAPH <" + graphUri + "> { <" + nodeUri + "> ?p ?o } }", callback); }
...
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example
.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
store.execute('PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\
PREFIX foaf: <http://xmlns.com/foaf/0.1/>\
PREFIX : <http://example.org/>\
SELECT ?s FROM NAMED :people { GRAPH ?g { ?s rdf:type foaf:Person } }',
...
registerCustomFunction = function (name, fn) { this.customFns[name] = fn; this.engine.setCustomFunctions(this.customFns); }
...
test:B test:prop 4.\
test:C test:prop 1.\
test:D test:prop 3.',
function(err) {
var invoked = false;
// instead of 'my_addition_check' a full URI can be used 'http://test.com/my_fns/my_addition_check'
;
store.registerCustomFunction('my_addition_check', function(engine,args) {
// equivalent to var v1 = parseInt(args[0].value), v2 = parseInt(args[1].value);
var v1 = engine.effectiveTypeValue(args[0]);
var v2 = engine.effectiveTypeValue(args[1]);
// equivalent to return {token: 'literal', type:"http://www.w3.org/2001/XMLSchema#boolean", value:(v1+v2
x3c;5)};
...
registerDefaultNamespace = function (ns, prefix) { this.rdf.prefixes.set(ns,prefix); this.engine.registerDefaultNamespace(ns,prefix); }
...
*
* @arguments
* @param {String} ns the name space to be regsitered
* @param {String} prefix the URI fragment associated to the name space
*/
Store.prototype.registerDefaultNamespace = function(ns, prefix) {
this.rdf.prefixes.set(ns,prefix);
this.engine.registerDefaultNamespace(ns,prefix);
};
/**
* Registers the default namespaces declared in the RDF JS Interfaces
* specification in the default Profile.
*/
Store.prototype.registerDefaultProfileNamespaces = function() {
...
registerDefaultProfileNamespaces = function () { var defaultNsMap = this.rdf.prefixes.values(); for (var p in defaultNsMap) { this.registerDefaultNamespace(p,defaultNsMap[p]); } }
...
Default RDF name-spaces can be specified using the *registerDefaultNamespace*. These names will be included automatically in all
queries. If the same name-space is specified by the client in the query string the new prefix will shadow the default one.
A collection of common name-spaces like rdf, rdfs, foaf, etc. can be automatically registered using the *registerDefaultProfileNamespace
* function.
```javascript
new Store({name:'test', overwrite:true}, function(err,store){
store.execute('INSERT DATA { <http://example/person1> <http://xmlns.com/foaf/0.1/name> "Celia"
; }', function(err){
store.registerDefaultProfileNamespaces();
store.execute('SELECT * { ?s foaf:name ?name }', function(err,results) {
test.ok(results.length === 1);
test.ok(results[0].name.value === "Celia");
});
});
});
...
registerParser = function (mediaType, parser) { this.engine.rdfLoader.registerParser(mediaType,parser); }
...
/* Registering a parser for a new media type */
// The parser object must implement a 'parse' function
// accepting the data to parse and a callback function.
store.registerParser("application/rdf+xml", rdXmlParser);
```
###RDF Interface API
The store object includes a 'rdf' object implementing a RDF environment as described in the [RDF Interfaces 1.0](http://
www.w3.org/TR/rdf-interfaces/) W3C's working draft.
This object can be used to access to the full RDF Interfaces 1.0 API.
...
registeredGraphs = function (callback) { this.engine.lexicon.registeredGraphs(true, function(graphs){ var graphNodes = _.map(graphs, function(graph){ return new RDFModel.NamedNode(graph); }); callback(null, graphNodes); }); }
...
* Returns the URI of all the graphs currently contained
* in the store
*
* @arguments:
* @param {Function} callback function that will receive a success notification and the array of graph URIs
*/
Store.prototype.registeredGraphs = function(callback) {
this.engine.lexicon.registeredGraphs(true, function(graphs){
var graphNodes = _.map(graphs, function(graph){
return new RDFModel.NamedNode(graph);
});
callback(null, graphNodes);
});
};
...
setBatchLoadEvents = function (mustFireEvents){ this.engine.eventsOnBatchLoad = mustFireEvents; }
n/a
setDefaultPrefix = function (uri) { this.rdf.setDefaultPrefix(uri); }
...
* API <code>RDFEnvironment</code> object associated to the store and available
* through the <code>storeInstance.rdf</code> property.
*
* @arguments
* @param {String} URIFragment The URI fragment will be used by default
*/
Store.prototype.setDefaultPrefix = function(uri) {
this.rdf.setDefaultPrefix(uri);
};
/**
* Inserts a RDF JS Interface API <code>Graph</code> object into the store.
* The function receives a mandatory <code>Graph</code> object whose triples
* will be inserted. Optionally, a URI string for a graph and a
* callback function can be passed as arguments.<br/>
...
setNetworkTransport = function (networkTransportImpl) { NetworkTransport = networkTransportImpl; }
n/a
setPrefix = function (prefix, uri) { this.rdf.setPrefix(prefix, uri); }
...
rdfstore-js is a pure Javascript implementation of a RDF graph store with support for the SPARQL query and data manipulation language
.
```javascript
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
store.execute('PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\
PREFIX foaf: <http://xmlns.com/foaf/0.1/>\
...
startObservingNode = function () { var uri, graphUri, callback; if(arguments.length === 2) { uri = arguments[0]; callback = arguments[1]; this.engine.callbacksBackend.observeNode(uri, callback, function(){}); } else if(arguments.length === 3) { uri = arguments[0]; graphUri = arguments[1]; callback = arguments[2]; this.engine.callbacksBackend.observeNode(uri, graphUri, callback, function(){}); } }
...
// If the node does not exist, the graph received will
// not contain triples.
console.log("The node has now "+node.toArray().length+" nodes");
}
// if only tow arguments are passed, the default graph will be used.
// A graph uri can be passed as an optional second argument.
store.startObservingNode("http://example/book",cb);
// .. do something;
// stop receiving notifications
store.stopObservingNode(cb);
```
...
startObservingQuery = function () { var query = arguments[0]; var callback = arguments[1]; var endCallback = arguments[2]; if(endCallback!=null) { this.engine.callbacksBackend.observeQuery(query, callback, endCallback); } else { this.engine.callbacksBackend.observeQuery(query, callback, function(){}); } }
n/a
stopObservingNode = function (callback) { this.engine.callbacksBackend.stopObservingNode(callback); }
...
// A graph uri can be passed as an optional second argument.
store.startObservingNode("http://example/book",cb);
// .. do something;
// stop receiving notifications
store.stopObservingNode(cb);
```
In the same way, there are *startObservingQuery* and *stopObservingQuery* functions that makes possible to set up callbacks for
whole SPARQL queries.
The store will try to be smart and not perform unnecessary evaluations of these query after quad insertion/deletions. Nevertheless
too broad queries must be used carefully with the events API.
###Custom Filter Functions
...
stopObservingQuery = function (query) { this.engine.callbacksBackend.stopObservingQuery(query); }
...
* Removes a callback function associated to a SPARQL query.<br/>
* The event listener function object must be passed as an argument.
*
* @arguments
* @param {Function} eventListener The event listener function to remove, the same passed as an argument to startObservingQuery
*/
Store.prototype.stopObservingQuery = function(query) {
this.engine.callbacksBackend.stopObservingQuery(query);
};
/**
* Associates an event listener to a pattern expressed as the
* subject, predicate, object and graph string parameters passed
* to the function. To match any value in that position, a <code>null</code>
* value can be passed as an argument. e.g. <code>subscribe(null, null, null, g, cb)</code>,
...
subscribe = function (s, p, o, g, callback) { var that = this; var adapterCb = function(event,triples){ var acum = []; var queryEnv = {blanks:{}, outCache:{}}; var bindings = []; _.each(triples, function(triple){ var s = RDFModel.buildRDFResource(triple.subject,bindings,that.engine,queryEnv); var p = RDFModel.buildRDFResource(triple.predicate,bindings,that.engine,queryEnv); var o = RDFModel.buildRDFResource(triple.object,bindings,that.engine,queryEnv); if(s!=null && p!=null && o!=null) { triple = new RDFModel.Triple(s,p,o); acum.push(triple); } }); callback(event,acum); }; this.functionMap[callback] = adapterCb; this.engine.callbacksBackend.subscribe(s,p,o,g,adapterCb,function(){}); }
...
if(event === 'added') {
console.log(triples.length+" triples have been added");
} else if(event === 'deleted') {
console.log(triples.length+" triples have been deleted");
}
}
store.subscribe("http://example/book",null,null,null,cb);
// .. do something;
// stop receiving notifications
store.unsubscribe(cb);
```
...
unsubscribe = function (callback) { var adapterCb = this.functionMap[callback]; this.engine.callbacksBackend.unsubscribe(adapterCb); delete this.functionMap[callback]; }
...
store.subscribe("http://example/book",null,null,null,cb);
// .. do something;
// stop receiving notifications
store.unsubscribe(cb);
```
The main difference between both methods is that *subscribe* receives the triples that have changed meanwhile *startObservingNode
* receives alway the whole node with its updated triples. *startObservingNode* receives the node as a RDF Interface graph object
.
```javascript
var cb = function(node){
// it will receive the updated version of the node each
...
AbstractQueryTree = function () { }
...
//imports
QueryEngine.QueryEngine = function(params) {
if(arguments.length != 0) {
this.backend = params.backend;
this.lexicon = params.lexicon;
this.abstractQueryTree = new AbstractQueryTree.AbstractQueryTree();
this.rdfLoader = new RDFLoader.RDFLoader(params['communication']);
this.callbacksBackend = new Callbacks.CallbacksBackend(this);
}
};
// Utils
...
function NonSupportedSparqlFeatureError(feature, message) { this.name = "NonSupportedSparqlFeatureError"; this.feature = feature; this.message = message || "SPARQL feature "+feature+" non supported"; }
n/a
function SparqlParserError(message) { this.name = ParserError; this.message = message || "Error parsing SPARQL query"; }
n/a
Node = function () { this.numberActives = 0; this.isLeaf = null; this.keys = []; this.children = []; this.level = 0; }
...
*
* This class can be overwritten by different versions of
* the tree t select the right kind of node to be used
*
* @returns the new alloacted node
*/
InMemoryAsyncBTree.Tree.prototype._allocateNode = function() {
return new InMemoryAsyncBTree.Node();
};
/**
* _diskWrite
*
* Persists the node to secondary memory.
*/
...
Tree = function (order, f) { if(arguments.length != 0) { this.order = order; this.root = this._allocateNode(); this.root.isLeaf = true; this.root.level = 0; var that = this; this._diskWrite(this.root, function(root){ that.root = root; that._updateRootNode(that.root, function(n){ that.comparator = function(a,b) { if(a < b) { return -1; } else if(a > b){ return 1; } else { return 0; } }; that.merger = null; // we notify we are ready if(f!=null) { f(that); } })}); } }
...
describe('BTree', function(){
it("Should be possible to find data that has been inserted in the tree as well as walk through it.", function(done){
async.seq(function(_,c){
new btree.Tree(2,function(tree){
c(null,tree);
});
},function(tree,c){
async.eachSeries([11, 2, 14, 15, 1, 7, 5, 8, 4, 6, 3],
function(i,cc){
tree.insert(i,i,function(){ cc(); });
},function(e){
...
Tree = function (keyFun, f) { this.keyFun = keyFun; if(this.keyFun == null || typeof(keyFun) !== 'function') this.keyFun = function(x) { return x }; this.data = {}; if(f != null) return f(this); }
...
describe('BTree', function(){
it("Should be possible to find data that has been inserted in the tree as well as walk through it.", function(done){
async.seq(function(_,c){
new btree.Tree(2,function(tree){
c(null,tree);
});
},function(tree,c){
async.eachSeries([11, 2, 14, 15, 1, 7, 5, 8, 4, 6, 3],
function(i,cc){
tree.insert(i,i,function(){ cc(); });
},function(e){
...
CallbacksBackend = function () { this.aqt = new AbstractQueryTree(); this.engine = arguments[0]; this.indexMap = {}; this.observersMap = {}; this.queriesIndexMap = {}; this.emptyNotificationsMap = {}; this.queriesList = []; this.pendingQueries = []; this.matchedQueries = []; this.updateInProgress = null; this.indices = ['SPOG', 'GP', 'OGS', 'POG', 'GSP', 'OS']; this.componentOrders = { SPOG: ['subject', 'predicate', 'object', 'graph'], GP: ['graph', 'predicate', 'subject', 'object'], OGS: ['object', 'graph', 'subject', 'predicate'], POG: ['predicate', 'object', 'graph', 'subject'], GSP: ['graph', 'subject', 'predicate', 'object'], OS: ['object', 'subject', 'predicate', 'graph'] }; this.callbackCounter = 0; this.callbacksMap = {}; this.callbacksInverseMap = {}; this.queryCounter = 0; this.queriesMap = {}; this.queriesCallbacksMap = {}; this.queriesInverseMap = {}; for(var i=0; i<this.indices.length; i++) { var indexKey = this.indices[i]; this.indexMap[indexKey] = {}; this.queriesIndexMap[indexKey] = {}; } }
...
QueryEngine.QueryEngine = function(params) {
if(arguments.length != 0) {
this.backend = params.backend;
this.lexicon = params.lexicon;
this.abstractQueryTree = new AbstractQueryTree.AbstractQueryTree();
this.rdfLoader = new RDFLoader.RDFLoader(params['communication']);
this.callbacksBackend = new Callbacks.CallbacksBackend(this);
}
};
// Utils
QueryEngine.QueryEngine.prototype.registerNsInEnvironment = function(prologue, env) {
var prefixes = prologue.prefixes;
...
Lexicon = function (callback){ var that = this; this.defaultGraphOid = 0; this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph"; this.defaultGraphUriTerm = {"token":"uri","prefix":null,"suffix":null,"value":this.defaultGraphUri}; this.oidCounter = 1; async.seq(function(k){ new Tree(2,function(tree){ that.uris = tree; k(); }) }, function(k){ new Tree(2, function(tree){ that.literals = tree; k(); }) }, function(k){ new Tree(2, function(tree){ that.knownGraphs = tree; k(); }) },function(k){ new Tree(2,function(tree){ that.oidUris = tree; k(); }) }, function(k){ new Tree(2, function(tree){ that.oidLiterals = tree; k(); }) }, function(k){ new Tree(2, function(tree){ that.oidBlanks = tree; k(); }) })(function(){ if(callback != null) callback(that); }); }
...
params['treeOrder'] = 2;
}
this.rdf = RDFJSInterface.rdf;
this.functionMap = {};
var that = this;
new Lexicon.Lexicon(function(lexicon){
new QuadBackend.QuadBackend(params, function(backend){
params.backend = backend;
params.lexicon =lexicon;
that.engine = new QueryEngine.QueryEngine(params);
if(callback) {
callback(that);
}
...
Lexicon = function (callback){ this.uriToOID = {}; this.OIDToUri = {}; this.literalToOID = {}; this.OIDToLiteral = {}; this.OIDToBlank = {}; this.defaultGraphOid = 0; this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph"; this.oidCounter = 1; this.knownGraphs = {}; if(callback != null) { callback(this); } }
...
params['treeOrder'] = 2;
}
this.rdf = RDFJSInterface.rdf;
this.functionMap = {};
var that = this;
new Lexicon.Lexicon(function(lexicon){
new QuadBackend.QuadBackend(params, function(backend){
params.backend = backend;
params.lexicon =lexicon;
that.engine = new QueryEngine.QueryEngine(params);
if(callback) {
callback(that);
}
...
all = function (arr, iterator, main_callback) { async.forEach(arr, function (x, callback) { iterator(x, function (v) { if (!v) { main_callback(false); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(true); }); }
...
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
...
any = function (arr, iterator, main_callback) { async.forEach(arr, function (x, callback) { iterator(x, function (v) { if (v) { main_callback(true); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(false); }); }
n/a
apply = function (fn) { var args = Array.prototype.slice.call(arguments, 1); return function () { return fn.apply( null, args.concat(Array.prototype.slice.call(arguments)) ); }; }
...
break;
// slower
default:
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
handler.apply(this, args);
}
} else if (isObject(handler)) {
len = arguments.length;
args = new Array(len - 1);
for (i = 1; i < len; i++)
args[i - 1] = arguments[i];
...
auto = function (tasks, callback) { callback = callback || function () {}; var keys = _keys(tasks); if (!keys.length) { return callback(null); } var completed = []; var listeners = []; var addListener = function (fn) { listeners.unshift(fn); }; var removeListener = function (fn) { for (var i = 0; i < listeners.length; i += 1) { if (listeners[i] === fn) { listeners.splice(i, 1); return; } } }; var taskComplete = function () { _forEach(listeners, function (fn) { fn(); }); }; addListener(function () { if (completed.length === keys.length) { callback(null); } }); _forEach(keys, function (k) { var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k]; var taskCallback = function (err) { if (err) { callback(err); // stop subsequent errors hitting callback multiple times callback = function () {}; } else { completed.push(k); taskComplete(); } }; var requires = task.slice(0, Math.abs(task.length - 1)) || []; var ready = function () { return _reduce(requires, function (a, x) { return (a && _indexOf(completed, x) !== -1); }, true); }; if (ready()) { task[task.length - 1](taskCallback); } else { var listener = function () { if (ready()) { removeListener(listener); task[task.length - 1](taskCallback); } }; addListener(listener); } }); }
n/a
concat = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
...
default:
throw new Error('Unknown encoding')
}
return ret
}
Buffer.concat = function (list, totalLength) {
assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' +
'list should be an Array.')
if (list.length === 0) {
return new Buffer(0)
} else if (list.length === 1) {
return list[0]
}
...
concatSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
...
* @param {Function} callback
* @api public
*/
exports.runSuite = function (name, suite, opt, callback) {
var keys = _keys(suite);
async.concatSeries(keys, function (k, cb) {
var prop = suite[k], _name;
_name = name ? [].concat(name, k) : [k];
_name.toString = function () {
// fallback for old one
return this.join(' - ');
...
detect = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
n/a
detectSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
n/a
dir = function (fn) { var args = Array.prototype.slice.call(arguments, 1); fn.apply(null, args.concat([function (err) { var args = Array.prototype.slice.call(arguments, 1); if (typeof console !== 'undefined') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _forEach(args, function (x) { console[name](x); }); } } }])); }
n/a
every = function (arr, iterator, main_callback) { async.forEach(arr, function (x, callback) { iterator(x, function (v) { if (!v) { main_callback(false); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(true); }); }
n/a
filter = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
...
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf
:Person")));
store.execute('PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\
PREFIX foaf: <http://xmlns.com/foaf/0.1/>\
PREFIX : <http://example.org/>\
SELECT ?s FROM NAMED :people { GRAPH ?g { ?s rdf:type foaf:Person } }',
function(err, results) {
...
filterSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
n/a
foldl = function (arr, memo, iterator, callback) { async.forEachSeries(arr, function (x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }
n/a
foldr = function (arr, memo, iterator, callback) { var reversed = _map(arr, function (x) { return x; }).reverse(); async.reduce(reversed, memo, iterator, callback); }
n/a
forEach = function (arr, iterator, callback) { if (!arr.length) { return callback(); } var completed = 0; _forEach(arr, function (x) { iterator(x, function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed === arr.length) { callback(); } } }); }); }
...
store.execute(query, function(err, graph){
if(graph.some(store.rdf.filters.p(store.rdf.resolve('foaf:name')))) {
nameTriples = graph.match(null,
store.rdf.createNamedNode(rdf.resolve('foaf:name')),
null);
nameTriples.forEach(function(triple) {
console.log(triple.object.valueOf());
});
}
});
```
###Loading remote graphs
...
forEachSeries = function (arr, iterator, callback) { if (!arr.length) { return callback(); } var completed = 0; var iterate = function () { iterator(arr[completed], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed === arr.length) { callback(); } else { iterate(); } } }); }; iterate(); }
...
async.map = doParallel(_asyncMap);
async.mapSeries = doSeries(_asyncMap);
// reduce only has a series version, as doing reduce in parallel won't
// work in many situations.
async.reduce = function (arr, memo, iterator, callback) {
async.forEachSeries(arr, function (x, callback) {
iterator(memo, x, function (err, v) {
memo = v;
callback(err);
});
}, function (err) {
callback(err, memo);
});
...
inject = function (arr, memo, iterator, callback) { async.forEachSeries(arr, function (x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }
n/a
iterator = function (tasks) { var makeCallback = function (index) { var fn = function () { if (tasks.length) { tasks[index].apply(null, arguments); } return fn.next(); }; fn.next = function () { return (index < tasks.length - 1) ? makeCallback(index + 1): null; }; return fn; }; return makeCallback(0); }
...
}
async.nextTick(function () {
iterator.apply(null, args);
});
}
};
};
wrapIterator(async.iterator(tasks))();
};
async.parallel = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.map(tasks, function (fn, callback) {
if (fn) {
...
log = function (fn) { var args = Array.prototype.slice.call(arguments, 1); fn.apply(null, args.concat([function (err) { var args = Array.prototype.slice.call(arguments, 1); if (typeof console !== 'undefined') { if (err) { if (console.error) { console.error(err); } } else if (console[name]) { _forEach(args, function (x) { console[name](x); }); } } }])); }
...
store.execute('PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\
PREFIX foaf: <http://xmlns.com/foaf/0.1/>\
PREFIX : <http://example.org/>\
SELECT ?s FROM NAMED :people { GRAPH ?g { ?s rdf:type foaf:Person } }',
function(err, results) {
console.log(peopleGraph.toArray()[0].subject.valueOf() === results[0].s.value
);
});
});
});
});
```
...
map = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
...
obj = undefined;
}
if (typeof obj === 'object') {
return map(objectKeys(obj), function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
...
mapSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
...
});
}
};
async.series = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.mapSeries(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args || null);
...
memoize = function (fn, hasher) { var memo = {}; hasher = hasher || function (x) { return x; }; return function () { var args = Array.prototype.slice.call(arguments); var callback = args.pop(); var key = hasher.apply(null, args); if (key in memo) { callback.apply(null, memo[key]); } else { fn.apply(null, args.concat([function () { memo[key] = arguments; callback.apply(null, arguments); }])); } }; }
...
findMemoNodes(childNodes[i], appendToArray);
}
}
return {
memoize: function (callback) {
if (typeof callback != "function")
throw new Error("You can only pass a function to ko.memoization.memoize()
x22;);
var memoId = generateRandomId();
memos[memoId] = callback;
return "<!--[ko_memo:" + memoId + "]-->";
},
unmemoize: function (memoId, callbackParams) {
var callback = memos[memoId];
...
function nextTick(callback) { if (typeof callback !== 'function') throw new TypeError('callback is not a function'); // on the way out, don't bother. it won't get fired anyway. if (process._exiting) return; var args; if (arguments.length > 1) { args = new Array(arguments.length - 1); for (var i = 1; i < arguments.length; i++) args[i - 1] = arguments[i]; } nextTickQueue.push({ callback, domain: process.domain || null, args }); tickInfo[kLength]++; }
...
* [skipExpansion] true to assume the input is expanded and skip
* expansion, false not to, defaults to false.
* [documentLoader(url, callback(err, remoteDoc))] the document loader.
* @param callback(err, compacted, ctx) called once the operation completes.
*/
jsonld.compact = function(input, ctx, options, callback) {
if(arguments.length < 2) {
return jsonld.nextTick(function() {
callback(new TypeError('Could not compact, too few arguments.'));
});
}
// get arguments
if(typeof options === 'function') {
callback = options;
...
noConflict = function () { root.async = previous_async; return async; }
n/a
parallel = function (tasks, callback) { callback = callback || function () {}; if (tasks.constructor === Array) { async.map(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args || null); }); } }, callback); } else { var results = {}; async.forEach(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }
n/a
queue = function (worker, concurrency) { var workers = 0; var tasks = []; var q = { concurrency: concurrency, push: function (data, callback) { tasks.push({data: data, callback: callback}); async.nextTick(q.process); }, process: function () { if (workers < q.concurrency && tasks.length) { var task = tasks.splice(0, 1)[0]; workers += 1; worker(task.data, function () { workers -= 1; if (task.callback) { task.callback.apply(task, arguments); } q.process(); }); } }, length: function () { return tasks.length; } }; return q; }
n/a
reduce = function (arr, memo, iterator, callback) { async.forEachSeries(arr, function (x, callback) { iterator(memo, x, function (err, v) { memo = v; callback(err); }); }, function (err) { callback(err, memo); }); }
...
return name + ': ' + str;
}
function reduceToSingleString(output, base, braces) {
var numLinesEst = 0;
var length = output.reduce(function(prev, cur) {
numLinesEst++;
if (cur.indexOf('\n') >= 0) numLinesEst++;
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
}, 0);
if (length > 60) {
return braces[0] +
...
reduceRight = function (arr, memo, iterator, callback) { var reversed = _map(arr, function (x) { return x; }).reverse(); async.reduce(reversed, memo, iterator, callback); }
n/a
reject = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
...
callbacks.push(callback);
this.emptyNotificationsMap[event] = callbacks;
};
Callbacks.CallbacksBackend.prototype.unsubscribeEmpty = function(event, callback) {
var callbacks = this.emptyNotificationsMap[event];
if(callbacks != null) {
callbacks = _.reject(callbacks, function(cb){ return cb === callback });
}
this.emptyNotificationsMap[event] = callbacks;
};
Callbacks.CallbacksBackend.prototype.subscribe = function(s,p,o,g,callback, doneCallback) {
var quad = this._tokenizeComponents(s,p,o,g);
var queryEnv = {blanks:{}, outCache:{}};
...
rejectSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
n/a
select = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEach].concat(args)); }
...
* Filters the variable bindings held by this {@link jQuery.rdf} object down to those listed in the bindings parameter. This mirrors
the <a href="http://www.w3.org/TR/rdf-sparql-query/#select">SELECT</a> form in SPARQL.
* @param {String[]} [bindings] The variables that you're interested in. The returned objects will only contain those variables
. If bindings is undefined, you will get all the variable bindings in the returned objects.
* @returns {Object[]} An array of objects with the properties named by the bindings parameter.
* @example
* var filtered = rdf
* .where('?photo dc:creator ?creator')
* .where('?creator foaf:img ?photo');
* var selected = rdf.select(['creator']);
*/
select: function (bindings) {
var s = [], i, j;
for (i = 0; i < this.length; i += 1) {
if (bindings === undefined) {
s[i] = this[i];
} else {
...
selectSeries = function () { var args = Array.prototype.slice.call(arguments); return fn.apply(null, [async.forEachSeries].concat(args)); }
n/a
series = function (tasks, callback) { callback = callback || function () {}; if (tasks.constructor === Array) { async.mapSeries(tasks, function (fn, callback) { if (fn) { fn(function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } callback.call(null, err, args || null); }); } }, callback); } else { var results = {}; async.forEachSeries(_keys(tasks), function (k, callback) { tasks[k](function (err) { var args = Array.prototype.slice.call(arguments, 1); if (args.length <= 1) { args = args[0]; } results[k] = args; callback(err); }); }, function (err) { callback(err, results); }); } }
n/a
some = function (arr, iterator, main_callback) { async.forEach(arr, function (x, callback) { iterator(x, function (v) { if (v) { main_callback(true); main_callback = function () {}; } callback(); }); }, function (err) { main_callback(false); }); }
...
###Construct queries RDF Interfaces API
```javascript
var query = "CONSTRUCT { <http://example.org/people/Alice> ?p ?o } \
WHERE { <http://example.org/people/Alice> ?p ?o }";
store.execute(query, function(err, graph){
if(graph.some(store.rdf.filters.p(store.rdf.resolve('foaf:name')))) {
nameTriples = graph.match(null,
store.rdf.createNamedNode(rdf.resolve('foaf:name')),
null);
nameTriples.forEach(function(triple) {
console.log(triple.object.valueOf());
});
...
sortBy = function (arr, iterator, callback) { async.map(arr, function (x, callback) { iterator(x, function (err, criteria) { if (err) { callback(err); } else { callback(null, {value: x, criteria: criteria}); } }); }, function (err, results) { if (err) { return callback(err); } else { var fn = function (left, right) { var a = left.criteria, b = right.criteria; return a < b ? -1 : a > b ? 1 : 0; }; callback(null, _map(results.sort(fn), function (x) { return x.value; })); } }); }
...
f(null);
}
});
};
Tree.prototype.walk = function(f,e) {
var that = this;
var keys = _.chain(this.data).keys().sortBy(this.keyFun).value();
_.forEach(keys,function(key){
var node = {'key':key,'data':that.data[key]};
f(node);
that.data[key] = node['data']
});
...
until = function (test, iterator, callback) { if (!test()) { iterator(function (err) { if (err) { return callback(err); } async.until(test, iterator, callback); }); } else { callback(); } }
...
async.until = function (test, iterator, callback) {
if (!test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
async.until(test, iterator, callback);
});
}
else {
callback();
}
};
...
waterfall = function (tasks, callback) { if (!tasks.length) { return callback(); } callback = callback || function () {}; var wrapIterator = function (iterator) { return function (err) { if (err) { callback(err); callback = function () {}; } else { var args = Array.prototype.slice.call(arguments, 1); var next = iterator.next(); if (next) { args.push(wrapIterator(next)); } else { args.push(callback); } async.nextTick(function () { iterator.apply(null, args); }); } }; }; wrapIterator(async.iterator(tasks))(); }
...
}
// 1) Create the normalization state.
// Note: Optimize by generating non-normalized blank node map concurrently.
var nonNormalized = {};
self.waterfall([
function(callback) {
// 2) For every quad in input dataset:
self.forEach(dataset, function(triples, graphName, callback) {
if(graphName === '@default') {
graphName = null;
}
self.forEach(triples, function(quad, idx, callback) {
...
whilst = function (test, iterator, callback) { if (test()) { iterator(function (err) { if (err) { return callback(err); } async.whilst(test, iterator, callback); }); } else { callback(); } }
...
// blank node to quads map.
// Note: We use a map here and it was generated during step 2.
// 4) Initialize simple, a boolean flag, to true.
var simple = true;
// 5) While simple is true, issue canonical identifiers for blank nodes:
self.whilst(function() { return simple; }, function(callback) {
// 5.1) Set simple to false.
simple = false;
// 5.2) Clear hash to blank nodes map.
self.hashToBlankNodes = {};
self.waterfall([
...
function peg$SyntaxError(message, expected, found, location) { this.message = message; this.expected = expected; this.found = found; this.location = location; this.name = "SyntaxError"; if (typeof Error.captureStackTrace === "function") { Error.captureStackTrace(this, peg$SyntaxError); } }
...
* - |rightmostMatchFailuresExpected| contains at least one failure
*
* All code following this comment (including called functions) must
* handle these states.
*/
if (result === null || pos !== input.length) {
var errorPosition = computeErrorPosition();
throw new this.SyntaxError(
buildErrorMessage(),
errorPosition.line,
errorPosition.column
);
}
return result;
...
function peg$parse(input, options) { options = options !== void 0 ? options : {}; var peg$FAILED = {}, peg$startRuleFunctions = { DOCUMENT: peg$parseDOCUMENT }, peg$startRuleFunction = peg$parseDOCUMENT, peg$c0 = peg$otherExpectation("[1] QueryUnit"), peg$c1 = peg$otherExpectation("[2] Query"), peg$c2 = function(p, q, v) { return { token: 'query', kind: 'query', prologue: p, units: [q], inlineData: v } }, peg$c3 = peg$otherExpectation("[3] Prologue"), peg$c4 = function(b, pfx) { return { token: 'prologue', base: b, prefixes: pfx } }, peg$c5 = peg$otherExpectation("[4] BaseDecl"), peg$c6 = "BASE", peg$c7 = peg$literalExpectation("BASE", false), peg$c8 = "base", peg$c9 = peg$literalExpectation("base", false), peg$c10 = function(i) { registerDefaultPrefix(i); var base = {}; base.token = 'base'; base.value = i; return base; }, peg$c11 = peg$otherExpectation("[5] PrefixDecl"), peg$c12 = "PREFIX", peg$c13 = peg$literalExpectation("PREFIX", false), peg$c14 = "prefix", peg$c15 = peg$literalExpectation("prefix", false), peg$c16 = function(p, l) { registerPrefix(p,l); var prefix = {}; prefix.token = 'prefix'; prefix.prefix = p; prefix.local = l; return prefix; }, peg$c17 = peg$otherExpectation("[6] SelectQuery"), peg$c18 = function(s, gs, w, sm) { var dataset = {'named':[], 'implicit':[]}; for(var i=0; i<gs.length; i++) { var g = gs[i]; if(g.kind === 'default') { dataset['implicit'].push(g.graph); } else { dataset['named'].push(g.graph) } } if(dataset['named'].length === 0 && dataset['implicit'].length === 0) { dataset['implicit'].push({token:'uri', prefix:null, suffix:null, value:'https://github.com/antoniogarrote/rdfstore-js#default_graph'}); } var query = {}; query.kind = 'select'; query.token = 'executableunit'; query.dataset = dataset; query.projection = s.vars; query.modifier = s.modifier; query.pattern = w; if(sm!=null && sm.limit!=null) { query.limit = sm.limit; } if(sm!=null && sm.offset!=null) { query.offset = sm.offset; } if(sm!=null && (sm.order!=null && sm.order!="")) { query.order = sm.order; } if(sm!=null && sm.group!=null) { query.group = sm.group; } return query; }, peg$c19 = peg$otherExpectation("[7] SubSelect"), peg$c20 = function(s, w, sm) { var query = {}; query.kind = 'select'; query.token = 'subselect'; query.projection = s.vars; query.modifier = s.modifier; query.pattern = w; if(sm!=null && sm.limit!=null) { query.limit = sm.limit; } if(sm!=null && sm.offset!=null) { query.offset = sm.offset; } if(sm!=null && (sm.order!=null && sm.order!="")) { query.order = sm.order; } if(sm!=null && sm.group!=null) { query.group = sm.group; } return query; }, peg$c21 = peg$otherExpectation("[8] SelectClause"), peg$c22 = "SELECT", peg$c23 = peg$literalExpectation("SELECT", false), peg$c24 = "select", peg$c25 = peg$literalExpectation("select", false), peg$c26 = "DISTINCT", peg$c27 = peg$literalExpectation("DISTINCT", false), peg$c28 = "distinct", peg$c29 = peg$literalExpectation("distinct", false), peg$c30 = "REDUCED", peg$c31 = peg$literalExpectation("REDUCED", false), peg$c32 = "reduced", peg$c33 = peg$literalExpectation("reduced", false), peg$c34 = "(", peg$ ...
...
var http = module.exports;
var EventEmitter = _dereq_('events').EventEmitter;
var Request = _dereq_('./lib/request');
var url = _dereq_('url')
http.request = function (params, cb) {
if (typeof params === 'string') {
params = url.parse(params)
}
if (!params) params = {};
if (!params.host && !params.port) {
params.port = parseInt(window.location.port, 10);
}
if (!params.host && params.hostname) {
params.host = params.hostname;
...
PersistentLexicon = function (callback, dbName){ var that = this; utils.registerIndexedDB(that); this.defaultGraphOid = 0; this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph"; this.defaultGraphUriTerm = {"token":"uri","prefix":null,"suffix":null,"value":this.defaultGraphUri}; this.oidCounter = 1; that.dbName = dbName || "rdfstorejs"; var request = that.indexedDB.open(this.dbName+"_lexicon", 1); request.onerror = function(event) { callback(null,new Error("Error opening IndexedDB: " + event.target.errorCode)); }; request.onsuccess = function(event) { that.db = event.target.result; callback(that); }; request.onupgradeneeded = function(event) { that.db = event.target.result; // graphs var graphStore = that.db.createObjectStore('knownGraphs', { keyPath: 'oid'}); graphStore.createIndex("uriToken","uriToken",{unique: true}); // uris,literal,blanks mapping var uriStore = that.db.createObjectStore('components', { keyPath: 'id', autoIncrement : true }); uriStore.createIndex("value","value",{unique: true}); //setTimeout(function(){ callback(that); },0); }; }
n/a
PersistentQuadBackend = function (configuration, callback) { var that = this; if (arguments !== 0) { utils.registerIndexedDB(that); this.indexMap = {}; this.indices = ['S','P','O','G','SP','SO','SG','PO','PG','OG','SPO','SPG','SOG','POG','SPOG'] this.componentOrders = { S: ['subject','predicate','object','graph'], P: ['predicate','subject','object','graph'], O: ['object','subject','predicate','graph'], G: ['graph','subject','predicate','object'], SP: ['subject','predicate','object','graph'], SO: ['subject', 'object','predicate','graph'], SG: ['subject', 'graph','predicate','object'], PO: ['predicate','object','subject','graph'], PG: ['predicate', 'graph','subject','object'], OG: ['object','graph','subject','predicate'], SPO: ['subject','predicate','object','graph'], SPG: ['subject', 'predicate', 'graph','object'], SOG: ['subject', 'object', 'graph','predicate'], POG: ['predicate', 'object', 'graph','subject'], SPOG: ['subject', 'predicate', 'object', 'graph'] }; this.componentOrdersMap = {}; for(var index in this.componentOrders) { var indexComponents = this.componentOrders[index]; var key = indexComponents.slice(0,index.length).sort().join("."); this.componentOrdersMap[key] = index; } that.dbName = configuration['name'] || "rdfstorejs"; var request = that.indexedDB.open(this.dbName+"_db", 1); request.onerror = function(event) { callback(null,new Error("Error opening IndexedDB: " + event.target.errorCode)); }; request.onsuccess = function(event) { that.db = event.target.result; callback(that); }; request.onupgradeneeded = function(event) { var db = event.target.result; var objectStore = db.createObjectStore(that.dbName, { keyPath: 'SPOG'}); utils.each(that.indices, function(index){ if(index !== 'SPOG') { objectStore.createIndex(index,index,{unique: false}); } }); }; } }
n/a
QuadBackend = function (configuration, callback) { this.indexMap = {}; this.treeOrder = configuration['treeOrder']; this.indices = (configuration["index"] || QuadBackend.allIndices); this.componentOrders = QuadBackend.componentOrders; var that = this; utils.eachSeries(this.indices,function(indexKey, k){ new QuadIndex({ order:that.treeOrder, componentOrder:that.componentOrders[indexKey] },function (tree) { that.indexMap[indexKey] = tree; k(); }); },function(){ callback(that); }); }
...
}
this.rdf = RDFJSInterface.rdf;
this.functionMap = {};
var that = this;
new Lexicon.Lexicon(function(lexicon){
new QuadBackend.QuadBackend(params, function(backend){
params.backend = backend;
params.lexicon =lexicon;
that.engine = new QueryEngine.QueryEngine(params);
if(callback) {
callback(that);
}
})
...
NodeKey = function (components, order) { this.subject = components.subject; this.predicate = components.predicate; this.object = components.object; this.graph = components.graph; this.order = order; }
...
async.eachSeries(quads, function(quad,k){
var newQuad = {};
async.eachSeries(['subject','predicate','object','graph'], function(component,kk
){
registerComponent(quad, component, newQuad, kk)
}, function(){
var originalQuad = quad;
quad = newQuad;
var key = new QuadIndex.NodeKey(quad);
that.backend.search(key, function(result){
if(!result) {
that.backend.index(key, function(result){
if(result){
if(that.eventsOnBatchLoad)
that.callbacksBackend.nextGraphModification(Callbacks.added, [originalQuad,quad]);
...
Pattern = function (components) { this.subject = components.subject; this.predicate = components.predicate; this.object = components.object; this.graph = components.graph; this.indexKey = []; this.keyComponents = {}; var order = []; var indiferent = []; var that = this; // components must have been already normalized and // inserted in the lexicon. // OIDs retrieved from the lexicon *are* numbers so // they can be told apart from variables (strings) _.forEach(['subject', 'predicate', 'object', 'graph'], function(component){ if (typeof(that[component]) === 'string') { indiferent.push(component); that.keyComponents[component] = null; } else { order.push(component); that.keyComponents[component] = that[component]; that.indexKey.push(component); } }); this.order = order.concat(indiferent); this.key = new NodeKey(this.keyComponents, this.order); }
...
};
QueryEngine.prototype.rangeQuery = function(quad, queryEnv, callback) {
var that = this;
that.normalizeQuad(quad, queryEnv, false, function(key){
if(key != null) {
that.backend.range(new QuadIndex.Pattern(key), function(quads) {
if(quads == null || quads.length == 0) {
callback([]);
} else {
callback(quads);
}
});
} else {
...
QuadIndex = function (params, callback) { if (arguments != 0) { this.componentOrder = params.componentOrder; BaseTree.call(this, params.order, function (tree) { // For exact matches. Used by search. tree.comparator = function (a, b) { for (var i = 0; i < tree.componentOrder.length; i++) { var component = tree.componentOrder[i]; var vala = a[component]; var valb = b[component]; if (vala < valb) { return -1; } else if (vala > valb) { return 1; } } return 0; }; // For range matches. tree.rangeComparator = function (a, b) { for (var i = 0; i < tree.componentOrder.length; i++) { var component = tree.componentOrder[i]; if (b[component] == null || a[component] == null) { return 0; } else { if (a[component] < b[component]) { return -1 } else if (a[component] > b[component]) { return 1 } } } return 0; }; callback(tree); }); } }
n/a
QueryEngine = function (params) { if(arguments.length != 0) { this.backend = params.backend; this.lexicon = params.lexicon; // batch loads should generate events? this.eventsOnBatchLoad = (params.eventsOnBatchLoad || false); // list of namespaces that will be automatically added to every query this.defaultPrefixes = {}; this.abstractQueryTree = new AbstractQueryTree(); this.rdfLoader = new RDFLoader(params['communication']); this.callbacksBackend = new Callbacks(this); this.customFns = params.customFns || {}; } }
...
this.functionMap = {};
var that = this;
new Lexicon.Lexicon(function(lexicon){
new QuadBackend.QuadBackend(params, function(backend){
params.backend = backend;
params.lexicon =lexicon;
that.engine = new QueryEngine.QueryEngine(params);
if(callback) {
callback(that);
}
})
});
};
...
RDFLoader = function (params) { this.precedences = ["text/turtle", "text/n3", "application/ld+json", "application/json"]; this.parsers = {"text/turtle":RVN3Parser.parser, "text/n3":RVN3Parser.parser, "application/ld+json":JSONLDParser.parser, "application /json":JSONLDParser.parser}; // Conditionally adding RDFXML parser if(typeof(RDFXMLParser) !== 'undefined') { this.precedences.push("application/rdf+xml"); this.parsers["application/rdf+xml"] = RDFXMLParser.parser; } if (params != null) { for (var mime in params["parsers"]) { this.parsers[mime] = params["parsers"][mime]; } } if (params && params["precedences"] != null) { this.precedences = params["precedences"]; for (var mime in params["parsers"]) { if (!Utils.include(this.precedences, mime)) { this.precedences.push(mime); } } } this.acceptHeaderValue = ""; for (var i = 0; i < this.precedences.length; i++) { if (i != 0) { this.acceptHeaderValue = this.acceptHeaderValue + "," + this.precedences[i]; } else { this.acceptHeaderValue = this.acceptHeaderValue + this.precedences[i]; } } }
...
};
module.exports = {
RDFLoader: RDFLoader
};
// var loader = require("./js-communication/src/rdf_loader").RDFLoader; loader = new loader.RDFLoader(); loader.load('http://dbpedialite.org/titles/Lisp_%28programming_language%29', function(success, results
){console.log("hey"); console.log(success); console.log(results)})
},{"./jsonld_parser":43,"./network_transport":45,"./rvn3_parser":56,"./utils":57,"fs
":5}],55:[function(_dereq_,module,exports){
// imports
var _ = _dereq_("./utils");
var QueryFilters = _dereq_("./query_filters").QueryFilters;
RDFModel = {};
...
BlankNode = function (bnodeId) { RDFModel.RDFNode.call(this, "BlankNode"); this.nominalValue = "_:"+bnodeId; this.bnodeId = bnodeId; }
...
for (var p in RDFModel.defaultContext) {
this.prefixes.set(p, RDFModel.defaultContext[p]);
}
};
RDFModel.RDFEnvironment.prototype = _.create(RDFModel.Profile.prototype,{'constructor': RDFModel.RDFEnvironment});
RDFModel.RDFEnvironment.prototype.createBlankNode = function() {
var bnode = new RDFModel.BlankNode(this.blankNodeCounter);
this.blankNodeCounter++;
return bnode;
};
RDFModel.RDFEnvironment.prototype.createNamedNode = function(value) {
var resolvedValue = this.resolve(value);
if(resolvedValue != null) {
...
Graph = function () { this.triples = []; this.duplicates = {}; this.actions = []; this.length = 0; }
...
aqt.projection = [{"token": "variable", "kind": "*"}];
that = this;
this.executeSelect(aqt, queryEnv, defaultDataset, namedDataset, function(err, result){
if(err == null) {
that.denormalizeBindingsList(result, queryEnv, function(result){
if(result != null) {
var graph = new RDFModel.Graph();
// CONSTRUCT WHERE {} case
if(aqt.template == null) {
aqt.template = {triplesContext: aqt.pattern};
}
var blankIdCounter = 1;
var toClear = [];
...
Literal = function (value, language, datatype) { RDFModel.RDFNode.call(this, "Literal"); this.nominalValue = value; if(language != null) { this.language = language; } else if(datatype != null) { this.datatype = datatype; } }
...
} else {
return new RDFModel.NamedNode(value);
}
};
RDFModel.RDFEnvironment.prototype.createLiteral = function(value, language, datatype) {
if(datatype != null) {
return new RDFModel.Literal(value, language, datatype.toString());
} else {
return new RDFModel.Literal(value, language, datatype);
}
};
RDFModel.RDFEnvironment.prototype.createTriple = function(subject, predicate, object) {
return new RDFModel.Triple(subject, predicate, object);
...
NamedNode = function (val) { RDFModel.RDFNode.call(this, "NamedNode"); if(val.value != null) { this.nominalValue = val.value; } else { this.nominalValue = val; } }
...
*
* @arguments:
* @param {Function} callback function that will receive a success notification and the array of graph URIs
*/
Store.prototype.registeredGraphs = function(callback) {
this.engine.lexicon.registeredGraphs(true, function(graphs){
var graphNodes = _.map(graphs, function(graph){
return new RDFModel.NamedNode(graph);
});
callback(null, graphNodes);
});
};
/**
...
Profile = function () { this.prefixes = new RDFModel.UrisMap(); this.terms = new RDFModel.UrisMap(); }
...
}
}
};
RDFModel.RDFEnvironment.prototype.createProfile = function(empty) {
// empty (opt);
if(empty === true) {
return new RDFModel.RDFEnvironment.Profile();
} else {
var profile = new RDFModel.RDFEnvironment.Profile();
profile.importProfile(this);
return profile;
}
};
...
RDFEnvironment = function () { RDFModel.Profile.call(this); this.blankNodeCounter = 0; var that = this; this.filters = { s:function (s) { return function (t) { return t.subject.equals(s); }; }, p:function (p) { return function (t) { return t.predicate.equals(p); }; }, o:function (o) { return function (t) { return t.object.equals(o); }; }, sp:function (s, p) { return function (t) { return t.subject.equals(s) && t.predicate.equals(p); }; }, so:function (s, o) { return function (t) { return t.subject.equals(s) && t.object.equals(o); }; }, po:function (p, o) { return function (t) { return t.predicate.equals(p) && t.object.equals(o); }; }, spo:function (s, p, o) { return function (t) { return t.subject.equals(s) && t.predicate.equals(p) && t.object.equals(o); }; }, describes:function (v) { return function (t) { return t.subject.equals(v) || t.object.equals(v); }; }, type:function (o) { var type = that.resolve("rdf:type"); return function (t) { return t.predicate.equals(type) && t.object.equals(o); }; } }; for (var p in RDFModel.defaultContext) { this.prefixes.set(p, RDFModel.defaultContext[p]); } }
...
return new RDFModel.NamedNode(value);
} else {
return new RDFModel.NamedNode(value);
}
}
};
RDFModel.rdf = new RDFModel.RDFEnvironment();
module.exports = RDFModel;
},{"./query_filters":52,"./utils":57}],56:[function(_dereq_,module,exports){
var N3Parser = _dereq_('n3').Parser;
//var N3Parser = require('../node_modules/n3/lib/N3Parser');
...
RDFNode = function (interfaceName){ this.interfaceName = interfaceName; this.attributes = ["interfaceName", "nominalValue"] }
n/a
Triple = function (subject, predicate, object){ this.subject = subject; this.predicate = predicate; this.object = object; }
...
var bindings = [];
_.each(triples, function(triple){
var s = RDFModel.buildRDFResource(triple.subject,bindings,that.engine,queryEnv);
var p = RDFModel.buildRDFResource(triple.predicate,bindings,that.engine,queryEnv);
var o = RDFModel.buildRDFResource(triple.object,bindings,that.engine,queryEnv);
if(s!=null && p!=null && o!=null) {
triple = new RDFModel.Triple(s,p,o);
acum.push(triple);
}
});
callback(event,acum);
};
...
UrisMap = function () { this.defaultNs = ""; this.interfaceProperties = ['get', 'remove', 'set', 'setDefault', 'addAll', 'resolve', 'shrink']; }
...
return iri;
};
// Profile
RDFModel.Profile = function() {
this.prefixes = new RDFModel.UrisMap();
this.terms = new RDFModel.UrisMap();
};
RDFModel.Profile.prototype.importProfile = function(profile, override) {
this.prefixes.addAll(profile.prefixes, override);
this.terms.addAll(profile.terms, override);
};
...
buildBlankNode = function (value, bindings, engine, env) { if(value.valuetmp != null) { value.value = value.valuetmp; } if(value.value.indexOf("_:") === 0) { value.value = value.value.split("_:")[1]; } return new RDFModel.BlankNode(value.value); }
...
return n3;
};
// Builders for the query engine
RDFModel.buildRDFResource = function(value, bindings, engine, env) {
if(value.token === 'blank') {
return RDFModel.buildBlankNode(value, bindings, engine, env);
} else if(value.token === 'literal') {
return RDFModel.buildLiteral(value, bindings, engine, env);
} else if(value.token === 'uri') {
return RDFModel.buildNamedNode(value, bindings, engine, env);
} else if(value.token === 'var') {
var result = bindings[value.value];
if(result != null) {
...
buildLiteral = function (value, bindings, engine, env) { return new RDFModel.Literal(value.value, value.lang, value.type); }
...
// Builders for the query engine
RDFModel.buildRDFResource = function(value, bindings, engine, env) {
if(value.token === 'blank') {
return RDFModel.buildBlankNode(value, bindings, engine, env);
} else if(value.token === 'literal') {
return RDFModel.buildLiteral(value, bindings, engine, env);
} else if(value.token === 'uri') {
return RDFModel.buildNamedNode(value, bindings, engine, env);
} else if(value.token === 'var') {
var result = bindings[value.value];
if(result != null) {
return RDFModel.buildRDFResource(result, bindings, engine, env);
} else {
...
buildNamedNode = function (value, bindings, engine, env) { if(value.value != null) { return new RDFModel.NamedNode(value); } else { if(value.prefix != null) { var prefix = engine.resolveNsInEnvironment(value.prefix, env); value.value = prefix+value.suffix; return new RDFModel.NamedNode(value); } else { return new RDFModel.NamedNode(value); } } }
...
RDFModel.buildRDFResource = function(value, bindings, engine, env) {
if(value.token === 'blank') {
return RDFModel.buildBlankNode(value, bindings, engine, env);
} else if(value.token === 'literal') {
return RDFModel.buildLiteral(value, bindings, engine, env);
} else if(value.token === 'uri') {
return RDFModel.buildNamedNode(value, bindings, engine, env);
} else if(value.token === 'var') {
var result = bindings[value.value];
if(result != null) {
return RDFModel.buildRDFResource(result, bindings, engine, env);
} else {
return null;
}
...
buildRDFResource = function (value, bindings, engine, env) { if(value.token === 'blank') { return RDFModel.buildBlankNode(value, bindings, engine, env); } else if(value.token === 'literal') { return RDFModel.buildLiteral(value, bindings, engine, env); } else if(value.token === 'uri') { return RDFModel.buildNamedNode(value, bindings, engine, env); } else if(value.token === 'var') { var result = bindings[value.value]; if(result != null) { return RDFModel.buildRDFResource(result, bindings, engine, env); } else { return null; } } else { return null; } }
...
var that = this;
var adapterCb = function(event,triples){
var acum = [];
var queryEnv = {blanks:{}, outCache:{}};
var bindings = [];
_.each(triples, function(triple){
var s = RDFModel.buildRDFResource(triple.subject,bindings,that.engine,queryEnv);
var p = RDFModel.buildRDFResource(triple.predicate,bindings,that.engine,queryEnv);
var o = RDFModel.buildRDFResource(triple.object,bindings,that.engine,queryEnv);
if(s!=null && p!=null && o!=null) {
triple = new RDFModel.Triple(s,p,o);
acum.push(triple);
}
});
...
Store = function (arg1, arg2) { var callback = null; var params = null; if(arguments.length == 0) { params ={}; } else if(arguments.length == 1) { params = {}; callback = arg1; } else if(arguments.length > 1) { params = arg1; callback = arg2; } else { throw("An optional argument map and a callback must be provided"); } if(params['treeOrder'] == null) { params['treeOrder'] = 15; } var Lexicon = InMemoryLexicon; var QuadBackend = InMemoryQuadBackend; if(params['persistent'] === true){ Lexicon = PersistentLexicon; QuadBackend = PersistentBackend; } this.functionMap = {}; var that = this; this.customFns = {}; new Lexicon(function(lexicon){ var createQuadBackend = function() { new QuadBackend(params, function (backend) { var createEngine = function() { params.backend = backend; params.lexicon = lexicon; that.engine = new QueryEngine(params); callback(null, that); }; if(params['overwrite']) { backend.clear(createEngine) } else { createEngine(); } }); }; if(params['overwrite'] === true) { // delete lexicon values lexicon.clear(createQuadBackend); } else { createQuadBackend(); } },params['name']); }
...
// alt 1
rdfstore.create(function(err, store) {
// the new store is ready
});
// alt 2
new rdfstore.Store(function(err, store) {
// the new store is ready
});
```
###Query execution
```javascript
...
connect = function () { var callback; if(arguments.length == 1) { callback = arguments[0]; } else if(arguments.length == 2) { callback = arguments[1]; } else { callback = arguments[2]; } callback(new Error("Store#connect is not supported in the 0.9.X series of the library")); }
n/a
create = function (){ if(arguments.length == 1) { return new Store(arguments[0]); } else if(arguments.length == 2) { return new Store(arguments[0], arguments[1]); } else { return new Store(); }; }
...
## Introduction
rdfstore-js is a pure Javascript implementation of a RDF graph store with support for the SPARQL query and data manipulation language
.
```javascript
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
...
clone = function (value) { return JSON.parse(JSON.stringify(value)); }
...
_isArray(localCtx['@context'])) {
localCtx = localCtx['@context'];
}
var ctxs = _isArray(localCtx) ? localCtx : [localCtx];
// no contexts in array, clone existing context
if(ctxs.length === 0) {
return activeCtx.clone();
}
// process each context in order, update active context
// on each iteration to ensure proper caching
var rval = activeCtx;
for(var i = 0; i < ctxs.length; ++i) {
var ctx = ctxs[i];
...
compareDateComponents = function (stra, strb) { var dateA = parseISO8601(stra); var dateB = parseISO8601(strb); if(dateA == dateB) { return 0; } else if(dateA < dateB) { return -1; } else { return 1; } }
...
if(QueryFilters.isXsdType("dateTime", op1) && QueryFilters.isXsdType("date", op2)) {
return QueryFilters.ebvFalse();
}
if(QueryFilters.isXsdType("date", op1) && QueryFilters.isXsdType("dateTime", op2)) {
return QueryFilters.ebvFalse();
}
var comp = Utils.compareDateComponents(op1.value, op2.value);
if(comp != null) {
if(comp == 0) {
return QueryFilters.ebvTrue();
} else {
return QueryFilters.ebvFalse();
}
} else {
...
create = function (prototype) { if (isObject(prototype)) { Object.prototype = prototype; var result = new Object; Object.prototype = null; } return result || Object(); }
...
## Introduction
rdfstore-js is a pure Javascript implementation of a RDF graph store with support for the SPARQL query and data manipulation language
.
```javascript
var rdfstore = require('rdfstore');
rdfstore.create(function(err, store) {
store.execute('LOAD <http://dbpedia.org/resource/Tim_Berners-Lee> INTO GRAPH <http://example.org/people>
;', function() {
store.setPrefix('dbp', 'http://dbpedia.org/resource/');
store.node(store.rdf.resolve('dbp:Tim_Berners-Lee'), "http://example.org/people", function(err, graph) {
var peopleGraph = graph.filter(store.rdf.filters.type(store.rdf.resolve("foaf:Person")));
...
each = function (xs, f) { if(xs.forEach) { xs.forEach(f); } else { for (var i = 0; i < xs.length; i++) f(xs[i]); } }
...
Store.prototype.subscribe = function(s, p, o, g, callback) {
var that = this;
var adapterCb = function(event,triples){
var acum = [];
var queryEnv = {blanks:{}, outCache:{}};
var bindings = [];
_.each(triples, function(triple){
var s = RDFModel.buildRDFResource(triple.subject,bindings,that.engine,queryEnv);
var p = RDFModel.buildRDFResource(triple.predicate,bindings,that.engine,queryEnv);
var o = RDFModel.buildRDFResource(triple.object,bindings,that.engine,queryEnv);
if(s!=null && p!=null && o!=null) {
triple = new RDFModel.Triple(s,p,o);
acum.push(triple);
}
...
eachParallel = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var failed = false; var completed = 0; var innerCallback = function(err) { if(err) { failed = true; throw(new Error(err)); } if(!failed) { completed++; if(completed === arr.length) callback(); } }; for(var i=0; i<arr.length; i++) { (function(arr,i,callback,iterator) { nextTick(function(){ try { iterator(arr[i], function () { callback(); }) } catch (e) { callback(e); } }); })(arr,i,innerCallback,iterator) } }
...
expect(values[0]).toBe(1);
expect(values[1]).toBe('c');
done();
})
it("Should compute parallel computations", function(done) {
var totals = {};
Utils.eachParallel([1,2,3,4], function(i,k){
totals[i] = i;
k();
}, function() {
expect(totals[1]).toBe(1);
expect(totals[2]).toBe(2);
expect(totals[3]).toBe(3);
expect(totals[4]).toBe(4);
...
eachSeries = function (arr, iterator, callback) { callback = callback || function () {}; if (!arr.length) { return callback(); } var completed = 0; var iterate = function () { iterator(arr[completed], function (err) { if (err) { callback(err); callback = function () {}; } else { completed += 1; if (completed >= arr.length) { callback(); } else { nextTick(iterate); } } }); }; iterate(); }
...
var counter = this.queryCounter;
this.queryCounter++;
this.queriesMap[counter] = query;
this.queriesInverseMap[query] = counter;
this.queriesList.push(counter);
this.queriesCallbacksMap[counter] = callback;
async.eachSeries(patterns, function(quad, k) {
if(quad.graph == null) {
quad.graph = that.engine.lexicon.defaultGraphUriTerm;
}
that.engine.normalizeQuad(quad, queryEnv, true, function(normalized) {
var pattern = new Pattern(normalized);
var indexKey = that._indexForPattern(pattern);
...
forEach = function (xs, f) { if(xs.forEach) { xs.forEach(f); } else { for (var i = 0; i < xs.length; i++) f(xs[i]); } }
...
store.execute(query, function(err, graph){
if(graph.some(store.rdf.filters.p(store.rdf.resolve('foaf:name')))) {
nameTriples = graph.match(null,
store.rdf.createNamedNode(rdf.resolve('foaf:name')),
null);
nameTriples.forEach(function(triple) {
console.log(triple.object.valueOf());
});
}
});
```
###Loading remote graphs
...
guid = function () { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); }
n/a
hasTerm = function (term) { try { if(term == null) { return ""; } if(term.token==='uri') { return "u"+term.value; } else if(term.token === 'blank') { return "b"+term.value; } else if(term.token === 'literal') { var l = "l"+term.value; l = l + (term.type || ""); l = l + (term.lang || ""); return l; } } catch(e) { if(typeof(term) === 'object') { var key = ""; for(p in term) { key = key + p + term[p]; } return key; } return term; } }
n/a
hashTerm = function (term) { try { if(term == null) { return ""; } if(term.token==='uri') { return "u"+term.value; } else if(term.token === 'blank') { return "b"+term.value; } else if(term.token === 'literal') { var l = "l"+term.value; l = l + (term.type || ""); l = l + (term.lang || ""); return l; } } catch(e) { if(typeof(term) === 'object') { var key = ""; for(p in term) { key = key + p + term[p]; } return key; } return term; } }
...
} else if(aggregator.expression.aggregateType === 'count') {
var distinct = {};
var count = 0;
if(aggregator.expression.expression === '*') {
if(aggregator.expression.distinct != null && aggregator.expression.distinct != '') {
for(var i=0; i< bindingsGroup.length; i++) {
var bindings = bindingsGroup[i];
var key = Utils.hashTerm(bindings);
if(distinct[key] == null) {
distinct[key] = true;
count++;
}
}
} else {
count = bindingsGroup.length;
...
include = function (xs, p) { for(var i=0; i<xs.length; i++){ if(xs[i] === p) return true; } return false; }
...
var indexKey = pattern.indexKey;
var matchingIndices = this.indices;
for(var i=0; i<matchingIndices.length; i++) {
var index = matchingIndices[i];
var indexComponents = this.componentOrders[index];
for(var j=0; j<indexComponents.length; j++) {
if(_.include(indexKey, indexComponents[j])===false) {
break;
}
if(j==indexKey.length-1) {
return index;
}
}
}
...
isWorker = function () { if(typeof(process) === "undefined" || process.browser === true) { if (typeof(window) === "undefined") { return true; } else { return false; } } else { return false; } }
...
module.exports = {
Lexicon: Lexicon
};
},{"./btree":40,"./utils":57}],45:[function(_dereq_,module,exports){
var utils = _dereq_("./utils");
if(!utils.isWorker()) {
var http = _dereq_("http");
var https = _dereq_("https");
var url = _dereq_("url");
NetworkTransport = {
load: function (uri, accept, callback, redirect) {
...
iso8601 = function (date) { return date.toISOString(); }
...
from.value = 'false';
}
return from;
} else if(from.type == xmlSchema+"dateTime" ||
from.type == xmlSchema+"date") {
from.type = fun;
if(typeof(from.value) != 'string') {
from.value = Utils.iso8601(from.value);
}
return from;
} else if(from.type == null) {
from.value = ""+from.value;
from.type = fun;
return from;
} else {
...
keys = function (xs) { var acc = []; for(var p in xs) acc.push(p); return acc; }
...
if(!_isArray(ctx)) {
ctx = [ctx];
}
// remove empty contexts
var tmp = ctx;
ctx = [];
for(var i = 0; i < tmp.length; ++i) {
if(!_isObject(tmp[i]) || Object.keys(tmp[i]).length > 0) {
ctx.push(tmp[i]);
}
}
// remove array if only one context
var hasContext = (ctx.length > 0);
if(ctx.length === 1) {
...
lexicalFormBaseUri = function (term, env) { var uri = null; env = env || {}; if(term.value == null) { // URI has prefix and suffix, we'll try to resolve it. var prefix = term.prefix; var suffix = term.suffix; var resolvedPrefix = env.namespaces[prefix]; if(resolvedPrefix != null) { uri = resolvedPrefix+suffix; } else { uri = prefix+":"+suffix; } } else { // URI is not prefixed uri = term.value; } if(uri===null) { return null; } else { // Should we apply the base URI namespace? if(uri.indexOf(":") == -1) { uri = (env.base||"") + uri; // applyBaseUri } } return uri; }
...
QueryEngine.prototype.resolveNsInEnvironment = function(prefix, env) {
var namespaces = env.namespaces;
return namespaces[prefix];
};
QueryEngine.prototype.normalizeTerm = function(term, env, shouldIndex, callback) {
if(term.token === 'uri') {
var uri = Utils.lexicalFormBaseUri(term, env);
if(uri == null) {
callback(null);
} else {
if(shouldIndex) {
this.lexicon.registerUri(uri,callback);
} else {
this.lexicon.resolveUri(uri,callback);
...
lexicalFormLiteral = function (term, env) { var value = term.value; var lang = term.lang; var type = term.type; var indexedValue = null; if(value != null && type != null && typeof(type) != 'string') { var typeValue = type.value; if(typeValue == null) { var typePrefix = type.prefix; var typeSuffix = type.suffix; var resolvedPrefix = env.namespaces[typePrefix]; term.type = resolvedPrefix+typeSuffix; typeValue = resolvedPrefix+typeSuffix; } // normalization if(typeValue.indexOf('hexBinary') != -1) { indexedValue = '"' + term.value.toLowerCase() + '"^^<' + typeValue + '>'; } else { indexedValue = '"' + term.value + '"^^<' + typeValue + '>'; } } else { if(lang == null && type == null) { indexedValue = '"' + value + '"'; } else if(type == null) { indexedValue = '"' + value + '"' + "@" + lang; } else { // normalization if(type.indexOf('hexBinary') != -1) { indexedValue = '"' + term.value.toLowerCase() + '"^^<'+type+'>'; } else { indexedValue = '"' + term.value + '"^^<'+type+'>'; } } } return indexedValue; }
...
this.lexicon.registerUri(uri,callback);
} else {
this.lexicon.resolveUri(uri,callback);
}
}
} else if(term.token === 'literal') {
var lexicalFormLiteral = Utils.lexicalFormLiteral(term, env);
if(shouldIndex) {
this.lexicon.registerLiteral(lexicalFormLiteral,callback);
} else {
this.lexicon.resolveLiteral(lexicalFormLiteral,callback);
}
} else if(term.token === 'blank') {
var label = term.value;
...
map = function (xs, f) { if(xs.map) { return xs.map(f); } else { var acc = []; for (var i = 0; i < xs.length; i++) acc[i] = f(xs[i]); return acc; } }
...
obj = undefined;
}
if (typeof obj === 'object') {
return map(objectKeys(obj), function(k) {
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
if (isArray(obj[k])) {
return obj[k].map(function(v) {
return ks + encodeURIComponent(stringifyPrimitive(v));
}).join(sep);
} else {
return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
}
}).join(sep);
...
nextTick = function (f) { spin++; if(spin < yieldFrequency) { f(); } else { spin = 0; slowNextTick(f); } }
...
* [skipExpansion] true to assume the input is expanded and skip
* expansion, false not to, defaults to false.
* [documentLoader(url, callback(err, remoteDoc))] the document loader.
* @param callback(err, compacted, ctx) called once the operation completes.
*/
jsonld.compact = function(input, ctx, options, callback) {
if(arguments.length < 2) {
return jsonld.nextTick(function() {
callback(new TypeError('Could not compact, too few arguments.'));
});
}
// get arguments
if(typeof options === 'function') {
callback = options;
...
normalizeUnicodeLiterals = function (string) { var escapedUnicode = string.match(/\\u[0-9abcdefABCDEF]{4,4}/g) || []; var dups = {}; for (var i = 0; i < escapedUnicode.length; i++) { if (dups[escapedUnicode[i]] == null) { dups[escapedUnicode[i]] = true; string = string.replace(new RegExp("\\" + escapedUnicode[i], "g"), eval("'" + escapedUnicode[i] + "'")); } } return string; }
...
});
};
// Queries execution
QueryEngine.prototype.execute = function(queryString, callback, defaultDataset, namedDataset){
//try{
queryString = Utils.normalizeUnicodeLiterals(queryString);
var syntaxTree = this.abstractQueryTree.parseQueryString(queryString);
if(syntaxTree == null) {
callback(false,"Error parsing query string");
} else {
if(syntaxTree.token === 'query' && syntaxTree.kind == 'update') {
this.callbacksBackend.startGraphModification();
var that = this;
...
parseISO8601 = function (str) { return Date.parse(str); }
...
// return false;
//} else {
return tmp;
//}
} else if (val.type == xmlSchema+"date" ||
val.type == xmlSchema+"dateTime" ) {
try {
var d = Utils.parseISO8601(val.value);
return(d);
} catch(e) {
return null;
}
} else if (val.type == xmlSchema+"boolean" ) {
return val.value === true || val.value === 'true' || val.value === '1' || val.value === 1 || val.value ===
true ? true :
val.value === false || val.value === 'false' || val.value === '0' || val.value === 0 || val.value ===
false ? false :
...
registerIndexedDB = function (that) { if(typeof(window) === 'undefined' && typeof(process) !== "undefined" && process.browser === false) { var sqlite3 = _dereq_('sqlite3') var indexeddbjs = _dereq_("indexeddb-js"); var engine = new sqlite3.Database(':memory:'); var scope = indexeddbjs.makeScope('sqlite3', engine); that.indexedDB = scope.indexedDB; that.IDBKeyRange = scope.IDBKeyRange; } else { // In the following line, you should include the prefixes of implementations you want to test. var context if(typeof(window) === "undefined") { context = self; } else { context = window; } context.indexedDB = context.indexedDB || context.mozIndexedDB || context.webkitIndexedDB || context.msIndexedDB; context.IDBKeyRange = context.IDBKeyRange || context.webkitIDBKeyRange || context.msIDBKeyRange; // DON'T use "var indexedDB = ..." if you're not in a function. // Moreover, you may need references to some window.IDB* objects: if (!context.indexedDB) { console.log("The browser does not support IndexDB."); } else { that.indexedDB = context.indexedDB; that.IDBKeyRange = context.IDBKeyRange; } } }
...
* Temporal implementation of the lexicon
*/
PersistentLexicon = function(callback, dbName){
var that = this;
utils.registerIndexedDB(that);
this.defaultGraphOid = 0;
this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph";
this.defaultGraphUriTerm = {"token":"uri","prefix":null,"suffix":null,"value":
this.defaultGraphUri};
this.oidCounter = 1;
that.dbName = dbName || "rdfstorejs";
...
reject = function (xs, p) { var acc = []; for(var i=0; i<xs.length; i++) { if(p(xs[i])) { acc.push(xs[i]); } } return acc; }
...
callbacks.push(callback);
this.emptyNotificationsMap[event] = callbacks;
};
Callbacks.CallbacksBackend.prototype.unsubscribeEmpty = function(event, callback) {
var callbacks = this.emptyNotificationsMap[event];
if(callbacks != null) {
callbacks = _.reject(callbacks, function(cb){ return cb === callback });
}
this.emptyNotificationsMap[event] = callbacks;
};
Callbacks.CallbacksBackend.prototype.subscribe = function(s,p,o,g,callback, doneCallback) {
var quad = this._tokenizeComponents(s,p,o,g);
var queryEnv = {blanks:{}, outCache:{}};
...
remove = function (xs, p) { var acc = []; for(var i=0; i<xs.length; i++) { if(p(xs[i])) { acc.push(xs[i]); } } return acc; }
...
var p = RDFModel.buildRDFResource(triple.predicate,bindings,that.engine,queryEnv);
var o = RDFModel.buildRDFResource(triple.object,bindings,that.engine,queryEnv);
if(s!=null && p!=null && o!=null) {
triple = new RDFModel.Triple(s,p,o);
if(event === Callbacks['added']) {
node.add(triple);
} else if(event === Callbacks['deleted']) {
node.remove(triple);
}
}
}
}
};
that.observersMap[callback] = observer;
that.subscribeEmpty(Callbacks['eventsFlushed'], observer);
...
seq = function () { var fns = arguments; return function () { var that = this; var args = Array.prototype.slice.call(arguments); var callback = args.pop(); reduce(fns, args, function (newargs, fn, cb) { fn.apply(that, newargs.concat([function () { var err = arguments[0]; var nextargs = Array.prototype.slice.call(arguments, 1); cb(err, nextargs); }])); }, function (err, results) { callback.apply(that, [err].concat(results)); }); }; }
...
Lexicon = function(callback){
var that = this;
this.defaultGraphOid = 0;
this.defaultGraphUri = "https://github.com/antoniogarrote/rdfstore-js#default_graph";
this.defaultGraphUriTerm = {"token":"uri","prefix":null,"suffix":null,"value":
this.defaultGraphUri};
this.oidCounter = 1;
async.seq(function(k){
new Tree(2,function(tree){
that.uris = tree;
k();
})
}, function(k){
new Tree(2, function(tree){
that.literals = tree;
...
size = function (xs) { if(xs.length) { return xs.length; } else { var acc = 0; for(var p in xs) acc++; return acc; } }
...
} else {
// this group does not need merge for the next iteration
newGroups[nextGroupId] = groups[nextGroupId];
newGroupVars[nextGroupId] = groupVars[nextGroupId];
}
}
if(_.size(toJoin) === 0) {
// we haven't found a single existing group sharing vars
// with the BGP. We need to create a new group only for this BGP.
newGroups['g'+groupId] = [bgp];
newGroupVars['g'+groupId] = "/"+(vars.join("/"))+"/";
groupId++;
} else {
// We merge all the groups sharing vars with the BGP.
...
values = function (xs) { var acc = []; for(var p in xs) acc.push(xs[p]); return acc; }
...
};
/**
* Registers the default namespaces declared in the RDF JS Interfaces
* specification in the default Profile.
*/
Store.prototype.registerDefaultProfileNamespaces = function() {
var defaultNsMap = this.rdf.prefixes.values();
for (var p in defaultNsMap) {
this.registerDefaultNamespace(p,defaultNsMap[p]);
}
};
/**
* Load triples into a graph in the store. Data can be passed directly to the method
...
whilst = function (test, iterator, callback) { if (test()) { iterator(function (err) { if (err) { return callback(err); } whilst(test, iterator, callback); }); } else { callback(); } }
...
// blank node to quads map.
// Note: We use a map here and it was generated during step 2.
// 4) Initialize simple, a boolean flag, to true.
var simple = true;
// 5) While simple is true, issue canonical identifiers for blank nodes:
self.whilst(function() { return simple; }, function(callback) {
// 5.1) Set simple to false.
simple = false;
// 5.2) Clear hash to blank nodes map.
self.hashToBlankNodes = {};
self.waterfall([
...
yieldFrequency = function (value){ yieldFrequency = value; }
...
###Controlling the frequency of function yielding
Performance of the store can be improved by reducing the frequency the 'nexTick' mechanism is used to cancel the the calls
stack.
You can reduce this frequency by invoking the `yieldFrequency` function on the Store object and passing a bigger number:
``` javascript
var rdfstore = require('rdfstore')
rdfstore.Store.yieldFrequency(200); // will only yield after 200 invocations of nextTick
```
If the number is too big a number can produce stack overflow errors during execution. If you find this problem, reduce the value
provided for `yieldFrequency`.
##Dependencies
The library include dependencies to two semantic-web libraries for
...