diff --git a/network-store-server/pom.xml b/network-store-server/pom.xml index 4a1c9f8e..a8e37c4a 100644 --- a/network-store-server/pom.xml +++ b/network-store-server/pom.xml @@ -107,7 +107,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..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 @@ -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; @@ -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; @@ -30,10 +32,8 @@ 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.io.UncheckedIOException; +import java.sql.*; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -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,8 +1877,24 @@ private Map mergeLimitsIntoLimitsInfos(Map> getOldTemporaryLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + try (var connection = dataSource.getConnection()) { + + // 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()); preparedStmt.setInt(2, variantNum); @@ -1827,6 +1906,19 @@ public Map> getTemporaryLimits(UUID ne } } + public Map> getOldPermanentLimits(UUID networkUuid, int variantNum, String columnNameForWhereClause, String valueForWhereClause) { + try (var connection = dataSource.getConnection()) { + 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)); @@ -1844,7 +1936,30 @@ private Map> innerGetTemporaryLimits(P try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { + OwnerInfo owner = new OwnerInfo(); + // 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)); + 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 UncheckedIOException(e); + } + } + 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 : @@ -1860,7 +1975,6 @@ private Map> innerGetTemporaryLimits(P 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); } @@ -1872,7 +1986,28 @@ private Map> innerGetPermanentLimits(P try (ResultSet resultSet = preparedStmt.executeQuery()) { Map> map = new HashMap<>(); while (resultSet.next()) { + 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)); + 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 UncheckedIOException(e); + } + } + 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 : @@ -1914,29 +2049,27 @@ 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<>(11); + 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()); + values.add(entry.getValue().stream() + .map(TemporaryLimitSqlData::of).toList()); bindValues(preparedStmt, values, mapper); preparedStmt.addBatch(); + } } preparedStmt.executeBatch(); @@ -1950,27 +2083,25 @@ 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); 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(); } @@ -2034,8 +2165,31 @@ 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()))) { + 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); @@ -2049,8 +2203,31 @@ 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()))) { + 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 8025f140..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 @@ -39,13 +39,16 @@ 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_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"; static final String SIDE_COLUMN = "side"; - static final String LIMIT_TYPE_COLUMN = "limitType"; private QueryCatalog() { } @@ -278,151 +281,225 @@ 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 + " = ?"; + // temporary limits + public static String buildInsertTemporaryLimitsQuery() { + return "insert into " + TEMPORARY_LIMITS_TABLE + "(" + + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + TEMPORARY_LIMITS + ") " + + " values (?, ?, ?, ?, ?)"; } - 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 buildDeleteTemporaryLimitsQuery() { + return "delete from " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ?"; } - public static String buildTemporaryLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + public static String buildDeleteTemporaryLimitsVariantQuery() { + 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 "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) + "?)"; + 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 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 " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + EQUIPMENT_ID_COLUMN + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeleteTemporaryLimitsVariantEquipmentINQuery(int numberOfValues) { + public static String buildTemporaryLimitWithInClauseQuery(String columnNameForInClause, 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) + "?)"; + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + TEMPORARY_LIMITS + + " from " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeleteTemporaryLimitsVariantQuery() { - return "delete from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ? and " + - VARIANT_NUM_COLUMN + " = ?"; + 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 " + OLD_TEMPORARY_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeleteTemporaryLimitsQuery() { - return "delete from temporarylimit where " + - NETWORK_UUID_COLUMN + " = ?"; + 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 + ", " + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + TEMPORARY_LIMITS + " from " + TEMPORARY_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; } - // 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 + " = ?"; + public static String buildTemporaryLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + TEMPORARY_LIMITS + + " from " + TEMPORARY_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; } - public static String buildPermanentLimitQuery(String columnNameForWhereClause) { + public static String buildOldTemporaryLimitQuery(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 + " = ?"; + 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 buildPermanentLimitWithInClauseQuery(String columnNameForInClause, int numberOfValues) { + public static String buildDeleteOldTemporaryLimitsVariantEquipmentClauseQuery(String columnNameForWhereClause) { + return "delete from " + OLD_TEMPORARY_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; + } + + // permanent limits + public static String buildInsertPermanentLimitsQuery() { + return "insert into " + PERMANENT_LIMITS_TABLE + " (" + + EQUIPMENT_ID_COLUMN + ", " + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + PERMANENT_LIMITS + ") " + + " values (?, ?, ?, ?, ?)"; + } + + public static String buildDeletePermanentLimitsQuery() { + return "delete from " + PERMANENT_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ?"; + } + + public static String buildDeletePermanentLimitsVariantQuery() { + 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 "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) + "?)"; + 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 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 (?, ?, ?, ?, ?, ?, ?, ?)"; + public static String buildDeletePermanentLimitsVariantEquipmentINQuery(int numberOfValues) { + if (numberOfValues < 1) { + throw new IllegalArgumentException(MINIMAL_VALUE_REQUIREMENT_ERROR); + } + return "delete from " + PERMANENT_LIMITS_TABLE + " 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 buildPermanentLimitWithInClauseQuery(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_TABLE + " 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 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 " + OLD_PERMANENT_LIMITS + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForInClause + " in (" + + "?, ".repeat(numberOfValues - 1) + "?)"; } - public static String buildDeletePermanentLimitsQuery() { - return "delete from permanentlimit where " + - NETWORK_UUID_COLUMN + " = ?"; + 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 + ", " + + EQUIPMENT_TYPE_COLUMN + ", ?, ?, " + PERMANENT_LIMITS + " from " + PERMANENT_LIMITS_TABLE + " where " + NETWORK_UUID_COLUMN + + " = ? and " + VARIANT_NUM_COLUMN + " = ?"; + } + + public static String buildPermanentLimitQuery(String columnNameForWhereClause) { + return "select " + EQUIPMENT_ID_COLUMN + ", " + + EQUIPMENT_TYPE_COLUMN + ", " + + NETWORK_UUID_COLUMN + ", " + + VARIANT_NUM_COLUMN + ", " + + PERMANENT_LIMITS + + " from " + PERMANENT_LIMITS_TABLE + " where " + + NETWORK_UUID_COLUMN + " = ? and " + + VARIANT_NUM_COLUMN + " = ? and " + + columnNameForWhereClause + " = ?"; + } + + 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) { + return "delete from " + OLD_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/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/json/PermanentLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java new file mode 100644 index 00000000..25d24cb6 --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/PermanentLimitSqlData.java @@ -0,0 +1,51 @@ +/** + * 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.json; + +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() { + // empty constructor for Jackson + } + + 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/json/TemporaryLimitSqlData.java b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java new file mode 100644 index 00000000..d9c9e687 --- /dev/null +++ b/network-store-server/src/main/java/com/powsybl/network/store/server/json/TemporaryLimitSqlData.java @@ -0,0 +1,59 @@ +/** + * 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.json; + +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() { + // empty constructor for Jackson + } + + 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/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..ae7a25f7 --- /dev/null +++ b/network-store-server/src/main/resources/db/changelog/changesets/changelog_20241121T110000Z.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file 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 new file mode 100644 index 00000000..f691a599 --- /dev/null +++ b/network-store-server/src/main/resources/db/changelog/changesets/refactor_limits_20241121T110000Z.sql @@ -0,0 +1,22 @@ +-- will be used in next deployment +INSERT INTO newtemporarylimits (equipmentid, equipmenttype, networkuuid, variantnum, temporarylimits) +SELECT equipmentid, equipmenttype, networkuuid, variantnum, + json_agg(json_build_object( + 'operationalLimitsGroupId', operationalLimitsGroupId, + 'side', side, + 'limitType', limitType, + 'name', name, + 'value', value_, + 'acceptableDuration', acceptableduration, + 'fictitious', fictitious + )) as temporarylimits FROM temporarylimit +GROUP BY equipmentid, equipmenttype, networkuuid, variantnum; +INSERT INTO newpermanentlimits (equipmentid, equipmenttype, networkuuid, variantnum, permanentlimits) +SELECT equipmentid, equipmenttype, networkuuid, variantnum, + json_agg(json_build_object( + 'operationalLimitsGroupId', operationalLimitsGroupId, + 'value', value_, + 'side', side, + 'limitType', limitType + )) as permanentlimits FROM permanentlimit +GROUP BY equipmentid, equipmenttype, networkuuid, variantnum; \ 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 diff --git a/pom.xml b/pom.xml index bc999588..994ab433 100644 --- a/pom.xml +++ b/pom.xml @@ -50,7 +50,6 @@ 1.0 2.16.0 -