From edd52a97b46672507b0658f733fcabaef3fe3c60 Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 14 Sep 2025 15:28:55 +0200 Subject: [PATCH] Replace INSERT OR REPLACE with INSERT ON CONFLICT DO UPDATE The latter doesn't cause foreign key delete cascades --- .../storage/UnknownStorageIdStore.java | 3 ++- .../manager/storage/groups/GroupStore.java | 9 ++++++--- .../storage/identities/IdentityKeyStore.java | 3 ++- .../senderKeys/SenderKeyRecordStore.java | 20 ++----------------- .../senderKeys/SenderKeySharedStore.java | 3 ++- .../storage/sessions/SessionStore.java | 3 ++- 6 files changed, 16 insertions(+), 25 deletions(-) diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/UnknownStorageIdStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/UnknownStorageIdStore.java index 5ea5eff0..f4ad0437 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/UnknownStorageIdStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/UnknownStorageIdStore.java @@ -58,9 +58,10 @@ public class UnknownStorageIdStore { } public void addUnknownStorageIds(Connection connection, Collection storageIds) throws SQLException { + deleteUnknownStorageIds(connection, storageIds); final var sql = ( """ - INSERT OR REPLACE INTO %s (type, storage_id) + INSERT INTO %s (type, storage_id) VALUES (?, ?) """ ).formatted(TABLE_STORAGE_ID); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java index cb9bd24b..814773fa 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupStore.java @@ -165,8 +165,9 @@ public class GroupStore { if (endorsements != null) { final var sqlInsertMember = """ - INSERT OR REPLACE INTO %s (group_id, recipient_id, endorsement) + INSERT INTO %s (group_id, recipient_id, endorsement) VALUES (?, ?, ?) + ON CONFLICT (group_id, recipient_id) DO UPDATE SET endorsement=excluded.endorsement """.formatted(TABLE_GROUP_V2_MEMBER); try (final var statement = connection.prepareStatement(sqlInsertMember)) { for (final var entry : endorsements.entrySet()) { @@ -612,8 +613,9 @@ public class GroupStore { } } final var sql = """ - INSERT OR REPLACE INTO %s (_id, group_id, group_id_v2, name, color, expiration_time, blocked, archived, storage_id) + INSERT INTO %s (_id, group_id, group_id_v2, name, color, expiration_time, blocked, archived, storage_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (_id) DO UPDATE SET group_id=excluded.group_id, group_id_v2=excluded.group_id_v2, name=excluded.name, color=excluded.color, expiration_time=excluded.expiration_time, blocked=excluded.blocked, archived=excluded.archived, storage_id=excluded.storage_id RETURNING _id """.formatted(TABLE_GROUP_V1); try (final var statement = connection.prepareStatement(sql)) { @@ -641,8 +643,9 @@ public class GroupStore { } } final var sqlInsertMember = """ - INSERT OR REPLACE INTO %s (group_id, recipient_id) + INSERT INTO %s (group_id, recipient_id) VALUES (?, ?) + ON CONFLICT (group_id, recipient_id) DO NOTHING """.formatted(TABLE_GROUP_V1_MEMBER); try (final var statement = connection.prepareStatement(sqlInsertMember)) { for (final var recipient : groupV1.getMembers()) { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java index a2d03a21..ad069a1f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/identities/IdentityKeyStore.java @@ -280,8 +280,9 @@ public class IdentityKeyStore { identityInfo.getDateAddedTimestamp()); final var sql = ( """ - INSERT OR REPLACE INTO %s (address, identity_key, added_timestamp, trust_level) + INSERT INTO %s (address, identity_key, added_timestamp, trust_level) VALUES (?, ?, ?, ?) + ON CONFLICT (address) DO UPDATE SET identity_key=excluded.identity_key, added_timestamp=excluded.added_timestamp, trust_level=excluded.trust_level """ ).formatted(TABLE_IDENTITY); try (final var statement = connection.prepareStatement(sql)) { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeyRecordStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeyRecordStore.java index dd48fcdc..90739ac0 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeyRecordStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeyRecordStore.java @@ -171,27 +171,11 @@ public class SenderKeyRecordStore implements SenderKeyStore { final Key key, final SenderKeyRecord senderKeyRecord ) throws SQLException { - final var sqlUpdate = """ - UPDATE %s - SET record = ? - WHERE address = ? AND device_id = ? and distribution_id = ? - """.formatted(TABLE_SENDER_KEY); - try (final var statement = connection.prepareStatement(sqlUpdate)) { - statement.setBytes(1, senderKeyRecord.serialize()); - statement.setString(2, key.address()); - statement.setLong(3, key.deviceId()); - statement.setBytes(4, UuidUtil.toByteArray(key.distributionId())); - final var rows = statement.executeUpdate(); - if (rows > 0) { - return; - } - } - - // Record doesn't exist yet, creating a new one final var sqlInsert = ( """ - INSERT OR REPLACE INTO %s (address, device_id, distribution_id, record, created_timestamp) + INSERT INTO %s (address, device_id, distribution_id, record, created_timestamp) VALUES (?, ?, ?, ?, ?) + ON CONFLICT (address, device_id, distribution_id) DO UPDATE SET record=excluded.record """ ).formatted(TABLE_SENDER_KEY); try (final var statement = connection.prepareStatement(sqlInsert)) { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeySharedStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeySharedStore.java index 175524f5..2c83764b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeySharedStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/senderKeys/SenderKeySharedStore.java @@ -197,8 +197,9 @@ public class SenderKeySharedStore { ) throws SQLException { final var sql = ( """ - INSERT OR REPLACE INTO %s (address, device_id, distribution_id, timestamp) + INSERT INTO %s (address, device_id, distribution_id, timestamp) VALUES (?, ?, ?, ?) + ON CONFLICT (address, device_id, distribution_id) DO UPDATE SET timestamp=excluded.timestamp """ ).formatted(TABLE_SENDER_KEY_SHARED); try (final var statement = connection.prepareStatement(sql)) { diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/sessions/SessionStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/sessions/SessionStore.java index 86fe875e..cc12d2ee 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/sessions/SessionStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/sessions/SessionStore.java @@ -351,8 +351,9 @@ public class SessionStore implements SignalServiceSessionStore { } final var sql = """ - INSERT OR REPLACE INTO %s (account_id_type, address, device_id, record) + INSERT INTO %s (account_id_type, address, device_id, record) VALUES (?, ?, ?, ?) + ON CONFLICT (account_id_type, address, device_id) DO UPDATE SET record=excluded.record """.formatted(TABLE_SESSION); try (final var statement = connection.prepareStatement(sql)) { statement.setInt(1, accountIdType);