From e7e3263cf875b6db653320d6250f3890be86b041 Mon Sep 17 00:00:00 2001
From: maxlastglance <e52004266@student.tuwien.ac.at>
Date: Mon, 10 Mar 2025 12:30:55 +0100
Subject: [PATCH] update timestamp table on delete

---
 .../java/at/tuwien/mapper/MariaDbMapper.java  |  4 +-
 .../service/impl/TableServiceMariaDbImpl.java | 75 ++++++++++++++-----
 2 files changed, 61 insertions(+), 18 deletions(-)

diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
index 9f2e89c32f..c870c0bc04 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/mapper/MariaDbMapper.java
@@ -797,7 +797,9 @@ public interface MariaDbMapper {
             }
             statement.append("`").append(pkColumn).append("` = ").append(valueStr);
         }
-        statement.append(";");
+
+        // Append ORDER BY clause to sort by ROW_START descending and limit the result to the most recent row.
+        statement.append(" ORDER BY `ROW_START` DESC LIMIT 1;");
 
         log.trace("mapped select system timestamps query: {}", statement);
         return statement.toString();
diff --git a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
index aaaf84003c..ab31033524 100644
--- a/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
+++ b/dbrepo-data-service/services/src/main/java/at/tuwien/service/impl/TableServiceMariaDbImpl.java
@@ -253,14 +253,69 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi
             final int[] idx = new int[]{1};
             final PreparedStatement statement = connection.prepareStatement(mariaDbMapper.tupleToRawDeleteQuery(table, data));
             for (String column : data.getKeys().keySet()) {
-                mariaDbMapper.prepareStatementWithColumnTypeObject(statement,
-                        getColumnType(table.getColumns(), column), idx[0], column, data.getKeys().get(column));
+                mariaDbMapper.prepareStatementWithColumnTypeObject(
+                        statement,
+                        getColumnType(table.getColumns(), column),
+                        idx[0],
+                        column,
+                        data.getKeys().get(column));
                 idx[0]++;
             }
             final long start = System.currentTimeMillis();
             statement.executeUpdate();
             log.trace("executed statement in {} ms", System.currentTimeMillis() - start);
             connection.commit();
+
+            String selectQuery = mariaDbMapper.tupleToRawSelectSystemTimestampsQuery(
+                    table, TupleDto.builder().data(data.getKeys()).build());
+            try (PreparedStatement selectStmt = connection.prepareStatement(selectQuery);
+                 ResultSet rs = selectStmt.executeQuery()) {
+                if (rs.next()) {
+                    // Retrieve the new primary key values from the updated row (if needed).
+                    Map<String, Object> pkData = new HashMap<>();
+                    for (PrimaryKeyDto pk : table.getConstraints().getPrimaryKey()) {
+                        pkData.put(pk.getColumn().getInternalName(),
+                                rs.getObject(pk.getColumn().getInternalName()));
+                    }
+                    Timestamp tsAdd = rs.getTimestamp("ROW_START");
+                    Timestamp tsDelete = rs.getTimestamp("ROW_END");
+
+                    // Build the update query for the _timestamps table.
+                    String updateTsQuery = mariaDbMapper.tupleToRawUpdateTimestampQuery(
+                            table, TupleUpdateDto.builder().data(data.getKeys()).build(), tsAdd, tsDelete);
+                    try (PreparedStatement ps = connection.prepareStatement(updateTsQuery)) {
+                        int parameterIndex = 1;
+
+                        // SET clause: new timestamp values.
+                        ps.setTimestamp(parameterIndex++, tsAdd);
+                        ps.setTimestamp(parameterIndex++, tsDelete);
+
+                        // SET clause: new primary key values (assumed to be provided in data.getKeys())
+                        for (PrimaryKeyDto pk : table.getConstraints().getPrimaryKey()) {
+                            Object newPkValue = data.getKeys().get(pk.getColumn().getInternalName());
+                            ps.setObject(parameterIndex++, newPkValue);
+                        }
+
+                        // WHERE clause: bind the database id.
+                        String databaseId = table.getDatabase().getInternalName();
+                        ps.setString(parameterIndex++, databaseId);
+
+                        // WHERE clause: bind the old primary key values.
+                        for (PrimaryKeyDto pk : table.getConstraints().getPrimaryKey()) {
+                            log.info("Setting new primary key value: {}", pk.getColumn().getInternalName());
+                            Object oldPkValue = data.getKeys().get(pk.getColumn().getInternalName());
+                            log.info("Old primary key value: {}", oldPkValue);
+                            ps.setObject(parameterIndex++, oldPkValue);
+                        }
+                        int rowsUpdated = ps.executeUpdate();
+                    } catch (SQLException e) {
+                        log.error("Error updating timestamp table", e);
+                        throw new RuntimeException("Error updating timestamp table", e);
+                    }
+                } else {
+                    log.warn("No row found for updated PK; timestamps not updated.");
+                }
+            } // End of try-with-resources for selectStmt and rs.
         } catch (SQLException e) {
             connection.rollback();
             log.error("Failed to delete tuple: {}", e.getMessage());
@@ -271,6 +326,7 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi
         log.info("Deleted tuple(s) from table: {}.{}", table.getDatabase(), table.getInternalName());
     }
 
+
     @Override
     public void createTuple(TableDto table, TupleDto data) throws SQLException, QueryMalformedException,
             TableMalformedException, StorageUnavailableException, StorageNotFoundException {
@@ -426,9 +482,7 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi
 
                         // SET clause: new primary key values (assumed to be provided in data.getData())
                         for (PrimaryKeyDto pk : table.getConstraints().getPrimaryKey()) {
-                            log.info("Setting new primary key value: {}", pk.getColumn().getInternalName());
                             Object newPkValue = data.getData().get(pk.getColumn().getInternalName());
-                            log.info("New primary key value: {}", newPkValue);
                             ps.setObject(parameterIndex++, newPkValue);
                         }
 
@@ -443,20 +497,7 @@ public class TableServiceMariaDbImpl extends DataConnector implements TableServi
                             log.info("Old primary key value: {}", oldPkValue);
                             ps.setObject(parameterIndex++, oldPkValue);
                         }
-
-                        log.info("SQL Query: " + updateTsQuery);
-                        log.info("Bound parameters: tsAdd={}, tsDelete={}, newPKValues={}, databaseId={}, oldPKValues={}",
-                                tsAdd, tsDelete,
-                                table.getConstraints().getPrimaryKey().stream()
-                                        .map(pk -> data.getData().get(pk.getColumn().getInternalName()))
-                                        .collect(Collectors.toList()),
-                                databaseId,
-                                table.getConstraints().getPrimaryKey().stream()
-                                        .map(pk -> data.getKeys().get(pk.getColumn().getInternalName()))
-                                        .collect(Collectors.toList()));
-
                         int rowsUpdated = ps.executeUpdate();
-                        log.info("Updated {} row(s) in {}_timestamps table.", rowsUpdated, table.getInternalName());
                     }
                 } else {
                     log.warn("No row found for updated PK; timestamps not updated.");
-- 
GitLab