|
1 | 1 | /* |
2 | | - * Copyright (C) 2017-2024 HERE Europe B.V. |
| 2 | + * Copyright (C) 2017-2025 HERE Europe B.V. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
29 | 29 | import com.here.xyz.util.db.datasource.DataSourceProvider; |
30 | 30 | import com.here.xyz.util.db.datasource.DatabaseSettings.ScriptResourcePath; |
31 | 31 | import java.io.BufferedReader; |
32 | | -import java.io.File; |
33 | 32 | import java.io.FileNotFoundException; |
34 | 33 | import java.io.IOException; |
35 | 34 | import java.io.InputStream; |
@@ -153,9 +152,11 @@ private void install(String targetSchema, boolean deleteBefore) throws SQLExcept |
153 | 152 | } |
154 | 153 |
|
155 | 154 | List<SQLQuery> installationQueries = new ArrayList<>(); |
156 | | -// TODO: Remove uncommented code once "drop schema cascade" issue creating orphan functions is resolved |
157 | | -// if (deleteBefore) |
158 | | -// installationQueries.add(buildDeleteSchemaQuery(getTargetSchema(targetSchema))); |
| 155 | + if (deleteBefore) { |
| 156 | + //TODO: Remove following workaround once "drop schema cascade"-bug creating orphaned functions is fixed in postgres |
| 157 | + installationQueries.addAll(buildDeleteFunctionQueries(loadSchemaFunctions(targetSchema))); |
| 158 | + installationQueries.add(buildDeleteSchemaQuery(getTargetSchema(targetSchema))); |
| 159 | + } |
159 | 160 | installationQueries.addAll(List.of(buildCreateSchemaQuery(targetSchema), buildSetCurrentSearchPathQuery(targetSchema), |
160 | 161 | buildHashFunctionQuery(), buildVersionFunctionQuery(), scriptContent)); |
161 | 162 |
|
@@ -359,11 +360,39 @@ private void uninstall(String scriptVersion) throws SQLException { |
359 | 360 | if (scriptVersion.equals(loadLatestVersion())) |
360 | 361 | throw new IllegalStateException("The script version " + getScriptName() + ":" + scriptVersion |
361 | 362 | + " is still in use on DB " + getDbId() + " and can not be uninstalled."); |
362 | | -// TODO: Remove uncommented code once "drop schema cascade" issue creating orphan functions is resolved |
363 | | -// buildDeleteSchemaQuery(getTargetSchema(scriptVersion)).write(dataSourceProvider); |
| 363 | + |
| 364 | + //TODO: Remove following workaround once "drop schema cascade"-bug creating orphaned functions is fixed in postgres |
| 365 | + String schema = getTargetSchema(scriptVersion); |
| 366 | + batchDeleteFunctions(loadSchemaFunctions(schema)); |
| 367 | + buildDeleteSchemaQuery(schema).write(dataSourceProvider); |
| 368 | + |
364 | 369 | compatibleVersions = new HashMap<>(); //Reset the cache |
365 | 370 | } |
366 | 371 |
|
| 372 | + private void batchDeleteFunctions(List<String> functionSignatures) throws SQLException { |
| 373 | + SQLQuery.batchOf(buildDeleteFunctionQueries(functionSignatures)) |
| 374 | + .writeBatch(dataSourceProvider); |
| 375 | + } |
| 376 | + |
| 377 | + private static List<SQLQuery> buildDeleteFunctionQueries(List<String> functionSignatures) { |
| 378 | + return functionSignatures.stream() |
| 379 | + .map(signature -> new SQLQuery("DROP FUNCTION " + signature)) |
| 380 | + .toList(); |
| 381 | + } |
| 382 | + |
| 383 | + private List<String> loadSchemaFunctions(String schema) throws SQLException { |
| 384 | + return new SQLQuery(""" |
| 385 | + SELECT proc.oid::REGPROCEDURE FROM pg_proc proc LEFT JOIN pg_namespace ns ON proc.pronamespace = ns.oid |
| 386 | + WHERE ns.nspname = #{schema} |
| 387 | + """ |
| 388 | + ).run(dataSourceProvider, rs -> { |
| 389 | + List<String> signatures = new ArrayList<>(); |
| 390 | + while (rs.next()) |
| 391 | + signatures.add(rs.getString("schema_name")); |
| 392 | + return signatures; |
| 393 | + }); |
| 394 | + } |
| 395 | + |
367 | 396 | public void cleanupOldScriptVersions(int versionsToKeep) { |
368 | 397 | try { |
369 | 398 | final List<String> scriptVersions = listInstalledScriptVersions(); |
|
0 commit comments