feature (console): add GQL util function to generate insert mutations + tests

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/7512
GitOrigin-RevId: 3e89bcd114a42c9e2fa97f1a05d5c871329c8dd9
This commit is contained in:
Vijay Prasanna 2023-01-16 12:20:17 +05:30 committed by hasura-bot
parent 1280ca8533
commit 0bc363de6e
3 changed files with 147 additions and 19 deletions

View File

@ -0,0 +1,120 @@
import { formatSdl } from 'format-graphql';
import { generateGraphQLInsertMutation } from './generateGraphQLInsertMutation';
describe('generateGraphQLInsertMutation for table with', () => {
it('no table customization + no source customization', () => {
const result = generateGraphQLInsertMutation({
defaultQueryRoot: 'Album',
objects: [
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
],
mutationName: 'insertAlbumRows',
});
const expectedGqlQuery = `
mutation insertAlbumRows {
insert_Album(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
affected_rows
}
}
`;
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
});
it('with table customization (only custom name) + no source customization', () => {
const result = generateGraphQLInsertMutation({
defaultQueryRoot: 'Album',
objects: [
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
],
mutationName: 'insertAlbumRows',
tableCustomization: {
custom_name: 'CustomTableName',
},
});
const expectedGqlQuery = `
mutation insertAlbumRows {
insert_CustomTableName(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
affected_rows
}
}
`;
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
});
it('with table customization (custom insert root) + no source customization', () => {
const result = generateGraphQLInsertMutation({
defaultQueryRoot: 'Album',
objects: [
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
],
mutationName: 'insertAlbumRows',
tableCustomization: {
custom_root_fields: { insert: 'CustomInsertRoot' },
},
});
const expectedGqlQuery = `
mutation insertAlbumRows {
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
affected_rows
}
}
`;
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
});
it('with table customization (custom name + custom insert root) + no source customization', () => {
const result = generateGraphQLInsertMutation({
defaultQueryRoot: 'Album',
objects: [
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
],
mutationName: 'insertAlbumRows',
tableCustomization: {
custom_name: 'CustomTableName',
custom_root_fields: { insert: 'CustomInsertRoot' },
},
});
const expectedGqlQuery = `
mutation insertAlbumRows {
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
affected_rows
}
}
`;
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
});
it('with table customization (custom name + custom insert root) + source customization', () => {
const result = generateGraphQLInsertMutation({
defaultQueryRoot: 'Album',
objects: [
{ AlbumId: 1, ArtistId: 1, Title: 'foo' },
{ AlbumId: 2, ArtistId: 2, Title: 'bar' },
],
mutationName: 'insertAlbumRows',
tableCustomization: {
custom_name: 'CustomTableName',
custom_root_fields: { insert: 'CustomInsertRoot' },
},
sourceCustomization: {
root_fields: {
namespace: 'MySourceNamespace',
},
},
});
const expectedGqlQuery = `
mutation insertAlbumRows {
MySourceNamespace {
CustomInsertRoot(objects: [{AlbumId: 1, ArtistId: 1, Title: "foo"},{AlbumId: 2, ArtistId: 2, Title: "bar"}]) {
affected_rows
}
}
}
`;
expect(result.query).toMatch(formatSdl(expectedGqlQuery));
});
});

View File

@ -1,18 +1,19 @@
import { MetadataTable, Source } from '@/features/hasura-metadata-types';
import { formatSdl } from 'format-graphql';
import { getMutationRoot } from './getMutationRoot';
export const generateGraphQLMutation = async ({
export const generateGraphQLInsertMutation = ({
defaultQueryRoot,
tableCustomization,
sourceCustomization,
objects,
operationName,
mutationName,
}: {
operationName?: string;
mutationName: string;
defaultQueryRoot: string;
tableCustomization: MetadataTable['configuration'];
sourceCustomization: Source['customization'];
objects: Record<string, string | number | boolean>;
tableCustomization?: MetadataTable['configuration'];
sourceCustomization?: Source['customization'];
objects: Record<string, string | number | boolean>[];
}) => {
const queryRoot = getMutationRoot({
defaultQueryRoot,
@ -29,34 +30,38 @@ export const generateGraphQLMutation = async ({
sourceCustomization,
});
const objectToInsert = Object.entries(objects).reduce<string>((acc, x) => {
const [column, value] = x;
return `${column}: ${typeof value === 'string' ? `"${value}"` : value}`;
}, '');
const objectToInsert = objects
.map(object => {
return `{${Object.entries(object)
.map(
([column, value]) =>
`${column}: ${typeof value === 'string' ? `"${value}"` : value}`
)
.join()}}`;
})
.join();
/**
* If the source has a GQL namespace set for it, then we query for our `queryRoot` under that namespace
*/
if (sourceCustomization?.root_fields?.namespace)
return {
query: `mutation ${operationName ?? 'MyMutation'} {
${
sourceCustomization.root_fields.namespace
} (objects: { ${objectToInsert} }) {
${queryRoot} {
query: formatSdl(`mutation ${mutationName} {
${sourceCustomization.root_fields.namespace} {
${queryRoot} (objects: [ ${objectToInsert} ]){
affected_rows
}
}
}`,
}`),
resultPath: `${sourceCustomization.root_fields?.namespace}.${queryRoot}`,
};
return {
query: `query ${operationName ?? 'MyQuery'} {
${queryRoot} (objects: { ${objectToInsert} }) {
query: formatSdl(`mutation ${mutationName} {
${queryRoot} (objects: [ ${objectToInsert} ]) {
affected_rows
}
}`,
}`),
resultPath: queryRoot,
};
};

View File

@ -5,6 +5,7 @@ export type AllowedMutationOperation =
| 'insert_one'
| 'update'
| 'update_by_pk'
| 'update_many'
| 'delete'
| 'delete_by_pk';
@ -52,6 +53,8 @@ export const getMutationRoot = ({
if (operation === 'update') baseQueryRoot = `update_${baseQueryRoot}`;
if (operation === 'update_by_pk')
baseQueryRoot = `update_${baseQueryRoot}_by_pk`;
if (operation === 'update_many')
baseQueryRoot = `update_${baseQueryRoot}_many`;
if (operation === 'delete_by_pk')
baseQueryRoot = `delete_${baseQueryRoot}_by_pk`;