Skip to content

Commit edd2df0

Browse files
committed
add created_at and updated_at to core database entities
1 parent 2ab9c2d commit edd2df0

9 files changed

Lines changed: 269 additions & 0 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
START TRANSACTION;
2+
3+
ALTER TABLE address
4+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
5+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
6+
7+
ALTER TABLE charge_box
8+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
9+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
10+
11+
ALTER TABLE charging_profile
12+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
13+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
14+
15+
ALTER TABLE ocpp_tag
16+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
17+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
18+
19+
ALTER TABLE reservation
20+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
21+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
22+
23+
ALTER TABLE `user`
24+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
25+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
26+
27+
ALTER TABLE web_user
28+
ADD COLUMN created_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
29+
ADD COLUMN updated_at TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
30+
31+
COMMIT;

src/test/java/de/rwth/idsg/steve/repository/impl/AbstractRepositoryITBase.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package de.rwth.idsg.steve.repository.impl;
2020

2121
import de.rwth.idsg.steve.utils.__DatabasePreparer__;
22+
import org.joda.time.DateTime;
2223
import org.jooq.DSLContext;
2324
import org.jooq.exception.DataAccessException;
2425
import org.junit.jupiter.api.Assertions;
@@ -85,6 +86,29 @@ private static boolean containsDatabaseException(Throwable t) {
8586
return false;
8687
}
8788

89+
protected static void assertAuditTimestampsAreSet(DateTime createdAt, DateTime updatedAt) {
90+
Assertions.assertNotNull(createdAt);
91+
Assertions.assertNotNull(updatedAt);
92+
}
93+
94+
protected static void assertAuditTimestampsAfterUpdate(DateTime createdAtBefore,
95+
DateTime updatedAtBefore,
96+
DateTime createdAtAfter,
97+
DateTime updatedAtAfter) {
98+
Assertions.assertEquals(createdAtBefore, createdAtAfter);
99+
Assertions.assertTrue(updatedAtAfter.isAfter(updatedAtBefore),
100+
() -> "Expected updated_at to advance from " + updatedAtBefore + " to " + updatedAtAfter);
101+
}
102+
103+
protected static void waitForTimestampTick() {
104+
try {
105+
Thread.sleep(50);
106+
} catch (InterruptedException e) {
107+
Thread.currentThread().interrupt();
108+
Assertions.fail("Interrupted while waiting for timestamp tick", e);
109+
}
110+
}
111+
88112
protected static void resetDatabase(DSLContext dslContext) {
89113
var preparer = new __DatabasePreparer__(dslContext);
90114
preparer.prepare();

src/test/java/de/rwth/idsg/steve/repository/impl/AddressRepositoryImplIT.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,32 @@ public void delete() {
9191
.fetchOne(0, int.class);
9292
Assertions.assertEquals(0, count);
9393
}
94+
95+
@Test
96+
public void auditTimestamps() {
97+
Integer pk = dslContext.insertInto(ADDRESS)
98+
.set(ADDRESS.CITY, "Bonn")
99+
.returning(ADDRESS.ADDRESS_PK)
100+
.fetchOne()
101+
.getAddressPk();
102+
103+
var before = dslContext.select(ADDRESS.CREATED_AT, ADDRESS.UPDATED_AT)
104+
.from(ADDRESS)
105+
.where(ADDRESS.ADDRESS_PK.eq(pk))
106+
.fetchOne();
107+
assertAuditTimestampsAreSet(before.value1(), before.value2());
108+
109+
waitForTimestampTick();
110+
111+
dslContext.update(ADDRESS)
112+
.set(ADDRESS.CITY, "Munich")
113+
.where(ADDRESS.ADDRESS_PK.eq(pk))
114+
.execute();
115+
116+
var after = dslContext.select(ADDRESS.CREATED_AT, ADDRESS.UPDATED_AT)
117+
.from(ADDRESS)
118+
.where(ADDRESS.ADDRESS_PK.eq(pk))
119+
.fetchOne();
120+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
121+
}
94122
}

src/test/java/de/rwth/idsg/steve/repository/impl/ChargePointRepositoryImplIT.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,35 @@ public void deleteChargePoint() {
165165
Assertions.assertEquals(0, count);
166166
}
167167

168+
@Test
169+
public void auditTimestamps() {
170+
String chargeBoxId = uniqueId("cp");
171+
Integer chargeBoxPk = dslContext.insertInto(CHARGE_BOX)
172+
.set(CHARGE_BOX.CHARGE_BOX_ID, chargeBoxId)
173+
.returning(CHARGE_BOX.CHARGE_BOX_PK)
174+
.fetchOne()
175+
.getChargeBoxPk();
176+
177+
var before = dslContext.select(CHARGE_BOX.CREATED_AT, CHARGE_BOX.UPDATED_AT)
178+
.from(CHARGE_BOX)
179+
.where(CHARGE_BOX.CHARGE_BOX_PK.eq(chargeBoxPk))
180+
.fetchOne();
181+
assertAuditTimestampsAreSet(before.value1(), before.value2());
182+
183+
waitForTimestampTick();
184+
185+
dslContext.update(CHARGE_BOX)
186+
.set(CHARGE_BOX.DESCRIPTION, "audit-update")
187+
.where(CHARGE_BOX.CHARGE_BOX_PK.eq(chargeBoxPk))
188+
.execute();
189+
190+
var after = dslContext.select(CHARGE_BOX.CREATED_AT, CHARGE_BOX.UPDATED_AT)
191+
.from(CHARGE_BOX)
192+
.where(CHARGE_BOX.CHARGE_BOX_PK.eq(chargeBoxPk))
193+
.fetchOne();
194+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
195+
}
196+
168197
private static ChargePointForm chargePointForm(String chargeBoxId) {
169198
var form = new ChargePointForm();
170199
form.setChargeBoxId(chargeBoxId);

src/test/java/de/rwth/idsg/steve/repository/impl/ChargingProfileRepositoryImplIT.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,38 @@ public void delete() {
160160
Assertions.assertEquals(0, count);
161161
}
162162

163+
@Test
164+
public void auditTimestamps() {
165+
Integer profilePk = dslContext.insertInto(CHARGING_PROFILE)
166+
.set(CHARGING_PROFILE.DESCRIPTION, "audit")
167+
.set(CHARGING_PROFILE.STACK_LEVEL, 0)
168+
.set(CHARGING_PROFILE.CHARGING_PROFILE_PURPOSE, ocpp.cp._2015._10.ChargingProfilePurposeType.TX_PROFILE.value())
169+
.set(CHARGING_PROFILE.CHARGING_PROFILE_KIND, ocpp.cp._2015._10.ChargingProfileKindType.ABSOLUTE.value())
170+
.set(CHARGING_PROFILE.CHARGING_RATE_UNIT, ocpp.cp._2015._10.ChargingRateUnitType.W.value())
171+
.returning(CHARGING_PROFILE.CHARGING_PROFILE_PK)
172+
.fetchOne()
173+
.getChargingProfilePk();
174+
175+
var before = dslContext.select(CHARGING_PROFILE.CREATED_AT, CHARGING_PROFILE.UPDATED_AT)
176+
.from(CHARGING_PROFILE)
177+
.where(CHARGING_PROFILE.CHARGING_PROFILE_PK.eq(profilePk))
178+
.fetchOne();
179+
assertAuditTimestampsAreSet(before.value1(), before.value2());
180+
181+
waitForTimestampTick();
182+
183+
dslContext.update(CHARGING_PROFILE)
184+
.set(CHARGING_PROFILE.DESCRIPTION, "audit-updated")
185+
.where(CHARGING_PROFILE.CHARGING_PROFILE_PK.eq(profilePk))
186+
.execute();
187+
188+
var after = dslContext.select(CHARGING_PROFILE.CREATED_AT, CHARGING_PROFILE.UPDATED_AT)
189+
.from(CHARGING_PROFILE)
190+
.where(CHARGING_PROFILE.CHARGING_PROFILE_PK.eq(profilePk))
191+
.fetchOne();
192+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
193+
}
194+
163195
private static ChargingProfileForm chargingProfileForm() {
164196
var form = new ChargingProfileForm();
165197
form.setDescription("it");

src/test/java/de/rwth/idsg/steve/repository/impl/OcppTagRepositoryImplIT.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,33 @@ public void deleteOcppTag() {
175175
.fetchOne(0, int.class);
176176
Assertions.assertEquals(0, count);
177177
}
178+
179+
@Test
180+
public void auditTimestamps() {
181+
String idTag = uniqueId("tag");
182+
Integer pk = dslContext.insertInto(OCPP_TAG)
183+
.set(OCPP_TAG.ID_TAG, idTag)
184+
.returning(OCPP_TAG.OCPP_TAG_PK)
185+
.fetchOne()
186+
.getOcppTagPk();
187+
188+
var before = dslContext.select(OCPP_TAG.CREATED_AT, OCPP_TAG.UPDATED_AT)
189+
.from(OCPP_TAG)
190+
.where(OCPP_TAG.OCPP_TAG_PK.eq(pk))
191+
.fetchOne();
192+
assertAuditTimestampsAreSet(before.value1(), before.value2());
193+
194+
waitForTimestampTick();
195+
196+
dslContext.update(OCPP_TAG)
197+
.set(OCPP_TAG.NOTE, "audit-update")
198+
.where(OCPP_TAG.OCPP_TAG_PK.eq(pk))
199+
.execute();
200+
201+
var after = dslContext.select(OCPP_TAG.CREATED_AT, OCPP_TAG.UPDATED_AT)
202+
.from(OCPP_TAG)
203+
.where(OCPP_TAG.OCPP_TAG_PK.eq(pk))
204+
.fetchOne();
205+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
206+
}
178207
}

src/test/java/de/rwth/idsg/steve/repository/impl/ReservationRepositoryImplIT.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,42 @@ public void cancelActiveReservations() {
155155
Assertions.assertEquals("CANCELLED", status);
156156
}
157157

158+
@Test
159+
public void auditTimestamps() {
160+
Integer connectorPk = dslContext.select(CONNECTOR.CONNECTOR_PK)
161+
.from(CONNECTOR)
162+
.where(CONNECTOR.CHARGE_BOX_ID.eq(KNOWN_CHARGE_BOX_ID))
163+
.and(CONNECTOR.CONNECTOR_ID.eq(1))
164+
.fetchOne(CONNECTOR.CONNECTOR_PK);
165+
166+
Integer id = dslContext.insertInto(RESERVATION)
167+
.set(RESERVATION.CONNECTOR_PK, connectorPk)
168+
.set(RESERVATION.ID_TAG, KNOWN_OCPP_TAG)
169+
.set(RESERVATION.STATUS, "WAITING")
170+
.returning(RESERVATION.RESERVATION_PK)
171+
.fetchOne()
172+
.getReservationPk();
173+
174+
var before = dslContext.select(RESERVATION.CREATED_AT, RESERVATION.UPDATED_AT)
175+
.from(RESERVATION)
176+
.where(RESERVATION.RESERVATION_PK.eq(id))
177+
.fetchOne();
178+
assertAuditTimestampsAreSet(before.value1(), before.value2());
179+
180+
waitForTimestampTick();
181+
182+
dslContext.update(RESERVATION)
183+
.set(RESERVATION.STATUS, "ACCEPTED")
184+
.where(RESERVATION.RESERVATION_PK.eq(id))
185+
.execute();
186+
187+
var after = dslContext.select(RESERVATION.CREATED_AT, RESERVATION.UPDATED_AT)
188+
.from(RESERVATION)
189+
.where(RESERVATION.RESERVATION_PK.eq(id))
190+
.fetchOne();
191+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
192+
}
193+
158194
private void useReservation(int reservationConnectorId, String idTagFromTransaction) {
159195
Integer id = repository.insert(insertReservationParams(reservationConnectorId));
160196
repository.accepted(id);

src/test/java/de/rwth/idsg/steve/repository/impl/UserRepositoryImplIT.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,34 @@ public void delete() {
104104
Assertions.assertEquals(0, count);
105105
}
106106

107+
@Test
108+
public void auditTimestamps() {
109+
Integer pk = dslContext.insertInto(USER)
110+
.set(USER.FIRST_NAME, "Audit")
111+
.returning(USER.USER_PK)
112+
.fetchOne()
113+
.getUserPk();
114+
115+
var before = dslContext.select(USER.CREATED_AT, USER.UPDATED_AT)
116+
.from(USER)
117+
.where(USER.USER_PK.eq(pk))
118+
.fetchOne();
119+
assertAuditTimestampsAreSet(before.value1(), before.value2());
120+
121+
waitForTimestampTick();
122+
123+
dslContext.update(USER)
124+
.set(USER.LAST_NAME, "Updated")
125+
.where(USER.USER_PK.eq(pk))
126+
.execute();
127+
128+
var after = dslContext.select(USER.CREATED_AT, USER.UPDATED_AT)
129+
.from(USER)
130+
.where(USER.USER_PK.eq(pk))
131+
.fetchOne();
132+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
133+
}
134+
107135
private static UserForm userForm() {
108136
var form = new UserForm();
109137
form.setFirstName("Repo");

src/test/java/de/rwth/idsg/steve/repository/impl/WebUserRepositoryImplIT.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,38 @@ public void loadUserByUsername() {
242242
Assertions.assertEquals("[\"ROLE_LOAD\"]", loaded.getAuthorities().data());
243243
}
244244

245+
@Test
246+
public void auditTimestamps() {
247+
String username = uniqueUsername();
248+
Integer pk = dslContext.insertInto(WEB_USER)
249+
.set(WEB_USER.USERNAME, username)
250+
.set(WEB_USER.PASSWORD, "pw")
251+
.set(WEB_USER.ENABLED, true)
252+
.set(WEB_USER.AUTHORITIES, json("[\"ROLE_AUDIT\"]"))
253+
.returning(WEB_USER.WEB_USER_PK)
254+
.fetchOne()
255+
.getWebUserPk();
256+
257+
var before = dslContext.select(WEB_USER.CREATED_AT, WEB_USER.UPDATED_AT)
258+
.from(WEB_USER)
259+
.where(WEB_USER.WEB_USER_PK.eq(pk))
260+
.fetchOne();
261+
assertAuditTimestampsAreSet(before.value1(), before.value2());
262+
263+
waitForTimestampTick();
264+
265+
dslContext.update(WEB_USER)
266+
.set(WEB_USER.PASSWORD, "new-pw")
267+
.where(WEB_USER.WEB_USER_PK.eq(pk))
268+
.execute();
269+
270+
var after = dslContext.select(WEB_USER.CREATED_AT, WEB_USER.UPDATED_AT)
271+
.from(WEB_USER)
272+
.where(WEB_USER.WEB_USER_PK.eq(pk))
273+
.fetchOne();
274+
assertAuditTimestampsAfterUpdate(before.value1(), before.value2(), after.value1(), after.value2());
275+
}
276+
245277
private static String uniqueUsername() {
246278
return "repo_it_" + UUID.randomUUID().toString().replace("-", "");
247279
}

0 commit comments

Comments
 (0)