Skip to content

Commit

Permalink
feat: add top level delete to the schema
Browse files Browse the repository at this point in the history
  • Loading branch information
mjfwebb committed Aug 7, 2024
1 parent ae9ab22 commit fda2ffb
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 1 deletion.
57 changes: 57 additions & 0 deletions packages/graphql/src/api-v6/resolvers/translate-delete-resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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.
*/

import type { GraphQLResolveInfo } from "graphql";
import type { ConcreteEntity } from "../../schema-model/entity/ConcreteEntity";
import type { Neo4jGraphQLTranslationContext } from "../../types/neo4j-graphql-translation-context";
import { execute } from "../../utils";
import getNeo4jResolveTree from "../../utils/get-neo4j-resolve-tree";
import { parseResolveInfoTreeCreate } from "../queryIRFactory/resolve-tree-parser/parse-resolve-info-tree";
import { translateCreateResolver } from "../translators/translate-create-operation";

export function generateDeleteResolver({ entity }: { entity: ConcreteEntity }) {
return async function resolve(
_root: any,
args: any,
context: Neo4jGraphQLTranslationContext,
info: GraphQLResolveInfo
) {
const resolveTree = getNeo4jResolveTree(info, { args });
context.resolveTree = resolveTree;
// TODO: Implement delete resolver
const graphQLTreeCreate = parseResolveInfoTreeCreate({ resolveTree: context.resolveTree, entity });
const { cypher, params } = translateCreateResolver({
context: context,
graphQLTreeCreate,
entity,
});
const executeResult = await execute({
cypher,
params,
defaultAccessMode: "WRITE",
context,
info,
});
return {
info: {
...executeResult.statistics,
},
};
};
}
13 changes: 12 additions & 1 deletion packages/graphql/src/api-v6/schema-generation/SchemaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ import type { Neo4jGraphQLSchemaModel } from "../../schema-model/Neo4jGraphQLSch
import type { ConcreteEntity } from "../../schema-model/entity/ConcreteEntity";
import { generateGlobalNodeResolver } from "../resolvers/global-node-resolver";
import { generateReadResolver } from "../resolvers/read-resolver";
import { generateCreateResolver } from "../resolvers/translate-create-resolver";
import { generateDeleteResolver } from "../resolvers/translate-delete-resolver";
import { SchemaBuilder } from "./SchemaBuilder";
import { SchemaTypes } from "./schema-types/SchemaTypes";
import { StaticSchemaTypes } from "./schema-types/StaticSchemaTypes";
import { TopLevelEntitySchemaTypes } from "./schema-types/TopLevelEntitySchemaTypes";
import { generateCreateResolver } from "../resolvers/translate-create-resolver";

export class SchemaGenerator {
private schemaBuilder: SchemaBuilder;
Expand All @@ -41,6 +42,7 @@ export class SchemaGenerator {
const entityTypesMap = this.generateEntityTypes(schemaModel);
this.generateTopLevelQueryFields(entityTypesMap);
this.generateTopLevelCreateFields(entityTypesMap);
this.generateTopLevelDeleteFields(entityTypesMap);

this.generateGlobalNodeQueryField(schemaModel);

Expand Down Expand Up @@ -86,6 +88,15 @@ export class SchemaGenerator {
}
}

private generateTopLevelDeleteFields(entityTypesMap: Map<ConcreteEntity, TopLevelEntitySchemaTypes>): void {
for (const [entity, entitySchemaTypes] of entityTypesMap.entries()) {
const resolver = generateDeleteResolver({
entity,
});
entitySchemaTypes.addTopLevelDeleteField(resolver);
}
}

private generateGlobalNodeQueryField(schemaModel: Neo4jGraphQLSchemaModel): void {
const globalEntities = schemaModel.concreteEntities.filter((e) => e.globalIdField);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ export class StaticSchemaTypes {
});
}

public get deleteInfo(): ObjectTypeComposer {
return this.schemaBuilder.getOrCreateObjectType("DeleteInfo", () => {
return {
fields: {
nodesDeleted: this.schemaBuilder.types.int.NonNull,
relationshipsDeleted: this.schemaBuilder.types.int.NonNull,
},
};
});
}

@Memoize()
public get sortDirection(): EnumTypeComposer {
return this.schemaBuilder.createEnumType("SortDirection", ["ASC", "DESC"]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,24 @@ export class TopLevelEntitySchemaTypes {
});
}

public addTopLevelDeleteField(
resolver: (
_root: any,
args: any,
context: Neo4jGraphQLTranslationContext,
info: GraphQLResolveInfo
) => Promise<any>
) {
this.schemaBuilder.addMutationField({
name: this.entity.typeNames.deleteField,
type: this.deleteType,
args: {
where: this.filterSchemaTypes.operationWhereTopLevel,
},
resolver,
});
}

protected get connectionSort(): InputTypeComposer {
return this.schemaBuilder.getOrCreateInputType(this.entityTypeNames.connectionSort, () => {
return {
Expand Down Expand Up @@ -312,6 +330,16 @@ export class TopLevelEntitySchemaTypes {
};
});
}

public get deleteType(): ObjectTypeComposer {
return this.schemaBuilder.getOrCreateObjectType(this.entityTypeNames.deleteResponse, () => {
return {
fields: {
info: this.schemaTypes.staticTypes.deleteInfo,
},
};
});
}
}

function typeToResolver(type: Neo4jGraphQLScalarType): GraphQLResolver | undefined {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,17 @@ export class TopLevelEntityTypeNames extends EntityTypeNames {
public get createInfo(): string {
return `${upperFirst(this.entityName)}CreateInfo`;
}

/** Top Level Delete field */
public get deleteField(): string {
return `delete${upperFirst(plural(this.entityName))}`;
}

public get deleteResponse(): string {
return `${upperFirst(this.entityName)}DeleteResponse`;
}

public get deleteInfo(): string {
return `${upperFirst(this.entityName)}DeleteInfo`;
}
}

0 comments on commit fda2ffb

Please sign in to comment.