@neo4j/graphql
Version:
A GraphQL to Cypher query execution layer for Neo4j and JavaScript GraphQL implementations
116 lines • 6.35 kB
JavaScript
"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.CompositeReadPartial = void 0;
const cypher_builder_1 = __importDefault(require("@neo4j/cypher-builder"));
const context_has_target_1 = require("../../../utils/context-has-target");
const wrap_subquery_in_calls_1 = require("../../../utils/wrap-subquery-in-calls");
const ReadOperation_1 = require("../ReadOperation");
class CompositeReadPartial extends ReadOperation_1.ReadOperation {
transpile(context) {
if (this.relationship) {
return this.transpileNestedCompositeRelationship(this.relationship, context);
}
else {
return this.transpileTopLevelCompositeEntity(context);
}
}
transpileNestedCompositeRelationship(entity, context) {
if (!(0, context_has_target_1.hasTarget)(context)) {
throw new Error("No parent node found!");
}
// eslint-disable-next-line prefer-const
let { selection: matchClause, nestedContext } = this.selection.apply(context);
let extraMatches = this.getChildren().flatMap((f) => {
return f.getSelection(nestedContext);
});
const filterSubqueries = (0, wrap_subquery_in_calls_1.wrapSubqueriesInCypherCalls)(nestedContext, this.filters, [nestedContext.target]);
const filterPredicates = this.getPredicates(nestedContext);
const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext).map((sq) => new cypher_builder_1.default.Call(sq, [nestedContext.target]));
const authFiltersPredicate = this.getAuthFilterPredicate(nestedContext);
const validations = this.getValidations(nestedContext);
if (extraMatches.length > 0 || filterSubqueries.length > 0 || authFilterSubqueries.length > 0) {
extraMatches = [matchClause, ...extraMatches];
matchClause = new cypher_builder_1.default.With("*");
}
const wherePredicate = cypher_builder_1.default.and(filterPredicates, ...authFiltersPredicate);
if (wherePredicate) {
// NOTE: This is slightly different to ReadOperation for cypher compatibility, this could use `WITH *`
matchClause.where(wherePredicate);
}
const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext);
const subqueries = cypher_builder_1.default.utils.concat(...this.getFieldsSubqueries(nestedContext), ...cypherFieldSubqueries);
const sortSubqueries = this.sortFields
.flatMap((sq) => sq.getSubqueries(nestedContext))
.map((sq) => new cypher_builder_1.default.Call(sq, [nestedContext.target]));
const ret = this.getProjectionClause(nestedContext, context.returnVariable);
const clause = cypher_builder_1.default.utils.concat(...extraMatches, ...filterSubqueries, ...authFilterSubqueries, matchClause, ...validations, subqueries, ...sortSubqueries, ret);
return {
clauses: [clause],
projectionExpr: nestedContext.returnVariable,
};
}
// dupe from transpileNestedCompositeRelationship
transpileTopLevelCompositeEntity(context) {
// eslint-disable-next-line prefer-const
let { selection: matchClause, nestedContext } = this.selection.apply(context);
let extraMatches = this.getChildren().flatMap((f) => {
return f.getSelection(nestedContext);
});
const filterSubqueries = (0, wrap_subquery_in_calls_1.wrapSubqueriesInCypherCalls)(nestedContext, this.filters, [nestedContext.target]);
if (extraMatches.length > 0 || filterSubqueries.length > 0) {
extraMatches = [matchClause, ...extraMatches];
matchClause = new cypher_builder_1.default.With("*");
}
const filterPredicates = this.getPredicates(nestedContext);
const authFilterSubqueries = this.getAuthFilterSubqueries(nestedContext);
const authFiltersPredicate = this.getAuthFilterPredicate(nestedContext);
const validations = this.getValidations(nestedContext);
const wherePredicate = cypher_builder_1.default.and(filterPredicates, ...authFiltersPredicate);
if (wherePredicate) {
matchClause.where(wherePredicate);
}
const cypherFieldSubqueries = this.getCypherFieldsSubqueries(nestedContext);
const subqueries = cypher_builder_1.default.utils.concat(...this.getFieldsSubqueries(nestedContext), ...cypherFieldSubqueries);
const ret = this.getProjectionClause(nestedContext, context.returnVariable);
const clause = cypher_builder_1.default.utils.concat(...extraMatches, ...filterSubqueries, ...authFilterSubqueries, matchClause, ...validations, subqueries, ret);
return {
clauses: [clause],
projectionExpr: context.returnVariable,
};
}
getProjectionClause(context, returnVariable) {
if (!(0, context_has_target_1.hasTarget)(context))
throw new Error("No parent node found!");
const projection = this.getProjectionMap(context);
const targetNodeName = this.target.name;
projection.set({
__resolveType: new cypher_builder_1.default.Literal(targetNodeName),
__id: cypher_builder_1.default.id(context.target),
});
const withClause = new cypher_builder_1.default.With([projection, returnVariable]);
return withClause.return(returnVariable);
}
}
exports.CompositeReadPartial = CompositeReadPartial;
//# sourceMappingURL=CompositeReadPartial.js.map