graphql-to-sparql
Version:
Converts GraphQL queries to SPARQL queries
87 lines • 4.59 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeHandlerDocument = void 0;
const algebra_transformations_1_2_1 = require("@traqula/algebra-transformations-1-2");
const NodeHandlerAdapter_1 = require("./NodeHandlerAdapter");
/**
* Converts GraphQL documents to joined operations for all its definitions.
*/
class NodeHandlerDocument extends NodeHandlerAdapter_1.NodeHandlerAdapter {
constructor(util, settings) {
super('Document', util, settings);
}
handle(document, convertContext) {
const definitionOperations = document.definitions
.map((definition) => {
var _a, _b;
const subjectOutput = this.getNodeQuadContextDefinitionNode(definition, Object.assign(Object.assign({}, convertContext), { ignoreUnknownVariables: true }));
const queryParseContext = Object.assign(Object.assign({}, convertContext), { graph: (_a = subjectOutput.graph) !== null && _a !== void 0 ? _a : convertContext.graph, subject: (_b = subjectOutput.subject) !== null && _b !== void 0 ? _b : this.util.dataFactory.blankNode() });
let definitionOperation = this.util.handleNode(definition, queryParseContext);
if (subjectOutput && subjectOutput.auxiliaryPatterns) {
definitionOperation = this.util.joinOperations([
definitionOperation,
this.util.operationFactory.createBgp(subjectOutput.auxiliaryPatterns),
]);
}
return definitionOperation;
});
const operation = this.util.operationFactory.createProject(definitionOperations.length === 1 ?
definitionOperations[0] :
this.util.operationFactory.createUnion(definitionOperations), convertContext.terminalVariables);
// Convert blank nodes to variables
return this.translateBlankNodesToVariables(operation);
}
/**
* Get the quad context of a definition node that should be used for the whole definition node.
* @param {DefinitionNode} definition A definition node.
* @param {IConvertContext} convertContext A convert context.
* @return {INodeQuadContext} The subject and optional auxiliary patterns.
*/
getNodeQuadContextDefinitionNode(definition, convertContext) {
if (definition.kind === 'OperationDefinition') {
return this.getNodeQuadContextSelectionSet(definition.selectionSet, definition.name ? definition.name.value : '', convertContext);
}
throw new Error(`Unsupported definition: ${definition.kind}`);
}
/**
* Translates blank nodes inside the query to variables.
* @param {Project} operation The operation to translate.
* @return {Operation} The transformed operation.
*/
translateBlankNodesToVariables(operation) {
const blankToVariableMapping = {};
const variablesRaw = new Set(operation.variables.map(x => x.value));
const uniqueVar = (label, _variables) => {
let counter = 0;
let labelLoop = label;
while (variablesRaw.has(labelLoop)) {
labelLoop = `${label}${counter++}`;
}
return this.util.dataFactory.variable(labelLoop);
};
const blankToVariable = (term) => {
if (term.termType === 'BlankNode') {
let variable = blankToVariableMapping[term.value];
if (!variable) {
variable = uniqueVar(term.value, variablesRaw);
variablesRaw.add(variable.value);
blankToVariableMapping[term.value] = variable;
}
return variable;
}
return term;
};
return algebra_transformations_1_2_1.algebraUtils.mapOperation(operation, {
[algebra_transformations_1_2_1.Algebra.Types.PATH]: {
preVisitor: () => ({ continue: false }),
transform: (op) => this.util.operationFactory.createPath(blankToVariable(op.subject), op.predicate, blankToVariable(op.object), blankToVariable(op.graph)),
},
[algebra_transformations_1_2_1.Algebra.Types.PATTERN]: {
preVisitor: () => ({ continue: false }),
transform: (op) => this.util.operationFactory.createPattern(blankToVariable(op.subject), blankToVariable(op.predicate), blankToVariable(op.object), blankToVariable(op.graph)),
},
});
}
}
exports.NodeHandlerDocument = NodeHandlerDocument;
//# sourceMappingURL=NodeHandlerDocument.js.map