88// except according to the terms contained in the LICENSE file.
99
1010const { sql } = require ( 'slonik' ) ;
11+ const { arrayHasElements } = require ( '../../util/util' ) ;
1112
1213
1314const stateFilterToQueryFragments = ( field , states , pgType = 'text' ) => {
@@ -17,37 +18,36 @@ const stateFilterToQueryFragments = (field, states, pgType = 'text') => {
1718 const theFilters = [ alsoNullFilter , alsoOtherStatesFilter ] . filter ( el => el !== null ) ;
1819 switch ( theFilters . length ) {
1920 case 1 :
20- return sql `AND ${ theFilters [ 0 ] } ` ;
21+ return sql `${ theFilters [ 0 ] } ` ;
2122 case 2 :
22- return sql `AND ${ theFilters [ 0 ] } OR ${ theFilters [ 1 ] } ` ;
23+ return sql `${ theFilters [ 0 ] } OR ${ theFilters [ 1 ] } ` ;
2324 default :
2425 return sql `` ;
2526 }
2627} ;
2728
28- const getSubmissionFeatureCollectionGeoJson = ( formPK , fieldPaths , submitterIds , TSTZRange , reviewStates , deleted , limit ) => ( { db } ) => {
29-
30- const formFieldFilter = fieldPaths . length ? sql `AND ffgeo.path = ANY (${ sql . array ( fieldPaths , 'text' ) } )` : sql `AND ffgeo.is_default` ;
31- const doPathInProperties = fieldPaths . length ? sql `, 'properties', NULL` : sql `, 'properties', json_build_object('fieldpath', path)` ;
32- const doAggregateByPath = fieldPaths . length ? sql `` : sql `, path` ;
33- const submitterFilter = submitterIds . length ? sql `AND sdef."submitterId" = ANY(${ sql . array ( submitterIds , 'int4' ) } )` : sql `` ;
34- const TSTZRangeFilter = TSTZRange ? sql `AND sdef."createdAt" <@ tstzrange(${ TSTZRange [ 0 ] } , ${ TSTZRange [ 1 ] } , ${ TSTZRange [ 2 ] } )` : sql `` ;
35- const reviewStateFilter = reviewStates . length ? stateFilterToQueryFragments ( [ 'sub' , 'reviewState' ] , reviewStates ) : sql `` ;
36- const deletedFilter = deleted ? sql `IS NOT NULL` : sql `IS NULL` ;
29+ const getSubmissionFeatureCollectionGeoJson = ( formPK , IDs , fieldPaths , submitterIds , TSTZRange , reviewStates , deleted , limit , onlyCurrent = true , assumeRootSubmissionId = true ) => ( { db } ) => {
30+ const idFilterPredicate = sql `AND ${ sql . identifier ( [ onlyCurrent ? 'sub' : 'sdef' , 'instanceId' ] ) } = ANY(${ sql . array ( IDs , 'text' ) } )` ;
31+ const submissionIdFilter = ( onlyCurrent && arrayHasElements ( IDs ) ) ? idFilterPredicate : sql `` ;
32+ const submissionDefIdFilter = ( ! onlyCurrent && arrayHasElements ( IDs ) ) ? idFilterPredicate : sql `` ;
33+ const onlyCurrentFilter = onlyCurrent ? sql `AND sdef.current` : sql `` ;
34+ const formFieldFilter = arrayHasElements ( fieldPaths ) ? ( fieldPaths . includes ( 'all' ) ? sql `` : sql `AND ffgeo.path = ANY (${ sql . array ( fieldPaths , 'text' ) } )` ) : sql `AND ffgeo.is_default` ;
35+ const doPathInProperties = arrayHasElements ( fieldPaths ) ? sql `, 'properties', NULL` : sql `, 'properties', json_build_object('fieldpath', path)` ;
36+ const doAggregateByPath = arrayHasElements ( fieldPaths ) ? sql `` : sql `, path` ;
37+ const submitterFilter = arrayHasElements ( submitterIds ) ? sql `AND sdef."submitterId" = ANY(${ sql . array ( submitterIds , 'int4' ) } )` : sql `` ;
38+ const TSTZRangeFilter = arrayHasElements ( TSTZRange ) ? sql `AND sdef."createdAt" <@ tstzrange(${ TSTZRange [ 0 ] } , ${ TSTZRange [ 1 ] } , ${ TSTZRange [ 2 ] } )` : sql `` ;
39+ const reviewStateFilter = arrayHasElements ( reviewStates ) ? sql `AND ${ stateFilterToQueryFragments ( [ 'sub' , 'reviewState' ] , reviewStates ) } ` : sql `` ;
40+ const deletedFilter = deleted ? sql `AND sub."deletedAt" IS NOT NULL` : sql `AND sub."deletedAt" IS NULL` ;
3741 const queryLimit = limit ? sql `LIMIT ${ limit } ` : sql `` ;
38-
42+ // data coming from revisions are in some cases expected to take on the instanceId of the root of the edit-lineage. And in some other cases, not.
43+ const reportedInstanceIdPicker = assumeRootSubmissionId ? sql `CASE WHEN root THEN sdef."instanceId" ELSE sub."instanceId" END as "instanceId"` : sql `sdef."instanceId"` ;
3944 return db . oneFirst ( sql `
4045 -- all targeted submission fields, with info on whether the geojson-value is cached
4146 WITH geo_needed AS (
4247 SELECT
4348 sxg.submission_def_id IS NOT NULL as is_cached,
4449 sdef.id as submission_def_id,
45- CASE
46- WHEN root
47- THEN sdef."instanceId"
48- ELSE
49- sub."instanceId" -- revisions take on the instanceId of the root of the edit-lineage
50- END as "instanceId",
50+ ${ reportedInstanceIdPicker } ,
5151 ffgeo.type,
5252 ffgeo.fieldhash,
5353 ffgeo.repeatgroup_cardinality,
@@ -60,15 +60,15 @@ const getSubmissionFeatureCollectionGeoJson = (formPK, fieldPaths, submitterIds,
6060 fdef."formId" = ${ formPK }
6161 AND
6262 sdef."formDefId" = fdef.id
63- AND
64- sdef.current
63+ ${ submissionDefIdFilter }
64+ ${ onlyCurrentFilter }
6565 ${ submitterFilter }
6666 ${ TSTZRangeFilter }
6767 )
6868 INNER JOIN submissions sub ON (
6969 sdef."submissionId" = sub.id
70- AND
71- sub."deletedAt" ${ deletedFilter }
70+ ${ submissionIdFilter }
71+ ${ deletedFilter }
7272 ${ reviewStateFilter }
7373 )
7474 INNER JOIN form_field_geo ffgeo ON (
@@ -183,11 +183,12 @@ const getSubmissionFeatureCollectionGeoJson = (formPK, fieldPaths, submitterIds,
183183} ;
184184
185185
186- const getEntityFeatureCollectionGeoJson = ( datasetPK , creatorIds , TSTZRange , conflictStates , deleted , limit ) => ( { db } ) => {
186+ const getEntityFeatureCollectionGeoJson = ( datasetPK , IDs , creatorIds , TSTZRange , conflictStates , deleted , limit ) => ( { db } ) => {
187187
188- const creatorFilter = creatorIds . length ? sql `AND e."creatorId" = ANY(${ sql . array ( creatorIds , 'int4' ) } )` : sql `` ;
189- const TSTZRangeFilter = TSTZRange ? sql `AND e."createdAt" <@ tstzrange(${ TSTZRange [ 0 ] } , ${ TSTZRange [ 1 ] } , ${ TSTZRange [ 2 ] } )` : sql `` ;
190- const conflictStatusFilter = conflictStates . length ? stateFilterToQueryFragments ( [ 'e' , 'conflict' ] , conflictStates , 'conflictType' ) : sql `` ;
188+ const idFilter = arrayHasElements ( IDs ) ? sql `AND e.uuid = ANY(${ sql . array ( IDs , 'text' ) } )` : sql `` ; // TODO: this should be a uuid[] array once/if the entities."uuid" column is converted from varchar(255) to uuid
189+ const creatorFilter = arrayHasElements ( creatorIds ) ? sql `AND e."creatorId" = ANY(${ sql . array ( creatorIds , 'int4' ) } )` : sql `` ;
190+ const TSTZRangeFilter = arrayHasElements ( TSTZRange ) ? sql `AND e."createdAt" <@ tstzrange(${ TSTZRange [ 0 ] } , ${ TSTZRange [ 1 ] } , ${ TSTZRange [ 2 ] } )` : sql `` ;
191+ const conflictStatusFilter = arrayHasElements ( conflictStates ) ? sql `AND ${ stateFilterToQueryFragments ( [ 'e' , 'conflict' ] , conflictStates , 'conflictType' ) } ` : sql `` ;
191192 const deletedFilter = deleted ? sql `IS NOT NULL` : sql `IS NULL` ;
192193 const queryLimit = limit ? sql `LIMIT ${ limit } ` : sql `` ;
193194
@@ -208,6 +209,7 @@ const getEntityFeatureCollectionGeoJson = (datasetPK, creatorIds, TSTZRange, con
208209 e."datasetId" = ds.id
209210 AND
210211 e."deletedAt" ${ deletedFilter }
212+ ${ idFilter }
211213 ${ creatorFilter }
212214 ${ TSTZRangeFilter }
213215 ${ conflictStatusFilter }
0 commit comments