Socket
Socket
Sign inDemoInstall

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 2.2.2 to 2.3.0

68

lib/algebra.d.ts

@@ -37,2 +37,14 @@ import * as rdfjs from "rdf-js";

ZERO_OR_ONE_PATH: string;
COMPOSITE_UPDATE: string;
INSERT_DATA: string;
DELETE_DATA: string;
DELETE_INSERT: string;
DELETE_WHERE: string;
LOAD: string;
CLEAR: string;
CREATE: string;
DROP: string;
ADD: string;
MOVE: string;
COPY: string;
}>;

@@ -226,1 +238,57 @@ export declare const expressionTypes: Readonly<{

}
export interface CompositeUpdate extends Operation {
type: 'compositeupdate';
updates: Update[];
}
export interface Update extends Operation {
}
export interface InsertData extends Update {
type: 'insertdata';
quads: Pattern[];
}
export interface DeleteData extends Update {
type: 'deletedata';
quads: Pattern[];
}
export interface DeleteInsert extends Update, Single {
type: 'deleteinsert';
delete?: Pattern[];
insert?: Pattern[];
}
export interface DeleteWhere extends Update {
type: 'deletewhere';
patterns: Pattern[];
}
export interface UpdateGraph extends Update {
silent?: boolean;
}
export interface Load extends UpdateGraph {
type: 'load';
source: rdfjs.NamedNode;
destination?: rdfjs.NamedNode;
}
export interface Clear extends UpdateGraph {
type: 'clear';
source: 'DEFAULT' | 'NAMED' | 'ALL' | rdfjs.NamedNode;
}
export interface Create extends UpdateGraph {
type: 'create';
source: rdfjs.NamedNode;
}
export interface Drop extends UpdateGraph {
type: 'drop';
source: 'DEFAULT' | 'NAMED' | 'ALL' | rdfjs.NamedNode;
}
export interface UpdateGraphShortcut extends UpdateGraph {
source: 'DEFAULT' | rdfjs.NamedNode;
destination: 'DEFAULT' | rdfjs.NamedNode;
}
export interface Add extends UpdateGraphShortcut {
type: 'add';
}
export interface Move extends UpdateGraphShortcut {
type: 'move';
}
export interface Copy extends UpdateGraphShortcut {
type: 'copy';
}

@@ -38,2 +38,14 @@ "use strict";

ZERO_OR_ONE_PATH: 'ZeroOrOnePath',
COMPOSITE_UPDATE: 'compositeupdate',
INSERT_DATA: 'insertdata',
DELETE_DATA: 'deletedata',
DELETE_INSERT: 'deleteinsert',
DELETE_WHERE: 'deletewhere',
LOAD: 'load',
CLEAR: 'clear',
CREATE: 'create',
DROP: 'drop',
ADD: 'add',
MOVE: 'move',
COPY: 'copy',
});

@@ -40,0 +52,0 @@ exports.expressionTypes = Object.freeze({

@@ -47,2 +47,15 @@ import * as A from './algebra';

createTerm(str: string): RDF.Term;
createCompositeUpdate(updates: A.Update[]): A.CompositeUpdate;
createInsertData(quads: A.Pattern[]): A.InsertData;
createDeleteData(quads: A.Pattern[]): A.DeleteData;
createDeleteInsert(input: A.Operation, deleteQuads?: A.Pattern[], insertQuads?: A.Pattern[]): A.DeleteInsert;
createDeleteWhere(patterns: A.Pattern[]): A.DeleteWhere;
createLoad(source: RDF.NamedNode, destination?: RDF.NamedNode, silent?: boolean): A.Load;
createClear(source: 'DEFAULT' | 'NAMED' | 'ALL' | RDF.NamedNode, silent?: boolean): A.Clear;
createCreate(source: RDF.NamedNode, silent?: boolean): A.Create;
createDrop(source: 'DEFAULT' | 'NAMED' | 'ALL' | RDF.NamedNode, silent?: boolean): A.Drop;
createAdd(source: 'DEFAULT' | RDF.NamedNode, destination: 'DEFAULT' | RDF.NamedNode, silent?: boolean): A.Add;
createMove(source: 'DEFAULT' | RDF.NamedNode, destination: 'DEFAULT' | RDF.NamedNode, silent?: boolean): A.Move;
createCopy(source: 'DEFAULT' | RDF.NamedNode, destination: 'DEFAULT' | RDF.NamedNode, silent?: boolean): A.Copy;
private addSilent;
}

43

lib/factory.js

@@ -74,8 +74,49 @@ "use strict";

createWildcardExpression() { return { type: 'expression', expressionType: 'wildcard', wildcard: new Wildcard() }; }
;
createTerm(str) {
return rdf_string_1.stringToTerm(str, this.dataFactory);
}
// Update functions
createCompositeUpdate(updates) { return { type: 'compositeupdate', updates }; }
createInsertData(quads) { return { type: 'insertdata', quads }; }
createDeleteData(quads) { return { type: 'deletedata', quads }; }
createDeleteInsert(input, deleteQuads, insertQuads) {
const result = { type: 'deleteinsert', input };
if (deleteQuads)
result.delete = deleteQuads;
if (insertQuads)
result.insert = insertQuads;
return result;
}
createDeleteWhere(patterns) { return { type: 'deletewhere', patterns }; }
createLoad(source, destination, silent) {
const result = { type: 'load', source };
if (destination)
result.destination = destination;
return this.addSilent(result, silent);
}
createClear(source, silent) {
return this.addSilent({ type: 'clear', source }, silent);
}
createCreate(source, silent) {
return this.addSilent({ type: 'create', source }, silent);
}
createDrop(source, silent) {
return this.addSilent({ type: 'drop', source }, silent);
}
createAdd(source, destination, silent) {
return this.addSilent({ type: 'add', source, destination }, silent);
}
createMove(source, destination, silent) {
return this.addSilent({ type: 'move', source, destination }, silent);
}
createCopy(source, destination, silent) {
return this.addSilent({ type: 'copy', source, destination }, silent);
}
addSilent(input, silent) {
if (silent)
input.silent = silent;
return input;
}
}
exports.default = Factory;
//# sourceMappingURL=factory.js.map

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

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

@@ -64,2 +61,15 @@ context = { project: false, extend: [], group: [], aggregates: [], order: [] };

case types.VALUES: return translateValues(op);
// UPDATE operations
case types.COMPOSITE_UPDATE: return translateCompositeUpdate(op);
case types.INSERT_DATA: return translateInsertData(op);
case types.DELETE_DATA: return translateDeleteData(op);
case types.DELETE_INSERT: return translateDeleteInsert(op);
case types.DELETE_WHERE: return translateDeleteWhere(op);
case types.LOAD: return translateLoad(op);
case types.CLEAR: return translateClear(op);
case types.CREATE: return translateCreate(op);
case types.DROP: return translateDrop(op);
case types.ADD: return translateAdd(op);
case types.MOVE: return translateMove(op);
case types.COPY: return translateCopy(op);
}

@@ -111,3 +121,3 @@ throw new Error('Unknown Operation type ' + op.type);

operator: expr.not ? 'notexists' : 'exists',
args: flatten([
args: util_1.default.flatten([
translateOperation(expr.input)

@@ -165,3 +175,3 @@ ])

template: op.template.map(translatePattern),
where: flatten([
where: util_1.default.flatten([
translateOperation(op.input)

@@ -182,3 +192,3 @@ ])

}
return flatten([
return util_1.default.flatten([
translateOperation(op.input),

@@ -205,3 +215,3 @@ {

type: 'group',
patterns: flatten([
patterns: util_1.default.flatten([
translateOperation(op.input),

@@ -215,3 +225,3 @@ { type: 'filter', expression: translateExpression(op.expression) }

type: 'graph',
patterns: flatten([translateOperation(op.input)]),
patterns: util_1.default.flatten([translateOperation(op.input)]),
name: op.name

@@ -229,3 +239,3 @@ };

function translateJoin(op) {
return flatten([
return util_1.default.flatten([
translateOperation(op.left),

@@ -248,4 +258,4 @@ translateOperation(op.right)

}
leftjoin.patterns = flatten(leftjoin.patterns);
return flatten([
leftjoin.patterns = util_1.default.flatten(leftjoin.patterns);
return util_1.default.flatten([
translateOperation(op.left),

@@ -259,3 +269,3 @@ leftjoin

patterns = patterns.patterns;
return flatten([
return util_1.default.flatten([
translateOperation(op.left),

@@ -284,3 +294,2 @@ {

function translatePattern(op) {
// TODO: quads back to graph statement
return {

@@ -331,3 +340,3 @@ subject: op.subject,

context.project = true;
let input = flatten([translateOperation(op.input)]);
let input = util_1.default.flatten([translateOperation(op.input)]);
if (input.length === 1 && input[0].type === 'group')

@@ -382,3 +391,3 @@ input = input[0].patterns;

if (objectContainsValues(filter, Object.keys(aggregators))) {
result.having = flatten([replaceAggregatorVariables(filter.expression, aggregators)]);
result.having = util_1.default.flatten([replaceAggregatorVariables(filter.expression, aggregators)]);
result.where.splice(-1);

@@ -438,3 +447,3 @@ }

type: 'union',
patterns: flatten([
patterns: util_1.default.flatten([
translateOperation(op.left),

@@ -563,2 +572,119 @@ translateOperation(op.right)

}
// UPDATE OPERATIONS
function translateCompositeUpdate(op) {
const updates = op.updates.map(update => {
const result = translateOperation(update);
return result.updates[0];
});
return { prefixes: {}, type: 'update', updates };
}
function translateInsertData(op) {
const updates = [{ updateType: 'insert', insert: convertUpdatePatterns(op.quads) }];
return { prefixes: {}, type: 'update', updates };
}
function translateDeleteData(op) {
const updates = [{ updateType: 'delete', delete: convertUpdatePatterns(op.quads) }];
return { prefixes: {}, type: 'update', updates };
}
function translateDeleteInsert(op) {
let where = op.input;
let using = undefined;
if (op.input.type === types.FROM) {
let from = op.input;
where = from.input;
using = { default: from.default, named: from.named };
}
const updates = [{
updateType: 'insertdelete',
delete: convertUpdatePatterns(op.delete),
insert: convertUpdatePatterns(op.insert),
}];
if (using)
updates[0].using = using;
// corresponds to empty array in SPARQL.js
if (where.type === types.BGP && where.patterns.length === 0)
updates[0].where = [];
else {
const graphs = {};
let result = translateOperation(removeQuadsRecursive(where, graphs));
if (result.type === 'group')
updates[0].where = result.patterns;
else
updates[0].where = [result];
// graph might not be applied yet since there was no project
// this can only happen if there was a single graph
const graphNames = Object.keys(graphs);
if (graphNames.length > 0) {
if (graphNames.length !== 1)
throw new Error('This is unexpected and might indicate an error in graph handling for updates.');
// ignore if default graph
if (graphs[graphNames[0]].graph.value !== '')
updates[0].where = [{ type: 'graph', patterns: updates[0].where, name: graphs[graphNames[0]].graph }];
}
}
return { prefixes: {}, type: 'update', updates };
}
function translateDeleteWhere(op) {
const updates = [{ updateType: 'deletewhere', delete: convertUpdatePatterns(op.patterns) }];
return { prefixes: {}, type: 'update', updates };
}
function translateLoad(op) {
const updates = [{ type: 'load', silent: Boolean(op.silent), source: op.source }];
if (op.destination)
updates[0].destination = op.destination;
return { prefixes: {}, type: 'update', updates };
}
function translateClear(op) {
return translateClearCreateDrop(op, 'clear');
}
function translateCreate(op) {
return translateClearCreateDrop(op, 'create');
}
function translateDrop(op) {
return translateClearCreateDrop(op, 'drop');
}
function translateClearCreateDrop(op, type) {
const updates = [{ type, silent: Boolean(op.silent) }];
if (op.source === 'DEFAULT')
updates[0].graph = { default: true };
else if (op.source === 'NAMED')
updates[0].graph = { named: true };
else if (op.source === 'ALL')
updates[0].graph = { all: true };
else
updates[0].graph = { type: 'graph', name: op.source };
return { prefixes: {}, type: 'update', updates };
}
function translateAdd(op) {
return translateUpdateGraphShortcut(op, 'add');
}
function translateMove(op) {
return translateUpdateGraphShortcut(op, 'move');
}
function translateCopy(op) {
return translateUpdateGraphShortcut(op, 'copy');
}
function translateUpdateGraphShortcut(op, type) {
const updates = [{ type, silent: Boolean(op.silent) }];
updates[0].source = op.source === 'DEFAULT' ? { type: 'graph', default: true } : { type: 'graph', name: op.source };
updates[0].destination = op.destination === 'DEFAULT' ? { type: 'graph', default: true } : { type: 'graph', name: op.destination };
return { prefixes: {}, type: 'update', updates };
}
// similar to removeQuads but more simplified for UPDATEs
function convertUpdatePatterns(patterns) {
if (!patterns)
return [];
const graphs = {};
patterns.forEach(pattern => {
const graph = pattern.graph.value;
if (!graphs[graph])
graphs[graph] = [];
graphs[graph].push(pattern);
});
return Object.keys(graphs).map(graph => {
if (graph === '')
return { type: 'bgp', triples: graphs[graph].map(translatePattern) };
return { type: 'graph', triples: graphs[graph].map(translatePattern), name: graphs[graph][0].graph };
});
}
function removeQuads(op) {

@@ -573,2 +699,5 @@ return removeQuadsRecursive(op, {});

return op;
// UPDATE operations with Patterns handle graphs a bit differently
if ([types.INSERT_DATA, types.DELETE_DATA, types.DELETE_INSERT, types.DELETE_WHERE].includes(op.type))
return op;
if ((op.type === types.PATTERN || op.type === types.PATH) && op.graph) {

@@ -575,0 +704,0 @@ if (!graphs[op.graph.value])

@@ -42,9 +42,15 @@ "use strict";

useQuads = quads;
if (sparql.type !== 'query')
throw new Error('Translate only works on complete query objects.');
// group and where are identical, having only 1 makes parsing easier, can be undefined in DESCRIBE
let group = { type: 'group', patterns: sparql.where || [] };
let vars = new Set(Object.keys(inScopeVariables(group)).map(factory.createTerm.bind(factory)));
let res = translateGroupGraphPattern(group);
res = translateAggregates(sparql, res, vars);
if (sparql.type !== 'query' && sparql.type !== 'update')
throw new Error('Translate only works on complete query or update objects.');
let vars = new Set(Object.keys(inScopeVariables(sparql)).map(factory.createTerm.bind(factory)));
let res;
if (sparql.type === 'query') {
// group and where are identical, having only 1 makes parsing easier, can be undefined in DESCRIBE
let group = { type: 'group', patterns: sparql.where || [] };
res = translateGroupGraphPattern(group);
res = translateAggregates(sparql, res, vars);
}
else if (sparql.type === 'update') {
res = translateUpdate(sparql);
}
if (blankToVariable) {

@@ -176,3 +182,3 @@ res = translateBlankNodesToVariables(res, vars);

else
patterns.push(translateTriple(t));
patterns.push(translateQuad(t));
}

@@ -254,4 +260,4 @@ if (patterns.length > 0)

}
function translateTriple(triple) {
return factory.createPattern(triple.subject, triple.predicate, triple.object);
function translateQuad(quad) {
return factory.createPattern(quad.subject, quad.predicate, quad.object, quad.graph);
}

@@ -435,3 +441,3 @@ function translateGraph(graph) {

if (exp.descending)
result = factory.createOperatorExpression(types.DESC, [result]); // TODO: should this really be an epxression?
result = factory.createOperatorExpression(types.DESC, [result]); // TODO: should this really be an expression?
return result;

@@ -451,3 +457,3 @@ }));

if (query.queryType === 'CONSTRUCT')
res = factory.createConstruct(res, query.template.map(translateTriple));
res = factory.createConstruct(res, query.template.map(translateQuad));
else if (query.queryType === 'ASK')

@@ -501,2 +507,83 @@ res = factory.createAsk(res);

}
function translateUpdate(thingy) {
if (thingy.updates.length === 1)
return translateSingleUpdate(thingy.updates[0]);
return factory.createCompositeUpdate(thingy.updates.map(translateSingleUpdate));
}
function translateSingleUpdate(thingy) {
if (thingy.updateType === 'insertdelete' || thingy.updateType === 'deletewhere' || thingy.updateType === 'delete' || thingy.updateType === 'insert')
return translateInsertDelete(thingy);
if (thingy.type === 'load')
return translateUpdateGraphLoad(thingy);
if (thingy.type === 'clear' || thingy.type === 'create' || thingy.type === 'drop')
return translateUpdateGraph(thingy);
if (thingy.type === 'add' || thingy.type === 'copy' || thingy.type === 'move')
return translateUpdateGraphShortcut(thingy);
throw new Error(`Unknown update type ${thingy.updateType}`);
}
function translateInsertDelete(thingy) {
if (!useQuads)
throw new Error('INSERT/DELETE operations are only supported with quads option enabled');
let deleteTriples = [];
let insertTriples = [];
let where;
if (thingy.delete)
deleteTriples = util_1.default.flatten(thingy.delete.map(input => translateUpdateTriplesBlock(input, thingy.graph)));
if (thingy.insert)
insertTriples = util_1.default.flatten(thingy.insert.map(input => translateUpdateTriplesBlock(input, thingy.graph)));
if (thingy.where) {
where = translateGroupGraphPattern({ type: 'group', patterns: thingy.where });
if (thingy.using)
where = factory.createFrom(where, thingy.using.default, thingy.using.named);
else if (thingy.graph)
// this is equivalent
where = factory.createFrom(where, [thingy.graph], []);
}
if (thingy.updateType === 'insertdelete')
return factory.createDeleteInsert(where, deleteTriples.length > 0 ? deleteTriples.map(translateQuad) : undefined, insertTriples.length > 0 ? insertTriples.map(translateQuad) : undefined);
if (thingy.updateType === 'deletewhere')
return factory.createDeleteWhere(deleteTriples.map(translateQuad));
if (thingy.updateType === 'delete')
return factory.createDeleteData(deleteTriples.map(translateQuad));
if (thingy.updateType === 'insert')
return factory.createInsertData(insertTriples.map(translateQuad));
}
// for now, UPDATE parsing will always return quads and have no GRAPH elements
function translateUpdateTriplesBlock(thingy, graph) {
let currentGraph = graph;
if (thingy.type === 'graph')
currentGraph = thingy.name;
let currentTriples = thingy.triples;
if (currentGraph)
currentTriples = currentTriples.map(triple => Object.assign(triple, { graph: currentGraph }));
return currentTriples;
}
function translateUpdateGraph(thingy) {
let source;
if (thingy.graph.all)
source = 'ALL';
else if (thingy.graph.default)
source = 'DEFAULT';
else if (thingy.graph.named)
source = 'NAMED';
else
source = thingy.graph.name;
switch (thingy.type) {
case 'clear': return factory.createClear(source, thingy.silent);
case 'create': return factory.createCreate(source, thingy.silent);
case 'drop': return factory.createDrop(source, thingy.silent);
}
}
function translateUpdateGraphLoad(thingy) {
return factory.createLoad(thingy.source, thingy.destination, thingy.silent);
}
function translateUpdateGraphShortcut(thingy) {
const source = thingy.source.default ? 'DEFAULT' : thingy.source.name;
const destination = thingy.destination.default ? 'DEFAULT' : thingy.destination.name;
switch (thingy.type) {
case 'copy': return factory.createCopy(source, destination, thingy.silent);
case 'move': return factory.createMove(source, destination, thingy.silent);
case 'add': return factory.createAdd(source, destination, thingy.silent);
}
}
function translateBlankNodesToVariables(res, variables) {

@@ -503,0 +590,0 @@ const blankToVariableMapping = {};

@@ -7,2 +7,7 @@ import * as A from "./algebra";

/**
* Flattens an array of arrays to an array.
* @param arr - Array of arrays
*/
static flatten<T>(arr: T[][]): T[];
/**
* Detects all in-scope variables.

@@ -9,0 +14,0 @@ * In practice this means iterating through the entire algebra tree, finding all variables,

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

/**
* Flattens an array of arrays to an array.
* @param arr - Array of arrays
*/
static flatten(arr) {
return Array.prototype.concat(...arr).filter(x => x);
}
/**
* Detects all in-scope variables.

@@ -236,2 +243,35 @@ * In practice this means iterating through the entire algebra tree, finding all variables,

break;
// UPDATE operations
case algebra_1.types.COMPOSITE_UPDATE:
const cu = result;
cu.updates.forEach(update => recurseOp(update));
break;
case algebra_1.types.INSERT_DATA:
const id = result;
id.quads.forEach(pattern => recurseOp(pattern));
break;
case algebra_1.types.DELETE_DATA:
const dd = result;
dd.quads.forEach(pattern => recurseOp(pattern));
break;
case algebra_1.types.DELETE_INSERT:
const di = result;
if (di.delete)
di.delete.forEach(pattern => recurseOp(pattern));
if (di.insert)
di.insert.forEach(pattern => recurseOp(pattern));
recurseOp(di.input);
break;
case algebra_1.types.DELETE_WHERE:
const dw = result;
dw.patterns.forEach(pattern => recurseOp(pattern));
break;
// all of these only have graph IDs as values
case algebra_1.types.LOAD: break;
case algebra_1.types.CLEAR: break;
case algebra_1.types.CREATE: break;
case algebra_1.types.DROP: break;
case algebra_1.types.ADD: break;
case algebra_1.types.MOVE: break;
case algebra_1.types.COPY: break;
default: throw new Error('Unknown Operation type ' + result.type);

@@ -354,2 +394,40 @@ }

return factory.createZeroOrOnePath(mapOp(zoo.path));
// UPDATE operations
case algebra_1.types.COMPOSITE_UPDATE:
const cu = result;
return factory.createCompositeUpdate(cu.updates.map(mapOp));
case algebra_1.types.INSERT_DATA:
const id = result;
return factory.createInsertData(id.quads.map(mapOp));
break;
case algebra_1.types.DELETE_DATA:
const dd = result;
return factory.createDeleteData(dd.quads.map(mapOp));
case algebra_1.types.DELETE_INSERT:
const di = result;
return factory.createDeleteInsert(mapOp(di.input), di.delete ? di.delete.map(mapOp) : undefined, di.insert ? di.insert.map(mapOp) : undefined);
case algebra_1.types.DELETE_WHERE:
const dw = result;
return factory.createDeleteWhere(dw.patterns.map(mapOp));
case algebra_1.types.LOAD:
const load = result;
return factory.createLoad(load.source, load.destination, load.silent);
case algebra_1.types.CLEAR:
const clear = result;
return factory.createClear(clear.source, clear.silent);
case algebra_1.types.CREATE:
const create = result;
return factory.createCreate(create.source, create.silent);
case algebra_1.types.DROP:
const drop = result;
return factory.createDrop(drop.source, drop.silent);
case algebra_1.types.ADD:
const add = result;
return factory.createAdd(add.source, add.destination);
case algebra_1.types.MOVE:
const move = result;
return factory.createMove(move.source, move.destination);
case algebra_1.types.COPY:
const copy = result;
return factory.createCopy(copy.source, copy.destination);
default: throw new Error('Unknown Operation type ' + result.type);

@@ -356,0 +434,0 @@ }

2

package.json
{
"name": "sparqlalgebrajs",
"version": "2.2.2",
"version": "2.3.0",
"description": "Convert SPARQL to SPARQL algebra",

@@ -5,0 +5,0 @@ "author": "Joachim Van Herwegen",

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