Skip to content

Commit cbac06e

Browse files
committed
add an optional pgColumnFilter for the columns plugin
closes #65
1 parent 1c53afb commit cbac06e

File tree

5 files changed

+1471
-146
lines changed

5 files changed

+1471
-146
lines changed

packages/graphile-build-pg/src/plugins/PgColumnsPlugin.js

Lines changed: 145 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,46 @@ import type { Plugin } from "graphile-build";
66
const nullableIf = (condition, Type) =>
77
condition ? Type : new GraphQLNonNull(Type);
88

9+
const defaultPgColumnFilter = (..._) => true;
10+
911
export default (function PgColumnsPlugin(
1012
builder,
11-
{ pgInflection: inflection }
13+
{ pgInflection: inflection, pgColumnFilter = defaultPgColumnFilter }
1214
) {
13-
builder.hook(
14-
"GraphQLObjectType:fields",
15-
(
15+
builder.hook("GraphQLObjectType:fields", (fields, build, context) => {
16+
const {
17+
extend,
18+
pgGqlTypeByTypeId: gqlTypeByTypeId,
19+
pgIntrospectionResultsByKind: introspectionResultsByKind,
20+
pgSql: sql,
21+
pg2gql,
22+
getAliasFromResolveInfo,
23+
pgTweakFragmentForType,
24+
} = build;
25+
const {
26+
scope: { isPgRowType, isPgCompoundType, pgIntrospection: table },
27+
fieldWithHooks,
28+
} = context;
29+
if (
30+
!(isPgRowType || isPgCompoundType) ||
31+
!table ||
32+
table.kind !== "class"
33+
) {
34+
return fields;
35+
}
36+
return extend(
1637
fields,
17-
{
18-
extend,
19-
pgGqlTypeByTypeId: gqlTypeByTypeId,
20-
pgIntrospectionResultsByKind: introspectionResultsByKind,
21-
pgSql: sql,
22-
pg2gql,
23-
getAliasFromResolveInfo,
24-
pgTweakFragmentForType,
25-
},
26-
{
27-
scope: { isPgRowType, isPgCompoundType, pgIntrospection: table },
28-
fieldWithHooks,
29-
}
30-
) => {
31-
if (
32-
!(isPgRowType || isPgCompoundType) ||
33-
!table ||
34-
table.kind !== "class"
35-
) {
36-
return fields;
37-
}
38-
return extend(
39-
fields,
40-
introspectionResultsByKind.attribute
41-
.filter(attr => attr.classId === table.id)
42-
.reduce((memo, attr) => {
43-
/*
38+
introspectionResultsByKind.attribute
39+
.filter(attr => attr.classId === table.id)
40+
.filter(attr =>
41+
pgColumnFilter(
42+
attr,
43+
build,
44+
Object.assign({}, context, { type: "GraphQLObjectType" })
45+
)
46+
)
47+
.reduce((memo, attr) => {
48+
/*
4449
attr =
4550
{ kind: 'attribute',
4651
classId: '6546809',
@@ -51,122 +56,116 @@ export default (function PgColumnsPlugin(
5156
isNotNull: false,
5257
hasDefault: false }
5358
*/
54-
const fieldName = inflection.column(
55-
attr.name,
56-
table.name,
57-
table.namespaceName
58-
);
59-
memo[
60-
fieldName
61-
] = fieldWithHooks(
62-
fieldName,
63-
({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => {
64-
const ReturnType =
65-
gqlTypeByTypeId[attr.typeId] || GraphQLString;
66-
addDataGenerator(parsedResolveInfoFragment => {
67-
const { alias } = parsedResolveInfoFragment;
68-
if (attr.type.type === "c") {
69-
return {
70-
pgQuery: queryBuilder => {
71-
// json_build_object
72-
/*
73-
queryBuilder.select(
74-
sql.identifier(queryBuilder.getTableAlias(), attr.name),
75-
alias
76-
);
77-
*/
78-
const resolveData = getDataFromParsedResolveInfoFragment(
79-
parsedResolveInfoFragment,
80-
ReturnType
81-
);
82-
const jsonBuildObject = queryFromResolveData(
83-
sql.identifier(Symbol()), // Ignore!
84-
sql.fragment`(${queryBuilder.getTableAlias()}.${sql.identifier(
59+
const fieldName = inflection.column(
60+
attr.name,
61+
table.name,
62+
table.namespaceName
63+
);
64+
memo[
65+
fieldName
66+
] = fieldWithHooks(
67+
fieldName,
68+
({ getDataFromParsedResolveInfoFragment, addDataGenerator }) => {
69+
const ReturnType = gqlTypeByTypeId[attr.typeId] || GraphQLString;
70+
addDataGenerator(parsedResolveInfoFragment => {
71+
const { alias } = parsedResolveInfoFragment;
72+
if (attr.type.type === "c") {
73+
return {
74+
pgQuery: queryBuilder => {
75+
// json_build_object
76+
/*
77+
queryBuilder.select(
78+
sql.identifier(queryBuilder.getTableAlias(), attr.name),
79+
alias
80+
);
81+
*/
82+
const resolveData = getDataFromParsedResolveInfoFragment(
83+
parsedResolveInfoFragment,
84+
ReturnType
85+
);
86+
const jsonBuildObject = queryFromResolveData(
87+
sql.identifier(Symbol()), // Ignore!
88+
sql.fragment`(${queryBuilder.getTableAlias()}.${sql.identifier(
89+
attr.name
90+
)})`, // The brackets are necessary to stop the parser getting confused, ref: https://www.postgresql.org/docs/9.6/static/rowtypes.html#ROWTYPES-ACCESSING
91+
resolveData,
92+
{ onlyJsonField: true }
93+
);
94+
queryBuilder.select(jsonBuildObject, alias);
95+
},
96+
};
97+
} else {
98+
return {
99+
pgQuery: queryBuilder => {
100+
queryBuilder.select(
101+
pgTweakFragmentForType(
102+
sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(
85103
attr.name
86-
)})`, // The brackets are necessary to stop the parser getting confused, ref: https://www.postgresql.org/docs/9.6/static/rowtypes.html#ROWTYPES-ACCESSING
87-
resolveData,
88-
{ onlyJsonField: true }
89-
);
90-
queryBuilder.select(jsonBuildObject, alias);
91-
},
92-
};
93-
} else {
94-
return {
95-
pgQuery: queryBuilder => {
96-
queryBuilder.select(
97-
pgTweakFragmentForType(
98-
sql.fragment`${queryBuilder.getTableAlias()}.${sql.identifier(
99-
attr.name
100-
)}`,
101-
attr.type
102-
),
103-
alias
104-
);
105-
},
106-
};
107-
}
108-
});
109-
return {
110-
description: attr.description,
111-
type: nullableIf(!attr.isNotNull, ReturnType),
112-
resolve: (data, _args, _context, resolveInfo) => {
113-
const alias = getAliasFromResolveInfo(resolveInfo);
114-
return pg2gql(data[alias], attr.type);
115-
},
116-
};
117-
}
118-
);
119-
return memo;
120-
}, {})
121-
);
122-
}
123-
);
124-
builder.hook(
125-
"GraphQLInputObjectType:fields",
126-
(
127-
fields,
128-
{
129-
extend,
130-
pgGqlInputTypeByTypeId: gqlInputTypeByTypeId,
131-
pgIntrospectionResultsByKind: introspectionResultsByKind,
104+
)}`,
105+
attr.type
106+
),
107+
alias
108+
);
109+
},
110+
};
111+
}
112+
});
113+
return {
114+
description: attr.description,
115+
type: nullableIf(!attr.isNotNull, ReturnType),
116+
resolve: (data, _args, _context, resolveInfo) => {
117+
const alias = getAliasFromResolveInfo(resolveInfo);
118+
return pg2gql(data[alias], attr.type);
119+
},
120+
};
121+
}
122+
);
123+
return memo;
124+
}, {})
125+
);
126+
});
127+
builder.hook("GraphQLInputObjectType:fields", (fields, build, context) => {
128+
const {
129+
extend,
130+
pgGqlInputTypeByTypeId: gqlInputTypeByTypeId,
131+
pgIntrospectionResultsByKind: introspectionResultsByKind,
132+
} = build;
133+
const {
134+
scope: {
135+
isPgRowType,
136+
isPgCompoundType,
137+
isPgPatch,
138+
pgIntrospection: table,
139+
pgAddSubfield,
132140
},
133-
{
134-
scope: {
135-
isPgRowType,
136-
isPgCompoundType,
137-
isPgPatch,
138-
pgIntrospection: table,
139-
pgAddSubfield,
140-
},
141-
}
142-
) => {
143-
if (
144-
!(isPgRowType || isPgCompoundType) ||
145-
!table ||
146-
table.kind !== "class"
147-
) {
148-
return fields;
149-
}
150-
return extend(
151-
fields,
152-
introspectionResultsByKind.attribute
153-
.filter(attr => attr.classId === table.id)
154-
.reduce((memo, attr) => {
155-
const fieldName = inflection.column(
156-
attr.name,
157-
table.name,
158-
table.namespaceName
159-
);
160-
memo[fieldName] = pgAddSubfield(fieldName, attr.name, attr.type, {
161-
description: attr.description,
162-
type: nullableIf(
163-
isPgPatch || !attr.isNotNull || attr.hasDefault,
164-
gqlInputTypeByTypeId[attr.typeId] || GraphQLString
165-
),
166-
});
167-
return memo;
168-
}, {})
169-
);
141+
} = context;
142+
if (
143+
!(isPgRowType || isPgCompoundType) ||
144+
!table ||
145+
table.kind !== "class"
146+
) {
147+
return fields;
170148
}
171-
);
149+
return extend(
150+
fields,
151+
introspectionResultsByKind.attribute
152+
.filter(attr => attr.classId === table.id)
153+
.filter(attr => pgColumnFilter(attr, build, context))
154+
.reduce((memo, attr) => {
155+
const fieldName = inflection.column(
156+
attr.name,
157+
table.name,
158+
table.namespaceName
159+
);
160+
memo[fieldName] = pgAddSubfield(fieldName, attr.name, attr.type, {
161+
description: attr.description,
162+
type: nullableIf(
163+
isPgPatch || !attr.isNotNull || attr.hasDefault,
164+
gqlInputTypeByTypeId[attr.typeId] || GraphQLString
165+
),
166+
});
167+
return memo;
168+
}, {})
169+
);
170+
});
172171
}: Plugin);

0 commit comments

Comments
 (0)