Skip to content

Commit ccc54db

Browse files
committed
refactor: introduce Ocpp1ConnectorEvseBridge
* previously, we were "insert or ignore"ing connector ids as they come. and then, we were using another SQL query to select the connector pk relating to this connector id, because the initial "insert or ignore" was not able to return the PK. with the new impl of insertIgnoreConnectorInternal, we can return evsePk. as a result, the additional SQL query is NOT necessary at all. subsequent queries that need evsePk can just use the literal value of returned evsePk. * localize all evsePk selection queries that are scattered across multiple repository impl classes. now, we have evsePkSelect methods in Ocpp1ConnectorEvseBridge, which can be referenced by repository impls.
1 parent 60e0121 commit ccc54db

5 files changed

Lines changed: 194 additions & 190 deletions

File tree

src/main/java/de/rwth/idsg/steve/repository/impl/ChargingProfileRepositoryImpl.java

Lines changed: 6 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,10 @@ public class ChargingProfileRepositoryImpl implements ChargingProfileRepository
7070

7171
@Override
7272
public void setProfile(int chargingProfilePk, String chargeBoxId, int connectorId) {
73-
OcppServerRepositoryImpl.insertIgnoreConnector(ctx, chargeBoxId, connectorId, false);
74-
75-
SelectConditionStep<Record1<Integer>> connectorPkSelect = ctx.select(EVSE.EVSE_PK)
76-
.from(EVSE)
77-
.where(EVSE.CHARGE_BOX_ID.eq(chargeBoxId))
78-
.and(EVSE.TOPOLOGY_SOURCE.eq(EvseTopologySource.ocpp1))
79-
.and(EVSE.EVSE_ID.eq(connectorId));
73+
int evsePk = Ocpp1ConnectorEvseBridge.insertIgnoreConnector(ctx, chargeBoxId, connectorId, false);
8074

8175
int count = ctx.insertInto(CONNECTOR_CHARGING_PROFILE)
82-
.set(CONNECTOR_CHARGING_PROFILE.EVSE_PK, connectorPkSelect)
76+
.set(CONNECTOR_CHARGING_PROFILE.EVSE_PK, evsePk)
8377
.set(CONNECTOR_CHARGING_PROFILE.CHARGING_PROFILE_PK, chargingProfilePk)
8478
.onDuplicateKeyIgnore()
8579
.execute();
@@ -91,13 +85,10 @@ public void setProfile(int chargingProfilePk, String chargeBoxId, int connectorI
9185

9286
@Override
9387
public void clearProfile(int chargingProfilePk, String chargeBoxId) {
94-
SelectConditionStep<Record1<Integer>> connectorPkSelect = ctx.select(EVSE.EVSE_PK)
95-
.from(EVSE)
96-
.where(EVSE.CHARGE_BOX_ID.eq(chargeBoxId))
97-
.and(EVSE.TOPOLOGY_SOURCE.eq(EvseTopologySource.ocpp1));
88+
var evsePkSelect = Ocpp1ConnectorEvseBridge.evsePkSelect(ctx, chargeBoxId);
9889

9990
ctx.delete(CONNECTOR_CHARGING_PROFILE)
100-
.where(CONNECTOR_CHARGING_PROFILE.EVSE_PK.in(connectorPkSelect))
91+
.where(CONNECTOR_CHARGING_PROFILE.EVSE_PK.in(evsePkSelect))
10192
.and(CONNECTOR_CHARGING_PROFILE.CHARGING_PROFILE_PK.eq(chargingProfilePk))
10293
.execute();
10394
}
@@ -112,13 +103,7 @@ public void clearProfile(@NotNull String chargeBoxId,
112103
// Connector select
113104
// -------------------------------------------------------------------------
114105

115-
Condition connectorIdCondition = (connectorId == null) ? DSL.trueCondition() : EVSE.EVSE_ID.eq(connectorId);
116-
117-
SelectConditionStep<Record1<Integer>> connectorPkSelect = ctx.select(EVSE.EVSE_PK)
118-
.from(EVSE)
119-
.where(EVSE.CHARGE_BOX_ID.eq(chargeBoxId))
120-
.and(EVSE.TOPOLOGY_SOURCE.eq(EvseTopologySource.ocpp1))
121-
.and(connectorIdCondition);
106+
var evsePkSelect = Ocpp1ConnectorEvseBridge.evsePkSelect(ctx, chargeBoxId, connectorId);
122107

123108
// -------------------------------------------------------------------------
124109
// Profile select
@@ -146,7 +131,7 @@ public void clearProfile(@NotNull String chargeBoxId,
146131
// -------------------------------------------------------------------------
147132

148133
ctx.delete(CONNECTOR_CHARGING_PROFILE)
149-
.where(CONNECTOR_CHARGING_PROFILE.EVSE_PK.in(connectorPkSelect))
134+
.where(CONNECTOR_CHARGING_PROFILE.EVSE_PK.in(evsePkSelect))
150135
.and(profilePkCondition)
151136
.execute();
152137
}
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* SteVe - SteckdosenVerwaltung - https://github.com/steve-community/steve
3+
* Copyright (C) 2013-2026 SteVe Community Team
4+
* All Rights Reserved.
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
package de.rwth.idsg.steve.repository.impl;
20+
21+
import de.rwth.idsg.steve.SteveException;
22+
import jooq.steve.db.Tables;
23+
import jooq.steve.db.enums.EvseTopologySource;
24+
import lombok.extern.slf4j.Slf4j;
25+
import org.jetbrains.annotations.Nullable;
26+
import org.jooq.Condition;
27+
import org.jooq.DSLContext;
28+
import org.jooq.Record1;
29+
import org.jooq.SelectConditionStep;
30+
import org.jooq.impl.DSL;
31+
import org.springframework.util.CollectionUtils;
32+
33+
import java.util.Collections;
34+
import java.util.Set;
35+
36+
import static jooq.steve.db.tables.ChargeBox.CHARGE_BOX;
37+
import static jooq.steve.db.tables.Evse.EVSE;
38+
import static jooq.steve.db.tables.EvseConnector.EVSE_CONNECTOR;
39+
40+
/**
41+
* @author Sevket Goekay <sevketgokay@gmail.com>
42+
* @since 13.05.2026
43+
*/
44+
@Slf4j
45+
public class Ocpp1ConnectorEvseBridge {
46+
47+
public static SelectConditionStep<Record1<Integer>> evsePkSelect(DSLContext ctx, String chargeBoxId) {
48+
return evsePkSelect2(ctx, chargeBoxId, null);
49+
}
50+
51+
public static SelectConditionStep<Record1<Integer>> evsePkSelect(DSLContext ctx, String chargeBoxId, @Nullable Integer connectorId) {
52+
Set<Integer> connectorIds = (connectorId == null) ? Collections.emptySet() : Set.of(connectorId);
53+
return evsePkSelect2(ctx, chargeBoxId, connectorIds);
54+
}
55+
56+
public static SelectConditionStep<Record1<Integer>> evsePkSelect2(DSLContext ctx, String chargeBoxId, Set<Integer> connectorIds) {
57+
Condition evseIdCondition = CollectionUtils.isEmpty(connectorIds)
58+
? DSL.trueCondition()
59+
: Tables.EVSE.EVSE_ID.in(connectorIds);
60+
61+
return ctx.select(EVSE.EVSE_PK)
62+
.from(EVSE)
63+
.where(EVSE.CHARGE_BOX_ID.eq(chargeBoxId))
64+
.and(EVSE.TOPOLOGY_SOURCE.eq(EvseTopologySource.ocpp1))
65+
.and(evseIdCondition);
66+
}
67+
68+
/**
69+
* If the connector information was not received before, insert it. Otherwise, ignore.
70+
*
71+
* @return evsePk
72+
*/
73+
public static int insertIgnoreConnector(DSLContext ctx, String chargeBoxIdentity, int connectorId, boolean inTransactionAlready) {
74+
if (inTransactionAlready) {
75+
return insertIgnoreConnectorInternal(ctx, chargeBoxIdentity, connectorId);
76+
} else {
77+
return ctx.transactionResult(configuration ->
78+
insertIgnoreConnectorInternal(DSL.using(configuration), chargeBoxIdentity, connectorId)
79+
);
80+
}
81+
}
82+
83+
private static int insertIgnoreConnectorInternal(DSLContext ctx, String chargeBoxIdentity, int connectorId) {
84+
var topology = ctx.select(EVSE.EVSE_PK, EVSE_CONNECTOR.EVSE_CONNECTOR_PK)
85+
.from(CHARGE_BOX)
86+
.leftJoin(EVSE)
87+
.on(EVSE.CHARGE_BOX_ID.eq(CHARGE_BOX.CHARGE_BOX_ID))
88+
.and(EVSE.TOPOLOGY_SOURCE.eq(EvseTopologySource.ocpp1))
89+
.and(EVSE.EVSE_ID.eq(connectorId))
90+
.leftJoin(EVSE_CONNECTOR)
91+
.on(EVSE_CONNECTOR.EVSE_PK.eq(EVSE.EVSE_PK))
92+
.and(EVSE_CONNECTOR.CONNECTOR_ID.eq(1))
93+
.where(CHARGE_BOX.CHARGE_BOX_ID.eq(chargeBoxIdentity))
94+
.forUpdate()
95+
.fetchOne();
96+
97+
if (topology == null) {
98+
throw new SteveException("Charge box with id '%s' not found", chargeBoxIdentity); // should not happen
99+
}
100+
101+
Integer evsePk = topology.value1();
102+
Integer evseConnectorPk = topology.value2();
103+
104+
if (evsePk == null) {
105+
evsePk = ctx.insertInto(EVSE)
106+
.set(EVSE.CHARGE_BOX_ID, chargeBoxIdentity)
107+
.set(EVSE.TOPOLOGY_SOURCE, EvseTopologySource.ocpp1)
108+
.set(EVSE.EVSE_ID, connectorId)
109+
.returning(EVSE.EVSE_PK)
110+
.fetchOne(EVSE.EVSE_PK);
111+
112+
log.debug("The connector {}/{} is NEW, and inserted into DB.", chargeBoxIdentity, connectorId);
113+
}
114+
115+
if (connectorId != 0 && evseConnectorPk == null) {
116+
final int defaultEvseConnectorId = 1;
117+
118+
ctx.insertInto(EVSE_CONNECTOR)
119+
.set(EVSE_CONNECTOR.EVSE_PK, evsePk)
120+
.set(EVSE_CONNECTOR.CONNECTOR_ID, defaultEvseConnectorId)
121+
.execute();
122+
123+
log.debug("The evse_connector {}/{}/{} is NEW, and inserted into DB.", chargeBoxIdentity, connectorId, defaultEvseConnectorId);
124+
}
125+
126+
return evsePk;
127+
}
128+
}

0 commit comments

Comments
 (0)