Skip to content

Commit edbe365

Browse files
committed
Remove duplication
1 parent a933b6d commit edbe365

File tree

1 file changed

+54
-120
lines changed

1 file changed

+54
-120
lines changed

baremaps-core/src/main/java/org/apache/baremaps/tilestore/postgres/PostgresTileStore.java

Lines changed: 54 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -127,22 +127,8 @@ public ByteBuffer read(TileCoord tileCoord) throws TileStoreException {
127127
* @param zoom the zoom level
128128
* @return the prepared query
129129
*/
130-
protected Query prepareQuery(int zoom) {
131-
if (postgresVersion >= 16) {
132-
return prepareNewQuery(zoom);
133-
} else {
134-
return prepareLegacyQuery(zoom);
135-
}
136-
}
137-
138-
/**
139-
* Prepare the sql query for a given zoom level that uses the new version of postgresql (>= 16).
140-
*
141-
* @param zoom the zoom level
142-
* @return the prepared query
143-
*/
144130
@SuppressWarnings("squid:S3776")
145-
private Query prepareNewQuery(int zoom) {
131+
protected Query prepareQuery(int zoom) {
146132
// Initialize a builder for the tile sql
147133
var tileSql = new StringBuilder();
148134
tileSql.append("SELECT ");
@@ -179,17 +165,10 @@ private Query prepareNewQuery(int zoom) {
179165
.replace(";", "")
180166
.replace("?", "??")
181167
.replace("$zoom", String.valueOf(zoom));
182-
var querySqlWithParams = String.format(
183-
"""
184-
SELECT
185-
mvtData.id AS id,
186-
mvtData.tags - 'id' AS tags,
187-
ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
188-
FROM (%s) AS mvtData
189-
WHERE mvtData.geom IS NOT NULL
190-
AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
191-
""",
192-
querySql);
168+
169+
var querySqlWithParams =
170+
postgresVersion >= 16 ? prepareNewQuery(querySql) : prepareLegacyQuery(querySql);
171+
193172
layerSql.append(querySqlWithParams);
194173

195174
// Increase the parameter count (e.g. ?) and sql count
@@ -223,113 +202,68 @@ AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
223202
tileSql.append(tileQueryTail);
224203

225204
// Format the sql query
226-
var sql = tileSql.toString().replace("\n", " ");
205+
var sql = tileSql.toString().replaceAll("\\s+", " ");
227206

228207
return new Query(sql, paramCount);
229208
}
230209

231210
/**
232-
* Prepare the sql query for a given zoom level that uses the legacy versions of postgresql (<
233-
* 16).
211+
* Prepare the sql query for the new versions of postgresql (>= 16).
212+
* <p>
213+
* Recent versions of the postgresql database better optimize subqueries. Using subqueries is more
214+
* robust and allows for more complex queries.
234215
*
235-
* @param zoom the zoom level
216+
* @param sql the sql query
236217
* @return the prepared query
237218
*/
238219
@SuppressWarnings("squid:S3776")
239-
private Query prepareLegacyQuery(int zoom) {
240-
// Initialize a builder for the tile sql
241-
var tileSql = new StringBuilder();
242-
tileSql.append("SELECT ");
243-
244-
// Iterate over the layers and keep track of the number of layers and parameters included in the
245-
// final sql
246-
var layers = tileset.getVectorLayers();
247-
var layerCount = 0;
248-
var paramCount = 0;
249-
for (var layer : layers) {
250-
251-
// Initialize a builder for the layer sql
252-
var layerSql = new StringBuilder();
253-
var layerHead = String.format("(SELECT ST_AsMVT(mvtGeom.*, '%s') FROM (", layer.getId());
254-
layerSql.append(layerHead);
255-
256-
// Iterate over the queries and keep track of the number of queries included in the final
257-
// sql
258-
var queries = layer.getQueries();
259-
var queryCount = 0;
260-
for (var query : queries) {
261-
262-
// Only include the sql if the zoom level is in the range
263-
if (query.getMinzoom() <= zoom && zoom < query.getMaxzoom()) {
264-
265-
// Add a union between queries
266-
if (queryCount > 0) {
267-
layerSql.append("UNION ALL ");
268-
}
269-
270-
// Add the sql to the layer sql
271-
var querySql = query.getSql().trim()
272-
.replaceAll("\\s+", " ")
273-
.replace(";", "")
274-
.replace("?", "??")
275-
.replace("$zoom", String.valueOf(zoom));
276-
277-
// Append a new condition or a where clause
278-
if (querySql.toLowerCase().contains("where")) {
279-
querySql += " AND ";
280-
} else {
281-
querySql += " WHERE ";
282-
}
283-
284-
// Append the condition to the query sql
285-
querySql +=
286-
"geom IS NOT NULL AND geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))";
287-
288-
var querySqlWithParams = String.format(
289-
"""
290-
SELECT
291-
mvtData.id AS id,
292-
mvtData.tags - 'id' AS tags,
293-
ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
294-
FROM (%s) as mvtData
295-
""",
296-
querySql);
297-
layerSql.append(querySqlWithParams);
298-
299-
// Increase the parameter count (e.g. ?) and sql count
300-
paramCount += 6;
301-
queryCount++;
302-
}
303-
}
304-
305-
// Add the tail of the layer sql
306-
var layerQueryTail = ") AS mvtGeom)";
307-
layerSql.append(layerQueryTail);
308-
309-
// Only include the layer sql if queries were included for this layer
310-
if (queryCount > 0) {
311-
312-
// Add the concatenation between layer queries
313-
if (layerCount > 0) {
314-
tileSql.append(" || ");
315-
}
220+
private String prepareNewQuery(final String sql) {
221+
return String.format(
222+
"""
223+
SELECT
224+
mvtData.id AS id,
225+
mvtData.tags - 'id' AS tags,
226+
ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
227+
FROM (%s) AS mvtData
228+
WHERE mvtData.geom IS NOT NULL
229+
AND mvtData.geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))
230+
""",
231+
sql);
232+
}
316233

317-
// Add the layer sql to the mvt sql
318-
tileSql.append(layerSql);
234+
/**
235+
* Prepare the sql query for the legacy versions of postgresql (< 16).
236+
* <p>
237+
* Older versions of the postgresql database do not optimize subqueries. Therefore, the conditions
238+
* are appended to the sql query, which is less robust and error-prone.
239+
*
240+
* @param sql the sql query
241+
* @return the prepared query
242+
*/
243+
@SuppressWarnings("squid:S3776")
244+
private String prepareLegacyQuery(final String sql) {
245+
String query = sql;
319246

320-
// Increase the layer count
321-
layerCount++;
322-
}
247+
// Append a new condition or a where clause
248+
if (sql.toLowerCase().contains("where")) {
249+
query += " AND ";
250+
} else {
251+
query += " WHERE ";
323252
}
324253

325-
// Add the tail of the tile sql
326-
var tileQueryTail = " AS mvtTile";
327-
tileSql.append(tileQueryTail);
328-
329-
// Format the sql query
330-
var sql = tileSql.toString().replaceAll("\\s+", " ");
331-
332-
return new Query(sql, paramCount);
254+
// Append the condition to the query sql
255+
query +=
256+
"geom IS NOT NULL AND geom && ST_TileEnvelope(?, ?, ?, margin => (64.0/4096))";
257+
258+
return String.format(
259+
"""
260+
SELECT
261+
mvtData.id AS id,
262+
mvtData.tags - 'id' AS tags,
263+
ST_AsMVTGeom(mvtData.geom, ST_TileEnvelope(?, ?, ?)) AS geom
264+
FROM (%s) as mvtData
265+
""",
266+
query);
333267
}
334268

335269
/**

0 commit comments

Comments
 (0)