From 93d47436a8ad59b9b7ca24fec128ba66689ff903 Mon Sep 17 00:00:00 2001 From: Tour Date: Sun, 7 Dec 2025 12:56:53 +0100 Subject: [PATCH] goog Former-commit-id: 825058f790c5504e3ca47f9c12c7e76fbbf3892a --- src/main/java/auctiora/DatabaseService.java | 66 ++++++++++++++++----- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/src/main/java/auctiora/DatabaseService.java b/src/main/java/auctiora/DatabaseService.java index 91ddd8b..9e3a40b 100644 --- a/src/main/java/auctiora/DatabaseService.java +++ b/src/main/java/auctiora/DatabaseService.java @@ -411,9 +411,11 @@ public class DatabaseService { /** * Inserts or updates an auction record (typically called by external scraper) + * Handles both auction_id conflicts and url uniqueness constraints */ synchronized void upsertAuction(AuctionInfo auction) throws SQLException { - var sql = """ + // First try to INSERT with ON CONFLICT on auction_id + var insertSql = """ INSERT INTO auctions (auction_id, title, location, city, country, url, type, lot_count, closing_time, discovered_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(auction_id) DO UPDATE SET @@ -426,19 +428,55 @@ public class DatabaseService { lot_count = excluded.lot_count, closing_time = excluded.closing_time """; - - try (var conn = DriverManager.getConnection(url); var ps = conn.prepareStatement(sql)) { - ps.setLong(1, auction.auctionId()); - ps.setString(2, auction.title()); - ps.setString(3, auction.location()); - ps.setString(4, auction.city()); - ps.setString(5, auction.country()); - ps.setString(6, auction.url()); - ps.setString(7, auction.typePrefix()); - ps.setInt(8, auction.lotCount()); - ps.setString(9, auction.firstLotClosingTime() != null ? auction.firstLotClosingTime().toString() : null); - ps.setLong(10, Instant.now().getEpochSecond()); - ps.executeUpdate(); + + try (var conn = DriverManager.getConnection(url)) { + try (var ps = conn.prepareStatement(insertSql)) { + ps.setLong(1, auction.auctionId()); + ps.setString(2, auction.title()); + ps.setString(3, auction.location()); + ps.setString(4, auction.city()); + ps.setString(5, auction.country()); + ps.setString(6, auction.url()); + ps.setString(7, auction.typePrefix()); + ps.setInt(8, auction.lotCount()); + ps.setString(9, auction.firstLotClosingTime() != null ? auction.firstLotClosingTime().toString() : null); + ps.setLong(10, Instant.now().getEpochSecond()); + ps.executeUpdate(); + } catch (SQLException e) { + // If it fails due to UNIQUE constraint on url, try updating by url instead + if (e.getMessage().contains("UNIQUE constraint failed: auctions.url")) { + var updateByUrlSql = """ + UPDATE auctions SET + auction_id = ?, + title = ?, + location = ?, + city = ?, + country = ?, + type = ?, + lot_count = ?, + closing_time = ? + WHERE url = ? + """; + try (var ps = conn.prepareStatement(updateByUrlSql)) { + ps.setLong(1, auction.auctionId()); + ps.setString(2, auction.title()); + ps.setString(3, auction.location()); + ps.setString(4, auction.city()); + ps.setString(5, auction.country()); + ps.setString(6, auction.typePrefix()); + ps.setInt(7, auction.lotCount()); + ps.setString(8, auction.firstLotClosingTime() != null ? auction.firstLotClosingTime().toString() : null); + ps.setString(9, auction.url()); + + int updated = ps.executeUpdate(); + if (updated == 0) { + log.warn("Could not insert or update auction with url={}, auction_id={}", auction.url(), auction.auctionId()); + } + } + } else { + throw e; + } + } } }