sparqlalgebrajs
Advanced tools
Comparing version 0.5.3 to 0.6.0
import translate from './lib/sparqlAlgebra'; | ||
import * as Algebra from './lib/algebra'; | ||
export { translate, Algebra }; | ||
import Factory from './lib/Factory'; | ||
export { translate, Algebra, Factory }; |
19
index.js
@@ -7,2 +7,21 @@ "use strict"; | ||
exports.Algebra = Algebra; | ||
const Factory_1 = require("./lib/Factory"); | ||
exports.Factory = Factory_1.default; | ||
// let algebra = translate( | ||
// `PREFIX : <http://www.example.org> | ||
// PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> | ||
// SELECT ?L | ||
// WHERE { | ||
// ?O :hasItem [ rdfs:label ?L ] . | ||
// { | ||
// SELECT DISTINCT ?O | ||
// WHERE { ?O a :Order } | ||
// ORDER BY ?O | ||
// LIMIT 2 | ||
// } | ||
// } ORDER BY ?L` | ||
// ); | ||
// console.log(JSON.stringify(algebra, null, 2)); | ||
// console.log(JSON.stringify(toSparqlJs(algebra), null, 2)); | ||
// console.log(toSparql(algebra)); | ||
//# sourceMappingURL=index.js.map |
@@ -41,2 +41,3 @@ import * as rdfjs from "rdf-js"; | ||
export declare const expressionTypes: Readonly<{ | ||
AGGREGATE: string; | ||
EXISTENCE: string; | ||
@@ -60,4 +61,11 @@ NAMED: string; | ||
type: 'expression'; | ||
expressionType: 'existence' | 'named' | 'operator' | 'term'; | ||
expressionType: 'aggregate' | 'existence' | 'named' | 'operator' | 'term'; | ||
} | ||
export interface AggregateExpression extends Expression { | ||
expressionType: 'aggregate'; | ||
aggregator: string; | ||
distinct: boolean; | ||
separator?: string; | ||
expression: Expression; | ||
} | ||
export interface ExistenceExpression extends Expression { | ||
@@ -85,9 +93,3 @@ expressionType: 'existence'; | ||
} | ||
export interface Aggregate extends Operation { | ||
type: 'aggregate'; | ||
aggregator: string; | ||
separator?: string; | ||
expression: Expression; | ||
} | ||
export interface BoundAggregate extends Aggregate { | ||
export interface BoundAggregate extends AggregateExpression { | ||
variable: rdfjs.Variable; | ||
@@ -121,3 +123,3 @@ } | ||
type: 'group'; | ||
expressions: Expression[]; | ||
variables: rdfjs.Variable[]; | ||
aggregates: BoundAggregate[]; | ||
@@ -186,3 +188,5 @@ } | ||
variables: rdfjs.Variable[]; | ||
bindings: Map<rdfjs.Variable, rdfjs.Term>[]; | ||
bindings: { | ||
[key: string]: rdfjs.Term; | ||
}[]; | ||
} | ||
@@ -189,0 +193,0 @@ export interface ZeroOrMorePath extends Operation { |
@@ -44,2 +44,3 @@ "use strict"; | ||
exports.expressionTypes = Object.freeze({ | ||
AGGREGATE: 'aggregate', | ||
EXISTENCE: 'existence', | ||
@@ -46,0 +47,0 @@ NAMED: 'named', |
import * as A from './algebra'; | ||
import * as RDF from "rdf-js"; | ||
export default class Factory { | ||
static createAlt(left: A.Operation, right: A.Operation): A.Alt; | ||
static createAggregate(aggregator: string, expression: A.Expression, separator?: string): A.Aggregate; | ||
static createBoundAggregate(variable: RDF.Variable, aggregate: string, expression: A.Expression, separator?: string): A.BoundAggregate; | ||
static createBgp(patterns: A.Pattern[]): A.Bgp; | ||
static createConstruct(input: A.Operation, template: A.Pattern[]): A.Construct; | ||
static createDistinct(input: A.Operation): A.Distinct; | ||
static createExtend(input: A.Operation, variable: RDF.Variable, expression: A.Expression): A.Extend; | ||
static createFilter(input: A.Operation, expression: A.Expression): A.Filter; | ||
static createGraph(input: A.Operation, name: RDF.Term): A.Graph; | ||
static createGroup(input: A.Operation, expressions: A.Expression[], aggregates: A.BoundAggregate[]): A.Group; | ||
static createInv(path: A.Operation): A.Inv; | ||
static createJoin(left: A.Operation, right: A.Operation): A.Join; | ||
static createLeftJoin(left: A.Operation, right: A.Operation, expression?: A.Expression): A.LeftJoin; | ||
static createLink(iri: RDF.NamedNode): A.Link; | ||
static createMinus(left: A.Operation, right: A.Operation): A.Minus; | ||
static createNps(iris: RDF.NamedNode[]): A.Nps; | ||
static createOneOrMorePath(path: A.Operation): A.OneOrMorePath; | ||
static createOrderBy(input: A.Operation, expressions: A.Expression[]): A.OrderBy; | ||
static createPath(subject: RDF.Term, predicate: A.Operation, object: RDF.Term, graph: RDF.Term): A.Path; | ||
static createPattern(subject: RDF.Term, predicate: RDF.Term, object: RDF.Term, graph: RDF.Term): A.Pattern; | ||
static createProject(input: A.Operation, variables: RDF.Variable[]): A.Project; | ||
static createReduced(input: A.Operation): A.Reduced; | ||
static createSeq(left: A.Operation, right: A.Operation): A.Seq; | ||
static createSlice(input: A.Operation, start: number, length?: number): A.Slice; | ||
static createUnion(left: A.Operation, right: A.Operation): A.Union; | ||
static createValues(variables: RDF.Variable[], bindings: Map<RDF.Variable, RDF.Term>[]): A.Values; | ||
static createZeroOrMorePath(path: A.Operation): A.ZeroOrMorePath; | ||
static createZeroOrOnePath(path: A.Operation): A.ZeroOrOnePath; | ||
static createExistenceExpression(not: boolean, input: A.Operation): A.ExistenceExpression; | ||
static createNamedExpression(name: RDF.NamedNode, args: A.Expression[]): A.NamedExpression; | ||
static createOperatorExpression(operator: string, args: A.Expression[]): A.OperatorExpression; | ||
static createTermExpression(term: RDF.Term): A.TermExpression; | ||
dataFactory: RDF.DataFactory; | ||
stringType: RDF.NamedNode; | ||
constructor(dataFactory: RDF.DataFactory); | ||
createAlt(left: A.Operation, right: A.Operation): A.Alt; | ||
createBoundAggregate(variable: RDF.Variable, aggregate: string, expression: A.Expression, distinct: boolean, separator?: string): A.BoundAggregate; | ||
createBgp(patterns: A.Pattern[]): A.Bgp; | ||
createConstruct(input: A.Operation, template: A.Pattern[]): A.Construct; | ||
createDistinct(input: A.Operation): A.Distinct; | ||
createExtend(input: A.Operation, variable: RDF.Variable, expression: A.Expression): A.Extend; | ||
createFilter(input: A.Operation, expression: A.Expression): A.Filter; | ||
createGraph(input: A.Operation, name: RDF.Term): A.Graph; | ||
createGroup(input: A.Operation, variables: RDF.Variable[], aggregates: A.BoundAggregate[]): A.Group; | ||
createInv(path: A.Operation): A.Inv; | ||
createJoin(left: A.Operation, right: A.Operation): A.Join; | ||
createLeftJoin(left: A.Operation, right: A.Operation, expression?: A.Expression): A.LeftJoin; | ||
createLink(iri: RDF.NamedNode): A.Link; | ||
createMinus(left: A.Operation, right: A.Operation): A.Minus; | ||
createNps(iris: RDF.NamedNode[]): A.Nps; | ||
createOneOrMorePath(path: A.Operation): A.OneOrMorePath; | ||
createOrderBy(input: A.Operation, expressions: A.Expression[]): A.OrderBy; | ||
createPath(subject: RDF.Term, predicate: A.Operation, object: RDF.Term, graph?: RDF.Term): A.Path; | ||
createPattern(subject: RDF.Term, predicate: RDF.Term, object: RDF.Term, graph?: RDF.Term): A.Pattern; | ||
createProject(input: A.Operation, variables: RDF.Variable[]): A.Project; | ||
createReduced(input: A.Operation): A.Reduced; | ||
createSeq(left: A.Operation, right: A.Operation): A.Seq; | ||
createSlice(input: A.Operation, start: number, length?: number): A.Slice; | ||
createUnion(left: A.Operation, right: A.Operation): A.Union; | ||
createValues(variables: RDF.Variable[], bindings: { | ||
[key: string]: RDF.Term; | ||
}[]): A.Values; | ||
createZeroOrMorePath(path: A.Operation): A.ZeroOrMorePath; | ||
createZeroOrOnePath(path: A.Operation): A.ZeroOrOnePath; | ||
createAggregateExpression(aggregator: string, expression: A.Expression, distinct: boolean, separator?: string): A.AggregateExpression; | ||
createExistenceExpression(not: boolean, input: A.Operation): A.ExistenceExpression; | ||
createNamedExpression(name: RDF.NamedNode, args: A.Expression[]): A.NamedExpression; | ||
createOperatorExpression(operator: string, args: A.Expression[]): A.OperatorExpression; | ||
createTermExpression(term: RDF.Term): A.TermExpression; | ||
createTerm(str: string): RDF.Term; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const n3_1 = require("n3"); | ||
const _ = require("lodash"); | ||
const defaultGraph = { termType: 'DefaultGraph', value: '' }; | ||
class Factory { | ||
static createAlt(left, right) { return { type: 'alt', left, right }; } | ||
static createAggregate(aggregator, expression, separator) { | ||
if (separator) | ||
return { type: 'aggregate', aggregator, expression, separator }; | ||
return { type: 'aggregate', aggregator, expression }; | ||
constructor(dataFactory) { | ||
this.dataFactory = dataFactory; | ||
this.stringType = this.createTerm('http://www.w3.org/2001/XMLSchema#string'); | ||
} | ||
static createBoundAggregate(variable, aggregate, expression, separator) { | ||
let result = Factory.createAggregate(aggregate, expression, separator); | ||
createAlt(left, right) { return { type: 'alt', left, right }; } | ||
createBoundAggregate(variable, aggregate, expression, distinct, separator) { | ||
let result = this.createAggregateExpression(aggregate, expression, distinct, separator); | ||
result.variable = variable; | ||
return result; | ||
} | ||
static createBgp(patterns) { return { type: 'bgp', patterns }; } | ||
static createConstruct(input, template) { return { type: 'construct', input, template }; } | ||
static createDistinct(input) { return { type: 'distinct', input }; } | ||
static createExtend(input, variable, expression) { return { type: 'extend', input, variable, expression }; } | ||
static createFilter(input, expression) { return { type: 'filter', input, expression }; } | ||
static createGraph(input, name) { return { type: 'graph', input, name }; } | ||
static createGroup(input, expressions, aggregates) { return { type: 'group', input, expressions, aggregates }; } | ||
static createInv(path) { return { type: 'inv', path }; } | ||
static createJoin(left, right) { return { type: 'join', left, right }; } | ||
static createLeftJoin(left, right, expression) { | ||
createBgp(patterns) { return { type: 'bgp', patterns }; } | ||
createConstruct(input, template) { return { type: 'construct', input, template }; } | ||
createDistinct(input) { return { type: 'distinct', input }; } | ||
createExtend(input, variable, expression) { return { type: 'extend', input, variable, expression }; } | ||
createFilter(input, expression) { return { type: 'filter', input, expression }; } | ||
createGraph(input, name) { return { type: 'graph', input, name }; } | ||
createGroup(input, variables, aggregates) { return { type: 'group', input, variables, aggregates }; } | ||
createInv(path) { return { type: 'inv', path }; } | ||
createJoin(left, right) { return { type: 'join', left, right }; } | ||
createLeftJoin(left, right, expression) { | ||
if (expression) | ||
@@ -29,14 +31,26 @@ return { type: 'leftjoin', left, right, expression }; | ||
} | ||
static createLink(iri) { return { type: 'link', iri }; } | ||
static createMinus(left, right) { return { type: 'minus', left, right }; } | ||
static createNps(iris) { return { type: 'nps', iris }; } | ||
static createOneOrMorePath(path) { return { type: 'OneOrMorePath', path }; } | ||
static createOrderBy(input, expressions) { return { type: 'orderby', input, expressions }; } | ||
static createPath(subject, predicate, object, graph) { return { type: 'path', subject, predicate, object, graph }; } | ||
createLink(iri) { return { type: 'link', iri }; } | ||
createMinus(left, right) { return { type: 'minus', left, right }; } | ||
createNps(iris) { return { type: 'nps', iris }; } | ||
createOneOrMorePath(path) { return { type: 'OneOrMorePath', path }; } | ||
createOrderBy(input, expressions) { return { type: 'orderby', input, expressions }; } | ||
createPath(subject, predicate, object, graph) { | ||
if (graph) | ||
return { type: 'path', subject, predicate, object, graph }; | ||
return { type: 'path', subject, predicate, object, graph: defaultGraph }; | ||
} | ||
// TODO: cast needed due to missing equals method (could use https://github.com/rdf-ext/rdf-data-model ) | ||
static createPattern(subject, predicate, object, graph) { return { type: 'pattern', subject, predicate, object, graph }; } | ||
static createProject(input, variables) { return { type: 'project', input, variables }; } | ||
static createReduced(input) { return { type: 'reduced', input }; } | ||
static createSeq(left, right) { return { type: 'seq', left, right }; } | ||
static createSlice(input, start, length) { | ||
createPattern(subject, predicate, object, graph) { | ||
let pattern; | ||
if (graph) | ||
pattern = this.dataFactory.quad(subject, predicate, object, graph); | ||
else | ||
pattern = this.dataFactory.triple(subject, predicate, object); | ||
pattern.type = 'pattern'; | ||
return pattern; | ||
} | ||
createProject(input, variables) { return { type: 'project', input, variables }; } | ||
createReduced(input) { return { type: 'reduced', input }; } | ||
createSeq(left, right) { return { type: 'seq', left, right }; } | ||
createSlice(input, start, length) { | ||
if (length !== undefined) | ||
@@ -46,12 +60,35 @@ return { type: 'slice', input, start, length }; | ||
} | ||
static createUnion(left, right) { return { type: 'union', left, right }; } | ||
static createValues(variables, bindings) { return { type: 'values', variables, bindings }; } | ||
static createZeroOrMorePath(path) { return { type: 'ZeroOrMorePath', path }; } | ||
static createZeroOrOnePath(path) { return { type: 'ZeroOrOnePath', path }; } | ||
static createExistenceExpression(not, input) { return { type: 'expression', expressionType: 'existence', not, input }; } | ||
static createNamedExpression(name, args) { return { type: 'expression', expressionType: 'named', name, args }; } | ||
static createOperatorExpression(operator, args) { return { type: 'expression', expressionType: 'operator', operator, args }; } | ||
static createTermExpression(term) { return { type: 'expression', expressionType: 'term', term }; } | ||
createUnion(left, right) { return { type: 'union', left, right }; } | ||
createValues(variables, bindings) { return { type: 'values', variables, bindings }; } | ||
createZeroOrMorePath(path) { return { type: 'ZeroOrMorePath', path }; } | ||
createZeroOrOnePath(path) { return { type: 'ZeroOrOnePath', path }; } | ||
createAggregateExpression(aggregator, expression, distinct, separator) { | ||
if (separator) | ||
return { type: 'expression', expressionType: 'aggregate', aggregator, expression, separator, distinct }; | ||
return { type: 'expression', expressionType: 'aggregate', aggregator, expression, distinct }; | ||
} | ||
createExistenceExpression(not, input) { return { type: 'expression', expressionType: 'existence', not, input }; } | ||
createNamedExpression(name, args) { return { type: 'expression', expressionType: 'named', name, args }; } | ||
createOperatorExpression(operator, args) { return { type: 'expression', expressionType: 'operator', operator, args }; } | ||
createTermExpression(term) { return { type: 'expression', expressionType: 'term', term }; } | ||
createTerm(str) { | ||
if (str[0] === '?') | ||
return this.dataFactory.variable(str.substring(1)); | ||
if (_.startsWith(str, '_:')) | ||
return this.dataFactory.blankNode(str.substring(2)); | ||
if (n3_1.Util.isLiteral(str)) { | ||
let value = n3_1.Util.getLiteralValue(str); | ||
let lang = n3_1.Util.getLiteralLanguage(str); | ||
if (lang && lang.length > 0) | ||
return this.dataFactory.literal(value, lang); | ||
let type = n3_1.Util.getLiteralType(str); | ||
let datatype = this.stringType; | ||
if (type && type.length > 0) | ||
datatype = this.createTerm(type); | ||
return this.dataFactory.literal(value, datatype); | ||
} | ||
return { termType: 'NamedNode', value: str }; | ||
} | ||
} | ||
exports.default = Factory; | ||
//# sourceMappingURL=Factory.js.map |
import * as Algebra from './algebra'; | ||
export default function translate(sparql: any, quads?: boolean): Algebra.Operation; | ||
import * as RDF from 'rdf-js'; | ||
/** | ||
* Translates the given SPARQL query to SPARQL Algebra. | ||
* @param sparql - Either a SPARQL string or an object generated by sparql.js | ||
* @param options - Options object. Current options: | ||
* * dataFactory: The Datafactory used to generate terms | ||
* * quads?: Boolean indicating whether triples should be converted to Quads (consumes GRAPH statements) | ||
* @returns {Operation} | ||
*/ | ||
export default function translate(sparql: any, options: { | ||
dataFactory: RDF.DataFactory; | ||
quads?: boolean; | ||
}): Algebra.Operation; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const _ = require("lodash"); | ||
const Algebra = require("./algebra"); | ||
const Factory_1 = require("./Factory"); | ||
const n3_1 = require("n3"); | ||
const factory_1 = require("./factory"); | ||
const Parser = require('sparqljs').Parser; | ||
const isEqual = require('lodash.isequal'); | ||
const types = Algebra.types; | ||
const eTypes = Algebra.expressionTypes; | ||
let variables = new Set(); | ||
let varCount = 0; | ||
let useQuads = false; | ||
function translate(sparql, quads) { | ||
let factory; | ||
/** | ||
* Translates the given SPARQL query to SPARQL Algebra. | ||
* @param sparql - Either a SPARQL string or an object generated by sparql.js | ||
* @param options - Options object. Current options: | ||
* * dataFactory: The Datafactory used to generate terms | ||
* * quads?: Boolean indicating whether triples should be converted to Quads (consumes GRAPH statements) | ||
* @returns {Operation} | ||
*/ | ||
function translate(sparql, options) { | ||
factory = new factory_1.default(options.dataFactory); | ||
return translateQuery(sparql, options.quads); | ||
} | ||
exports.default = translate; | ||
function translateQuery(sparql, quads) { | ||
variables = new Set(); | ||
varCount = 0; | ||
useQuads = quads; | ||
if (_.isString(sparql)) { | ||
if (isString(sparql)) { | ||
let parser = new Parser(); | ||
@@ -28,3 +40,3 @@ // resets the identifier counter used for blank nodes | ||
let group = { type: 'group', patterns: sparql.where }; | ||
let vars = new Set(Object.keys(inScopeVariables(group)).map(translateTerm)); | ||
let vars = new Set(Object.keys(inScopeVariables(group)).map(factory.createTerm.bind(factory))); | ||
let res = translateGroupGraphPattern(group); | ||
@@ -34,6 +46,11 @@ res = translateAggregates(sparql, res, vars); | ||
} | ||
exports.default = translate; | ||
function isString(str) { | ||
return typeof str === 'string'; | ||
} | ||
function isObject(o) { | ||
return o !== null && typeof o === 'object'; | ||
} | ||
function isVariable(str) { | ||
// there is also a '?' operator... | ||
return _.isString(str) && str[0] === '?' && str.length > 1; | ||
return isString(str) && str[0] === '?' && str.length > 1; | ||
} | ||
@@ -47,3 +64,3 @@ // 18.2.1 | ||
} | ||
else if (_.isObject(thingy)) { | ||
else if (isObject(thingy)) { | ||
if (thingy.type === 'bind') { | ||
@@ -96,3 +113,3 @@ inScopeVariables(thingy.expression); // to fill `variables` | ||
return translateGroupGraphPattern(p); | ||
}).reduce((acc, item) => Factory_1.default.createUnion(acc, item)); | ||
}).reduce((acc, item) => factory.createUnion(acc, item)); | ||
else if (thingy.type === 'graph') | ||
@@ -102,7 +119,7 @@ // need to handle this separately since the filters need to be in the graph | ||
else if (thingy.type === 'group') | ||
result = nonfilters.reduce(accumulateGroupGraphPattern, Factory_1.default.createBgp([])); | ||
result = nonfilters.reduce(accumulateGroupGraphPattern, factory.createBgp([])); | ||
else if (thingy.type === 'values') | ||
result = translateInlineData(thingy); | ||
else if (thingy.type === 'query') | ||
result = translate(thingy, useQuads); | ||
result = translateQuery(thingy, useQuads); | ||
else | ||
@@ -113,3 +130,3 @@ throw new Error('Unexpected type: ' + thingy.type); | ||
if (expressions.length > 0) | ||
result = Factory_1.default.createFilter(result, expressions.reduce((acc, exp) => Factory_1.default.createOperatorExpression('&&', [acc, exp]))); | ||
result = factory.createFilter(result, expressions.reduce((acc, exp) => factory.createOperatorExpression('&&', [acc, exp]))); | ||
} | ||
@@ -119,12 +136,18 @@ return result; | ||
function translateExpression(exp) { | ||
if (_.isString(exp)) | ||
return Factory_1.default.createTermExpression(translateTerm(exp)); | ||
if (isString(exp)) | ||
return factory.createTermExpression(factory.createTerm(exp)); | ||
if (exp.aggregation) { | ||
let result = factory.createAggregateExpression(exp.aggregation, translateExpression(exp.expression), exp.distinct); | ||
if (exp.separator) | ||
result.separator = exp.separator; | ||
return result; | ||
} | ||
if (exp.function) | ||
return Factory_1.default.createNamedExpression(translateTerm(exp.function), exp.args.map(translateExpression)); | ||
return factory.createNamedExpression(factory.createTerm(exp.function), exp.args.map(translateExpression)); | ||
if (exp.operator) { | ||
if (exp.operator === 'exists' || exp.operator === 'notexists') | ||
return Factory_1.default.createExistenceExpression(exp.operator === 'notexists', translateGroupGraphPattern(exp.args[0])); | ||
return factory.createExistenceExpression(exp.operator === 'notexists', translateGroupGraphPattern(exp.args[0])); | ||
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 | ||
return Factory_1.default.createOperatorExpression(exp.operator, exp.args.map(translateExpression)); | ||
return factory.createOperatorExpression(exp.operator, exp.args.map(translateExpression)); | ||
} | ||
@@ -143,3 +166,3 @@ throw new Error('Unknown expression: ' + JSON.stringify(exp)); | ||
if (patterns.length > 0) | ||
joins.push(Factory_1.default.createBgp(patterns)); | ||
joins.push(factory.createBgp(patterns)); | ||
patterns = []; | ||
@@ -156,18 +179,18 @@ joins.push(p); | ||
if (patterns.length > 0) | ||
joins.push(Factory_1.default.createBgp(patterns)); | ||
joins.push(factory.createBgp(patterns)); | ||
if (joins.length === 1) | ||
return joins[0]; | ||
return joins.reduce((acc, item) => Factory_1.default.createJoin(acc, item)); | ||
return joins.reduce((acc, item) => factory.createJoin(acc, item)); | ||
} | ||
function translatePath(triple) { | ||
let sub = translateTerm(triple.subject); | ||
let sub = factory.createTerm(triple.subject); | ||
let pred = translatePathPredicate(triple.predicate); | ||
let obj = translateTerm(triple.object); | ||
let obj = factory.createTerm(triple.object); | ||
return simplifyPath(sub, pred, obj); | ||
} | ||
function translatePathPredicate(predicate) { | ||
if (_.isString(predicate)) | ||
return Factory_1.default.createLink(translateTerm(predicate)); | ||
if (isString(predicate)) | ||
return factory.createLink(factory.createTerm(predicate)); | ||
if (predicate.pathType === '^') | ||
return Factory_1.default.createInv(translatePathPredicate(predicate.items[0])); | ||
return factory.createInv(translatePathPredicate(predicate.items[0])); | ||
if (predicate.pathType === '!') { | ||
@@ -178,3 +201,3 @@ let normals = []; | ||
for (let item of items) { | ||
if (_.isString(item)) | ||
if (isString(item)) | ||
normals.push(item); | ||
@@ -187,4 +210,4 @@ else if (item.pathType === '^') | ||
// NPS elements do not have the LINK function | ||
let normalElement = Factory_1.default.createNps(normals.map(translateTerm)); | ||
let invertedElement = Factory_1.default.createInv(Factory_1.default.createNps(inverted.map(translateTerm))); | ||
let normalElement = factory.createNps(normals.map(factory.createTerm.bind(factory))); | ||
let invertedElement = factory.createInv(factory.createNps(inverted.map(factory.createTerm.bind(factory)))); | ||
if (inverted.length === 0) | ||
@@ -194,14 +217,14 @@ return normalElement; | ||
return invertedElement; | ||
return Factory_1.default.createAlt(normalElement, invertedElement); | ||
return factory.createAlt(normalElement, invertedElement); | ||
} | ||
if (predicate.pathType === '/') | ||
return predicate.items.map(translatePathPredicate).reduce((acc, p) => Factory_1.default.createSeq(acc, p)); | ||
return predicate.items.map(translatePathPredicate).reduce((acc, p) => factory.createSeq(acc, p)); | ||
if (predicate.pathType === '|') | ||
return predicate.items.map(translatePathPredicate).reduce((acc, p) => Factory_1.default.createAlt(acc, p)); | ||
return predicate.items.map(translatePathPredicate).reduce((acc, p) => factory.createAlt(acc, p)); | ||
if (predicate.pathType === '*') | ||
return Factory_1.default.createZeroOrMorePath(translatePathPredicate(predicate.items[0])); | ||
return factory.createZeroOrMorePath(translatePathPredicate(predicate.items[0])); | ||
if (predicate.pathType === '+') | ||
return Factory_1.default.createOneOrMorePath(translatePathPredicate(predicate.items[0])); | ||
return factory.createOneOrMorePath(translatePathPredicate(predicate.items[0])); | ||
if (predicate.pathType === '?') | ||
return Factory_1.default.createZeroOrOnePath(translatePathPredicate(predicate.items[0])); | ||
return factory.createZeroOrOnePath(translatePathPredicate(predicate.items[0])); | ||
throw new Error('Unable to translate path expression ' + predicate); | ||
@@ -211,3 +234,3 @@ } | ||
if (predicate.type === types.LINK) | ||
return [Factory_1.default.createPattern(subject, predicate.iri, object, defaultGraph)]; | ||
return [factory.createPattern(subject, predicate.iri, object)]; | ||
if (predicate.type === types.INV) | ||
@@ -221,3 +244,3 @@ return simplifyPath(object, predicate.path, subject); | ||
} | ||
return [Factory_1.default.createPath(subject, predicate, object, defaultGraph)]; | ||
return [factory.createPath(subject, predicate, object)]; | ||
} | ||
@@ -229,33 +252,9 @@ function generateFreshVar() { | ||
variables.add(v); | ||
return translateTerm(v); | ||
return factory.createTerm(v); | ||
} | ||
const defaultGraph = { termType: 'DefaultGraph', value: '' }; | ||
function translateTriple(triple) { | ||
return Factory_1.default.createPattern(translateTerm(triple.subject), translateTerm(triple.predicate), translateTerm(triple.object), defaultGraph); | ||
return factory.createPattern(factory.createTerm(triple.subject), factory.createTerm(triple.predicate), factory.createTerm(triple.object)); | ||
} | ||
const stringType = translateTerm('http://www.w3.org/2001/XMLSchema#string'); | ||
const langStringType = translateTerm('http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); | ||
function translateTerm(str) { | ||
if (str[0] === '?') | ||
return { termType: 'Variable', value: str.substring(1) }; | ||
if (_.startsWith(str, '_:')) | ||
return { termType: 'BlankNode', value: str.substring(2) }; | ||
if (n3_1.Util.isLiteral(str)) { | ||
let literal = { termType: 'Literal', value: n3_1.Util.getLiteralValue(str), language: '', datatype: stringType }; | ||
let lang = n3_1.Util.getLiteralLanguage(str); | ||
if (lang && lang.length > 0) { | ||
literal.language = lang; | ||
literal.datatype = langStringType; | ||
} | ||
else { | ||
let type = n3_1.Util.getLiteralType(str); | ||
if (type && type.length > 0) | ||
literal.datatype = translateTerm(type); | ||
} | ||
return literal; | ||
} | ||
return { termType: 'NamedNode', value: str }; | ||
} | ||
function translateGraph(graph) { | ||
let name = translateTerm(graph.name); | ||
let name = factory.createTerm(graph.name); | ||
graph.type = 'group'; | ||
@@ -266,3 +265,3 @@ let result = translateGroupGraphPattern(graph); | ||
else | ||
result = Factory_1.default.createGraph(result, name); | ||
result = factory.createGraph(result, name); | ||
return result; | ||
@@ -281,3 +280,3 @@ } | ||
for (let key of Object.keys(thingy)) { | ||
if (_.isArray(thingy[key])) | ||
if (Array.isArray(thingy[key])) | ||
thingy[key] = thingy[key].map((x) => recurseGraph(x, graph)); | ||
@@ -296,6 +295,6 @@ else if (typeVals.indexOf(thingy[key].type) >= 0) | ||
let filter = A; | ||
G = Factory_1.default.createLeftJoin(G, filter.input, filter.expression); | ||
G = factory.createLeftJoin(G, filter.input, filter.expression); | ||
} | ||
else | ||
G = Factory_1.default.createLeftJoin(G, A); | ||
G = factory.createLeftJoin(G, A); | ||
} | ||
@@ -305,6 +304,6 @@ else if (E.type === 'minus') { | ||
let A = translateGroupGraphPattern({ type: 'group', patterns: E.patterns }); | ||
G = Factory_1.default.createMinus(G, A); | ||
G = factory.createMinus(G, A); | ||
} | ||
else if (E.type === 'bind') | ||
G = Factory_1.default.createExtend(G, translateTerm(E.variable), translateExpression(E.expression)); | ||
G = factory.createExtend(G, factory.createTerm(E.variable), translateExpression(E.expression)); | ||
else { | ||
@@ -317,3 +316,3 @@ // 18.2.2.8 (simplification) | ||
else | ||
G = Factory_1.default.createJoin(G, translateGroupGraphPattern(E)); | ||
G = factory.createJoin(G, translateGroupGraphPattern(E)); | ||
} | ||
@@ -323,12 +322,12 @@ return G; | ||
function translateInlineData(values) { | ||
let variables = (values.values.length === 0 ? [] : Object.keys(values.values[0])).map(translateTerm); | ||
let variables = (values.values.length === 0 ? [] : Object.keys(values.values[0])).map(factory.createTerm.bind(factory)); | ||
let bindings = values.values.map((binding) => { | ||
let keys = Object.keys(binding); | ||
keys = keys.filter(k => binding[k] !== undefined); | ||
let map = new Map(); | ||
let map = {}; | ||
for (let key of keys) | ||
map.set(translateTerm(key), translateTerm(binding[key])); | ||
map[key] = factory.createTerm(binding[key]); | ||
return map; | ||
}); | ||
return Factory_1.default.createValues(variables, bindings); | ||
return factory.createValues(variables, bindings); | ||
} | ||
@@ -345,11 +344,15 @@ // --------------------------------------- AGGREGATES | ||
if (query.group || Object.keys(A).length > 0) { | ||
let aggregates = Object.keys(A).map(v => translateBoundAggregate(A[v], translateTerm(v))); | ||
let exps = []; | ||
let aggregates = Object.keys(A).map(v => translateBoundAggregate(A[v], factory.createTerm(v))); | ||
let vars = []; | ||
if (query.group) { | ||
for (let entry of query.group) | ||
if (entry.variable) | ||
E.push(entry); | ||
exps = query.group.map((e) => e.expression).map(translateExpression); | ||
for (let e of query.group) { | ||
if (e.variable) { | ||
res = factory.createExtend(res, factory.createTerm(e.variable), translateExpression(e.expression)); | ||
vars.push(factory.createTerm(e.variable)); | ||
} | ||
else | ||
vars.push(factory.createTerm(e.expression)); // this will always be a var, otherwise sparql would be invalid | ||
} | ||
} | ||
res = Factory_1.default.createGroup(res, exps, aggregates); | ||
res = factory.createGroup(res, vars, aggregates); | ||
} | ||
@@ -359,6 +362,6 @@ // 18.2.4.2 | ||
for (let filter of query.having) | ||
res = Factory_1.default.createFilter(res, translateExpression(filter)); | ||
res = factory.createFilter(res, translateExpression(filter)); | ||
// 18.2.4.3 | ||
if (query.values) | ||
res = Factory_1.default.createJoin(res, translateInlineData(query)); | ||
res = factory.createJoin(res, translateInlineData(query)); | ||
// 18.2.4.4 | ||
@@ -372,5 +375,5 @@ let PV = new Set(); | ||
if (isVariable(v)) | ||
PV.add(translateTerm(v)); | ||
PV.add(factory.createTerm(v)); | ||
else if (v.variable) { | ||
PV.add(translateTerm(v.variable)); | ||
PV.add(factory.createTerm(v.variable)); | ||
E.push(v); | ||
@@ -382,3 +385,3 @@ } | ||
for (let v of E) | ||
res = Factory_1.default.createExtend(res, translateTerm(v.variable), translateExpression(v.expression)); | ||
res = factory.createExtend(res, factory.createTerm(v.variable), translateExpression(v.expression)); | ||
// 18.2.5 | ||
@@ -388,23 +391,25 @@ // not using toList and toMultiset | ||
if (query.order) | ||
res = Factory_1.default.createOrderBy(res, query.order.map((exp) => { | ||
res = factory.createOrderBy(res, query.order.map((exp) => { | ||
let result = translateExpression(exp.expression); | ||
if (exp.descending) | ||
result = Factory_1.default.createOperatorExpression(types.DESC, [result]); // TODO: should this really be an epxression? | ||
result = factory.createOperatorExpression(types.DESC, [result]); // TODO: should this really be an epxression? | ||
return result; | ||
})); | ||
// 18.2.5.2 | ||
res = Factory_1.default.createProject(res, Array.from(PV)); | ||
// construct does not need a project (select, ask and describe do) | ||
if (query.queryType !== 'CONSTRUCT') | ||
res = factory.createProject(res, Array.from(PV)); | ||
// 18.2.5.3 | ||
if (query.distinct) | ||
res = Factory_1.default.createDistinct(res); | ||
res = factory.createDistinct(res); | ||
// 18.2.5.4 | ||
if (query.reduced) | ||
res = Factory_1.default.createReduced(res); | ||
res = factory.createReduced(res); | ||
// NEW: support for construct queries | ||
// limits are also applied to construct results, which is why those come last, although results should be the same | ||
if (query.queryType === 'CONSTRUCT') | ||
res = Factory_1.default.createConstruct(res, query.template.map(translateTriple)); | ||
res = factory.createConstruct(res, query.template.map(translateTriple)); | ||
// 18.2.5.5 | ||
if (query.offset || query.limit) { | ||
res = Factory_1.default.createSlice(res, query.offset || 0); | ||
res = factory.createSlice(res, query.offset || 0); | ||
if (query.limit) | ||
@@ -423,3 +428,3 @@ res.length = query.limit; | ||
for (let key of Object.keys(aggregates)) { | ||
if (_.isEqual(aggregates[key], thingy)) { | ||
if (isEqual(aggregates[key], thingy)) { | ||
v = key; | ||
@@ -441,3 +446,3 @@ found = true; | ||
mapAggregates(thingy.args, aggregates); | ||
else if (_.isArray(thingy)) | ||
else if (Array.isArray(thingy)) | ||
thingy.forEach((subthingy, idx) => thingy[idx] = mapAggregates(subthingy, aggregates)); | ||
@@ -449,7 +454,6 @@ return thingy; | ||
throw new Error('Unexpected input: ' + JSON.stringify(thingy)); | ||
let A = Factory_1.default.createBoundAggregate(v, thingy.aggregation, translateExpression(thingy.expression)); | ||
if (thingy.separator) | ||
A.separator = thingy.separator; | ||
let A = translateExpression(thingy); | ||
A.variable = v; | ||
return A; | ||
} | ||
//# sourceMappingURL=sparqlAlgebra.js.map |
{ | ||
"name": "sparqlalgebrajs", | ||
"version": "0.5.3", | ||
"version": "0.6.0", | ||
"description": "Convert SPARQL to SPARL algebra", | ||
@@ -13,3 +13,3 @@ "author": "Joachim Van Herwegen", | ||
"dependencies": { | ||
"lodash": "^4.13.1", | ||
"lodash.isequal": "^4.5.0", | ||
"minimist": "^1.2.0", | ||
@@ -21,8 +21,12 @@ "n3": "^0.11.2", | ||
"@types/lodash": "^4.14.77", | ||
"@types/lodash.isequal": "^4.5.2", | ||
"@types/minimist": "^1.2.0", | ||
"@types/n3": "0.0.3", | ||
"@types/node": "^8.0.50", | ||
"@types/rdf-data-model": "^1.0.1", | ||
"@types/rdf-js": "^1.0.1", | ||
"lodash": "^4.13.1", | ||
"mocha": "^3.5.3", | ||
"pre-commit": "^1.2.2", | ||
"rdf-data-model": "^1.0.0", | ||
"typescript": "^2.5.3" | ||
@@ -29,0 +33,0 @@ }, |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
38679
866
12
+ Addedlodash.isequal@^4.5.0
+ Addedlodash.isequal@4.5.0(transitive)
- Removedlodash@^4.13.1
- Removedlodash@4.17.21(transitive)