Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pg) single backward relations with arguments if primary key covered partially #567

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
75 changes: 65 additions & 10 deletions packages/graphile-build-pg/src/plugins/PgBackwardRelationPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import debugFactory from "debug";

import { Plugin } from "graphile-build";
import { stringTag } from "./PgBasicsPlugin";
import { PgEntityKind } from "./PgIntrospectionPlugin";
import { PgEntityKind, PgConstraint } from "./PgIntrospectionPlugin";

declare module "graphile-build" {
interface GraphileBuildOptions {
Expand Down Expand Up @@ -36,6 +36,7 @@ export default (function PgBackwardRelationPlugin(
extend,
getTypeByName,
pgGetGqlTypeByTypeIdAndModifier,
gql2pg,
pgIntrospectionResultsByKind: introspectionResultsByKind,
pgSql: sql,
getSafeAliasFromResolveInfo,
Expand Down Expand Up @@ -131,27 +132,49 @@ export default (function PgBackwardRelationPlugin(
const isUnique = !!table.constraints.find(
c =>
(c.type === "p" || c.type === "u") &&
c.keyAttributeNums.length === keys.length &&
c.keyAttributeNums.length <= keys.length &&
c.keyAttributeNums.every((n, i) => keys[i].num === n)
);

const isDeprecated = isUnique && legacyRelationMode === DEPRECATED;

const primaryKeyConstraint = table.primaryKeyConstraint;
const primaryKeys =
primaryKeyConstraint && primaryKeyConstraint.keyAttributes;
const uncoveredPrimaryKeys =
primaryKeys && keys.every(attr => primaryKeys.includes(attr))
? primaryKeys.filter(attr => !keys.includes(attr))
: [];
const parameterKeys = uncoveredPrimaryKeys.map(key => ({
...key,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's less risk of conflicts here if we don't splat this out:

Suggested change
...key,
key,

sqlIdentifier: sql.identifier(key.name),
paramName: inflection.column(key), // inflection.argument(key.name, i)
}));

const singleRelationFieldName = isUnique
? inflection.singleRelationByKeysBackwards(
keys,
table,
foreignTable,
constraint
)
: uncoveredPrimaryKeys.length
? inflection.rowByRelationBackwardsAndUniqueKeys(
uncoveredPrimaryKeys,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uncoveredPrimaryKeys,
uncoveredPrimaryKeys.map(details => details.key),

table,
foreignTable,
constraint,
primaryKeyConstraint as PgConstraint // not void
)
: null;

const primaryKeyConstraint = table.primaryKeyConstraint;
const primaryKeys =
primaryKeyConstraint && primaryKeyConstraint.keyAttributes;

const shouldAddSingleRelation =
isUnique && legacyRelationMode !== ONLY;
(isUnique && legacyRelationMode !== ONLY) ||
(!isUnique &&
!!uncoveredPrimaryKeys.length &&
primaryKeyConstraint &&
!omit(table, "single") &&
!omit(primaryKeyConstraint, "single") &&
!omit(constraint, "single"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a lot of potential omits. I'd like to really tighten up how omit works in V5, I think in this case it should be something like !omit(constraint, "backward")


const shouldAddManyRelation =
!isUnique ||
Expand All @@ -171,6 +194,7 @@ export default (function PgBackwardRelationPlugin(
({
getDataFromParsedResolveInfoFragment,
addDataGenerator,
addArgDataGenerator,
}) => {
const sqlFrom = sql.identifier(schema.name, table.name);
addDataGenerator(parsedResolveInfoFragment => {
Expand Down Expand Up @@ -222,12 +246,43 @@ export default (function PgBackwardRelationPlugin(
},
};
});
if (!isUnique) {
addArgDataGenerator(function idArgumentsGenerator(args) {
return {
pgQuery(queryBuilder): void {
const sqlTableAlias = queryBuilder.getTableAlias();
for (const key of parameterKeys)
queryBuilder.where(
sql.fragment`${sqlTableAlias}.${
key.sqlIdentifier
} = ${gql2pg(
args[key.paramName],
key.type,
key.typeModifier
)}`
);
},
};
});
}
return {
description:
stringTag(constraint, "backwardDescription") ||
`Reads a single \`${tableTypeName}\` that is related to this \`${foreignTableTypeName}\`.`,
`${
isUnique ? "Reads" : "Select"
} a single \`${tableTypeName}\` that is related to this \`${foreignTableTypeName}\`.`,
type: gqlTableType,
args: {},
args: parameterKeys.reduce((memo, key) => {
const ArgType = pgGetGqlTypeByTypeIdAndModifier(
key.typeId,
key.typeModifier
);
if (ArgType)
memo[key.paramName] = {
type: new GraphQLNonNull(ArgType),
};
return memo;
}, {}),
resolve: (data, _args, _resolveContext, resolveInfo) => {
const safeAlias = getSafeAliasFromResolveInfo(
resolveInfo
Expand Down
32 changes: 32 additions & 0 deletions packages/graphile-build-pg/src/plugins/PgBasicsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,13 @@ declare module "graphile-build" {
table: PgClass,
constraint: PgConstraint
): string;
rowByRelationBackwardsAndUniqueKeys(
detailedKeys: PgAttribute[],
table: PgClass,
_foreignTable: PgClass,
constraint: PgConstraint,
uniqueConstraint: PgConstraint
): string;
updateByKeys(
detailedKeys: PgAttribute[],
table: PgClass,
Expand Down Expand Up @@ -612,6 +619,31 @@ function makePgBaseInflectors(): Partial<Inflection> {
.join("-and-")}`
);
},
rowByRelationBackwardsAndUniqueKeys(
this: Inflection,
detailedKeys: PgAttribute[],
table: PgClass,
_foreignTable: PgClass,
constraint: PgConstraint,
uniqueConstraint: PgConstraint,
) {
const foreignSingleFieldName = stringTag(
constraint,
"foreignSingleFieldName"
);
if (foreignSingleFieldName) {
return foreignSingleFieldName;
}
const foreignFieldName = stringTag(constraint, "foreignFieldName");
if (foreignFieldName) {
return this.singularize(foreignFieldName);
}
return this.rowByUniqueKeys(
detailedKeys,
table,
uniqueConstraint
);
},
updateByKeys(
this: Inflection,
detailedKeys: PgAttribute[],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ query {
authorId
}
}
compoundKeyByPersonId1(personId1: 2) {
personId1
personId2
extra
}
compoundKeyByPersonId2(personId2: 3) {
personId1
personId2
extra
}
compoundKeysByPersonId1 {
nodes {
personId1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5972,6 +5972,12 @@ Object {
"allPeople": Object {
"nodes": Array [
Object {
"compoundKeyByPersonId1": Object {
"extra": false,
"personId1": 2,
"personId2": 1,
},
"compoundKeyByPersonId2": null,
"compoundKeysByPersonId1": Object {
"nodes": Array [
Object {
Expand Down Expand Up @@ -6012,6 +6018,12 @@ Object {
},
},
Object {
"compoundKeyByPersonId1": null,
"compoundKeyByPersonId2": Object {
"extra": null,
"personId1": 2,
"personId2": 3,
},
"compoundKeysByPersonId1": Object {
"nodes": Array [
Object {
Expand Down Expand Up @@ -6055,6 +6067,12 @@ Object {
},
},
Object {
"compoundKeyByPersonId1": Object {
"extra": null,
"personId1": 2,
"personId2": 3,
},
"compoundKeyByPersonId2": null,
"compoundKeysByPersonId1": Object {
"nodes": Array [],
},
Expand Down Expand Up @@ -6089,6 +6107,12 @@ Object {
},
},
Object {
"compoundKeyByPersonId1": null,
"compoundKeyByPersonId2": Object {
"extra": true,
"personId1": 4,
"personId2": 3,
},
"compoundKeysByPersonId1": Object {
"nodes": Array [
Object {
Expand Down Expand Up @@ -6119,6 +6143,12 @@ Object {
},
},
Object {
"compoundKeyByPersonId1": Object {
"extra": true,
"personId1": 2,
"personId2": 5,
},
"compoundKeyByPersonId2": null,
"compoundKeysByPersonId1": Object {
"nodes": Array [],
},
Expand All @@ -6145,6 +6175,8 @@ Object {
},
},
Object {
"compoundKeyByPersonId1": null,
"compoundKeyByPersonId2": null,
"compoundKeysByPersonId1": Object {
"nodes": Array [],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5773,6 +5773,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down Expand Up @@ -15853,6 +15859,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2863,6 +2863,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5773,6 +5773,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6098,6 +6098,9 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5768,6 +5768,12 @@ type Person implements N {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2863,6 +2863,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1793,6 +1793,12 @@ type Person implements Node {
about: String
aliases: [String]!

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId1(personId1: Int!): CompoundKey

"""Select a single \`CompoundKey\` that is related to this \`Person\`."""
compoundKeyByPersonId2(personId2: Int!): CompoundKey

"""Reads and enables pagination through a set of \`CompoundKey\`."""
compoundKeysByPersonId1(
"""Read all values in the set after (below) this cursor."""
Expand Down
Loading