Prevent duplicate key exception from being thrown entirely

Affects issues:
- Fixed #3543
This commit is contained in:
Aurora Lahtela 2024-03-30 10:11:15 +02:00
parent 49269d3aab
commit 8c36f318c7
4 changed files with 19 additions and 22 deletions

View File

@ -118,6 +118,8 @@ public abstract class Sql {
public abstract String dateToHour(String sql); public abstract String dateToHour(String sql);
public abstract String insertOrIgnore();
// https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html // https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html
public static class MySQL extends Sql { public static class MySQL extends Sql {
@ -150,6 +152,11 @@ public abstract class Sql {
public String dateToHour(String sql) { public String dateToHour(String sql) {
return "HOUR(" + sql + ") % 24"; return "HOUR(" + sql + ") % 24";
} }
@Override
public String insertOrIgnore() {
return "INSERT IGNORE INTO ";
}
} }
// https://sqlite.org/lang_datefunc.html // https://sqlite.org/lang_datefunc.html
@ -184,5 +191,10 @@ public abstract class Sql {
public String dateToHour(String sql) { public String dateToHour(String sql) {
return "strftime('%H'," + sql + ')'; return "strftime('%H'," + sql + ')';
} }
@Override
public String insertOrIgnore() {
return "INSERT OR IGNORE INTO ";
}
} }
} }

View File

@ -41,6 +41,10 @@ public class WebPermissionTable {
/* Static information class */ /* Static information class */
} }
public static String safeInsertSQL(DBType dbType) {
return dbType.getSql().insertOrIgnore() + TABLE_NAME + " (" + PERMISSION + ") VALUES (?)";
}
public static String createTableSQL(DBType dbType) { public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType) return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey() .column(ID, Sql.INT).primaryKey()

View File

@ -17,7 +17,6 @@
package com.djrapitops.plan.storage.database.transactions.patches; package com.djrapitops.plan.storage.database.transactions.patches;
import com.djrapitops.plan.delivery.domain.auth.WebPermission; import com.djrapitops.plan.delivery.domain.auth.WebPermission;
import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries; import com.djrapitops.plan.storage.database.queries.objects.WebUserQueries;
import com.djrapitops.plan.storage.database.sql.tables.webuser.WebPermissionTable; import com.djrapitops.plan.storage.database.sql.tables.webuser.WebPermissionTable;
import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement; import com.djrapitops.plan.storage.database.transactions.ExecBatchStatement;
@ -56,19 +55,11 @@ public class UpdateWebPermissionsPatch extends Patch {
@Override @Override
protected void applyPatch() { protected void applyPatch() {
try { storeMissing();
storeMissing();
} catch (DBOpException failed) {
if (failed.isDuplicateKeyViolation()) {
retry(failed);
} else {
throw failed;
}
}
} }
private void storeMissing() { private void storeMissing() {
execute(new ExecBatchStatement(WebPermissionTable.INSERT_STATEMENT) { execute(new ExecBatchStatement(WebPermissionTable.safeInsertSQL(dbType)) {
@Override @Override
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
for (String permission : missingPermissions) { for (String permission : missingPermissions) {
@ -78,14 +69,4 @@ public class UpdateWebPermissionsPatch extends Patch {
} }
}); });
} }
private void retry(DBOpException failed) {
try {
if (hasBeenApplied()) return;
storeMissing();
} catch (DBOpException anotherFail) {
anotherFail.addSuppressed(failed);
throw anotherFail;
}
}
} }

View File

@ -50,7 +50,7 @@ public class StoreMissingWebPermissionsTransaction extends Transaction {
missingPermissions.add(permission); missingPermissions.add(permission);
} }
} }
execute(new ExecBatchStatement(WebPermissionTable.INSERT_STATEMENT) { execute(new ExecBatchStatement(WebPermissionTable.safeInsertSQL(dbType)) {
@Override @Override
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
for (String permission : missingPermissions) { for (String permission : missingPermissions) {