Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sparqlalgebrajs

Package Overview
Dependencies
Maintainers
1
Versions
70
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sparqlalgebrajs - npm Package Compare versions

Comparing version 0.6.6 to 0.7.0

3

index.d.ts
import translate from './lib/sparqlAlgebra';
import * as Algebra from './lib/algebra';
import Factory from './lib/Factory';
export { translate, Algebra, Factory };
import { toSparql, toSparqlJs } from './lib/sparql';
export { translate, Algebra, Factory, toSparql, toSparqlJs };

@@ -9,2 +9,5 @@ "use strict";

exports.Factory = Factory_1.default;
const sparql_1 = require("./lib/sparql");
exports.toSparql = sparql_1.toSparql;
exports.toSparqlJs = sparql_1.toSparqlJs;
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const Algebra = require("./algebra");

@@ -16,2 +15,3 @@ const SparqlGenerator = require('sparqljs').Generator;

resetContext();
op = removeQuads(op);
return translateOperation(op);

@@ -21,3 +21,3 @@ }

function flatten(s) {
return Array.prototype.concat(...s);
return Array.prototype.concat(...s).filter(x => x);
}

@@ -29,8 +29,10 @@ function resetContext() {

// this allows us to differentiate between BIND and SELECT when translating EXTEND
if (op.type !== types.EXTEND)
if (op.type !== types.EXTEND && op.type !== types.ORDER_BY)
context.project = false;
switch (op.type) {
case types.EXPRESSION: return translateExpression(op);
case types.ASK: return translateProject(op, types.ASK);
case types.BGP: return translateBgp(op);
case types.CONSTRUCT: return translateConstruct(op);
case types.DESCRIBE: return translateProject(op, types.DESCRIBE);
case types.DISTINCT: return translateDistinct(op);

@@ -45,4 +47,5 @@ case types.EXTEND: return translateExtend(op);

case types.ORDER_BY: return translateOrderBy(op);
case types.PATH: return translatePath(op);
case types.PATTERN: return translatePattern(op);
case types.PROJECT: return translateProject(op);
case types.PROJECT: return translateProject(op, types.PROJECT);
case types.REDUCED: return translateReduced(op);

@@ -65,2 +68,15 @@ case types.SLICE: return translateSlice(op);

}
function translatePathComponent(path) {
switch (path.type) {
case types.ALT: return translateAlt(path);
case types.INV: return translateInv(path);
case types.LINK: return translateLink(path);
case types.NPS: return translateNps(path);
case types.ONE_OR_MORE_PATH: return translateOneOrMorePath(path);
case types.SEQ: return translateSeq(path);
case types.ZERO_OR_MORE_PATH: return translateZeroOrMorePath(path);
case types.ZERO_OR_ONE_PATH: return translateZeroOrOnePath(path);
}
return null;
}
function translateTerm(term) {

@@ -75,3 +91,3 @@ if (term.termType === 'BlankNode')

result += '@' + lit.language;
if (lit.datatype)
else if (lit.datatype && lit.datatype.value !== 'http://www.w3.org/2001/XMLSchema#string')
result += '^^' + lit.datatype.value;

@@ -88,3 +104,3 @@ return result;

function translateAggregateExpression(expr) {
return {
let result = {
expression: translateExpression(expr.expression),

@@ -95,2 +111,5 @@ type: 'aggregate',

};
if (expr.separator)
result.separator = expr.separator;
return result;
}

@@ -114,3 +133,3 @@ function translateExistenceExpression(expr) {

function translateOperatorExpression(expr) {
return {
let result = {
type: 'operation',

@@ -120,2 +139,5 @@ operator: expr.operator,

};
if (result.operator === 'in' || result.operator === 'notin')
result.args = [result.args[0]].concat([result.args.slice(1)]);
return result;
}

@@ -131,5 +153,8 @@ function translateTermExpression(expr) {

function translateBgp(op) {
let patterns = op.patterns.map(translatePattern);
if (patterns.length === 0)
return null;
return {
type: 'bgp',
triples: op.patterns.map(translatePattern)
triples: patterns
};

@@ -217,2 +242,5 @@ }

function translateMinus(op) {
let patterns = translateOperation(op.right);
if (patterns.type === 'group')
patterns = patterns.patterns;
return flatten([

@@ -222,3 +250,3 @@ translateOperation(op.left),

type: 'minus',
patterns: translateOperation(op.right)
patterns: patterns
}

@@ -232,2 +260,13 @@ ]);

}
function translatePath(op) {
// TODO: quads back to graph statement
return {
type: 'bgp',
triples: [{
subject: translateTerm(op.subject),
predicate: translatePathComponent(op.predicate),
object: translateTerm(op.object)
}]
};
}
function translatePattern(op) {

@@ -255,9 +294,18 @@ // TODO: quads back to graph statement

}
function translateProject(op) {
function translateProject(op, type) {
let result = {
type: 'query',
prefixes: {},
queryType: 'SELECT',
variables: op.variables.map(translateTerm)
prefixes: {}
};
if (type === types.PROJECT) {
result.queryType = 'SELECT';
result.variables = op.variables.map(translateTerm);
}
else if (type === types.ASK) {
result.queryType = 'ASK';
}
else if (type === types.DESCRIBE) {
result.queryType = 'DESCRIBE';
result.variables = op.terms.map(translateTerm);
}
// backup values in case of nested queries

@@ -271,3 +319,6 @@ // everything in extend, group, etc. is irrelevant for this project call

context.project = true;
result.where = flatten([translateOperation(op.input)]);
let input = flatten([translateOperation(op.input)]);
if (input.length === 1 && input[0].type === 'group')
input = input[0].patterns;
result.where = input;
let aggregators = {};

@@ -298,19 +349,20 @@ // these can not reference each other

if (context.order.length > 0)
result.order = context.order.map(translateOperation).map(o => {
if (typeof o === 'string')
return { expression: o };
return o;
result.order = context.order.map(translateOperation).map(o => ({ expression: o }));
// this needs to happen after the group because it might depend on variables generated there
if (result.variables) {
result.variables = result.variables.map((v) => {
if (extensions[v])
return {
variable: v,
expression: extensions[v]
};
return v;
});
// this needs to happen after the group because it might depend on variables generated there
result.variables = result.variables.map((v) => {
if (extensions[v])
return {
variable: v,
expression: extensions[v]
};
return v;
});
// if the * didn't match any variables this would be empty
if (result.variables.length === 0)
result.variables = ['*'];
}
// convert filter to 'having' if it contains an aggregator variable
// could always convert, but is nicer to use filter when possible
if (result.where[result.where.length - 1].type === 'filter') {
if (result.where.length > 0 && result.where[result.where.length - 1].type === 'filter') {
let filter = result.where[result.where.length - 1];

@@ -331,3 +383,3 @@ if (objectContainsValues(filter, Object.keys(aggregators))) {

return o.some(e => objectContainsValues(e, vals));
if (_.isObject(o))
if (o === Object(o))
return Object.keys(o).some(key => objectContainsValues(o[key], vals));

@@ -359,3 +411,2 @@ return vals.indexOf(o) >= 0;

function translateValues(op) {
// TODO: check if undef implementation is actually correct
// TODO: check if handled correctly when outside of select block

@@ -370,6 +421,135 @@ return {

result[s] = translateTerm(binding[s]);
else
result[s] = undefined;
}
return result;
})
};
}
// PATH COMPONENTS
function translateAlt(path) {
if (path.left.type === types.NPS || path.right.type === types.NPS) {
let left = translatePathComponent(path.left);
let right = translatePathComponent(path.right);
return {
type: 'path',
pathType: '!',
items: [{
type: 'path',
pathType: '|',
items: [].concat(left.items[0].items, right.items[0].items)
}]
};
}
return {
type: 'path',
pathType: '|',
items: [translatePathComponent(path.left), translatePathComponent(path.right)]
};
}
function translateInv(path) {
if (path.path.type === types.NPS) {
return {
type: 'path',
pathType: '!',
items: [{
type: 'path',
pathType: '|',
items: [path.iris.map((iri) => {
return {
type: 'path',
pathType: '^',
items: [iri]
};
})]
}]
};
}
return {
type: 'path',
pathType: '^',
items: [translatePathComponent(path.path)]
};
}
function translateLink(path) {
return translateTerm(path.iri);
}
function translateNps(path) {
return {
type: 'path',
pathType: '!',
items: [{
type: 'path',
pathType: '|',
items: path.iris.map(translateTerm)
}]
};
}
function translateOneOrMorePath(path) {
return {
type: 'path',
pathType: '+',
items: [translatePathComponent(path.path)]
};
}
function translateSeq(path) {
return {
type: 'path',
pathType: '/',
items: [translatePathComponent(path.left), translatePathComponent(path.right)]
};
}
function translateZeroOrMorePath(path) {
return {
type: 'path',
pathType: '*',
items: [translatePathComponent(path.path)]
};
}
function translateZeroOrOnePath(path) {
return {
type: 'path',
pathType: '?',
items: [translatePathComponent(path.path)]
};
}
function removeQuads(op) {
return removeQuadsRecursive(op, {});
}
// remove quads
function removeQuadsRecursive(op, graphs) {
if (Array.isArray(op))
return op.map(sub => removeQuadsRecursive(sub, graphs));
if (!op.type)
return op;
if ((op.type === types.PATTERN || op.type === types.PATH) && op.graph && op.graph.value.length > 0) {
graphs[op.graph.value] = op.graph;
return op;
}
let result = {};
let keyGraphs = {};
let graphNames = {};
for (let key of Object.keys(op)) {
result[key] = removeQuadsRecursive(op[key], graphs);
let graphsArray = Object.keys(graphs);
if (graphsArray.length > 0) {
let graphName = graphsArray[0];
keyGraphs[key] = graphs[graphName];
graphNames[keyGraphs[key].value] = keyGraphs[key];
delete graphs[graphName];
}
}
let graphNameSet = Object.keys(graphNames);
if (graphNameSet.length > 0) {
// also need to create graph statement if we are at the edge of the query
if (graphNameSet.length === 1 && op.type !== types.PROJECT)
graphs[graphNameSet[0]] = graphNames[graphNameSet[0]];
else {
// multiple graphs, need to create graph objects for them
for (let key of Object.keys(keyGraphs))
result[key] = { type: 'graph', input: result[key], name: keyGraphs[key] };
}
}
return result;
}
//# sourceMappingURL=sparql.js.map

@@ -148,3 +148,3 @@ "use strict";

if (exp.operator === 'in' || exp.operator === 'notin')
exp.args = [exp.args[0]].concat(exp.args[1]); // sparql.js uses 2 arguments with the second one bing a list
exp.args = [exp.args[0]].concat(exp.args[1]); // sparql.js uses 2 arguments with the second one being a list
return factory.createOperatorExpression(exp.operator, exp.args.map(translateExpression));

@@ -151,0 +151,0 @@ }

{
"name": "sparqlalgebrajs",
"version": "0.6.6",
"version": "0.7.0",
"description": "Convert SPARQL to SPARL algebra",

@@ -16,16 +16,14 @@ "author": "Joachim Van Herwegen",

"rdf-data-model": "^1.0.0",
"rdf-string": "^1.1.0",
"sparqljs": "^1.5.2"
"sparqljs": "^2.0.2"
},
"devDependencies": {
"@types/lodash": "^4.14.77",
"@types/chai": "^4.1.2",
"@types/lodash.isequal": "^4.5.2",
"@types/minimist": "^1.2.0",
"@types/n3": "0.0.3",
"@types/mocha": "^2.2.48",
"@types/node": "^8.0.50",
"@types/rdf-data-model": "^1.0.1",
"@types/rdf-js": "^1.0.1",
"lodash": "^4.13.1",
"chai": "^4.1.2",
"mocha": "^3.5.3",
"n3": "^0.11.2",
"pre-commit": "^1.2.2",

@@ -32,0 +30,0 @@ "typescript": "^2.5.3"

@@ -25,2 +25,4 @@ # SPARQL to SPARQL Algebra converter

Translating back to SPARQL can be done with the `toSparql` (or `toSparqlJs`) function.
## Algebra object

@@ -125,2 +127,6 @@ The algebra object contains a `types` object,

no prefixes are used (all uris get expanded)
and the project operation always gets used (even in the case of `SELECT *`).
and the project operation always gets used (even in the case of `SELECT *`).
## A note on tests
Every test consists of a sparql file and a corresponding json file containg the algebra result.
Tests ending with `(quads)` in their name are tested/generated with `quads: true` in the options.
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc