postgraphile-plugin-connection-filter-postgis
postgraphile-plugin-connection-filter-postgis copied to clipboard
extend plugin for additional feature: st_dwithin
I would like to extend the plugin to add the function st_dwithin. The postgis function is described here: https://postgis.net/docs/ST_DWithin.html I already made the following changes:
Use this draft to compare: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16
Modified the plugin itself by adding the function, typenames and other properties: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-3a39e3760ed128b03242f96a7d1ceeefR140
Modified fixtures: https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-59621d53d50374d9716154d866c9e7e9R10
With the modified geography fixtures I am currently getting some output:
[GraphQLError: function st_dwithin(geography, geography) does not exist]
In the geometry.graphql fixtures I added a second input value named $radius;
https://github.com/graphile-contrib/postgraphile-plugin-connection-filter-postgis/pull/16/files#diff-6638aac95b170cc236faa41b2939f63cR1
Which results in the following error:
[GraphQLError: Syntax Error: Expected Name, found $]
Additional notes: I've updated the pg library to work with node v14
here to follow :)
Does the draft PR actually work? I think you're getting [GraphQLError: function st_dwithin(geography, geography) does not exist] because it should be st_dwithin(geography, geography, double persision) (https://postgis.net/docs/ST_DWithin.html).
I'm in the process of trying to add st_dwithin support and this is what I added so far. Would welcome inputs on improvements.
// 3 Param Functions
for (const [fn, baseTypeNames, operatorName, description] of [
[
'ST_DWithin',
[GEOMETRY, GEOGRAPHY],
'dwithin',
'Returns true if the geometries are within the specified distance of one another. https://postgis.net/docs/ST_DWithin.html',
],
] as Operator[]) {
for (const baseTypeName of baseTypeNames) {
const sqlGisFunction =
pgGISExtension.namespaceName === 'public'
? sql.identifier(fn.toLowerCase())
: sql.identifier(pgGISExtension.namespaceName, fn.toLowerCase())
specs.push({
typeNames: gqlTypeNamesByGisBaseTypeName[baseTypeName],
operatorName,
description,
resolveType: (fieldType) =>
new GraphQLInputObjectType({
name: 'STDWithinInputs',
fields: {
gg2: {
type: fieldType,
description: 'The reference location',
},
distance: {
type: GraphQLInt,
description: 'distance_meters',
},
},
}),
resolve: (sqlIdentifier, sqlValue, input: any) => {
const { gg2, distance } = input as {
gg2: string
distance: number
}
if (!Array.isArray(sqlValue)) {
throw new Error('Expected sqlValue to be an array')
}
// Example sqlValue:
// [{"type":"RAW","text":"st_geomfromgeojson("},{"type":"VALUE","value":"123"},{"type":"RAW","text":"::text)::"},{"type":"IDENTIFIER","names":["public","geography"]}]
sqlValue[1] = sql.value(gg2)
return sql.query`${sqlGisFunction}(${sqlIdentifier}, ${sqlValue}, ${sql.value(
distance,
)})`
},
})
}
}