From 031bc5c59d9c244faf698b1bbd1a028f0ac9e3c2 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 21 Nov 2024 15:57:58 +0100 Subject: [PATCH 01/19] optimize temporary limits db writings and db reading Signed-off-by: Etienne LESOT --- network-store-server/pom.xml | 2 - .../store/server/NetworkStoreRepository.java | 73 ++++++----- .../network/store/server/QueryCatalog.java | 67 ++++++++++ .../powsybl/network/store/server/Utils.java | 3 + .../network/store/server/dto/LimitsInfos.java | 2 +- .../migrations/TemporaryLimitsMigration.java | 123 ++++++++++++++++++ .../changesets/changelog_20241121T110000Z.xml | 17 +++ ...imit_violation-arrays_20241121T110000Z.sql | 17 +++ .../db/changelog/db.changelog-master.yaml | 4 + 9 files changed, 271 insertions(+), 37 deletions(-) create mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java create mode 100644 network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml create mode 100644 network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql diff --git a/network-store-server/pom.xml b/network-store-server/pom.xml index 4a1c9f8e..feda1924 100644 --- a/network-store-server/pom.xml +++ b/network-store-server/pom.xml @@ -70,7 +70,6 @@ org.postgresql postgresql - runtime org.springframework.boot @@ -107,7 +106,6 @@ org.liquibase liquibase-core - runtime org.slf4j diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index d17a66f6..c528dde1 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -30,10 +30,7 @@ import org.springframework.stereotype.Repository; import javax.sql.DataSource; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.sql.*; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -279,7 +276,7 @@ public void deleteNetwork(UUID uuid) { } } // Delete of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.executeUpdate(); } @@ -339,7 +336,7 @@ public void deleteNetwork(UUID uuid, int variantNum) { } } // Delete of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsVariantQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsVariantQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.executeUpdate(); @@ -453,7 +450,7 @@ public void cloneNetworkElements(Connection connection, UUID uuid, UUID targetUu } } // Copy of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneTemporaryLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneNewTemporaryLimitsQuery())) { preparedStmt.setString(1, targetUuid.toString()); preparedStmt.setInt(2, targetVariantNum); preparedStmt.setString(3, uuid.toString()); @@ -1757,7 +1754,7 @@ public Map> getTemporaryLimitsWithInCl return Collections.emptyMap(); } try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewTemporaryLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < valuesForInClause.size(); i++) { @@ -1816,7 +1813,7 @@ private Map mergeLimitsIntoLimitsInfos(Map> getTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitQuery(columnNameForWhereClause)); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewTemporaryLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.setString(3, valueForWhereClause); @@ -1844,25 +1841,31 @@ private Map> innerGetTemporaryLimits(P try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { - OwnerInfo owner = new OwnerInfo(); - TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); // In order, from the QueryCatalog.buildTemporaryLimitQuery SQL query : // equipmentId, equipmentType, networkUuid, variantNum, side, limitType, name, value, acceptableDuration, fictitious owner.setEquipmentId(resultSet.getString(1)); owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); owner.setVariantNum(resultSet.getInt(4)); - temporaryLimit.setOperationalLimitsGroupId(resultSet.getString(5)); - temporaryLimit.setSide(resultSet.getInt(6)); - temporaryLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); - temporaryLimit.setName(resultSet.getString(8)); - temporaryLimit.setValue(resultSet.getDouble(9)); - temporaryLimit.setAcceptableDuration(resultSet.getInt(10)); - temporaryLimit.setFictitious(resultSet.getBoolean(11)); - - map.computeIfAbsent(owner, k -> new ArrayList<>()); - map.get(owner).add(temporaryLimit); + Array array = resultSet.getArray(5); + Object[] objects = (Object[]) array.getArray(); + List temporaryLimits = new ArrayList<>(); + for (Object tl : objects) { + String[] split = tl.toString().replace("(", "").replace(")", "").replace("\"", "").split(","); + TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); + temporaryLimit.setOperationalLimitsGroupId(split[0]); + temporaryLimit.setSide(Integer.valueOf(split[1])); + temporaryLimit.setLimitType(LimitType.valueOf(split[2])); + temporaryLimit.setName(split[3]); + temporaryLimit.setValue(Double.parseDouble(split[4])); + temporaryLimit.setAcceptableDuration(Integer.valueOf(split[5])); + temporaryLimit.setFictitious(split[6].equals("t")); + temporaryLimits.add(temporaryLimit); + } + if (!temporaryLimits.isEmpty()) { + map.put(owner, temporaryLimits); + } } return map; } @@ -1915,26 +1918,28 @@ public void insertTemporaryLimits(Map limitsInfos) { Map> temporaryLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTemporaryLimits())); try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertTemporaryLimitsQuery())) { - List values = new ArrayList<>(11); + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewTemporaryLimitsQuery())) { + List values = new ArrayList<>(5); List>> list = new ArrayList<>(temporaryLimits.entrySet()); for (List>> subUnit : Lists.partition(list, BATCH_SIZE)) { for (Map.Entry> entry : subUnit) { - for (TemporaryLimitAttributes temporaryLimit : entry.getValue()) { + if (!entry.getValue().isEmpty()) { values.clear(); - // In order, from the QueryCatalog.buildInsertTemporaryLimitsQuery SQL query : - // equipmentId, equipmentType, networkUuid, variantNum, operationalLimitsGroupId, side, limitType, name, value, acceptableDuration, fictitious values.add(entry.getKey().getEquipmentId()); values.add(entry.getKey().getEquipmentType().toString()); values.add(entry.getKey().getNetworkUuid()); values.add(entry.getKey().getVariantNum()); - values.add(temporaryLimit.getOperationalLimitsGroupId()); - values.add(temporaryLimit.getSide()); - values.add(temporaryLimit.getLimitType().toString()); - values.add(temporaryLimit.getName()); - values.add(temporaryLimit.getValue()); - values.add(temporaryLimit.getAcceptableDuration()); - values.add(temporaryLimit.isFictitious()); + Array array = connection.createArrayOf("TemporaryLimitClass", entry.getValue().stream().map(temporaryLimitAttributes -> + "(" + temporaryLimitAttributes.getOperationalLimitsGroupId() + "," + + temporaryLimitAttributes.getSide() + "," + + temporaryLimitAttributes.getLimitType() + "," + + temporaryLimitAttributes.getName() + "," + + temporaryLimitAttributes.getValue() + "," + + temporaryLimitAttributes.getAcceptableDuration() + "," + + temporaryLimitAttributes.isFictitious() + + ")") + .toArray()); + values.add(array); bindValues(preparedStmt, values, mapper); preparedStmt.addBatch(); } @@ -2036,7 +2041,7 @@ private void deletePermanentLimits(UUID networkUuid, int variantNum, String equi private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < equipmentIds.size(); i++) { diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index 8025f140..7d730226 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -41,6 +41,7 @@ public final class QueryCatalog { static final String ALPHA_COLUMN = "alpha"; static final String OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "operationalLimitsGroupId"; static final String SELECTED_OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "selectedOperationalLimitsGroupId"; + static final String TEMPORARY_LIMIT_ARRAY = "temporarylimits"; static final String TAP_CHANGER_STEP_TABLE = "tapChangerStep"; static final String REGULATING_POINT_TABLE = "regulatingPoint"; static final String REGULATION_MODE = "regulationMode"; @@ -354,6 +355,72 @@ public static String buildDeleteTemporaryLimitsQuery() { NETWORK_UUID_COLUMN + " = ?"; } + // new temporary limits + public static String buildInsertNewTemporaryLimitsQuery() { + return "insert into newtemporarylimits(" + + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMIT_ARRAY + ") " + + " values (?, ?, ?, ?, ?)"; + } + + public static String buildDeleteNewTemporaryLimitsQuery() { + return "delete from newtemporarylimits where " + + NETWORK_UUID_COLUMN + " = ?"; + } + + public static String buildDeleteNewTemporaryLimitsVariantQuery() { + return "delete from newtemporarylimits where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ?"; + } + + public static String buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "delete from newtemporarylimits where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + EQUIPMENT_ID_COLUMN + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + + public static String buildNewTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + TEMPORARY_LIMIT_ARRAY + + " from newtemporarylimits where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + + public static String buildCloneNewTemporaryLimitsQuery() { + return "insert into newtemporarylimits(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMIT_ARRAY + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMIT_ARRAY + " from newtemporarylimits where " + NETWORK_UUID_COLUMN + + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; + } + + public static String buildNewTemporaryLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + TEMPORARY_LIMIT_ARRAY + + " from newtemporarylimits where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; + } + // permanent Limits public static String buildClonePermanentLimitsQuery() { return "insert into permanentlimit(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java b/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java index d6a26128..6b1d3767 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.UncheckedIOException; +import java.sql.Array; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -48,6 +49,8 @@ static void bindValues(PreparedStatement statement, List values, ObjectM statement.setDate(++idx, new java.sql.Date(d.toEpochMilli())); } else if (o == null || !isCustomTypeJsonified(o.getClass())) { statement.setObject(++idx, o); + } else if (o instanceof Array array) { + statement.setArray(++idx, array); } else { try { statement.setObject(++idx, mapper.writeValueAsString(o)); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/dto/LimitsInfos.java b/network-store-server/src/main/java/com/powsybl/network/store/server/dto/LimitsInfos.java index 019adecf..fce7a0ad 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/dto/LimitsInfos.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/dto/LimitsInfos.java @@ -30,7 +30,7 @@ @Schema(description = "limits attributes") public class LimitsInfos { - @Schema(description = "List of permeant limits") + @Schema(description = "List of permanent limits") private List permanentLimits = new ArrayList<>(); @Schema(description = "List of temporary limits") diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java new file mode 100644 index 00000000..02210bcd --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java @@ -0,0 +1,123 @@ +/* + Copyright (c) 2024, RTE (http://www.rte-france.com) + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package com.powsybl.network.store.server.migrations; + +import com.google.common.collect.Lists; +import com.powsybl.iidm.network.LimitType; +import com.powsybl.network.store.model.ResourceType; +import com.powsybl.network.store.model.TemporaryLimitAttributes; +import com.powsybl.network.store.server.dto.OwnerInfo; +import liquibase.change.custom.CustomSqlChange; +import liquibase.database.Database; +import liquibase.exception.CustomChangeException; +import liquibase.exception.SetupException; +import liquibase.exception.ValidationErrors; +import liquibase.resource.ResourceAccessor; +import liquibase.statement.SqlStatement; +import liquibase.statement.core.InsertStatement; +import org.postgresql.jdbc.PgConnection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Array; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * @author Etienne Lesot + */ +public class TemporaryLimitsMigration implements CustomSqlChange { + private static final Logger LOGGER = LoggerFactory.getLogger(TemporaryLimitsMigration.class); + + @Override + public SqlStatement[] generateStatements(Database database) throws CustomChangeException { + PgConnection connection = (PgConnection) database.getConnection(); + List statements = new ArrayList<>(); + String requestStatement = "select equipmentid, equipmenttype, networkUuid, variantNum, operationalLimitsGroupId, side," + + "limitType, name, value_, acceptableDuration, fictitious from temporarylimit"; + try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { + Map> oldTemporaryLimits = getTemporaryLimits(stmt); + prepareStatements(oldTemporaryLimits, connection, database, statements); + } catch (SQLException e) { + throw new CustomChangeException(e); + } + return statements.toArray(new SqlStatement[0]); + } + + private Map> getTemporaryLimits(PreparedStatement stmt) throws SQLException { + ResultSet resultSet = stmt.executeQuery(); + Map> map = new HashMap<>(); + while (resultSet.next()) { + TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); + OwnerInfo owner = new OwnerInfo(); + owner.setEquipmentId(resultSet.getString(1)); + owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); + owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); + owner.setVariantNum(resultSet.getInt(4)); + temporaryLimit.setOperationalLimitsGroupId(resultSet.getString(5)); + temporaryLimit.setSide(resultSet.getInt(6)); + temporaryLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); + temporaryLimit.setName(resultSet.getString(8)); + temporaryLimit.setValue(resultSet.getDouble(9)); + temporaryLimit.setAcceptableDuration(resultSet.getInt(10)); + temporaryLimit.setFictitious(resultSet.getBoolean(11)); + map.computeIfAbsent(owner, k -> new ArrayList<>()); + map.get(owner).add(temporaryLimit); + } + return map; + } + + private void prepareStatements(Map> oldTemporaryLimits, PgConnection connection, Database database, List statements) throws SQLException { + List>> list = new ArrayList<>(oldTemporaryLimits.entrySet()); + for (List>> subUnit : Lists.partition(list, 1000)) { + for (Map.Entry> entry : subUnit) { + if (!entry.getValue().isEmpty()) { + Array array = connection.createArrayOf("TemporaryLimitClass", entry.getValue().stream().map(temporaryLimitAttributes -> + "(" + temporaryLimitAttributes.getOperationalLimitsGroupId() + "," + + temporaryLimitAttributes.getSide() + "," + + temporaryLimitAttributes.getLimitType() + "," + + temporaryLimitAttributes.getName() + "," + + temporaryLimitAttributes.getValue() + "," + + temporaryLimitAttributes.getAcceptableDuration() + "," + + temporaryLimitAttributes.isFictitious() + + ")") + .toArray()); + statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newtemporarylimits") + .addColumnValue("equipmentId", entry.getKey().getEquipmentId()) + .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) + .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) + .addColumnValue("variantnum", entry.getKey().getVariantNum()) + .addColumnValue("temporarylimits", array) + ); + } + + } + } + } + + @Override + public String getConfirmationMessage() { + return "temporary limits was successfully updated"; + } + + @Override + public void setUp() throws SetupException { + LOGGER.info("Set up migration for temporary limits"); + } + + @Override + public void setFileOpener(ResourceAccessor resourceAccessor) { + LOGGER.info("Set file opener for temporary limits"); + } + + @Override + public ValidationErrors validate(Database database) { + return new ValidationErrors(); + } +} diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml new file mode 100644 index 00000000..66a6f1c1 --- /dev/null +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file diff --git a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql new file mode 100644 index 00000000..343ea463 --- /dev/null +++ b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql @@ -0,0 +1,17 @@ +CREATE TYPE TemporaryLimitClass AS ( + operationallimitsgroupid VARCHAR(50), + side INTEGER, + limittype VARCHAR(50), + name_ VARCHAR(255), + value_ FLOAT8, + acceptableduration INTEGER, + fictitious BOOLEAN + ); + +CREATE TABLE newtemporarylimits ( + equipmentid VARCHAR(255), + equipmenttype VARCHAR(255), + networkuuid VARCHAR(255), + variantnum INTEGER, + temporarylimits TemporaryLimitClass[] +); \ No newline at end of file diff --git a/network-store-server/src/main/resources/db/changelog/db.changelog-master.yaml b/network-store-server/src/main/resources/db/changelog/db.changelog-master.yaml index a3b273af..84fde3c1 100644 --- a/network-store-server/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/network-store-server/src/main/resources/db/changelog/db.changelog-master.yaml @@ -87,3 +87,7 @@ databaseChangeLog: - include: file: changesets/changelog_20241031T110000Z.xml relativeToChangelogFile: true + + - include: + file: changesets/changelog_20241121T110000Z.xml + relativeToChangelogFile: true From db4983e1241d2efec8ef41ef4c19af318d2f1562 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 22 Nov 2024 15:47:51 +0100 Subject: [PATCH 02/19] replace array sql type by jackson text Signed-off-by: Etienne LESOT --- .../store/server/NetworkStoreRepository.java | 42 +++++--------- .../store/server/TemporaryLimitSqlData.java | 57 +++++++++++++++++++ .../powsybl/network/store/server/Utils.java | 3 - .../migrations/TemporaryLimitsMigration.java | 25 ++++---- ...imit_violation-arrays_20241121T110000Z.sql | 12 +--- 5 files changed, 82 insertions(+), 57 deletions(-) create mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index c528dde1..a28a8230 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -6,9 +6,9 @@ */ package com.powsybl.network.store.server; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.google.common.base.Stopwatch; import com.google.common.collect.Lists; @@ -1838,6 +1838,7 @@ public Map> getPermanentLimits(UUID ne } private Map> innerGetTemporaryLimits(PreparedStatement preparedStmt) throws SQLException { + preparedStmt.getConnection().getTypeMap().put("TemporaryLimitClass", TemporaryLimitSqlData.class); try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { @@ -1848,26 +1849,16 @@ private Map> innerGetTemporaryLimits(P owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); owner.setVariantNum(resultSet.getInt(4)); - Array array = resultSet.getArray(5); - Object[] objects = (Object[]) array.getArray(); - List temporaryLimits = new ArrayList<>(); - for (Object tl : objects) { - String[] split = tl.toString().replace("(", "").replace(")", "").replace("\"", "").split(","); - TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); - temporaryLimit.setOperationalLimitsGroupId(split[0]); - temporaryLimit.setSide(Integer.valueOf(split[1])); - temporaryLimit.setLimitType(LimitType.valueOf(split[2])); - temporaryLimit.setName(split[3]); - temporaryLimit.setValue(Double.parseDouble(split[4])); - temporaryLimit.setAcceptableDuration(Integer.valueOf(split[5])); - temporaryLimit.setFictitious(split[6].equals("t")); - temporaryLimits.add(temporaryLimit); - } + String temporaryLimitData = resultSet.getString(5); + List parsedTemporaryLimitData = mapper.readValue(temporaryLimitData, new TypeReference<>() { }); + List temporaryLimits = parsedTemporaryLimitData.stream().map(TemporaryLimitSqlData::toTemporaryLimitAttributes).toList(); if (!temporaryLimits.isEmpty()) { map.put(owner, temporaryLimits); } } return map; + } catch (JsonProcessingException e) { + throw new RuntimeException(e); } } @@ -1918,6 +1909,7 @@ public void insertTemporaryLimits(Map limitsInfos) { Map> temporaryLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTemporaryLimits())); try (var connection = dataSource.getConnection()) { + connection.getTypeMap().put("TemporaryLimitClass", TemporaryLimitSqlData.class); try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewTemporaryLimitsQuery())) { List values = new ArrayList<>(5); List>> list = new ArrayList<>(temporaryLimits.entrySet()); @@ -1929,19 +1921,11 @@ public void insertTemporaryLimits(Map limitsInfos) { values.add(entry.getKey().getEquipmentType().toString()); values.add(entry.getKey().getNetworkUuid()); values.add(entry.getKey().getVariantNum()); - Array array = connection.createArrayOf("TemporaryLimitClass", entry.getValue().stream().map(temporaryLimitAttributes -> - "(" + temporaryLimitAttributes.getOperationalLimitsGroupId() + "," - + temporaryLimitAttributes.getSide() + "," - + temporaryLimitAttributes.getLimitType() + "," - + temporaryLimitAttributes.getName() + "," - + temporaryLimitAttributes.getValue() + "," - + temporaryLimitAttributes.getAcceptableDuration() + "," - + temporaryLimitAttributes.isFictitious() - + ")") - .toArray()); - values.add(array); + values.add(entry.getValue().stream() + .map(TemporaryLimitSqlData::of).toList()); bindValues(preparedStmt, values, mapper); preparedStmt.addBatch(); + } } preparedStmt.executeBatch(); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java new file mode 100644 index 00000000..c2697d62 --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package com.powsybl.network.store.server; + +import com.powsybl.iidm.network.LimitType; +import com.powsybl.network.store.model.TemporaryLimitAttributes; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +/** + * @author Etienne Lesot + */ +@ToString +@Builder +@AllArgsConstructor +@Getter +public class TemporaryLimitSqlData { + private String operationalLimitsGroupId; + private Integer side; + private LimitType limitType; + private String name; + private double value; + private Integer acceptableDuration; + private boolean fictitious; + + public TemporaryLimitSqlData() { } + + public static TemporaryLimitSqlData of(TemporaryLimitAttributes temporaryLimit) { + return TemporaryLimitSqlData.builder() + .operationalLimitsGroupId(temporaryLimit.getOperationalLimitsGroupId()) + .side(temporaryLimit.getSide()) + .limitType(temporaryLimit.getLimitType()) + .name(temporaryLimit.getName()) + .value(temporaryLimit.getValue()) + .acceptableDuration(temporaryLimit.getAcceptableDuration()) + .fictitious(temporaryLimit.isFictitious()) + .build(); + } + + public TemporaryLimitAttributes toTemporaryLimitAttributes() { + return TemporaryLimitAttributes.builder() + .operationalLimitsGroupId(operationalLimitsGroupId) + .side(side) + .limitType(limitType) + .name(name) + .value(value) + .acceptableDuration(acceptableDuration) + .fictitious(fictitious) + .build(); + } +} diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java b/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java index 6b1d3767..d6a26128 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/Utils.java @@ -14,7 +14,6 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.sql.Array; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -49,8 +48,6 @@ static void bindValues(PreparedStatement statement, List values, ObjectM statement.setDate(++idx, new java.sql.Date(d.toEpochMilli())); } else if (o == null || !isCustomTypeJsonified(o.getClass())) { statement.setObject(++idx, o); - } else if (o instanceof Array array) { - statement.setArray(++idx, array); } else { try { statement.setObject(++idx, mapper.writeValueAsString(o)); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java index 02210bcd..eb2f41f8 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java @@ -6,10 +6,13 @@ */ package com.powsybl.network.store.server.migrations; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Lists; import com.powsybl.iidm.network.LimitType; import com.powsybl.network.store.model.ResourceType; import com.powsybl.network.store.model.TemporaryLimitAttributes; +import com.powsybl.network.store.server.TemporaryLimitSqlData; import com.powsybl.network.store.server.dto.OwnerInfo; import liquibase.change.custom.CustomSqlChange; import liquibase.database.Database; @@ -23,7 +26,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Array; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -34,6 +36,7 @@ */ public class TemporaryLimitsMigration implements CustomSqlChange { private static final Logger LOGGER = LoggerFactory.getLogger(TemporaryLimitsMigration.class); + private final ObjectMapper mapper = new ObjectMapper(); @Override public SqlStatement[] generateStatements(Database database) throws CustomChangeException { @@ -43,9 +46,11 @@ public SqlStatement[] generateStatements(Database database) throws CustomChangeE "limitType, name, value_, acceptableDuration, fictitious from temporarylimit"; try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { Map> oldTemporaryLimits = getTemporaryLimits(stmt); - prepareStatements(oldTemporaryLimits, connection, database, statements); + prepareStatements(oldTemporaryLimits, database, statements); } catch (SQLException e) { throw new CustomChangeException(e); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); } return statements.toArray(new SqlStatement[0]); } @@ -73,27 +78,19 @@ private Map> getTemporaryLimits(Prepar return map; } - private void prepareStatements(Map> oldTemporaryLimits, PgConnection connection, Database database, List statements) throws SQLException { + private void prepareStatements(Map> oldTemporaryLimits, Database database, List statements) throws SQLException, JsonProcessingException { List>> list = new ArrayList<>(oldTemporaryLimits.entrySet()); for (List>> subUnit : Lists.partition(list, 1000)) { for (Map.Entry> entry : subUnit) { if (!entry.getValue().isEmpty()) { - Array array = connection.createArrayOf("TemporaryLimitClass", entry.getValue().stream().map(temporaryLimitAttributes -> - "(" + temporaryLimitAttributes.getOperationalLimitsGroupId() + "," - + temporaryLimitAttributes.getSide() + "," - + temporaryLimitAttributes.getLimitType() + "," - + temporaryLimitAttributes.getName() + "," - + temporaryLimitAttributes.getValue() + "," - + temporaryLimitAttributes.getAcceptableDuration() + "," - + temporaryLimitAttributes.isFictitious() - + ")") - .toArray()); + List temporaryLimitSqlData = entry.getValue().stream().map(TemporaryLimitSqlData::of).toList(); + String serializedtemporaryLimitSqlData = mapper.writeValueAsString(temporaryLimitSqlData); statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newtemporarylimits") .addColumnValue("equipmentId", entry.getKey().getEquipmentId()) .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) .addColumnValue("variantnum", entry.getKey().getVariantNum()) - .addColumnValue("temporarylimits", array) + .addColumnValue("temporarylimits", temporaryLimitSqlData) ); } diff --git a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql index 343ea463..c11cc6bf 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql +++ b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql @@ -1,17 +1,7 @@ -CREATE TYPE TemporaryLimitClass AS ( - operationallimitsgroupid VARCHAR(50), - side INTEGER, - limittype VARCHAR(50), - name_ VARCHAR(255), - value_ FLOAT8, - acceptableduration INTEGER, - fictitious BOOLEAN - ); - CREATE TABLE newtemporarylimits ( equipmentid VARCHAR(255), equipmenttype VARCHAR(255), networkuuid VARCHAR(255), variantnum INTEGER, - temporarylimits TemporaryLimitClass[] + temporarylimits TEXT ); \ No newline at end of file From 0287fd3d90a15732971cc7aabf54a2093245db5c Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 22 Nov 2024 16:00:45 +0100 Subject: [PATCH 03/19] fix Signed-off-by: Etienne LESOT --- network-store-server/pom.xml | 1 + .../store/server/NetworkStoreRepository.java | 2 -- .../migrations/TemporaryLimitsMigration.java | 9 +++++---- .../changesets/changelog_20241121T110000Z.xml | 17 +++++++++++++++-- .../limit_violation-arrays_20241121T110000Z.sql | 7 ------- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/network-store-server/pom.xml b/network-store-server/pom.xml index feda1924..a8e37c4a 100644 --- a/network-store-server/pom.xml +++ b/network-store-server/pom.xml @@ -70,6 +70,7 @@ org.postgresql postgresql + runtime org.springframework.boot diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index a28a8230..00402182 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -1838,7 +1838,6 @@ public Map> getPermanentLimits(UUID ne } private Map> innerGetTemporaryLimits(PreparedStatement preparedStmt) throws SQLException { - preparedStmt.getConnection().getTypeMap().put("TemporaryLimitClass", TemporaryLimitSqlData.class); try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { @@ -1909,7 +1908,6 @@ public void insertTemporaryLimits(Map limitsInfos) { Map> temporaryLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTemporaryLimits())); try (var connection = dataSource.getConnection()) { - connection.getTypeMap().put("TemporaryLimitClass", TemporaryLimitSqlData.class); try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewTemporaryLimitsQuery())) { List values = new ArrayList<>(5); List>> list = new ArrayList<>(temporaryLimits.entrySet()); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java index eb2f41f8..5b9e8f0b 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java @@ -16,13 +16,14 @@ import com.powsybl.network.store.server.dto.OwnerInfo; import liquibase.change.custom.CustomSqlChange; import liquibase.database.Database; +import liquibase.database.jvm.JdbcConnection; import liquibase.exception.CustomChangeException; +import liquibase.exception.DatabaseException; import liquibase.exception.SetupException; import liquibase.exception.ValidationErrors; import liquibase.resource.ResourceAccessor; import liquibase.statement.SqlStatement; import liquibase.statement.core.InsertStatement; -import org.postgresql.jdbc.PgConnection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +41,7 @@ public class TemporaryLimitsMigration implements CustomSqlChange { @Override public SqlStatement[] generateStatements(Database database) throws CustomChangeException { - PgConnection connection = (PgConnection) database.getConnection(); + JdbcConnection connection = (JdbcConnection) database.getConnection(); List statements = new ArrayList<>(); String requestStatement = "select equipmentid, equipmenttype, networkUuid, variantNum, operationalLimitsGroupId, side," + "limitType, name, value_, acceptableDuration, fictitious from temporarylimit"; @@ -49,7 +50,7 @@ public SqlStatement[] generateStatements(Database database) throws CustomChangeE prepareStatements(oldTemporaryLimits, database, statements); } catch (SQLException e) { throw new CustomChangeException(e); - } catch (JsonProcessingException e) { + } catch (JsonProcessingException | DatabaseException e) { throw new RuntimeException(e); } return statements.toArray(new SqlStatement[0]); @@ -90,7 +91,7 @@ private void prepareStatements(Map> ol .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) .addColumnValue("variantnum", entry.getKey().getVariantNum()) - .addColumnValue("temporarylimits", temporaryLimitSqlData) + .addColumnValue("temporarylimits", serializedtemporaryLimitSqlData) ); } diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index 66a6f1c1..1813bbce 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -10,8 +10,21 @@ relativeToChangelogFile="true" splitStatements="true" stripComments="true"/> - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql index c11cc6bf..e69de29b 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql +++ b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql @@ -1,7 +0,0 @@ -CREATE TABLE newtemporarylimits ( - equipmentid VARCHAR(255), - equipmenttype VARCHAR(255), - networkuuid VARCHAR(255), - variantnum INTEGER, - temporarylimits TEXT -); \ No newline at end of file From b3889a9028a5f4bfc621801a33333c9a730c0b0c Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 22 Nov 2024 16:36:54 +0100 Subject: [PATCH 04/19] fix Signed-off-by: Etienne LESOT --- .../db/changelog/changesets/changelog_20241121T110000Z.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index 1813bbce..39d229c0 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -11,7 +11,7 @@ splitStatements="true" stripComments="true"/> - + From 778429a09d298a35d05ca630b4319aa0508f5014 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 22 Nov 2024 16:44:14 +0100 Subject: [PATCH 05/19] disable sonar on migration package Signed-off-by: Etienne LESOT --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bc999588..d4b4be58 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,8 @@ 1.0 2.16.0 - + + **/migration/**/* From d611ece0f0a7dc9f23362c7a140c10d0490b3c3b Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 22 Nov 2024 16:58:49 +0100 Subject: [PATCH 06/19] fix Signed-off-by: Etienne LESOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d4b4be58..5e125613 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ 1.0 2.16.0 - **/migration/**/* + **/migrations/**/* From 484702737aff7f5dbbc9465a88dd0026fcc63bc0 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 28 Nov 2024 10:36:47 +0100 Subject: [PATCH 07/19] log temporary limits insertion Signed-off-by: Etienne LESOT --- .../powsybl/network/store/server/NetworkStoreRepository.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index 00402182..24065fff 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -1926,7 +1926,10 @@ public void insertTemporaryLimits(Map limitsInfos) { } } + Stopwatch stopwatch = Stopwatch.createStarted(); preparedStmt.executeBatch(); + stopwatch.stop(); + LOGGER.info("one batch of temporary limits was created in {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS)); } } } catch (SQLException e) { From d0319e5f694fbdccf71a83308d296e3898c05e14 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 29 Nov 2024 14:01:52 +0100 Subject: [PATCH 08/19] refactor permanent limit too and clean Signed-off-by: Etienne LESOT --- .../store/server/NetworkStoreRepository.java | 60 ++--- .../store/server/PermanentLimitSqlData.java | 49 +++++ .../network/store/server/QueryCatalog.java | 206 ++++++------------ .../migrations/PermanentLimitsMigration.java | 118 ++++++++++ .../changesets/changelog_20241121T110000Z.xml | 26 ++- ...imit_violation-arrays_20241121T110000Z.sql | 0 6 files changed, 275 insertions(+), 184 deletions(-) create mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java create mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java delete mode 100644 network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index 24065fff..f3b22373 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -282,7 +282,7 @@ public void deleteNetwork(UUID uuid) { } // Delete permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.executeUpdate(); } @@ -343,7 +343,7 @@ public void deleteNetwork(UUID uuid, int variantNum) { } // Delete permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsVariantQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsVariantQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.executeUpdate(); @@ -459,7 +459,7 @@ public void cloneNetworkElements(Connection connection, UUID uuid, UUID targetUu } // Copy of the permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildClonePermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneNewPermanentLimitsQuery())) { preparedStmt.setString(1, targetUuid.toString()); preparedStmt.setInt(2, targetVariantNum); preparedStmt.setString(3, uuid.toString()); @@ -1772,7 +1772,7 @@ public Map> getPermanentLimitsWithInCl return Collections.emptyMap(); } try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewPermanentLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < valuesForInClause.size(); i++) { @@ -1826,7 +1826,7 @@ public Map> getTemporaryLimits(UUID ne public Map> getPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitQuery(columnNameForWhereClause)); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewPermanentLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.setString(3, valueForWhereClause); @@ -1865,24 +1865,21 @@ private Map> innerGetPermanentLimits(P try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { - OwnerInfo owner = new OwnerInfo(); - PermanentLimitAttributes permanentLimit = new PermanentLimitAttributes(); - // In order, from the QueryCatalog.buildTemporaryLimitQuery SQL query : - // equipmentId, equipmentType, networkUuid, variantNum, side, limitType, name, value, acceptableDuration, fictitious owner.setEquipmentId(resultSet.getString(1)); owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); owner.setVariantNum(resultSet.getInt(4)); - permanentLimit.setOperationalLimitsGroupId(resultSet.getString(5)); - permanentLimit.setSide(resultSet.getInt(6)); - permanentLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); - permanentLimit.setValue(resultSet.getDouble(8)); - - map.computeIfAbsent(owner, k -> new ArrayList<>()); - map.get(owner).add(permanentLimit); + String permanentLimitData = resultSet.getString(5); + List parsedTemporaryLimitData = mapper.readValue(permanentLimitData, new TypeReference<>() { }); + List permanentLimits = parsedTemporaryLimitData.stream().map(PermanentLimitSqlData::toPermanentLimitAttributes).toList(); + if (!permanentLimits.isEmpty()) { + map.put(owner, permanentLimits); + } } return map; + } catch (JsonProcessingException e) { + throw new RuntimeException(e); } } @@ -1926,10 +1923,7 @@ public void insertTemporaryLimits(Map limitsInfos) { } } - Stopwatch stopwatch = Stopwatch.createStarted(); preparedStmt.executeBatch(); - stopwatch.stop(); - LOGGER.info("one batch of temporary limits was created in {} ms", stopwatch.elapsed(TimeUnit.MILLISECONDS)); } } } catch (SQLException e) { @@ -1941,26 +1935,20 @@ public void insertPermanentLimits(Map limitsInfos) { Map> permanentLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getPermanentLimits())); try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertPermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewPermanentLimitsQuery())) { List values = new ArrayList<>(8); List>> list = new ArrayList<>(permanentLimits.entrySet()); for (List>> subUnit : Lists.partition(list, BATCH_SIZE)) { for (Map.Entry> entry : subUnit) { - for (PermanentLimitAttributes permanentLimit : entry.getValue()) { - values.clear(); - // In order, from the QueryCatalog.buildInsertTemporaryLimitsQuery SQL query : - // equipmentId, equipmentType, networkUuid, variantNum, operationalLimitsGroupId, side, limitType, value - values.add(entry.getKey().getEquipmentId()); - values.add(entry.getKey().getEquipmentType().toString()); - values.add(entry.getKey().getNetworkUuid()); - values.add(entry.getKey().getVariantNum()); - values.add(permanentLimit.getOperationalLimitsGroupId()); - values.add(permanentLimit.getSide()); - values.add(permanentLimit.getLimitType().toString()); - values.add(permanentLimit.getValue()); - bindValues(preparedStmt, values, mapper); - preparedStmt.addBatch(); - } + values.clear(); + values.add(entry.getKey().getEquipmentId()); + values.add(entry.getKey().getEquipmentType().toString()); + values.add(entry.getKey().getNetworkUuid()); + values.add(entry.getKey().getVariantNum()); + values.add(entry.getValue().stream() + .map(PermanentLimitSqlData::of).toList()); + bindValues(preparedStmt, values, mapper); + preparedStmt.addBatch(); } preparedStmt.executeBatch(); } @@ -2041,7 +2029,7 @@ private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < equipmentIds.size(); i++) { diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java new file mode 100644 index 00000000..8333ba0f --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package com.powsybl.network.store.server; + +import com.powsybl.iidm.network.LimitType; +import com.powsybl.network.store.server.dto.PermanentLimitAttributes; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +/** + * @author Etienne Lesot + */ +@ToString +@Builder +@AllArgsConstructor +@Getter +public class PermanentLimitSqlData { + + private String operationalLimitsGroupId; + private double value; + private Integer side; + private LimitType limitType; + + public PermanentLimitSqlData() { } + + public static PermanentLimitSqlData of(PermanentLimitAttributes permanentLimitAttributes) { + return PermanentLimitSqlData.builder() + .operationalLimitsGroupId(permanentLimitAttributes.getOperationalLimitsGroupId()) + .value(permanentLimitAttributes.getValue()) + .side(permanentLimitAttributes.getSide()) + .limitType(permanentLimitAttributes.getLimitType()) + .build(); + } + + public PermanentLimitAttributes toPermanentLimitAttributes() { + return PermanentLimitAttributes.builder() + .operationalLimitsGroupId(operationalLimitsGroupId) + .value(value) + .side(side) + .limitType(limitType) + .build(); + } +} diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index 7d730226..a8a4b0d8 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -41,7 +41,8 @@ public final class QueryCatalog { static final String ALPHA_COLUMN = "alpha"; static final String OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "operationalLimitsGroupId"; static final String SELECTED_OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "selectedOperationalLimitsGroupId"; - static final String TEMPORARY_LIMIT_ARRAY = "temporarylimits"; + static final String TEMPORARY_LIMITS = "temporarylimits"; + static final String PERMANENT_LIMITS = "permanentlimits"; static final String TAP_CHANGER_STEP_TABLE = "tapChangerStep"; static final String REGULATING_POINT_TABLE = "regulatingPoint"; static final String REGULATION_MODE = "regulationMode"; @@ -279,98 +280,22 @@ public static String buildCloneNetworksQuery(Collection columns) { "where uuid = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - // Temporary Limits - public static String buildCloneTemporaryLimitsQuery() { - return "insert into temporarylimit(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + NAME_COLUMN + - ", value_, acceptableDuration, fictitious) " + "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + NAME_COLUMN + - ", value_, acceptableDuration, fictitious from temporarylimit where " + NETWORK_UUID_COLUMN + - " = ? and " + VARIANT_NUM_COLUMN + " = ?"; - } - - public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { - return "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + - SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + - NAME_COLUMN + ", " + - "value_, acceptableDuration, fictitious " + - "from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - columnNameForWhereClause + " = ?"; - } - - public static String buildTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { - if (numberOfValues < 1) { - throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); - } - return "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + - SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + - NAME_COLUMN + ", " + - "value_, acceptableDuration, fictitious " + - "from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - columnNameForInClause + " in (" + - "?, ".repeat(numberOfValues - 1) + "?)"; - } - - public static String buildInsertTemporaryLimitsQuery() { - return "insert into temporarylimit(" + - EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + - NAME_COLUMN + ", value_, acceptableDuration, fictitious)" + - " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - } - - public static String buildDeleteTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { - if (numberOfValues < 1) { - throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); - } - return "delete from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - EQUIPMENT_ID_COLUMN + " in (" + - "?, ".repeat(numberOfValues - 1) + "?)"; - } - - public static String buildDeleteTemporaryLimitsVariantQuery() { - return "delete from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ?"; - } - - public static String buildDeleteTemporaryLimitsQuery() { - return "delete from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ?"; - } - - // new temporary limits + // temporary limits public static String buildInsertNewTemporaryLimitsQuery() { - return "insert into newtemporarylimits(" + + return "insert into " + TEMPORARY_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMIT_ARRAY + ") " + + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + " values (?, ?, ?, ?, ?)"; } public static String buildDeleteNewTemporaryLimitsQuery() { - return "delete from newtemporarylimits where " + + return "delete from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ?"; } public static String buildDeleteNewTemporaryLimitsVariantQuery() { - return "delete from newtemporarylimits where " + + return "delete from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } @@ -379,7 +304,7 @@ public static String buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(int nu if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } - return "delete from newtemporarylimits where " + + return "delete from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + EQUIPMENT_ID_COLUMN + " in (" + @@ -394,8 +319,8 @@ public static String buildNewTemporaryLimitWithInClauseQuery(String columnNameFo EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + - TEMPORARY_LIMIT_ARRAY + - " from newtemporarylimits where " + + TEMPORARY_LIMITS + + " from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForInClause + " in (" + @@ -403,9 +328,9 @@ public static String buildNewTemporaryLimitWithInClauseQuery(String columnNameFo } public static String buildCloneNewTemporaryLimitsQuery() { - return "insert into newtemporarylimits(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMIT_ARRAY + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMIT_ARRAY + " from newtemporarylimits where " + NETWORK_UUID_COLUMN + + return "insert into " + TEMPORARY_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMITS + " from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } @@ -414,82 +339,77 @@ public static String buildNewTemporaryLimitQuery(String columnNameForWhereClause EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + - TEMPORARY_LIMIT_ARRAY + - " from newtemporarylimits where " + + TEMPORARY_LIMITS + + " from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ?"; } - // permanent Limits - public static String buildClonePermanentLimitsQuery() { - return "insert into permanentlimit(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", value_) " + "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", value_ from permanentlimit where " + NETWORK_UUID_COLUMN + - " = ? and " + VARIANT_NUM_COLUMN + " = ?"; + // permanent limits + public static String buildInsertNewPermanentLimitsQuery() { + return "insert into " + PERMANENT_LIMITS + " (" + + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + + " values (?, ?, ?, ?, ?)"; } - public static String buildPermanentLimitQuery(String columnNameForWhereClause) { - return "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + - SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + - "value_ " + - "from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - columnNameForWhereClause + " = ?"; + public static String buildDeleteNewPermanentLimitsQuery() { + return "delete from " + PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ?"; } - public static String buildPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + public static String buildDeleteNewPermanentLimitsVariantQuery() { + return "delete from " + PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ?"; + } + + public static String buildDeleteNewPermanentLimitsVariantEquipmentINQuery(int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } - return "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + - SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", " + - "value_ " + - "from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - columnNameForInClause + " in (" + - "?, ".repeat(numberOfValues - 1) + "?)"; - } - - public static String buildInsertPermanentLimitsQuery() { - return "insert into permanentlimit(" + - EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + - VARIANT_NUM_COLUMN + ", " + - OPERATIONAL_LIMITS_GROUP_ID_COLUMN + ", " + SIDE_COLUMN + ", " + LIMIT_TYPE_COLUMN + ", value_)" + - " values (?, ?, ?, ?, ?, ?, ?, ?)"; + return "delete from " + PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + EQUIPMENT_ID_COLUMN + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeletePermanentLimitsVariantEquipmentINQuery(int numberOfValues) { + public static String buildNewPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } - return "delete from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ? and " + - EQUIPMENT_ID_COLUMN + " in (" + - "?, ".repeat(numberOfValues - 1) + "?)"; + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + PERMANENT_LIMITS + + " from " + PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeletePermanentLimitsVariantQuery() { - return "delete from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ?"; + public static String buildCloneNewPermanentLimitsQuery() { + return "insert into " + PERMANENT_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + PERMANENT_LIMITS + " from " + PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - public static String buildDeletePermanentLimitsQuery() { - return "delete from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ?"; + public static String buildNewPermanentLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + PERMANENT_LIMITS + + " from " + PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; } // Reactive Capability Curve Point diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java new file mode 100644 index 00000000..39299182 --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java @@ -0,0 +1,118 @@ +/* + Copyright (c) 2024, RTE (http://www.rte-france.com) + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package com.powsybl.network.store.server.migrations; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.Lists; +import com.powsybl.iidm.network.LimitType; +import com.powsybl.network.store.model.ResourceType; +import com.powsybl.network.store.server.PermanentLimitSqlData; +import com.powsybl.network.store.server.dto.OwnerInfo; +import com.powsybl.network.store.server.dto.PermanentLimitAttributes; +import liquibase.change.custom.CustomSqlChange; +import liquibase.database.Database; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.CustomChangeException; +import liquibase.exception.DatabaseException; +import liquibase.exception.SetupException; +import liquibase.exception.ValidationErrors; +import liquibase.resource.ResourceAccessor; +import liquibase.statement.SqlStatement; +import liquibase.statement.core.InsertStatement; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; + +/** + * @author Etienne Lesot + */ +public class PermanentLimitsMigration implements CustomSqlChange { + private static final Logger LOGGER = LoggerFactory.getLogger(PermanentLimitsMigration.class); + private final ObjectMapper mapper = new ObjectMapper(); + + @Override + public SqlStatement[] generateStatements(Database database) throws CustomChangeException { + JdbcConnection connection = (JdbcConnection) database.getConnection(); + List statements = new ArrayList<>(); + String requestStatement = "select equipmentid, equipmenttype, networkUuid, variantNum, operationalLimitsGroupId, side," + + "limitType, value_ from permanentlimit"; + try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { + Map> oldPermanentLimits = getPermanentLimits(stmt); + prepareStatements(oldPermanentLimits, database, statements); + } catch (SQLException e) { + throw new CustomChangeException(e); + } catch (JsonProcessingException | DatabaseException e) { + throw new RuntimeException(e); + } + return statements.toArray(new SqlStatement[0]); + } + + private Map> getPermanentLimits(PreparedStatement stmt) throws SQLException { + ResultSet resultSet = stmt.executeQuery(); + Map> map = new HashMap<>(); + while (resultSet.next()) { + PermanentLimitAttributes permanentLimit = new PermanentLimitAttributes(); + OwnerInfo owner = new OwnerInfo(); + owner.setEquipmentId(resultSet.getString(1)); + owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); + owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); + owner.setVariantNum(resultSet.getInt(4)); + permanentLimit.setOperationalLimitsGroupId(resultSet.getString(5)); + permanentLimit.setSide(resultSet.getInt(6)); + permanentLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); + permanentLimit.setValue(resultSet.getDouble(9)); + map.computeIfAbsent(owner, k -> new ArrayList<>()); + map.get(owner).add(permanentLimit); + } + return map; + } + + private void prepareStatements(Map> oldPermanentLimits, Database database, List statements) throws SQLException, JsonProcessingException { + List>> list = new ArrayList<>(oldPermanentLimits.entrySet()); + for (List>> subUnit : Lists.partition(list, 1000)) { + for (Map.Entry> entry : subUnit) { + if (!entry.getValue().isEmpty()) { + List permanentLimitSqlData = entry.getValue().stream().map(PermanentLimitSqlData::of).toList(); + String serializedpermanentLimitSqlData = mapper.writeValueAsString(permanentLimitSqlData); + statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newpermanentlimits") + .addColumnValue("equipmentId", entry.getKey().getEquipmentId()) + .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) + .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) + .addColumnValue("variantnum", entry.getKey().getVariantNum()) + .addColumnValue("permanentlimits", serializedpermanentLimitSqlData) + ); + } + + } + } + } + + @Override + public String getConfirmationMessage() { + return "permanent limits was successfully updated"; + } + + @Override + public void setUp() throws SetupException { + LOGGER.info("Set up migration for permanent limits"); + } + + @Override + public void setFileOpener(ResourceAccessor resourceAccessor) { + LOGGER.info("Set file opener for permanent limits"); + } + + @Override + public ValidationErrors validate(Database database) { + return new ValidationErrors(); + } +} diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index 39d229c0..b1cec951 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -5,11 +5,6 @@ https://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"> - @@ -25,6 +20,27 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql b/network-store-server/src/main/resources/db/changelog/changesets/limit_violation-arrays_20241121T110000Z.sql deleted file mode 100644 index e69de29b..00000000 From 38ffe4c0c0fda7633ceddfdf358335cc716315ee Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 29 Nov 2024 14:29:39 +0100 Subject: [PATCH 09/19] exclude sonar duplication for migrations server Signed-off-by: Etienne LESOT --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 5e125613..fb6bd817 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,7 @@ 2.16.0 **/migrations/**/* + **/migrations/**/* From 45bbcec6aa7893391d9386974c4b59a7fe02ca57 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 29 Nov 2024 15:47:03 +0100 Subject: [PATCH 10/19] fix disable duplication on migrations Signed-off-by: Etienne LESOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb6bd817..7bfb6b6a 100644 --- a/pom.xml +++ b/pom.xml @@ -52,7 +52,7 @@ 2.16.0 **/migrations/**/* - **/migrations/**/* + **/migrations/**/* From ba52b95b74fbb790a84b340b77ec3fb046438775 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 29 Nov 2024 16:06:18 +0100 Subject: [PATCH 11/19] fix sonar Signed-off-by: Etienne LESOT --- .../store/server/migrations/PermanentLimitsMigration.java | 6 ++---- .../store/server/migrations/TemporaryLimitsMigration.java | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java index 39299182..f42e4206 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java @@ -48,10 +48,8 @@ public SqlStatement[] generateStatements(Database database) throws CustomChangeE try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { Map> oldPermanentLimits = getPermanentLimits(stmt); prepareStatements(oldPermanentLimits, database, statements); - } catch (SQLException e) { + } catch (SQLException | JsonProcessingException | DatabaseException e) { throw new CustomChangeException(e); - } catch (JsonProcessingException | DatabaseException e) { - throw new RuntimeException(e); } return statements.toArray(new SqlStatement[0]); } @@ -76,7 +74,7 @@ private Map> getPermanentLimits(Prepar return map; } - private void prepareStatements(Map> oldPermanentLimits, Database database, List statements) throws SQLException, JsonProcessingException { + private void prepareStatements(Map> oldPermanentLimits, Database database, List statements) throws JsonProcessingException { List>> list = new ArrayList<>(oldPermanentLimits.entrySet()); for (List>> subUnit : Lists.partition(list, 1000)) { for (Map.Entry> entry : subUnit) { diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java index 5b9e8f0b..4214e6b6 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java @@ -48,10 +48,8 @@ public SqlStatement[] generateStatements(Database database) throws CustomChangeE try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { Map> oldTemporaryLimits = getTemporaryLimits(stmt); prepareStatements(oldTemporaryLimits, database, statements); - } catch (SQLException e) { + } catch (SQLException | JsonProcessingException | DatabaseException e) { throw new CustomChangeException(e); - } catch (JsonProcessingException | DatabaseException e) { - throw new RuntimeException(e); } return statements.toArray(new SqlStatement[0]); } @@ -79,7 +77,7 @@ private Map> getTemporaryLimits(Prepar return map; } - private void prepareStatements(Map> oldTemporaryLimits, Database database, List statements) throws SQLException, JsonProcessingException { + private void prepareStatements(Map> oldTemporaryLimits, Database database, List statements) throws JsonProcessingException { List>> list = new ArrayList<>(oldTemporaryLimits.entrySet()); for (List>> subUnit : Lists.partition(list, 1000)) { for (Map.Entry> entry : subUnit) { From 042ee22d01465cd45af7e5d3fbbcc11d5cf930e1 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Tue, 3 Dec 2024 10:58:57 +0100 Subject: [PATCH 12/19] review and fixes Signed-off-by: Etienne LESOT --- .../store/server/NetworkStoreRepository.java | 30 ++++++++++--------- .../network/store/server/QueryCatalog.java | 28 ++++++++--------- .../{ => json}/PermanentLimitSqlData.java | 2 +- .../{ => json}/TemporaryLimitSqlData.java | 2 +- .../migrations/PermanentLimitsMigration.java | 10 +++---- .../migrations/TemporaryLimitsMigration.java | 8 ++--- .../changesets/changelog_20241121T110000Z.xml | 4 ++- 7 files changed, 44 insertions(+), 40 deletions(-) rename network-store-server/src/main/java/com/powsybl/network/store/server/{ => json}/PermanentLimitSqlData.java (97%) rename network-store-server/src/main/java/com/powsybl/network/store/server/{ => json}/TemporaryLimitSqlData.java (97%) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index f3b22373..7aa3d861 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -22,6 +22,8 @@ import com.powsybl.network.store.server.dto.PermanentLimitAttributes; import com.powsybl.network.store.server.exceptions.JsonApiErrorResponseException; import com.powsybl.network.store.server.exceptions.UncheckedSqlException; +import com.powsybl.network.store.server.json.PermanentLimitSqlData; +import com.powsybl.network.store.server.json.TemporaryLimitSqlData; import com.powsybl.ws.commons.LogUtils; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.tuple.Pair; @@ -276,13 +278,13 @@ public void deleteNetwork(UUID uuid) { } } // Delete of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.executeUpdate(); } // Delete permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.executeUpdate(); } @@ -336,14 +338,14 @@ public void deleteNetwork(UUID uuid, int variantNum) { } } // Delete of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsVariantQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsVariantQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.executeUpdate(); } // Delete permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsVariantQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsVariantQuery())) { preparedStmt.setObject(1, uuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.executeUpdate(); @@ -450,7 +452,7 @@ public void cloneNetworkElements(Connection connection, UUID uuid, UUID targetUu } } // Copy of the temporary limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneNewTemporaryLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneTemporaryLimitsQuery())) { preparedStmt.setString(1, targetUuid.toString()); preparedStmt.setInt(2, targetVariantNum); preparedStmt.setString(3, uuid.toString()); @@ -459,7 +461,7 @@ public void cloneNetworkElements(Connection connection, UUID uuid, UUID targetUu } // Copy of the permanent limits (which are not Identifiables objects) - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildCloneNewPermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildClonePermanentLimitsQuery())) { preparedStmt.setString(1, targetUuid.toString()); preparedStmt.setInt(2, targetVariantNum); preparedStmt.setString(3, uuid.toString()); @@ -1754,7 +1756,7 @@ public Map> getTemporaryLimitsWithInCl return Collections.emptyMap(); } try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewTemporaryLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < valuesForInClause.size(); i++) { @@ -1772,7 +1774,7 @@ public Map> getPermanentLimitsWithInCl return Collections.emptyMap(); } try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewPermanentLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < valuesForInClause.size(); i++) { @@ -1813,7 +1815,7 @@ private Map mergeLimitsIntoLimitsInfos(Map> getTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewTemporaryLimitQuery(columnNameForWhereClause)); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.setString(3, valueForWhereClause); @@ -1826,7 +1828,7 @@ public Map> getTemporaryLimits(UUID ne public Map> getPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - var preparedStmt = connection.prepareStatement(QueryCatalog.buildNewPermanentLimitQuery(columnNameForWhereClause)); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); preparedStmt.setString(3, valueForWhereClause); @@ -1905,7 +1907,7 @@ public void insertTemporaryLimits(Map limitsInfos) { Map> temporaryLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTemporaryLimits())); try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewTemporaryLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertTemporaryLimitsQuery())) { List values = new ArrayList<>(5); List>> list = new ArrayList<>(temporaryLimits.entrySet()); for (List>> subUnit : Lists.partition(list, BATCH_SIZE)) { @@ -1935,7 +1937,7 @@ public void insertPermanentLimits(Map limitsInfos) { Map> permanentLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getPermanentLimits())); try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertNewPermanentLimitsQuery())) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertPermanentLimitsQuery())) { List values = new ArrayList<>(8); List>> list = new ArrayList<>(permanentLimits.entrySet()); for (List>> subUnit : Lists.partition(list, BATCH_SIZE)) { @@ -2014,7 +2016,7 @@ private void deletePermanentLimits(UUID networkUuid, int variantNum, String equi private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < equipmentIds.size(); i++) { @@ -2029,7 +2031,7 @@ private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { - try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteNewPermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); for (int i = 0; i < equipmentIds.size(); i++) { diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index a8a4b0d8..c044b235 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -281,7 +281,7 @@ public static String buildCloneNetworksQuery(Collection columns) { } // temporary limits - public static String buildInsertNewTemporaryLimitsQuery() { + public static String buildInsertTemporaryLimitsQuery() { return "insert into " + TEMPORARY_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + @@ -289,18 +289,18 @@ public static String buildInsertNewTemporaryLimitsQuery() { " values (?, ?, ?, ?, ?)"; } - public static String buildDeleteNewTemporaryLimitsQuery() { + public static String buildDeleteTemporaryLimitsQuery() { return "delete from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ?"; } - public static String buildDeleteNewTemporaryLimitsVariantQuery() { + public static String buildDeleteTemporaryLimitsVariantQuery() { return "delete from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - public static String buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { + public static String buildDeleteTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } @@ -311,7 +311,7 @@ public static String buildDeleteNewTemporaryLimitsVariantEquipmentINQuery(int nu "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildNewTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + public static String buildTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } @@ -327,14 +327,14 @@ public static String buildNewTemporaryLimitWithInClauseQuery(String columnNameFo "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildCloneNewTemporaryLimitsQuery() { + public static String buildCloneTemporaryLimitsQuery() { return "insert into " + TEMPORARY_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMITS + " from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - public static String buildNewTemporaryLimitQuery(String columnNameForWhereClause) { + public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { return "select " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + @@ -347,7 +347,7 @@ public static String buildNewTemporaryLimitQuery(String columnNameForWhereClause } // permanent limits - public static String buildInsertNewPermanentLimitsQuery() { + public static String buildInsertPermanentLimitsQuery() { return "insert into " + PERMANENT_LIMITS + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + @@ -355,18 +355,18 @@ public static String buildInsertNewPermanentLimitsQuery() { " values (?, ?, ?, ?, ?)"; } - public static String buildDeleteNewPermanentLimitsQuery() { + public static String buildDeletePermanentLimitsQuery() { return "delete from " + PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ?"; } - public static String buildDeleteNewPermanentLimitsVariantQuery() { + public static String buildDeletePermanentLimitsVariantQuery() { return "delete from " + PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - public static String buildDeleteNewPermanentLimitsVariantEquipmentINQuery(int numberOfValues) { + public static String buildDeletePermanentLimitsVariantEquipmentINQuery(int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } @@ -377,7 +377,7 @@ public static String buildDeleteNewPermanentLimitsVariantEquipmentINQuery(int nu "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildNewPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + public static String buildPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } @@ -393,14 +393,14 @@ public static String buildNewPermanentLimitWithInClauseQuery(String columnNameFo "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildCloneNewPermanentLimitsQuery() { + public static String buildClonePermanentLimitsQuery() { return "insert into " + PERMANENT_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + PERMANENT_LIMITS + " from " + PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - public static String buildNewPermanentLimitQuery(String columnNameForWhereClause) { + public static String buildPermanentLimitQuery(String columnNameForWhereClause) { return "select " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java similarity index 97% rename from network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java rename to network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java index 8333ba0f..af39493c 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/PermanentLimitSqlData.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package com.powsybl.network.store.server; +package com.powsybl.network.store.server.json; import com.powsybl.iidm.network.LimitType; import com.powsybl.network.store.server.dto.PermanentLimitAttributes; diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java similarity index 97% rename from network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java rename to network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java index c2697d62..a963aede 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/TemporaryLimitSqlData.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java @@ -4,7 +4,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -package com.powsybl.network.store.server; +package com.powsybl.network.store.server.json; import com.powsybl.iidm.network.LimitType; import com.powsybl.network.store.model.TemporaryLimitAttributes; diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java index f42e4206..086e3fd6 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java @@ -11,7 +11,7 @@ import com.google.common.collect.Lists; import com.powsybl.iidm.network.LimitType; import com.powsybl.network.store.model.ResourceType; -import com.powsybl.network.store.server.PermanentLimitSqlData; +import com.powsybl.network.store.server.json.PermanentLimitSqlData; import com.powsybl.network.store.server.dto.OwnerInfo; import com.powsybl.network.store.server.dto.PermanentLimitAttributes; import liquibase.change.custom.CustomSqlChange; @@ -67,7 +67,7 @@ private Map> getPermanentLimits(Prepar permanentLimit.setOperationalLimitsGroupId(resultSet.getString(5)); permanentLimit.setSide(resultSet.getInt(6)); permanentLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); - permanentLimit.setValue(resultSet.getDouble(9)); + permanentLimit.setValue(resultSet.getDouble(8)); map.computeIfAbsent(owner, k -> new ArrayList<>()); map.get(owner).add(permanentLimit); } @@ -82,9 +82,9 @@ private void prepareStatements(Map> ol List permanentLimitSqlData = entry.getValue().stream().map(PermanentLimitSqlData::of).toList(); String serializedpermanentLimitSqlData = mapper.writeValueAsString(permanentLimitSqlData); statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newpermanentlimits") - .addColumnValue("equipmentId", entry.getKey().getEquipmentId()) - .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) - .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) + .addColumnValue("equipmentid", entry.getKey().getEquipmentId()) + .addColumnValue("equipmenttype", entry.getKey().getEquipmentType().toString()) + .addColumnValue("networkuuid", entry.getKey().getNetworkUuid().toString()) .addColumnValue("variantnum", entry.getKey().getVariantNum()) .addColumnValue("permanentlimits", serializedpermanentLimitSqlData) ); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java index 4214e6b6..2f8063ad 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java @@ -12,7 +12,7 @@ import com.powsybl.iidm.network.LimitType; import com.powsybl.network.store.model.ResourceType; import com.powsybl.network.store.model.TemporaryLimitAttributes; -import com.powsybl.network.store.server.TemporaryLimitSqlData; +import com.powsybl.network.store.server.json.TemporaryLimitSqlData; import com.powsybl.network.store.server.dto.OwnerInfo; import liquibase.change.custom.CustomSqlChange; import liquibase.database.Database; @@ -85,9 +85,9 @@ private void prepareStatements(Map> ol List temporaryLimitSqlData = entry.getValue().stream().map(TemporaryLimitSqlData::of).toList(); String serializedtemporaryLimitSqlData = mapper.writeValueAsString(temporaryLimitSqlData); statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newtemporarylimits") - .addColumnValue("equipmentId", entry.getKey().getEquipmentId()) - .addColumnValue("equipmentType", entry.getKey().getEquipmentType()) - .addColumnValue("networkuuid", entry.getKey().getNetworkUuid()) + .addColumnValue("equipmentid", entry.getKey().getEquipmentId()) + .addColumnValue("equipmenttype", entry.getKey().getEquipmentType().toString()) + .addColumnValue("networkuuid", entry.getKey().getNetworkUuid().toString()) .addColumnValue("variantnum", entry.getKey().getVariantNum()) .addColumnValue("temporarylimits", serializedtemporaryLimitSqlData) ); diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index b1cec951..db786d33 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -18,7 +18,7 @@ - + @@ -37,6 +37,8 @@ + + Date: Thu, 5 Dec 2024 09:06:08 +0100 Subject: [PATCH 13/19] fix sonar Signed-off-by: Etienne LESOT --- .../powsybl/network/store/server/NetworkStoreRepository.java | 5 +++-- .../network/store/server/json/PermanentLimitSqlData.java | 4 +++- .../network/store/server/json/TemporaryLimitSqlData.java | 4 +++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index 7aa3d861..f26462af 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -32,6 +32,7 @@ import org.springframework.stereotype.Repository; import javax.sql.DataSource; +import java.io.UncheckedIOException; import java.sql.*; import java.util.*; import java.util.concurrent.TimeUnit; @@ -1859,7 +1860,7 @@ private Map> innerGetTemporaryLimits(P } return map; } catch (JsonProcessingException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } @@ -1881,7 +1882,7 @@ private Map> innerGetPermanentLimits(P } return map; } catch (JsonProcessingException e) { - throw new RuntimeException(e); + throw new UncheckedIOException(e); } } diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java index af39493c..25d24cb6 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java @@ -27,7 +27,9 @@ public class PermanentLimitSqlData { private Integer side; private LimitType limitType; - public PermanentLimitSqlData() { } + public PermanentLimitSqlData() { + // empty constructor for Jackson + } public static PermanentLimitSqlData of(PermanentLimitAttributes permanentLimitAttributes) { return PermanentLimitSqlData.builder() diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java index a963aede..d9c9e687 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java @@ -29,7 +29,9 @@ public class TemporaryLimitSqlData { private Integer acceptableDuration; private boolean fictitious; - public TemporaryLimitSqlData() { } + public TemporaryLimitSqlData() { + // empty constructor for Jackson + } public static TemporaryLimitSqlData of(TemporaryLimitAttributes temporaryLimit) { return TemporaryLimitSqlData.builder() From 07e71b788926d5879ae9aceab0bc19de6ffce3ab Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 5 Dec 2024 15:08:28 +0100 Subject: [PATCH 14/19] add index Signed-off-by: Etienne LESOT --- .../powsybl/network/store/server/QueryCatalog.java | 3 --- .../changesets/changelog_20241121T110000Z.xml | 12 ++++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index c044b235..c0f9bd33 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -39,15 +39,12 @@ public final class QueryCatalog { static final String INDEX_COLUMN = "index"; static final String TAPCHANGER_TYPE_COLUMN = "tapChangerType"; static final String ALPHA_COLUMN = "alpha"; - static final String OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "operationalLimitsGroupId"; - static final String SELECTED_OPERATIONAL_LIMITS_GROUP_ID_COLUMN = "selectedOperationalLimitsGroupId"; static final String TEMPORARY_LIMITS = "temporarylimits"; static final String PERMANENT_LIMITS = "permanentlimits"; static final String TAP_CHANGER_STEP_TABLE = "tapChangerStep"; static final String REGULATING_POINT_TABLE = "regulatingPoint"; static final String REGULATION_MODE = "regulationMode"; static final String SIDE_COLUMN = "side"; - static final String LIMIT_TYPE_COLUMN = "limitType"; private QueryCatalog() { } diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index db786d33..25eeb005 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -16,7 +16,6 @@ - @@ -31,7 +30,6 @@ - @@ -43,6 +41,16 @@ newTableName="permanentlimits"/> + + + + + + + + + + \ No newline at end of file From 78bdf52b059abdf34a47c3cd88f15ed4003d2101 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 5 Dec 2024 15:20:18 +0100 Subject: [PATCH 15/19] fix index Signed-off-by: Etienne LESOT --- .../db/changelog/changesets/changelog_20241121T110000Z.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index 25eeb005..df466f30 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -46,7 +46,7 @@ - + From e434daa84e284383bc02c604339146df1ed476cb Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 6 Dec 2024 15:30:25 +0100 Subject: [PATCH 16/19] change java migration to sql migration Signed-off-by: Etienne LESOT --- .../migrations/PermanentLimitsMigration.java | 116 ----------------- .../migrations/TemporaryLimitsMigration.java | 119 ------------------ .../changesets/changelog_20241121T110000Z.xml | 13 +- .../refactor_limits_20241121T110000Z.sql | 21 ++++ pom.xml | 3 - 5 files changed, 32 insertions(+), 240 deletions(-) delete mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java delete mode 100644 network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java create mode 100644 network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java deleted file mode 100644 index 086e3fd6..00000000 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/PermanentLimitsMigration.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (c) 2024, RTE (http://www.rte-france.com) - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package com.powsybl.network.store.server.migrations; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; -import com.powsybl.iidm.network.LimitType; -import com.powsybl.network.store.model.ResourceType; -import com.powsybl.network.store.server.json.PermanentLimitSqlData; -import com.powsybl.network.store.server.dto.OwnerInfo; -import com.powsybl.network.store.server.dto.PermanentLimitAttributes; -import liquibase.change.custom.CustomSqlChange; -import liquibase.database.Database; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.CustomChangeException; -import liquibase.exception.DatabaseException; -import liquibase.exception.SetupException; -import liquibase.exception.ValidationErrors; -import liquibase.resource.ResourceAccessor; -import liquibase.statement.SqlStatement; -import liquibase.statement.core.InsertStatement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * @author Etienne Lesot - */ -public class PermanentLimitsMigration implements CustomSqlChange { - private static final Logger LOGGER = LoggerFactory.getLogger(PermanentLimitsMigration.class); - private final ObjectMapper mapper = new ObjectMapper(); - - @Override - public SqlStatement[] generateStatements(Database database) throws CustomChangeException { - JdbcConnection connection = (JdbcConnection) database.getConnection(); - List statements = new ArrayList<>(); - String requestStatement = "select equipmentid, equipmenttype, networkUuid, variantNum, operationalLimitsGroupId, side," + - "limitType, value_ from permanentlimit"; - try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { - Map> oldPermanentLimits = getPermanentLimits(stmt); - prepareStatements(oldPermanentLimits, database, statements); - } catch (SQLException | JsonProcessingException | DatabaseException e) { - throw new CustomChangeException(e); - } - return statements.toArray(new SqlStatement[0]); - } - - private Map> getPermanentLimits(PreparedStatement stmt) throws SQLException { - ResultSet resultSet = stmt.executeQuery(); - Map> map = new HashMap<>(); - while (resultSet.next()) { - PermanentLimitAttributes permanentLimit = new PermanentLimitAttributes(); - OwnerInfo owner = new OwnerInfo(); - owner.setEquipmentId(resultSet.getString(1)); - owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); - owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); - owner.setVariantNum(resultSet.getInt(4)); - permanentLimit.setOperationalLimitsGroupId(resultSet.getString(5)); - permanentLimit.setSide(resultSet.getInt(6)); - permanentLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); - permanentLimit.setValue(resultSet.getDouble(8)); - map.computeIfAbsent(owner, k -> new ArrayList<>()); - map.get(owner).add(permanentLimit); - } - return map; - } - - private void prepareStatements(Map> oldPermanentLimits, Database database, List statements) throws JsonProcessingException { - List>> list = new ArrayList<>(oldPermanentLimits.entrySet()); - for (List>> subUnit : Lists.partition(list, 1000)) { - for (Map.Entry> entry : subUnit) { - if (!entry.getValue().isEmpty()) { - List permanentLimitSqlData = entry.getValue().stream().map(PermanentLimitSqlData::of).toList(); - String serializedpermanentLimitSqlData = mapper.writeValueAsString(permanentLimitSqlData); - statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newpermanentlimits") - .addColumnValue("equipmentid", entry.getKey().getEquipmentId()) - .addColumnValue("equipmenttype", entry.getKey().getEquipmentType().toString()) - .addColumnValue("networkuuid", entry.getKey().getNetworkUuid().toString()) - .addColumnValue("variantnum", entry.getKey().getVariantNum()) - .addColumnValue("permanentlimits", serializedpermanentLimitSqlData) - ); - } - - } - } - } - - @Override - public String getConfirmationMessage() { - return "permanent limits was successfully updated"; - } - - @Override - public void setUp() throws SetupException { - LOGGER.info("Set up migration for permanent limits"); - } - - @Override - public void setFileOpener(ResourceAccessor resourceAccessor) { - LOGGER.info("Set file opener for permanent limits"); - } - - @Override - public ValidationErrors validate(Database database) { - return new ValidationErrors(); - } -} diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java b/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java deleted file mode 100644 index 2f8063ad..00000000 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/migrations/TemporaryLimitsMigration.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - Copyright (c) 2024, RTE (http://www.rte-france.com) - This Source Code Form is subject to the terms of the Mozilla Public - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ -package com.powsybl.network.store.server.migrations; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.Lists; -import com.powsybl.iidm.network.LimitType; -import com.powsybl.network.store.model.ResourceType; -import com.powsybl.network.store.model.TemporaryLimitAttributes; -import com.powsybl.network.store.server.json.TemporaryLimitSqlData; -import com.powsybl.network.store.server.dto.OwnerInfo; -import liquibase.change.custom.CustomSqlChange; -import liquibase.database.Database; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.CustomChangeException; -import liquibase.exception.DatabaseException; -import liquibase.exception.SetupException; -import liquibase.exception.ValidationErrors; -import liquibase.resource.ResourceAccessor; -import liquibase.statement.SqlStatement; -import liquibase.statement.core.InsertStatement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -/** - * @author Etienne Lesot - */ -public class TemporaryLimitsMigration implements CustomSqlChange { - private static final Logger LOGGER = LoggerFactory.getLogger(TemporaryLimitsMigration.class); - private final ObjectMapper mapper = new ObjectMapper(); - - @Override - public SqlStatement[] generateStatements(Database database) throws CustomChangeException { - JdbcConnection connection = (JdbcConnection) database.getConnection(); - List statements = new ArrayList<>(); - String requestStatement = "select equipmentid, equipmenttype, networkUuid, variantNum, operationalLimitsGroupId, side," + - "limitType, name, value_, acceptableDuration, fictitious from temporarylimit"; - try (PreparedStatement stmt = connection.prepareStatement(requestStatement)) { - Map> oldTemporaryLimits = getTemporaryLimits(stmt); - prepareStatements(oldTemporaryLimits, database, statements); - } catch (SQLException | JsonProcessingException | DatabaseException e) { - throw new CustomChangeException(e); - } - return statements.toArray(new SqlStatement[0]); - } - - private Map> getTemporaryLimits(PreparedStatement stmt) throws SQLException { - ResultSet resultSet = stmt.executeQuery(); - Map> map = new HashMap<>(); - while (resultSet.next()) { - TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); - OwnerInfo owner = new OwnerInfo(); - owner.setEquipmentId(resultSet.getString(1)); - owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); - owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); - owner.setVariantNum(resultSet.getInt(4)); - temporaryLimit.setOperationalLimitsGroupId(resultSet.getString(5)); - temporaryLimit.setSide(resultSet.getInt(6)); - temporaryLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); - temporaryLimit.setName(resultSet.getString(8)); - temporaryLimit.setValue(resultSet.getDouble(9)); - temporaryLimit.setAcceptableDuration(resultSet.getInt(10)); - temporaryLimit.setFictitious(resultSet.getBoolean(11)); - map.computeIfAbsent(owner, k -> new ArrayList<>()); - map.get(owner).add(temporaryLimit); - } - return map; - } - - private void prepareStatements(Map> oldTemporaryLimits, Database database, List statements) throws JsonProcessingException { - List>> list = new ArrayList<>(oldTemporaryLimits.entrySet()); - for (List>> subUnit : Lists.partition(list, 1000)) { - for (Map.Entry> entry : subUnit) { - if (!entry.getValue().isEmpty()) { - List temporaryLimitSqlData = entry.getValue().stream().map(TemporaryLimitSqlData::of).toList(); - String serializedtemporaryLimitSqlData = mapper.writeValueAsString(temporaryLimitSqlData); - statements.add(new InsertStatement(database.getDefaultCatalogName(), database.getDefaultSchemaName(), "newtemporarylimits") - .addColumnValue("equipmentid", entry.getKey().getEquipmentId()) - .addColumnValue("equipmenttype", entry.getKey().getEquipmentType().toString()) - .addColumnValue("networkuuid", entry.getKey().getNetworkUuid().toString()) - .addColumnValue("variantnum", entry.getKey().getVariantNum()) - .addColumnValue("temporarylimits", serializedtemporaryLimitSqlData) - ); - } - - } - } - } - - @Override - public String getConfirmationMessage() { - return "temporary limits was successfully updated"; - } - - @Override - public void setUp() throws SetupException { - LOGGER.info("Set up migration for temporary limits"); - } - - @Override - public void setFileOpener(ResourceAccessor resourceAccessor) { - LOGGER.info("Set file opener for temporary limits"); - } - - @Override - public ValidationErrors validate(Database database) { - return new ValidationErrors(); - } -} diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index df466f30..578e5b49 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -33,8 +33,17 @@ - - + + + + + + 1.0 2.16.0 - - **/migrations/**/* - **/migrations/**/* From 4bd3ce47e9f128eb2e81e563d4672845c166da03 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Thu, 12 Dec 2024 16:38:50 +0100 Subject: [PATCH 17/19] refactor and annd transfer method when getting Signed-off-by: Etienne LESOT --- .../store/server/NetworkStoreRepository.java | 47 ++++++++ .../network/store/server/QueryCatalog.java | 104 +++++++++++++++--- .../changesets/changelog_20241121T110000Z.xml | 21 +--- .../refactor_limits_20241121T110000Z.sql | 1 + 4 files changed, 138 insertions(+), 35 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index f26462af..a0b5bb87 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -1816,6 +1816,22 @@ private Map mergeLimitsIntoLimitsInfos(Map> getTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { + // because the migration between old and new database for temporary limit is long we transfer data when we get + // transfer data to new table + var preparedStmtToTransfer = connection.prepareStatement(QueryCatalog.buildTransferTemporaryLimitsToNewDatabase(columnNameForWhereClause)); + preparedStmtToTransfer.setString(1, networkUuid.toString()); + preparedStmtToTransfer.setInt(2, variantNum); + preparedStmtToTransfer.setString(3, valueForWhereClause); + preparedStmtToTransfer.executeUpdate(); + + // delete from old table + var preparedStmtToDelete = connection.prepareStatement(QueryCatalog.buildDeleteOldTemporaryLimitsVariantEquipmentClauseQuery(columnNameForWhereClause)); + preparedStmtToDelete.setString(1, networkUuid.toString()); + preparedStmtToDelete.setInt(2, variantNum); + preparedStmtToDelete.setString(3, valueForWhereClause); + preparedStmtToDelete.executeUpdate(); + + // get from new table var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); @@ -1829,6 +1845,21 @@ public Map> getTemporaryLimits(UUID ne public Map> getPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { + // because the migration between old and new database for temporary limit is long we transfer data when we get + // transfer data to new table + var preparedStmtToTransfer = connection.prepareStatement(QueryCatalog.buildTransferPermanentLimitsToNewDatabase(columnNameForWhereClause)); + preparedStmtToTransfer.setString(1, networkUuid.toString()); + preparedStmtToTransfer.setInt(2, variantNum); + preparedStmtToTransfer.setString(3, valueForWhereClause); + preparedStmtToTransfer.executeUpdate(); + + // delete from old table + var preparedStmtToDelete = connection.prepareStatement(QueryCatalog.buildDeleteOldPermanentLimitsVariantEquipmentClauseQuery(columnNameForWhereClause)); + preparedStmtToDelete.setString(1, networkUuid.toString()); + preparedStmtToDelete.setInt(2, variantNum); + preparedStmtToDelete.setString(3, valueForWhereClause); + preparedStmtToDelete.executeUpdate(); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); @@ -2017,6 +2048,14 @@ private void deletePermanentLimits(UUID networkUuid, int variantNum, String equi private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < equipmentIds.size(); i++) { + preparedStmt.setString(3 + i, equipmentIds.get(i)); + } + preparedStmt.executeUpdate(); + } try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); @@ -2032,6 +2071,14 @@ private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldPermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < equipmentIds.size(); i++) { + preparedStmt.setString(3 + i, equipmentIds.get(i)); + } + preparedStmt.executeUpdate(); + } try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeletePermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index c0f9bd33..dd80ab86 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -39,8 +39,12 @@ public final class QueryCatalog { static final String INDEX_COLUMN = "index"; static final String TAPCHANGER_TYPE_COLUMN = "tapChangerType"; static final String ALPHA_COLUMN = "alpha"; + static final String TEMPORARY_LIMITS_TABLE = "newtemporarylimits"; static final String TEMPORARY_LIMITS = "temporarylimits"; + static final String OLD_TEMPORARY_LIMITS = "temporarylimit"; + static final String PERMANENT_LIMITS_TABLE = "newpermanentlimits"; static final String PERMANENT_LIMITS = "permanentlimits"; + static final String OLD_PERMANENT_LIMITS = "permanentlimit"; static final String TAP_CHANGER_STEP_TABLE = "tapChangerStep"; static final String REGULATING_POINT_TABLE = "regulatingPoint"; static final String REGULATION_MODE = "regulationMode"; @@ -279,7 +283,7 @@ public static String buildCloneNetworksQuery(Collection columns) { // temporary limits public static String buildInsertTemporaryLimitsQuery() { - return "insert into " + TEMPORARY_LIMITS + "(" + + return "insert into " + TEMPORARY_LIMITS_TABLE + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + @@ -287,21 +291,32 @@ public static String buildInsertTemporaryLimitsQuery() { } public static String buildDeleteTemporaryLimitsQuery() { - return "delete from " + TEMPORARY_LIMITS + " where " + + return "delete from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ?"; } public static String buildDeleteTemporaryLimitsVariantQuery() { - return "delete from " + TEMPORARY_LIMITS + " where " + + return "delete from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } + public static String buildDeleteOldTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "delete from " + OLD_TEMPORARY_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + EQUIPMENT_ID_COLUMN + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + public static String buildDeleteTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } - return "delete from " + TEMPORARY_LIMITS + " where " + + return "delete from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + EQUIPMENT_ID_COLUMN + " in (" + @@ -317,7 +332,7 @@ public static String buildTemporaryLimitWithInClauseQuery(String columnNameForIn NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + - " from " + TEMPORARY_LIMITS + " where " + + " from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForInClause + " in (" + @@ -325,9 +340,9 @@ public static String buildTemporaryLimitWithInClauseQuery(String columnNameForIn } public static String buildCloneTemporaryLimitsQuery() { - return "insert into " + TEMPORARY_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + return "insert into " + TEMPORARY_LIMITS_TABLE + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMITS + " from " + TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMITS + " from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } @@ -337,7 +352,31 @@ public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + - " from " + TEMPORARY_LIMITS + " where " + + " from " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; + } + + public static String buildTransferTemporaryLimitsToNewDatabase(String columnNameForWhereClause) { + return "INSERT INTO " + TEMPORARY_LIMITS_TABLE + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + + " SELECT " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + "," + + " json_agg(json_build_object(" + + "'operationalLimitsGroupId', operationalLimitsGroupId, " + + "'side', side, " + + "'limitType', limitType, " + + "'name', name, " + + "'value', value_, " + + "'acceptableDuration', acceptableduration, " + + "'fictitious', fictitious )) as " + TEMPORARY_LIMITS + " FROM " + OLD_TEMPORARY_LIMITS + + " WHERE " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ? " + + "GROUP BY " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN; + } + + public static String buildDeleteOldTemporaryLimitsVariantEquipmentClauseQuery(String columnNameForWhereClause) { + return "delete from " + OLD_TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ?"; @@ -345,7 +384,7 @@ public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { // permanent limits public static String buildInsertPermanentLimitsQuery() { - return "insert into " + PERMANENT_LIMITS + " (" + + return "insert into " + PERMANENT_LIMITS_TABLE + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + @@ -353,21 +392,32 @@ public static String buildInsertPermanentLimitsQuery() { } public static String buildDeletePermanentLimitsQuery() { - return "delete from " + PERMANENT_LIMITS + " where " + + return "delete from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ?"; } public static String buildDeletePermanentLimitsVariantQuery() { - return "delete from " + PERMANENT_LIMITS + " where " + + return "delete from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } + public static String buildDeleteOldPermanentLimitsVariantEquipmentINQuery(int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "delete from " + OLD_PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + EQUIPMENT_ID_COLUMN + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + public static String buildDeletePermanentLimitsVariantEquipmentINQuery(int numberOfValues) { if (numberOfValues < 1) { throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); } - return "delete from " + PERMANENT_LIMITS + " where " + + return "delete from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + EQUIPMENT_ID_COLUMN + " in (" + @@ -383,7 +433,7 @@ public static String buildPermanentLimitWithInClauseQuery(String columnNameForIn NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + - " from " + PERMANENT_LIMITS + " where " + + " from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForInClause + " in (" + @@ -391,9 +441,9 @@ public static String buildPermanentLimitWithInClauseQuery(String columnNameForIn } public static String buildClonePermanentLimitsQuery() { - return "insert into " + PERMANENT_LIMITS + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + return "insert into " + PERMANENT_LIMITS_TABLE + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + - EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + PERMANENT_LIMITS + " from " + PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + PERMANENT_LIMITS + " from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } @@ -403,7 +453,29 @@ public static String buildPermanentLimitQuery(String columnNameForWhereClause) { NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + - " from " + PERMANENT_LIMITS + " where " + + " from " + PERMANENT_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; + } + + public static String buildTransferPermanentLimitsToNewDatabase(String columnNameForWhereClause) { + return "INSERT INTO " + PERMANENT_LIMITS_TABLE + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", permanentlimits) " + + "SELECT " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + + "json_agg(json_build_object(" + + "'operationalLimitsGroupId', operationalLimitsGroupId, " + + "'side', side, " + + "'value', value_, " + + "'limitType', limitType" + + ")) as permanentlimits FROM " + OLD_PERMANENT_LIMITS + + " WHERE " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ? " + + "GROUP BY " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN; + } + + public static String buildDeleteOldPermanentLimitsVariantEquipmentClauseQuery(String columnNameForWhereClause) { + return "delete from " + OLD_PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ?"; diff --git a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml index 578e5b49..ae7a25f7 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -33,29 +33,12 @@ - - - - - - - - - - - + - + diff --git a/network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql b/network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql index 1fa78421..f691a599 100644 --- a/network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql +++ b/network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql @@ -1,3 +1,4 @@ +-- will be used in next deployment INSERT INTO newtemporarylimits (equipmentid, equipmenttype, networkuuid, variantnum, temporarylimits) SELECT equipmentid, equipmenttype, networkuuid, variantnum, json_agg(json_build_object( From 577bdadb04797604b3f371db1a99f390936660e1 Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 13 Dec 2024 15:06:17 +0100 Subject: [PATCH 18/19] fix and migrate in java Signed-off-by: Etienne LESOT --- .../store/server/NetworkStoreRepository.java | 209 +++++++++++++++--- .../network/store/server/QueryCatalog.java | 77 ++++--- 2 files changed, 228 insertions(+), 58 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java index a0b5bb87..e397a5a8 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/NetworkStoreRepository.java @@ -1770,6 +1770,24 @@ public Map> getTemporaryLimitsWithInCl } } + public Map> getOldTemporaryLimitsWithInClause(UUID networkUuid, int variantNum, String columnNameForWhereClause, List valuesForInClause) { + if (valuesForInClause.isEmpty()) { + return Collections.emptyMap(); + } + try (var connection = dataSource.getConnection()) { + var preparedStmt = connection.prepareStatement(QueryCatalog.buildOldTemporaryLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < valuesForInClause.size(); i++) { + preparedStmt.setString(3 + i, valuesForInClause.get(i)); + } + + return innerGetOldTemporaryLimits(preparedStmt); + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + public Map> getPermanentLimitsWithInClause(UUID networkUuid, int variantNum, String columnNameForWhereClause, List valuesForInClause) { if (valuesForInClause.isEmpty()) { return Collections.emptyMap(); @@ -1788,13 +1806,58 @@ public Map> getPermanentLimitsWithInCl } } + public Map> getOldPermanentLimitsWithInClause(UUID networkUuid, int variantNum, String columnNameForWhereClause, List valuesForInClause) { + if (valuesForInClause.isEmpty()) { + return Collections.emptyMap(); + } + try (var connection = dataSource.getConnection()) { + var preparedStmt = connection.prepareStatement(QueryCatalog.buildOldPermanentLimitWithInClauseQuery(columnNameForWhereClause, valuesForInClause.size())); + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < valuesForInClause.size(); i++) { + preparedStmt.setString(3 + i, valuesForInClause.get(i)); + } + + return innerGetOldPermanentLimits(preparedStmt); + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + public Map getLimitsInfos(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + // migrate data from old limit table to new limit table + Map> oldTemporaryLimits = getOldTemporaryLimits(networkUuid, variantNum, columnNameForWhereClause, valueForWhereClause); + insertTemporaryLimitsAttributes(oldTemporaryLimits); + Map> oldPermanentLimits = getOldPermanentLimits(networkUuid, variantNum, columnNameForWhereClause, valueForWhereClause); + insertPermanentLimitsAttributes(oldPermanentLimits); + + // delete in old table + if (!oldPermanentLimits.keySet().isEmpty()) { + deleteOldPermanentLimits(networkUuid, variantNum, oldPermanentLimits.keySet().stream().map(OwnerInfo::getEquipmentId).toList()); + } + if (!oldTemporaryLimits.keySet().isEmpty()) { + deleteOldTemporaryLimits(networkUuid, variantNum, oldTemporaryLimits.keySet().stream().map(OwnerInfo::getEquipmentId).toList()); + } + + // get data from the new limit table Map> temporaryLimits = getTemporaryLimits(networkUuid, variantNum, columnNameForWhereClause, valueForWhereClause); Map> permanentLimits = getPermanentLimits(networkUuid, variantNum, columnNameForWhereClause, valueForWhereClause); return mergeLimitsIntoLimitsInfos(temporaryLimits, permanentLimits); } public Map getLimitsInfosWithInClause(UUID networkUuid, int variantNum, String columnNameForWhereClause, List valuesForInClause) { + // migrate data from old limit table to new limit table + Map> oldTemporaryLimits = getOldTemporaryLimitsWithInClause(networkUuid, variantNum, columnNameForWhereClause, valuesForInClause); + insertTemporaryLimitsAttributes(oldTemporaryLimits); + Map> oldPermanentLimits = getOldPermanentLimitsWithInClause(networkUuid, variantNum, columnNameForWhereClause, valuesForInClause); + insertPermanentLimitsAttributes(oldPermanentLimits); + // delete in old table + if (!oldPermanentLimits.keySet().isEmpty()) { + deleteOldPermanentLimits(networkUuid, variantNum, oldPermanentLimits.keySet().stream().map(OwnerInfo::getEquipmentId).toList()); + } + if (!oldTemporaryLimits.keySet().isEmpty()) { + deleteOldTemporaryLimits(networkUuid, variantNum, oldTemporaryLimits.keySet().stream().map(OwnerInfo::getEquipmentId).toList()); + } Map> temporaryLimits = getTemporaryLimitsWithInClause(networkUuid, variantNum, columnNameForWhereClause, valuesForInClause); Map> permanentLimits = getPermanentLimitsWithInClause(networkUuid, variantNum, columnNameForWhereClause, valuesForInClause); return mergeLimitsIntoLimitsInfos(temporaryLimits, permanentLimits); @@ -1814,23 +1877,23 @@ private Map mergeLimitsIntoLimitsInfos(Map> getTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + public Map> getOldTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - // because the migration between old and new database for temporary limit is long we transfer data when we get - // transfer data to new table - var preparedStmtToTransfer = connection.prepareStatement(QueryCatalog.buildTransferTemporaryLimitsToNewDatabase(columnNameForWhereClause)); - preparedStmtToTransfer.setString(1, networkUuid.toString()); - preparedStmtToTransfer.setInt(2, variantNum); - preparedStmtToTransfer.setString(3, valueForWhereClause); - preparedStmtToTransfer.executeUpdate(); - - // delete from old table - var preparedStmtToDelete = connection.prepareStatement(QueryCatalog.buildDeleteOldTemporaryLimitsVariantEquipmentClauseQuery(columnNameForWhereClause)); - preparedStmtToDelete.setString(1, networkUuid.toString()); - preparedStmtToDelete.setInt(2, variantNum); - preparedStmtToDelete.setString(3, valueForWhereClause); - preparedStmtToDelete.executeUpdate(); + // get from old table + var preparedStmt = connection.prepareStatement(QueryCatalog.buildOldTemporaryLimitQuery(columnNameForWhereClause)); + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + preparedStmt.setString(3, valueForWhereClause); + + return innerGetOldTemporaryLimits(preparedStmt); + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + + public Map> getTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + try (var connection = dataSource.getConnection()) { // get from new table var preparedStmt = connection.prepareStatement(QueryCatalog.buildTemporaryLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); @@ -1843,23 +1906,21 @@ public Map> getTemporaryLimits(UUID ne } } - public Map> getPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + public Map> getOldPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { try (var connection = dataSource.getConnection()) { - // because the migration between old and new database for temporary limit is long we transfer data when we get - // transfer data to new table - var preparedStmtToTransfer = connection.prepareStatement(QueryCatalog.buildTransferPermanentLimitsToNewDatabase(columnNameForWhereClause)); - preparedStmtToTransfer.setString(1, networkUuid.toString()); - preparedStmtToTransfer.setInt(2, variantNum); - preparedStmtToTransfer.setString(3, valueForWhereClause); - preparedStmtToTransfer.executeUpdate(); - - // delete from old table - var preparedStmtToDelete = connection.prepareStatement(QueryCatalog.buildDeleteOldPermanentLimitsVariantEquipmentClauseQuery(columnNameForWhereClause)); - preparedStmtToDelete.setString(1, networkUuid.toString()); - preparedStmtToDelete.setInt(2, variantNum); - preparedStmtToDelete.setString(3, valueForWhereClause); - preparedStmtToDelete.executeUpdate(); + var preparedStmt = connection.prepareStatement(QueryCatalog.buildOldPermanentLimitQuery(columnNameForWhereClause)); + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + preparedStmt.setString(3, valueForWhereClause); + return innerGetOldPermanentLimits(preparedStmt); + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + + public Map> getPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + try (var connection = dataSource.getConnection()) { var preparedStmt = connection.prepareStatement(QueryCatalog.buildPermanentLimitQuery(columnNameForWhereClause)); preparedStmt.setString(1, networkUuid.toString()); preparedStmt.setInt(2, variantNum); @@ -1895,6 +1956,32 @@ private Map> innerGetTemporaryLimits(P } } + private Map> innerGetOldTemporaryLimits(PreparedStatement preparedStmt) throws SQLException { + try (ResultSet resultSet = preparedStmt.executeQuery()) { + Map> map = new HashMap<>(); + while (resultSet.next()) { + OwnerInfo owner = new OwnerInfo(); + TemporaryLimitAttributes temporaryLimit = new TemporaryLimitAttributes(); + // In order, from the QueryCatalog.buildTemporaryLimitQuery SQL query : + // equipmentId, equipmentType, networkUuid, variantNum, side, limitType, name, value, acceptableDuration, fictitious + owner.setEquipmentId(resultSet.getString(1)); + owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); + owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); + owner.setVariantNum(resultSet.getInt(4)); + temporaryLimit.setOperationalLimitsGroupId(resultSet.getString(5)); + temporaryLimit.setSide(resultSet.getInt(6)); + temporaryLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); + temporaryLimit.setName(resultSet.getString(8)); + temporaryLimit.setValue(resultSet.getDouble(9)); + temporaryLimit.setAcceptableDuration(resultSet.getInt(10)); + temporaryLimit.setFictitious(resultSet.getBoolean(11)); + map.computeIfAbsent(owner, k -> new ArrayList<>()); + map.get(owner).add(temporaryLimit); + } + return map; + } + } + private Map> innerGetPermanentLimits(PreparedStatement preparedStmt) throws SQLException { try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); @@ -1917,6 +2004,30 @@ private Map> innerGetPermanentLimits(P } } + private Map> innerGetOldPermanentLimits(PreparedStatement preparedStmt) throws SQLException { + try (ResultSet resultSet = preparedStmt.executeQuery()) { + Map> map = new HashMap<>(); + while (resultSet.next()) { + OwnerInfo owner = new OwnerInfo(); + PermanentLimitAttributes permanentLimit = new PermanentLimitAttributes(); + // In order, from the QueryCatalog.buildTemporaryLimitQuery SQL query : + // equipmentId, equipmentType, networkUuid, variantNum, side, limitType, name, value, acceptableDuration, fictitious + owner.setEquipmentId(resultSet.getString(1)); + owner.setEquipmentType(ResourceType.valueOf(resultSet.getString(2))); + owner.setNetworkUuid(UUID.fromString(resultSet.getString(3))); + owner.setVariantNum(resultSet.getInt(4)); + permanentLimit.setOperationalLimitsGroupId(resultSet.getString(5)); + permanentLimit.setSide(resultSet.getInt(6)); + permanentLimit.setLimitType(LimitType.valueOf(resultSet.getString(7))); + permanentLimit.setValue(resultSet.getDouble(8)); + + map.computeIfAbsent(owner, k -> new ArrayList<>()); + map.get(owner).add(permanentLimit); + } + return map; + } + } + protected Map getLimitsInfosFromEquipments(UUID networkUuid, List> resources) { Map map = new HashMap<>(); @@ -1938,6 +2049,10 @@ protected Map limitsInfos) { Map> temporaryLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getTemporaryLimits())); + insertTemporaryLimitsAttributes(temporaryLimits); + } + + public void insertTemporaryLimitsAttributes(Map> temporaryLimits) { try (var connection = dataSource.getConnection()) { try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertTemporaryLimitsQuery())) { List values = new ArrayList<>(5); @@ -1968,6 +2083,10 @@ public void insertTemporaryLimits(Map limitsInfos) { public void insertPermanentLimits(Map limitsInfos) { Map> permanentLimits = limitsInfos.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getPermanentLimits())); + insertPermanentLimitsAttributes(permanentLimits); + } + + public void insertPermanentLimitsAttributes(Map> permanentLimits) { try (var connection = dataSource.getConnection()) { try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildInsertPermanentLimitsQuery())) { List values = new ArrayList<>(8); @@ -2046,6 +2165,21 @@ private void deletePermanentLimits(UUID networkUuid, int variantNum, String equi deletePermanentLimits(networkUuid, variantNum, List.of(equipmentId)); } + private void deleteOldTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { + try (var connection = dataSource.getConnection()) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < equipmentIds.size(); i++) { + preparedStmt.setString(3 + i, equipmentIds.get(i)); + } + preparedStmt.executeUpdate(); + } + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldTemporaryLimitsVariantEquipmentINQuery(equipmentIds.size()))) { @@ -2069,6 +2203,21 @@ private void deleteTemporaryLimits(UUID networkUuid, int variantNum, List equipmentIds) { + try (var connection = dataSource.getConnection()) { + try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldPermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { + preparedStmt.setString(1, networkUuid.toString()); + preparedStmt.setInt(2, variantNum); + for (int i = 0; i < equipmentIds.size(); i++) { + preparedStmt.setString(3 + i, equipmentIds.get(i)); + } + preparedStmt.executeUpdate(); + } + } catch (SQLException e) { + throw new UncheckedSqlException(e); + } + } + private void deletePermanentLimits(UUID networkUuid, int variantNum, List equipmentIds) { try (var connection = dataSource.getConnection()) { try (var preparedStmt = connection.prepareStatement(QueryCatalog.buildDeleteOldPermanentLimitsVariantEquipmentINQuery(equipmentIds.size()))) { diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index dd80ab86..77b7dc23 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -339,6 +339,22 @@ public static String buildTemporaryLimitWithInClauseQuery(String columnNameForIn "?, ".repeat(numberOfValues - 1) + "?)"; } + public static String buildOldTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + "operationallimitsgroupid, side, limittype, name, value_, acceptableduration, fictitious" + + " from " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + public static String buildCloneTemporaryLimitsQuery() { return "insert into " + TEMPORARY_LIMITS_TABLE + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + @@ -358,21 +374,15 @@ public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { columnNameForWhereClause + " = ?"; } - public static String buildTransferTemporaryLimitsToNewDatabase(String columnNameForWhereClause) { - return "INSERT INTO " + TEMPORARY_LIMITS_TABLE + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + - " SELECT " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + "," + - " json_agg(json_build_object(" + - "'operationalLimitsGroupId', operationalLimitsGroupId, " + - "'side', side, " + - "'limitType', limitType, " + - "'name', name, " + - "'value', value_, " + - "'acceptableDuration', acceptableduration, " + - "'fictitious', fictitious )) as " + TEMPORARY_LIMITS + " FROM " + OLD_TEMPORARY_LIMITS + - " WHERE " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ? " + - "GROUP BY " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN; + public static String buildOldTemporaryLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", operationallimitsgroupid, side, limittype, name, value_, acceptableduration, fictitious" + + " from " + OLD_TEMPORARY_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; } public static String buildDeleteOldTemporaryLimitsVariantEquipmentClauseQuery(String columnNameForWhereClause) { @@ -440,6 +450,21 @@ public static String buildPermanentLimitWithInClauseQuery(String columnNameForIn "?, ".repeat(numberOfValues - 1) + "?)"; } + public static String buildOldPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", operationallimitsgroupid, side, limittype, value_ " + + " from " + PERMANENT_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; + } + public static String buildClonePermanentLimitsQuery() { return "insert into " + PERMANENT_LIMITS_TABLE + "(" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + "select " + EQUIPMENT_ID_COLUMN + ", " + @@ -459,19 +484,15 @@ public static String buildPermanentLimitQuery(String columnNameForWhereClause) { columnNameForWhereClause + " = ?"; } - public static String buildTransferPermanentLimitsToNewDatabase(String columnNameForWhereClause) { - return "INSERT INTO " + PERMANENT_LIMITS_TABLE + " (" + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", permanentlimits) " + - "SELECT " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + - "json_agg(json_build_object(" + - "'operationalLimitsGroupId', operationalLimitsGroupId, " + - "'side', side, " + - "'value', value_, " + - "'limitType', limitType" + - ")) as permanentlimits FROM " + OLD_PERMANENT_LIMITS + - " WHERE " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForWhereClause + " = ? " + - "GROUP BY " + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + - NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN; + public static String buildOldPermanentLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", operationallimitsgroupid, side, limittype, value_" + + " from " + OLD_TEMPORARY_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; } public static String buildDeleteOldPermanentLimitsVariantEquipmentClauseQuery(String columnNameForWhereClause) { From 7547a85ddcdf9f9f041c849377d469d0e0882c3f Mon Sep 17 00:00:00 2001 From: Etienne LESOT Date: Fri, 13 Dec 2024 16:03:28 +0100 Subject: [PATCH 19/19] fix Signed-off-by: Etienne LESOT --- .../java/com/powsybl/network/store/server/QueryCatalog.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java index 77b7dc23..a466727f 100644 --- a/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/QueryCatalog.java @@ -348,7 +348,7 @@ public static String buildOldTemporaryLimitWithInClauseQuery(String columnNameFo NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", " + "operationallimitsgroupid, side, limittype, name, value_, acceptableduration, fictitious" + - " from " + TEMPORARY_LIMITS_TABLE + " where " + + " from " + OLD_TEMPORARY_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForInClause + " in (" + @@ -458,7 +458,7 @@ public static String buildOldPermanentLimitWithInClauseQuery(String columnNameFo EQUIPMENT_TYPE_COLUMN + ", " + NETWORK_UUID_COLUMN + ", " + VARIANT_NUM_COLUMN + ", operationallimitsgroupid, side, limittype, value_ " + - " from " + PERMANENT_LIMITS_TABLE + " where " + + " from " + OLD_PERMANENT_LIMITS + " where " + NETWORK_UUID_COLUMN + " = ? and " + VARIANT_NUM_COLUMN + " = ? and " + columnNameForInClause + " in (" +