/
ActorQueryOperationTyped.ts
70 lines (63 loc) 路 2.73 KB
/
ActorQueryOperationTyped.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import { KeysInitQuery, KeysQueryOperation } from '@comunica/context-entries';
import type { IActorTest } from '@comunica/core';
import { cachifyMetadata } from '@comunica/metadata';
import type {
IQueryOperationResult,
IPhysicalQueryPlanLogger,
IActionContext,
IMetadata,
} from '@comunica/types';
import type * as RDF from '@rdfjs/types';
import type { Algebra } from 'sparqlalgebrajs';
import type { IActionQueryOperation, IActorQueryOperationArgs } from './ActorQueryOperation';
import { ActorQueryOperation } from './ActorQueryOperation';
/**
* A base implementation for query operation actors for a specific operation type.
*/
export abstract class ActorQueryOperationTyped<O extends Algebra.Operation> extends ActorQueryOperation {
public readonly operationName: string;
protected constructor(args: IActorQueryOperationArgs, operationName: string) {
super(<any> { ...args, operationName });
if (!this.operationName) {
throw new Error('A valid "operationName" argument must be provided.');
}
}
public async test(action: IActionQueryOperation): Promise<IActorTest> {
if (!action.operation) {
throw new Error('Missing field \'operation\' in a query operation action.');
}
if (action.operation.type !== this.operationName) {
throw new Error(`Actor ${this.name} only supports ${this.operationName} operations, but got ${
action.operation.type}`);
}
const operation: O = <O> action.operation;
return this.testOperation(operation, action.context);
}
public async run(action: IActionQueryOperation): Promise<IQueryOperationResult> {
// Log to physical plan
const physicalQueryPlanLogger: IPhysicalQueryPlanLogger | undefined = action.context
.get(KeysInitQuery.physicalQueryPlanLogger);
if (physicalQueryPlanLogger) {
physicalQueryPlanLogger.logOperation(
action.operation.type,
undefined,
action.operation,
action.context.get(KeysInitQuery.physicalQueryPlanNode),
this.name,
{},
);
action.context = action.context.set(KeysInitQuery.physicalQueryPlanNode, action.operation);
}
const operation: O = <O> action.operation;
const subContext = action.context.set(KeysQueryOperation.operation, operation);
const output: IQueryOperationResult = await this.runOperation(operation, subContext);
if ('metadata' in output) {
output.metadata = <any>
cachifyMetadata<IMetadata<RDF.QuadTermName | RDF.Variable>, RDF.QuadTermName | RDF.Variable>(output.metadata);
}
return output;
}
protected abstract testOperation(operation: O, context: IActionContext): Promise<IActorTest>;
protected abstract runOperation(operation: O, context: IActionContext):
Promise<IQueryOperationResult>;
}