UNPKG

@neo4j/graphql

Version:

A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations

115 lines 5.12 kB
"use strict"; /* * Copyright (c) "Neo4j" * Neo4j Sweden AB [http://neo4j.com] * * This file is part of Neo4j. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.QueryAST = void 0; const cypher_builder_1 = __importDefault(require("@neo4j/cypher-builder")); const create_node_from_entity_1 = require("../utils/create-node-from-entity"); const QueryASTContext_1 = require("./QueryASTContext"); const AggregationOperation_1 = require("./operations/AggregationOperation"); const ConnectionReadOperation_1 = require("./operations/ConnectionReadOperation"); const DeleteOperation_1 = require("./operations/DeleteOperation"); const ReadOperation_1 = require("./operations/ReadOperation"); const TopLevelCreateMutationOperation_1 = require("./operations/TopLevelCreateMutationOperation"); const UnwindCreateOperation_1 = require("./operations/UnwindCreateOperation"); class QueryAST { constructor(operation) { this.operation = operation; } build(neo4jGraphQLContext, varName) { const context = this.buildQueryASTContext(neo4jGraphQLContext, varName); return cypher_builder_1.default.utils.concat(...this.transpile(context).clauses); } // TODO: refactor other top level operations to use this method instead of build buildNew(neo4jGraphQLContext, varName) { const context = this.buildQueryASTContext(neo4jGraphQLContext, varName); const { clauses, projectionExpr, extraProjectionColumns } = this.transpile(context); const returnClause = varName ? new cypher_builder_1.default.Return([projectionExpr, varName]) : new cypher_builder_1.default.Return(projectionExpr); if (extraProjectionColumns) { for (const projectionColumn of extraProjectionColumns) { returnClause.addColumns(projectionColumn); } } return cypher_builder_1.default.utils.concat(...clauses, returnClause); } /** * Transpile the QueryAST to a Cypher builder tree, this is used temporary to transpile incomplete trees, helpful to migrate the legacy code **/ transpile(context) { return this.operation.transpile(context); } buildQueryASTContext(neo4jGraphQLContext, varName) { const queryASTEnv = new QueryASTContext_1.QueryASTEnv(); const node = this.getTargetFromOperation(varName); const returnVariable = new cypher_builder_1.default.NamedVariable(varName ?? "this"); return new QueryASTContext_1.QueryASTContext({ target: node, env: queryASTEnv, neo4jGraphQLContext, returnVariable, }); } getTargetFromOperation(varName) { if (this.operation instanceof ReadOperation_1.ReadOperation || this.operation instanceof ConnectionReadOperation_1.ConnectionReadOperation || this.operation instanceof DeleteOperation_1.DeleteOperation || this.operation instanceof AggregationOperation_1.AggregationOperation || this.operation instanceof UnwindCreateOperation_1.UnwindCreateOperation || this.operation instanceof TopLevelCreateMutationOperation_1.TopLevelCreateMutationOperation) { return (0, create_node_from_entity_1.createNode)(varName); } } print() { const resultLines = getTreeLines(this.operation); return resultLines.join("\n"); } } exports.QueryAST = QueryAST; function getTreeLines(treeNode, depth = 0) { const nodeName = treeNode.print(); const resultLines = []; const line = "────"; if (depth === 0) { resultLines.push(`${nodeName}`); } else if (depth === 1) { resultLines.push(`|${line} ${nodeName}`); } else { // fillerLength is the line length repeated by the depth (minus 1 for the first line), // in case of depth > 2 there are two pipes rather than one. let fillerLength = (line.length + 1) * (depth - 1); if (depth > 2) { fillerLength += depth - 2; } resultLines.push(`|${" ".repeat(fillerLength)}|${line} ${nodeName}`); } const children = treeNode.getChildren(); if (children.length > 0) { children.forEach((curr) => { const childLines = getTreeLines(curr, depth + 1); resultLines.push(...childLines); }); } return resultLines; } //# sourceMappingURL=QueryAST.js.map