Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -153,16 +153,15 @@ export class ConnectOperation extends MutationOperation {

const filterSubqueries = wrapSubqueriesInCypherCalls(nestedContext, allFilters, [nestedContext.target]);

const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
let matchClause: Cypher.Clause;
if (filterSubqueries.length > 0) {
const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
matchClause = Cypher.utils.concat(
new Cypher.Match(matchPattern),
...filterSubqueries,
new Cypher.With("*").where(predicate)
);
} else {
const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
matchClause = new Cypher.Match(matchPattern).where(predicate);
}

Expand All @@ -187,22 +186,13 @@ export class ConnectOperation extends MutationOperation {
return input.getSubqueries(connectContext);
});

const authClausesBefore = this.getAuthorizationClauses(nestedContext);

const authClausesAfter = this.getAuthorizationClausesAfter(nestedContext);
const sourceAuthClausesAfter = this.getSourceAuthorizationClausesAfter(context);

const authClauses: Cypher.Clause[] = [];
if (authClausesAfter.length > 0 || sourceAuthClausesAfter.length > 0) {
authClauses.push(Cypher.utils.concat(...authClausesAfter, ...sourceAuthClausesAfter));
}

const clauses = Cypher.utils.concat(
matchClause,
...authClausesBefore,
...this.getAuthorizationClauses(nestedContext), // THESE ARE "BEFORE" AUTH
...mutationSubqueries,
connectClause,
...authClauses
...this.getAuthorizationClausesAfter(nestedContext), // THESE ARE "AFTER" AUTH
...this.getSourceAuthorizationClausesAfter(context) // ONLY RUN "AFTER" AUTH ON THE SOURCE NODE
);

const callClause = new Cypher.Call(clauses, [context.target]);
Expand All @@ -214,19 +204,16 @@ export class ConnectOperation extends MutationOperation {
}

private getAuthorizationClauses(context: QueryASTContext): Cypher.Clause[] {
const { selections, subqueries, predicates, validations } = this.transpileAuthClauses(context);
const predicate = Cypher.and(...predicates);
const lastSelection = selections[selections.length - 1];

if (!predicates.length && !validations.length) {
return [];
} else {
if (lastSelection) {
lastSelection.where(predicate);
return [...subqueries, new Cypher.With("*"), ...selections, ...validations];
const { subqueries, predicates, validations } = this.transpileAuthClauses(context);
if (!predicates.length) {
if (!validations.length) {
return [];
}
return [...subqueries, new Cypher.With("*").where(predicate), ...selections, ...validations];
return [...subqueries, ...validations];
}

const predicate = Cypher.and(...predicates);
return [...subqueries, new Cypher.With("*").where(predicate), ...validations];
}

private getAuthorizationClausesAfter(context: QueryASTContext): Cypher.Clause[] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,16 +148,15 @@ export class DisconnectOperation extends MutationOperation {

const filterSubqueries = wrapSubqueriesInCypherCalls(nestedContext, allFilters, [nestedContext.target]);

const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
let matchClause: Cypher.Clause;
if (filterSubqueries.length > 0) {
const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
matchClause = Cypher.utils.concat(
new Cypher.OptionalMatch(matchPattern),
...filterSubqueries,
new Cypher.With("*").where(predicate)
);
} else {
const predicate = Cypher.and(...allFilters.map((f) => f.getPredicate(nestedContext)));
matchClause = new Cypher.OptionalMatch(matchPattern).where(predicate);
}

Expand All @@ -173,30 +172,14 @@ export class DisconnectOperation extends MutationOperation {

const deleteClause = new Cypher.With(nestedContext.relationship!).delete(nestedContext.relationship!);

const authClausesBefore = this.getAuthorizationClauses(nestedContext);
const sourceAuthClausesBefore = this.getSourceAuthorizationClausesBefore(context);

const bothAuthClausesBefore: Cypher.Clause[] = [];
if (authClausesBefore.length === 0 && sourceAuthClausesBefore.length > 0) {
bothAuthClausesBefore.push(new Cypher.With("*"), ...sourceAuthClausesBefore);
} else {
bothAuthClausesBefore.push(Cypher.utils.concat(...authClausesBefore, ...sourceAuthClausesBefore));
}

const authClausesAfter = this.getAuthorizationClausesAfter(nestedContext);
const sourceAuthClausesAfter = this.getSourceAuthorizationClausesAfter(context);

const authClauses: Cypher.Clause[] = [];
if (authClausesAfter.length > 0 || sourceAuthClausesAfter.length > 0) {
authClauses.push(Cypher.utils.concat(...authClausesAfter, ...sourceAuthClausesAfter));
}

const clauses = Cypher.utils.concat(
matchClause,
...bothAuthClausesBefore,
...this.getAuthorizationClauses(nestedContext),
...this.getSourceAuthorizationClauses(context, "BEFORE"),
...mutationSubqueries,
deleteClause,
...authClauses
...this.getAuthorizationClausesAfter(nestedContext),
...this.getSourceAuthorizationClauses(context, "AFTER")
);

const callClause = new Cypher.Call(clauses, [context.target]);
Expand All @@ -205,24 +188,19 @@ export class DisconnectOperation extends MutationOperation {
projectionExpr: context.returnVariable,
clauses: [callClause],
};

// return { projectionExpr: context.returnVariable, clauses: [clauses] };
}

private getAuthorizationClauses(context: QueryASTContext): Cypher.Clause[] {
const { selections, subqueries, predicates, validations } = this.transpileAuthClauses(context);
const predicate = Cypher.and(...predicates);
const lastSelection = selections[selections.length - 1];

if (!predicates.length && !validations.length) {
return [];
} else {
if (lastSelection) {
lastSelection.where(predicate);
return [...subqueries, new Cypher.With("*"), ...selections, ...validations];
const { subqueries, predicates, validations } = this.transpileAuthClauses(context);
if (!predicates.length) {
if (!validations.length) {
return [];
}
return [...subqueries, new Cypher.With("*").where(predicate), ...selections, ...validations];
return [...subqueries, ...validations];
}

const predicate = Cypher.and(...predicates);
return [...subqueries, new Cypher.With("*").where(predicate), ...validations];
}

private getAuthorizationClausesAfter(context: QueryASTContext): Cypher.Clause[] {
Expand All @@ -240,31 +218,17 @@ export class DisconnectOperation extends MutationOperation {
return [];
}

private getSourceAuthorizationClausesAfter(context: QueryASTContext): Cypher.Clause[] {
const validationsAfter: Cypher.VoidProcedure[] = [];
for (const authFilter of this.sourceAuthFilters) {
const validationAfter = authFilter.getValidation(context, "AFTER");
if (validationAfter) {
validationsAfter.push(validationAfter);
}
}

if (validationsAfter.length > 0) {
return [new Cypher.With("*"), ...validationsAfter];
}
return [];
}
private getSourceAuthorizationClausesBefore(context: QueryASTContext): Cypher.Clause[] {
const validationsAfter: Cypher.VoidProcedure[] = [];
private getSourceAuthorizationClauses(context: QueryASTContext, when: "BEFORE" | "AFTER"): Cypher.Clause[] {
const validations: Cypher.VoidProcedure[] = [];
for (const authFilter of this.sourceAuthFilters) {
const validationAfter = authFilter.getValidation(context, "BEFORE");
if (validationAfter) {
validationsAfter.push(validationAfter);
const validation = authFilter.getValidation(context, when);
if (validation) {
validations.push(validation);
}
}

if (validationsAfter.length > 0) {
return [new Cypher.With("*"), ...validationsAfter];
if (validations.length > 0) {
return [new Cypher.With("*"), ...validations];
}
return [];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,7 @@ import type { RelationshipAdapter } from "../../../../schema-model/relationship/
import { wrapSubqueriesInCypherCalls } from "../../utils/wrap-subquery-in-calls";
import type { Filter } from "../filters/Filter";
import { ParamInputField } from "../input-fields/ParamInputField";
/**
* This is currently just a dummy tree node,
* The whole mutation part is still implemented in the old way, the current scope of this node is just to contains the nested fields.
**/

export class UpdateOperation extends Operation {
public readonly target: ConcreteEntityAdapter;
public readonly relationship: RelationshipAdapter | undefined;
Expand Down Expand Up @@ -128,14 +125,14 @@ export class UpdateOperation extends Operation {
if (!authSubqueries.length && !subqueries.length) {
return undefined;
}
if (authSubqueries.length > 0) {
if (authSubqueries.length && subqueries.length) {
return Cypher.utils.concat(...subqueries, new Cypher.With("*"), ...authSubqueries);
}
return Cypher.utils.concat(...subqueries);
return Cypher.utils.concat(...subqueries, ...authSubqueries);
})
.filter((s) => s !== undefined);

// This is a small optimisation, to avoid subqueries with no changes
// This is a small optimization, to avoid subqueries with no changes
// Top level should still be generated for projection
if (this.relationship) {
if (setParams.length === 0 && mutationSubqueries.length === 0) {
Expand All @@ -155,14 +152,9 @@ export class UpdateOperation extends Operation {
const predicate = this.getPredicate(nestedContext);

const matchClause = new Cypher.Match(pattern);
const filtersWith = new Cypher.With("*").where(predicate);
if (filtersWith) {
filtersWith.set(...setParams);
if (mutationSubqueries.length || afterFilterSubqueries.length) {
filtersWith.with("*");
}
} else {
matchClause.set(...setParams);
const filtersWith = new Cypher.With("*").where(predicate).set(...setParams);
if (afterFilterSubqueries.length) {
filtersWith.with("*");
}

const clauses = Cypher.utils.concat(
Expand All @@ -188,31 +180,23 @@ export class UpdateOperation extends Operation {
);
}

return [
// ...this.getAuthorizationClauses(nestedContext),
// ...this.inputFields.flatMap((inputField) => {
// return inputField.getAuthorizationSubqueries(nestedContext);
// }),
];
return [];
}

private getAuthorizationClauses(context: QueryASTContext): Cypher.Clause[] {
const { selections, subqueries, predicates, validations } = this.transpileAuthClauses(context);
const predicate = Cypher.and(...predicates);
const lastSelection = selections[selections.length - 1];

const { subqueries, predicates, validations } = this.transpileAuthClauses(context);
const authSubqueries = subqueries.map((sq) => {
return new Cypher.Call(sq, "*");
});
if (!predicates.length && !validations.length) {
return [];
} else {
if (lastSelection) {
lastSelection.where(predicate);
return [...authSubqueries, new Cypher.With("*"), ...selections, ...validations];
if (!predicates.length) {
if (!validations.length) {
return [];
}
return [...authSubqueries, new Cypher.With("*").where(predicate), ...selections, ...validations];
return [...authSubqueries, ...validations];
}

const predicate = Cypher.and(...predicates);
return [...authSubqueries, new Cypher.With("*").where(predicate), ...validations];
}

private getAuthorizationClausesAfter(context: QueryASTContext): Cypher.Clause[] {
Expand Down