@comunica/bus-query-operation 1.21.1 → 2.0.1-alpha.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +22 -0
- package/README.md +2 -2
- package/components/ActorQueryOperation.jsonld +213 -0
- package/components/ActorQueryOperationTyped.jsonld +218 -0
- package/components/ActorQueryOperationTypedMediated.jsonld +244 -0
- package/components/components.jsonld +7 -5
- package/components/context.jsonld +125 -8
- package/lib/ActorQueryOperation.d.ts +42 -120
- package/lib/ActorQueryOperation.js +44 -89
- package/lib/ActorQueryOperationTyped.d.ts +7 -12
- package/lib/ActorQueryOperationTyped.js +13 -11
- package/lib/ActorQueryOperationTypedMediated.d.ts +4 -5
- package/lib/Bindings.d.ts +13 -26
- package/lib/Bindings.js +61 -60
- package/lib/index.d.ts +4 -0
- package/{index.js → lib/index.js} +4 -4
- package/package.json +18 -39
- package/components/Actor/QueryOperation.jsonld +0 -31
- package/components/Actor/QueryOperationTypedMediated.jsonld +0 -34
- package/components/Bus/QueryOperation.jsonld +0 -8
- package/index.d.ts +0 -4
|
@@ -1,61 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ActorQueryOperation = void 0;
|
|
4
4
|
const context_entries_1 = require("@comunica/context-entries");
|
|
5
5
|
const core_1 = require("@comunica/core");
|
|
6
6
|
const data_factory_1 = require("@comunica/data-factory");
|
|
7
7
|
const Bindings_1 = require("./Bindings");
|
|
8
|
-
/**
|
|
9
|
-
* @type {string} Context entry for current metadata.
|
|
10
|
-
* I.e., the metadata that was used to determine the next BGP operation.
|
|
11
|
-
* @value {any} A metadata hash.
|
|
12
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
13
|
-
*/
|
|
14
|
-
exports.KEY_CONTEXT_BGP_CURRENTMETADATA = context_entries_1.KeysQueryOperation.bgpCurrentMetadata;
|
|
15
|
-
/**
|
|
16
|
-
* @type {string} Context entry for an array of parent metadata.
|
|
17
|
-
* I.e., an array of the metadata that was present before materializing the current BGP operations.
|
|
18
|
-
* This can be passed in 'bgp' actions.
|
|
19
|
-
* The array entries should correspond to the pattern entries in the BGP.
|
|
20
|
-
* @value {any} An array of metadata hashes.
|
|
21
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
22
|
-
*/
|
|
23
|
-
exports.KEY_CONTEXT_BGP_PARENTMETADATA = context_entries_1.KeysQueryOperation.bgpParentMetadata;
|
|
24
|
-
/**
|
|
25
|
-
* @type {string} Context entry for indicating which patterns were bound from variables.
|
|
26
|
-
* I.e., an array of the same length as the value of KeysQueryOperation.patternParentMetadata,
|
|
27
|
-
* where each array value corresponds to the pattern bindings for the corresponding pattern.
|
|
28
|
-
* @value {any} An array of {@link PatternBindings}.
|
|
29
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
30
|
-
*/
|
|
31
|
-
exports.KEY_CONTEXT_BGP_PATTERNBINDINGS = context_entries_1.KeysQueryOperation.bgpPatternBindings;
|
|
32
|
-
/**
|
|
33
|
-
* @type {string} Context entry for parent metadata.
|
|
34
|
-
* I.e., the metadata that was present before materializing the current operation.
|
|
35
|
-
* This can be passed in 'pattern' actions.
|
|
36
|
-
* @value {any} A metadata hash.
|
|
37
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
38
|
-
*/
|
|
39
|
-
exports.KEY_CONTEXT_PATTERN_PARENTMETADATA = context_entries_1.KeysQueryOperation.patternParentMetadata;
|
|
40
|
-
/**
|
|
41
|
-
* @type {string} Context entry for query's base IRI.
|
|
42
|
-
* @value {any} A string.
|
|
43
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
44
|
-
*/
|
|
45
|
-
exports.KEY_CONTEXT_BASEIRI = context_entries_1.KeysInitSparql.baseIRI;
|
|
46
|
-
/**
|
|
47
|
-
* @type {string} A timestamp representing the current time.
|
|
48
|
-
* This is required for certain SPARQL operations such as NOW().
|
|
49
|
-
* @value {any} a date.
|
|
50
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
51
|
-
*/
|
|
52
|
-
exports.KEY_CONTEXT_QUERY_TIMESTAMP = context_entries_1.KeysInitSparql.queryTimestamp;
|
|
53
|
-
/**
|
|
54
|
-
* @type {string} Context entry for indicating that only read operations are allowed, defaults to false.
|
|
55
|
-
* @value {any} A boolean.
|
|
56
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
57
|
-
*/
|
|
58
|
-
exports.KEY_CONTEXT_READONLY = context_entries_1.KeysQueryOperation.readOnly;
|
|
59
8
|
/**
|
|
60
9
|
* A counter that keeps track blank node generated through BNODE() SPARQL
|
|
61
10
|
* expressions.
|
|
@@ -72,17 +21,20 @@ let bnodeCounter = 0;
|
|
|
72
21
|
* * Output: IActorQueryOperationOutput: A bindings stream.
|
|
73
22
|
*
|
|
74
23
|
* @see IActionQueryOperation
|
|
75
|
-
* @see
|
|
24
|
+
* @see IQueryOperationResult
|
|
76
25
|
*/
|
|
77
26
|
class ActorQueryOperation extends core_1.Actor {
|
|
27
|
+
/**
|
|
28
|
+
* @param args - @defaultNested {<default_bus> a <cc:components/Bus.jsonld#Bus>} bus
|
|
29
|
+
*/
|
|
78
30
|
constructor(args) {
|
|
79
31
|
super(args);
|
|
80
32
|
}
|
|
81
33
|
/**
|
|
82
34
|
* Safely cast a query operation output to a bindings output.
|
|
83
35
|
* This will throw a runtime error if the output is of the incorrect type.
|
|
84
|
-
* @param {
|
|
85
|
-
* @return {
|
|
36
|
+
* @param {IQueryOperationResult} output A query operation output.
|
|
37
|
+
* @return {IQueryOperationResultBindings} A bindings query operation output.
|
|
86
38
|
*/
|
|
87
39
|
static getSafeBindings(output) {
|
|
88
40
|
ActorQueryOperation.validateQueryOutput(output, 'bindings');
|
|
@@ -91,8 +43,8 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
91
43
|
/**
|
|
92
44
|
* Safely cast a query operation output to a quads output.
|
|
93
45
|
* This will throw a runtime error if the output is of the incorrect type.
|
|
94
|
-
* @param {
|
|
95
|
-
* @return {
|
|
46
|
+
* @param {IQueryOperationResult} output A query operation output.
|
|
47
|
+
* @return {IQueryOperationResultQuads} A quads query operation output.
|
|
96
48
|
*/
|
|
97
49
|
static getSafeQuads(output) {
|
|
98
50
|
ActorQueryOperation.validateQueryOutput(output, 'quads');
|
|
@@ -101,36 +53,36 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
101
53
|
/**
|
|
102
54
|
* Safely cast a query operation output to a boolean output.
|
|
103
55
|
* This will throw a runtime error if the output is of the incorrect type.
|
|
104
|
-
* @param {
|
|
105
|
-
* @return {
|
|
56
|
+
* @param {IQueryOperationResult} output A query operation output.
|
|
57
|
+
* @return {IQueryOperationResultBoolean} A boolean query operation output.
|
|
106
58
|
*/
|
|
107
59
|
static getSafeBoolean(output) {
|
|
108
60
|
ActorQueryOperation.validateQueryOutput(output, 'boolean');
|
|
109
61
|
return output;
|
|
110
62
|
}
|
|
111
63
|
/**
|
|
112
|
-
* Safely cast a query operation output to
|
|
64
|
+
* Safely cast a query operation output to a void output.
|
|
113
65
|
* This will throw a runtime error if the output is of the incorrect type.
|
|
114
|
-
* @param {
|
|
115
|
-
* @return {
|
|
66
|
+
* @param {IQueryOperationResult} output A query operation output.
|
|
67
|
+
* @return {IQueryOperationResultVoid} A void query operation output.
|
|
116
68
|
*/
|
|
117
|
-
static
|
|
118
|
-
ActorQueryOperation.validateQueryOutput(output, '
|
|
69
|
+
static getSafeVoid(output) {
|
|
70
|
+
ActorQueryOperation.validateQueryOutput(output, 'void');
|
|
119
71
|
return output;
|
|
120
72
|
}
|
|
121
73
|
/**
|
|
122
74
|
* Convert a metadata callback to a lazy callback where the response value is cached.
|
|
123
|
-
* @param {() => Promise<
|
|
75
|
+
* @param {() => Promise<IMetadata>} metadata A metadata callback
|
|
124
76
|
* @return {() => Promise<{[p: string]: any}>} The callback where the response will be cached.
|
|
125
77
|
*/
|
|
126
78
|
static cachifyMetadata(metadata) {
|
|
127
79
|
let lastReturn;
|
|
128
80
|
// eslint-disable-next-line no-return-assign,@typescript-eslint/no-misused-promises
|
|
129
|
-
return (
|
|
81
|
+
return () => (lastReturn || (lastReturn = metadata()));
|
|
130
82
|
}
|
|
131
83
|
/**
|
|
132
84
|
* Throw an error if the output type does not match the expected type.
|
|
133
|
-
* @param {
|
|
85
|
+
* @param {IQueryOperationResult} output A query operation output.
|
|
134
86
|
* @param {string} expectedType The expected output type.
|
|
135
87
|
*/
|
|
136
88
|
static validateQueryOutput(output, expectedType) {
|
|
@@ -139,12 +91,21 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
139
91
|
}
|
|
140
92
|
}
|
|
141
93
|
static getBaseExpressionContext(context) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
94
|
+
const now = context.get(context_entries_1.KeysInitQuery.queryTimestamp);
|
|
95
|
+
const baseIRI = context.get(context_entries_1.KeysInitQuery.baseIRI);
|
|
96
|
+
// Handle two variants of providing extension functions
|
|
97
|
+
if (context.has(context_entries_1.KeysInitQuery.extensionFunctionCreator) && context.has(context_entries_1.KeysInitQuery.extensionFunctions)) {
|
|
98
|
+
throw new Error('Illegal simultaneous usage of extensionFunctionCreator and extensionFunctions in context');
|
|
99
|
+
}
|
|
100
|
+
let extensionFunctionCreator = context
|
|
101
|
+
.get(context_entries_1.KeysInitQuery.extensionFunctionCreator);
|
|
102
|
+
// Convert dictionary-based variant to callback
|
|
103
|
+
const extensionFunctions = context
|
|
104
|
+
.get(context_entries_1.KeysInitQuery.extensionFunctions);
|
|
105
|
+
if (extensionFunctions) {
|
|
106
|
+
extensionFunctionCreator = functionNamedNode => extensionFunctions[functionNamedNode.value];
|
|
146
107
|
}
|
|
147
|
-
return {};
|
|
108
|
+
return { now, baseIRI, extensionFunctionCreator };
|
|
148
109
|
}
|
|
149
110
|
/**
|
|
150
111
|
* Create an options object that can be used to construct a sparqlee synchronous evaluator.
|
|
@@ -153,7 +114,10 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
153
114
|
* If defined, the existence resolver will be defined as `exists`.
|
|
154
115
|
*/
|
|
155
116
|
static getExpressionContext(context, mediatorQueryOperation) {
|
|
156
|
-
return
|
|
117
|
+
return {
|
|
118
|
+
...this.getBaseExpressionContext(context),
|
|
119
|
+
bnode: (input) => new data_factory_1.BlankNodeBindingsScoped(input || `BNODE_${bnodeCounter++}`),
|
|
120
|
+
};
|
|
157
121
|
}
|
|
158
122
|
/**
|
|
159
123
|
* Create an options object that can be used to construct a sparqlee asynchronous evaluator.
|
|
@@ -162,8 +126,11 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
162
126
|
* If defined, the existence resolver will be defined as `exists`.
|
|
163
127
|
*/
|
|
164
128
|
static getAsyncExpressionContext(context, mediatorQueryOperation) {
|
|
165
|
-
const expressionContext =
|
|
166
|
-
|
|
129
|
+
const expressionContext = {
|
|
130
|
+
...this.getBaseExpressionContext(context),
|
|
131
|
+
bnode: (input) => Promise.resolve(new data_factory_1.BlankNodeBindingsScoped(input || `BNODE_${bnodeCounter++}`)),
|
|
132
|
+
};
|
|
133
|
+
if (mediatorQueryOperation) {
|
|
167
134
|
expressionContext.exists = ActorQueryOperation.createExistenceResolver(context, mediatorQueryOperation);
|
|
168
135
|
}
|
|
169
136
|
return expressionContext;
|
|
@@ -175,7 +142,7 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
175
142
|
*/
|
|
176
143
|
static createExistenceResolver(context, mediatorQueryOperation) {
|
|
177
144
|
return async (expr, bindings) => {
|
|
178
|
-
const operation = Bindings_1.materializeOperation(expr.input, bindings);
|
|
145
|
+
const operation = (0, Bindings_1.materializeOperation)(expr.input, bindings);
|
|
179
146
|
const outputRaw = await mediatorQueryOperation.mediate({ operation, context });
|
|
180
147
|
const output = ActorQueryOperation.getSafeBindings(outputRaw);
|
|
181
148
|
return new Promise((resolve, reject) => {
|
|
@@ -196,22 +163,10 @@ class ActorQueryOperation extends core_1.Actor {
|
|
|
196
163
|
* @param context An action context.
|
|
197
164
|
*/
|
|
198
165
|
static throwOnReadOnly(context) {
|
|
199
|
-
if (context
|
|
166
|
+
if (context.get(context_entries_1.KeysQueryOperation.readOnly)) {
|
|
200
167
|
throw new Error(`Attempted a write operation in read-only mode`);
|
|
201
168
|
}
|
|
202
169
|
}
|
|
203
170
|
}
|
|
204
171
|
exports.ActorQueryOperation = ActorQueryOperation;
|
|
205
|
-
/**
|
|
206
|
-
* Helper function to get the metadata of an action output.
|
|
207
|
-
* @param actionOutput An action output, with an optional metadata function.
|
|
208
|
-
* @return The metadata.
|
|
209
|
-
*/
|
|
210
|
-
function getMetadata(actionOutput) {
|
|
211
|
-
if (!actionOutput.metadata) {
|
|
212
|
-
return Promise.resolve({});
|
|
213
|
-
}
|
|
214
|
-
return actionOutput.metadata();
|
|
215
|
-
}
|
|
216
|
-
exports.getMetadata = getMetadata;
|
|
217
172
|
//# sourceMappingURL=ActorQueryOperation.js.map
|
|
@@ -1,21 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type {
|
|
3
|
-
import type { IActionQueryOperation, IActorQueryOperationOutput } from '@comunica/types';
|
|
1
|
+
import type { IActorTest } from '@comunica/core';
|
|
2
|
+
import type { IQueryOperationResult, IActionContext } from '@comunica/types';
|
|
4
3
|
import type { Algebra } from 'sparqlalgebrajs';
|
|
4
|
+
import type { IActionQueryOperation, IActorQueryOperationArgs } from './ActorQueryOperation';
|
|
5
5
|
import { ActorQueryOperation } from './ActorQueryOperation';
|
|
6
|
-
/**
|
|
7
|
-
* @type {string} Context entry for the current query operation.
|
|
8
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
9
|
-
*/
|
|
10
|
-
export declare const KEY_CONTEXT_QUERYOPERATION = KeysQueryOperation.operation;
|
|
11
6
|
/**
|
|
12
7
|
* A base implementation for query operation actors for a specific operation type.
|
|
13
8
|
*/
|
|
14
9
|
export declare abstract class ActorQueryOperationTyped<O extends Algebra.Operation> extends ActorQueryOperation {
|
|
15
10
|
readonly operationName: string;
|
|
16
|
-
protected constructor(args:
|
|
11
|
+
protected constructor(args: IActorQueryOperationArgs, operationName: string);
|
|
17
12
|
test(action: IActionQueryOperation): Promise<IActorTest>;
|
|
18
|
-
run(action: IActionQueryOperation): Promise<
|
|
19
|
-
protected abstract testOperation(operation: O, context:
|
|
20
|
-
protected abstract runOperation(operation: O, context:
|
|
13
|
+
run(action: IActionQueryOperation): Promise<IQueryOperationResult>;
|
|
14
|
+
protected abstract testOperation(operation: O, context: IActionContext): Promise<IActorTest>;
|
|
15
|
+
protected abstract runOperation(operation: O, context: IActionContext): Promise<IQueryOperationResult>;
|
|
21
16
|
}
|
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ActorQueryOperationTyped =
|
|
3
|
+
exports.ActorQueryOperationTyped = void 0;
|
|
4
4
|
const context_entries_1 = require("@comunica/context-entries");
|
|
5
5
|
const ActorQueryOperation_1 = require("./ActorQueryOperation");
|
|
6
|
-
/**
|
|
7
|
-
* @type {string} Context entry for the current query operation.
|
|
8
|
-
* @deprecated Import this constant from @comunica/context-entries.
|
|
9
|
-
*/
|
|
10
|
-
exports.KEY_CONTEXT_QUERYOPERATION = context_entries_1.KeysQueryOperation.operation;
|
|
11
6
|
/**
|
|
12
7
|
* A base implementation for query operation actors for a specific operation type.
|
|
13
8
|
*/
|
|
14
9
|
class ActorQueryOperationTyped extends ActorQueryOperation_1.ActorQueryOperation {
|
|
15
10
|
constructor(args, operationName) {
|
|
16
|
-
super(
|
|
11
|
+
super({ ...args, operationName });
|
|
17
12
|
if (!this.operationName) {
|
|
18
13
|
throw new Error('A valid "operationName" argument must be provided.');
|
|
19
14
|
}
|
|
@@ -29,12 +24,19 @@ class ActorQueryOperationTyped extends ActorQueryOperation_1.ActorQueryOperation
|
|
|
29
24
|
return this.testOperation(operation, action.context);
|
|
30
25
|
}
|
|
31
26
|
async run(action) {
|
|
27
|
+
// Log to physical plan
|
|
28
|
+
const physicalQueryPlanLogger = action.context
|
|
29
|
+
.get(context_entries_1.KeysInitQuery.physicalQueryPlanLogger);
|
|
30
|
+
if (physicalQueryPlanLogger) {
|
|
31
|
+
physicalQueryPlanLogger.logOperation(action.operation.type, undefined, action.operation, action.context.get(context_entries_1.KeysInitQuery.physicalQueryPlanNode), this.name, {});
|
|
32
|
+
action.context = action.context.set(context_entries_1.KeysInitQuery.physicalQueryPlanNode, action.operation);
|
|
33
|
+
}
|
|
32
34
|
const operation = action.operation;
|
|
33
|
-
const subContext = action.context
|
|
35
|
+
const subContext = action.context.set(context_entries_1.KeysQueryOperation.operation, operation);
|
|
34
36
|
const output = await this.runOperation(operation, subContext);
|
|
35
|
-
if (output
|
|
36
|
-
output.metadata =
|
|
37
|
-
|
|
37
|
+
if ('metadata' in output) {
|
|
38
|
+
output.metadata = ActorQueryOperation_1.ActorQueryOperation
|
|
39
|
+
.cachifyMetadata(output.metadata);
|
|
38
40
|
}
|
|
39
41
|
return output;
|
|
40
42
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import type { Actor, IActorArgs, IActorTest, Mediator } from '@comunica/core';
|
|
2
|
-
import type { IActionQueryOperation, IActorQueryOperationOutput } from '@comunica/types';
|
|
3
1
|
import type { Algebra } from 'sparqlalgebrajs';
|
|
2
|
+
import type { IActorQueryOperationArgs, MediatorQueryOperation } from './ActorQueryOperation';
|
|
4
3
|
import { ActorQueryOperationTyped } from './ActorQueryOperationTyped';
|
|
5
4
|
/**
|
|
6
5
|
* A base implementation for query operation actors for a specific operation type that have a query operation mediator.
|
|
7
6
|
*/
|
|
8
7
|
export declare abstract class ActorQueryOperationTypedMediated<O extends Algebra.Operation> extends ActorQueryOperationTyped<O> implements IActorQueryOperationTypedMediatedArgs {
|
|
9
|
-
readonly mediatorQueryOperation:
|
|
8
|
+
readonly mediatorQueryOperation: MediatorQueryOperation;
|
|
10
9
|
constructor(args: IActorQueryOperationTypedMediatedArgs, operationName: string);
|
|
11
10
|
}
|
|
12
|
-
export interface IActorQueryOperationTypedMediatedArgs extends
|
|
13
|
-
mediatorQueryOperation:
|
|
11
|
+
export interface IActorQueryOperationTypedMediatedArgs extends IActorQueryOperationArgs {
|
|
12
|
+
mediatorQueryOperation: MediatorQueryOperation;
|
|
14
13
|
}
|
package/lib/Bindings.d.ts
CHANGED
|
@@ -1,28 +1,6 @@
|
|
|
1
|
-
import type { Bindings
|
|
2
|
-
import type * as RDF from '
|
|
1
|
+
import type { Bindings } from '@comunica/types';
|
|
2
|
+
import type * as RDF from '@rdfjs/types';
|
|
3
3
|
import type { Algebra } from 'sparqlalgebrajs';
|
|
4
|
-
export declare type Bindings = _Bindings;
|
|
5
|
-
export type { BindingsStream };
|
|
6
|
-
/**
|
|
7
|
-
* A convenience constructor for bindings based on a given hash.
|
|
8
|
-
* @param {{[p: string]: RDF.Term}} hash A hash that maps variable names to terms.
|
|
9
|
-
* @return {Bindings} The immutable bindings from the hash.
|
|
10
|
-
* @constructor
|
|
11
|
-
*/
|
|
12
|
-
export declare function Bindings(hash: Record<string, RDF.Term>): Bindings;
|
|
13
|
-
/**
|
|
14
|
-
* Check if the given object is a bindings object.
|
|
15
|
-
* @param maybeBindings Any object.
|
|
16
|
-
* @return {boolean} If the object is a bindings object.
|
|
17
|
-
*/
|
|
18
|
-
export declare function isBindings(maybeBindings: any): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Convert the given object to a bindings object if it is not a bindings object yet.
|
|
21
|
-
* If it already is a bindings object, return the object as-is.
|
|
22
|
-
* @param maybeBindings Any object.
|
|
23
|
-
* @return {Bindings} A bindings object.
|
|
24
|
-
*/
|
|
25
|
-
export declare function ensureBindings(maybeBindings: any): Bindings;
|
|
26
4
|
/**
|
|
27
5
|
* Materialize a term with the given binding.
|
|
28
6
|
*
|
|
@@ -42,7 +20,16 @@ export declare function materializeTerm(term: RDF.Term, bindings: Bindings): RDF
|
|
|
42
20
|
* by the terms bound to the variables in the given bindings.
|
|
43
21
|
* @param {Operation} operation SPARQL algebra operation.
|
|
44
22
|
* @param {Bindings} bindings A bindings object.
|
|
45
|
-
* @param
|
|
23
|
+
* @param options Options for materializations.
|
|
46
24
|
* @return Algebra.Operation A new operation materialized with the given bindings.
|
|
47
25
|
*/
|
|
48
|
-
export declare function materializeOperation(operation: Algebra.Operation, bindings: Bindings,
|
|
26
|
+
export declare function materializeOperation(operation: Algebra.Operation, bindings: Bindings, options?: {
|
|
27
|
+
/**
|
|
28
|
+
* If target variable bindings (such as on SELECT or BIND) should not be allowed.
|
|
29
|
+
*/
|
|
30
|
+
strictTargetVariables?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* If filter expressions should be materialized
|
|
33
|
+
*/
|
|
34
|
+
bindFilter?: boolean;
|
|
35
|
+
}): Algebra.Operation;
|
package/lib/Bindings.js
CHANGED
|
@@ -1,39 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.materializeOperation = exports.materializeTerm =
|
|
4
|
-
const
|
|
3
|
+
exports.materializeOperation = exports.materializeTerm = void 0;
|
|
4
|
+
const bindings_factory_1 = require("@comunica/bindings-factory");
|
|
5
5
|
const rdf_string_1 = require("rdf-string");
|
|
6
6
|
const sparqlalgebrajs_1 = require("sparqlalgebrajs");
|
|
7
|
-
|
|
8
|
-
* A convenience constructor for bindings based on a given hash.
|
|
9
|
-
* @param {{[p: string]: RDF.Term}} hash A hash that maps variable names to terms.
|
|
10
|
-
* @return {Bindings} The immutable bindings from the hash.
|
|
11
|
-
* @constructor
|
|
12
|
-
*/
|
|
13
|
-
// eslint-disable-next-line no-redeclare
|
|
14
|
-
function Bindings(hash) {
|
|
15
|
-
return immutable_1.Map(hash);
|
|
16
|
-
}
|
|
17
|
-
exports.Bindings = Bindings;
|
|
18
|
-
/**
|
|
19
|
-
* Check if the given object is a bindings object.
|
|
20
|
-
* @param maybeBindings Any object.
|
|
21
|
-
* @return {boolean} If the object is a bindings object.
|
|
22
|
-
*/
|
|
23
|
-
function isBindings(maybeBindings) {
|
|
24
|
-
return immutable_1.Map.isMap(maybeBindings);
|
|
25
|
-
}
|
|
26
|
-
exports.isBindings = isBindings;
|
|
27
|
-
/**
|
|
28
|
-
* Convert the given object to a bindings object if it is not a bindings object yet.
|
|
29
|
-
* If it already is a bindings object, return the object as-is.
|
|
30
|
-
* @param maybeBindings Any object.
|
|
31
|
-
* @return {Bindings} A bindings object.
|
|
32
|
-
*/
|
|
33
|
-
function ensureBindings(maybeBindings) {
|
|
34
|
-
return isBindings(maybeBindings) ? maybeBindings : Bindings(maybeBindings);
|
|
35
|
-
}
|
|
36
|
-
exports.ensureBindings = ensureBindings;
|
|
7
|
+
const BF = new bindings_factory_1.BindingsFactory();
|
|
37
8
|
/**
|
|
38
9
|
* Materialize a term with the given binding.
|
|
39
10
|
*
|
|
@@ -48,7 +19,7 @@ exports.ensureBindings = ensureBindings;
|
|
|
48
19
|
*/
|
|
49
20
|
function materializeTerm(term, bindings) {
|
|
50
21
|
if (term.termType === 'Variable') {
|
|
51
|
-
const value = bindings.get(
|
|
22
|
+
const value = bindings.get(term);
|
|
52
23
|
if (value) {
|
|
53
24
|
return value;
|
|
54
25
|
}
|
|
@@ -62,10 +33,14 @@ exports.materializeTerm = materializeTerm;
|
|
|
62
33
|
* by the terms bound to the variables in the given bindings.
|
|
63
34
|
* @param {Operation} operation SPARQL algebra operation.
|
|
64
35
|
* @param {Bindings} bindings A bindings object.
|
|
65
|
-
* @param
|
|
36
|
+
* @param options Options for materializations.
|
|
66
37
|
* @return Algebra.Operation A new operation materialized with the given bindings.
|
|
67
38
|
*/
|
|
68
|
-
function materializeOperation(operation, bindings,
|
|
39
|
+
function materializeOperation(operation, bindings, options = {}) {
|
|
40
|
+
options = {
|
|
41
|
+
strictTargetVariables: 'strictTargetVariables' in options ? options.strictTargetVariables : false,
|
|
42
|
+
bindFilter: 'bindFilter' in options ? options.bindFilter : true,
|
|
43
|
+
};
|
|
69
44
|
return sparqlalgebrajs_1.Util.mapOperation(operation, {
|
|
70
45
|
path(op, factory) {
|
|
71
46
|
// Materialize variables in a path expression.
|
|
@@ -86,14 +61,14 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
86
61
|
// Materialize an extend operation.
|
|
87
62
|
// If strictTargetVariables is true, we throw if the extension target variable is attempted to be bound.
|
|
88
63
|
// Otherwise, we remove the extend operation.
|
|
89
|
-
if (bindings.has(
|
|
90
|
-
if (strictTargetVariables) {
|
|
91
|
-
throw new Error(`Tried to bind variable ${rdf_string_1.termToString(op.variable)} in a BIND operator.`);
|
|
64
|
+
if (bindings.has(op.variable)) {
|
|
65
|
+
if (options.strictTargetVariables) {
|
|
66
|
+
throw new Error(`Tried to bind variable ${(0, rdf_string_1.termToString)(op.variable)} in a BIND operator.`);
|
|
92
67
|
}
|
|
93
68
|
else {
|
|
94
69
|
return {
|
|
95
70
|
recurse: true,
|
|
96
|
-
result: materializeOperation(op.input, bindings,
|
|
71
|
+
result: materializeOperation(op.input, bindings, options),
|
|
97
72
|
};
|
|
98
73
|
}
|
|
99
74
|
}
|
|
@@ -106,10 +81,10 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
106
81
|
// Materialize a group operation.
|
|
107
82
|
// If strictTargetVariables is true, we throw if the group target variable is attempted to be bound.
|
|
108
83
|
// Otherwise, we just filter out the bound variables.
|
|
109
|
-
if (strictTargetVariables) {
|
|
84
|
+
if (options.strictTargetVariables) {
|
|
110
85
|
for (const variable of op.variables) {
|
|
111
|
-
if (bindings.has(
|
|
112
|
-
throw new Error(`Tried to bind variable ${rdf_string_1.termToString(variable)} in a GROUP BY operator.`);
|
|
86
|
+
if (bindings.has(variable)) {
|
|
87
|
+
throw new Error(`Tried to bind variable ${(0, rdf_string_1.termToString)(variable)} in a GROUP BY operator.`);
|
|
113
88
|
}
|
|
114
89
|
}
|
|
115
90
|
return {
|
|
@@ -117,7 +92,7 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
117
92
|
result: op,
|
|
118
93
|
};
|
|
119
94
|
}
|
|
120
|
-
const variables = op.variables.filter(variable => !bindings.has(
|
|
95
|
+
const variables = op.variables.filter(variable => !bindings.has(variable));
|
|
121
96
|
return {
|
|
122
97
|
recurse: true,
|
|
123
98
|
result: factory.createGroup(op.input, variables, op.aggregates),
|
|
@@ -127,10 +102,10 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
127
102
|
// Materialize a project operation.
|
|
128
103
|
// If strictTargetVariables is true, we throw if the project target variable is attempted to be bound.
|
|
129
104
|
// Otherwise, we just filter out the bound variables.
|
|
130
|
-
if (strictTargetVariables) {
|
|
105
|
+
if (options.strictTargetVariables) {
|
|
131
106
|
for (const variable of op.variables) {
|
|
132
|
-
if (bindings.has(
|
|
133
|
-
throw new Error(`Tried to bind variable ${rdf_string_1.termToString(variable)} in a SELECT operator.`);
|
|
107
|
+
if (bindings.has(variable)) {
|
|
108
|
+
throw new Error(`Tried to bind variable ${(0, rdf_string_1.termToString)(variable)} in a SELECT operator.`);
|
|
134
109
|
}
|
|
135
110
|
}
|
|
136
111
|
return {
|
|
@@ -138,30 +113,50 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
138
113
|
result: op,
|
|
139
114
|
};
|
|
140
115
|
}
|
|
141
|
-
const variables = op.variables.filter(variable => !bindings.has(
|
|
116
|
+
const variables = op.variables.filter(variable => !bindings.has(variable));
|
|
117
|
+
// Only include projected variables in the sub-bindings that will be passed down recursively.
|
|
118
|
+
// If we don't do this, we may be binding variables that may have the same label, but are not considered equal.
|
|
119
|
+
const subBindings = BF.bindings(op.variables.map(variable => {
|
|
120
|
+
const binding = bindings.get(variable);
|
|
121
|
+
if (binding) {
|
|
122
|
+
return [variable, binding];
|
|
123
|
+
}
|
|
124
|
+
// eslint-disable-next-line no-useless-return
|
|
125
|
+
return;
|
|
126
|
+
}).filter(entry => Boolean(entry)));
|
|
142
127
|
return {
|
|
143
|
-
recurse:
|
|
144
|
-
result: factory.createProject(op.input, variables),
|
|
128
|
+
recurse: false,
|
|
129
|
+
result: factory.createProject(materializeOperation(op.input, subBindings, options), variables),
|
|
145
130
|
};
|
|
146
131
|
},
|
|
147
132
|
values(op, factory) {
|
|
148
133
|
// Materialize a values operation.
|
|
149
134
|
// If strictTargetVariables is true, we throw if the values target variable is attempted to be bound.
|
|
150
135
|
// Otherwise, we just filter out the bound variables and their bindings.
|
|
151
|
-
if (strictTargetVariables) {
|
|
136
|
+
if (options.strictTargetVariables) {
|
|
152
137
|
for (const variable of op.variables) {
|
|
153
|
-
if (bindings.has(
|
|
154
|
-
throw new Error(`Tried to bind variable ${rdf_string_1.termToString(variable)} in a VALUES operator.`);
|
|
138
|
+
if (bindings.has(variable)) {
|
|
139
|
+
throw new Error(`Tried to bind variable ${(0, rdf_string_1.termToString)(variable)} in a VALUES operator.`);
|
|
155
140
|
}
|
|
156
141
|
}
|
|
157
142
|
}
|
|
158
143
|
else {
|
|
159
|
-
const variables = op.variables.filter(variable => !bindings.has(
|
|
144
|
+
const variables = op.variables.filter(variable => !bindings.has(variable));
|
|
160
145
|
const valueBindings = op.bindings.map(binding => {
|
|
161
|
-
const newBinding =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
146
|
+
const newBinding = { ...binding };
|
|
147
|
+
let valid = true;
|
|
148
|
+
bindings.forEach((value, key) => {
|
|
149
|
+
const keyString = (0, rdf_string_1.termToString)(key);
|
|
150
|
+
if (keyString in newBinding) {
|
|
151
|
+
if (!value.equals(newBinding[keyString])) {
|
|
152
|
+
// If the value of the binding is not equal, remove this binding completely from the VALUES clause
|
|
153
|
+
valid = false;
|
|
154
|
+
}
|
|
155
|
+
delete newBinding[keyString];
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return valid ? newBinding : undefined;
|
|
159
|
+
}).filter(Boolean);
|
|
165
160
|
return {
|
|
166
161
|
recurse: true,
|
|
167
162
|
result: factory.createValues(variables, valueBindings),
|
|
@@ -173,6 +168,12 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
173
168
|
};
|
|
174
169
|
},
|
|
175
170
|
expression(op, factory) {
|
|
171
|
+
if (!options.bindFilter) {
|
|
172
|
+
return {
|
|
173
|
+
recurse: false,
|
|
174
|
+
result: op,
|
|
175
|
+
};
|
|
176
|
+
}
|
|
176
177
|
if (op.expressionType === 'term') {
|
|
177
178
|
// Materialize a term expression
|
|
178
179
|
return {
|
|
@@ -182,12 +183,12 @@ function materializeOperation(operation, bindings, strictTargetVariables = false
|
|
|
182
183
|
}
|
|
183
184
|
if (op.expressionType === 'aggregate' &&
|
|
184
185
|
'variable' in op &&
|
|
185
|
-
bindings.has(
|
|
186
|
+
bindings.has(op.variable)) {
|
|
186
187
|
// Materialize a bound aggregate operation.
|
|
187
188
|
// If strictTargetVariables is true, we throw if the expression target variable is attempted to be bound.
|
|
188
189
|
// Otherwise, we ignore this operation.
|
|
189
|
-
if (strictTargetVariables) {
|
|
190
|
-
throw new Error(`Tried to bind ${rdf_string_1.termToString(op.variable)} in a ${op.aggregator} aggregate.`);
|
|
190
|
+
if (options.strictTargetVariables) {
|
|
191
|
+
throw new Error(`Tried to bind ${(0, rdf_string_1.termToString)(op.variable)} in a ${op.aggregator} aggregate.`);
|
|
191
192
|
}
|
|
192
193
|
else {
|
|
193
194
|
return {
|
package/lib/index.d.ts
ADDED
|
@@ -10,8 +10,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
10
10
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
11
|
};
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
__exportStar(require("./
|
|
14
|
-
__exportStar(require("./
|
|
15
|
-
__exportStar(require("./
|
|
16
|
-
__exportStar(require("./
|
|
13
|
+
__exportStar(require("./ActorQueryOperation"), exports);
|
|
14
|
+
__exportStar(require("./ActorQueryOperationTyped"), exports);
|
|
15
|
+
__exportStar(require("./ActorQueryOperationTypedMediated"), exports);
|
|
16
|
+
__exportStar(require("./Bindings"), exports);
|
|
17
17
|
//# sourceMappingURL=index.js.map
|