chore: mitigate possible future sqlite driver problems (#4200)

* chore: mitigate possible future sqlite driver problems

* chore/feat: log driver version on error

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
This commit is contained in:
Pierre Maurice Schwang 2023-10-09 16:55:09 +02:00 committed by GitHub
parent 0a390ab342
commit dc13783db8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -130,6 +130,7 @@ public class SQLManager implements AbstractDB {
public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks; public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks;
// Private // Private
private Connection connection; private Connection connection;
private boolean supportsGetGeneratedKeys;
private boolean closed = false; private boolean closed = false;
/** /**
@ -154,6 +155,8 @@ public class SQLManager implements AbstractDB {
this.worldConfiguration = worldConfiguration; this.worldConfiguration = worldConfiguration;
this.database = database; this.database = database;
this.connection = database.openConnection(); this.connection = database.openConnection();
final DatabaseMetaData databaseMetaData = this.connection.getMetaData();
this.supportsGetGeneratedKeys = databaseMetaData.supportsGetGeneratedKeys();
this.mySQL = database instanceof MySQL; this.mySQL = database instanceof MySQL;
this.globalTasks = new ConcurrentLinkedQueue<>(); this.globalTasks = new ConcurrentLinkedQueue<>();
this.notifyTasks = new ConcurrentLinkedQueue<>(); this.notifyTasks = new ConcurrentLinkedQueue<>();
@ -161,6 +164,14 @@ public class SQLManager implements AbstractDB {
this.playerTasks = new ConcurrentHashMap<>(); this.playerTasks = new ConcurrentHashMap<>();
this.clusterTasks = new ConcurrentHashMap<>(); this.clusterTasks = new ConcurrentHashMap<>();
this.prefix = prefix; this.prefix = prefix;
if (mySQL && !supportsGetGeneratedKeys) {
String driver = databaseMetaData.getDriverName();
String driverVersion = databaseMetaData.getDriverVersion();
throw new SQLException("Database Driver for MySQL does not support Statement#getGeneratedKeys - which breaks " +
"PlotSquared functionality (Using " + driver + ":" + driverVersion + ")");
}
this.SET_OWNER = "UPDATE `" + this.prefix this.SET_OWNER = "UPDATE `" + this.prefix
+ "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?"; + "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?";
this.GET_ALL_PLOTS = this.GET_ALL_PLOTS =
@ -171,20 +182,32 @@ public class SQLManager implements AbstractDB {
"INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values "; "INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values ";
this.CREATE_TIERS = this.CREATE_TIERS =
"INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values "; "INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values ";
this.CREATE_PLOT = "INSERT INTO `" + this.prefix String tempCreatePlot = "INSERT INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)"; + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)";
if (!supportsGetGeneratedKeys) {
tempCreatePlot += " RETURNING `id`";
}
this.CREATE_PLOT = tempCreatePlot;
if (mySQL) { if (mySQL) {
this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `" + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `"
+ this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)";
} else { } else {
this.CREATE_PLOT_SAFE = "INSERT INTO `" + this.prefix String tempCreatePlotSafe = "INSERT INTO `" + this.prefix
+ "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `" + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `"
+ this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)";
if (!supportsGetGeneratedKeys) {
tempCreatePlotSafe += " RETURNING `id`";
}
this.CREATE_PLOT_SAFE = tempCreatePlotSafe;
} }
this.CREATE_CLUSTER = "INSERT INTO `" + this.prefix String tempCreateCluster = "INSERT INTO `" + this.prefix
+ "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)"; + "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)";
if (!supportsGetGeneratedKeys) {
tempCreateCluster += " RETURNING `id`";
}
this.CREATE_CLUSTER = tempCreateCluster;
try { try {
createTables(); createTables();
} catch (SQLException e) { } catch (SQLException e) {
@ -1073,9 +1096,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
int inserted = statement.executeUpdate(); if (statement.execute() || statement.getUpdateCount() > 0) {
if (inserted > 0) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
try (ResultSet keys = statement.getGeneratedKeys()) {
if (keys.next()) { if (keys.next()) {
plot.temp = keys.getInt(1); plot.temp = keys.getInt(1);
addPlotTask(plot, new UniqueStatement( addPlotTask(plot, new UniqueStatement(
@ -1145,8 +1167,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
statement.executeUpdate(); statement.execute();
try (ResultSet keys = statement.getGeneratedKeys()) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
if (keys.next()) { if (keys.next()) {
plot.temp = keys.getInt(1); plot.temp = keys.getInt(1);
} }
@ -3058,8 +3080,8 @@ public class SQLManager implements AbstractDB {
@Override @Override
public void addBatch(PreparedStatement statement) throws SQLException { public void addBatch(PreparedStatement statement) throws SQLException {
statement.executeUpdate(); statement.execute();
try (ResultSet keys = statement.getGeneratedKeys()) { try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) {
if (keys.next()) { if (keys.next()) {
cluster.temp = keys.getInt(1); cluster.temp = keys.getInt(1);
} }