mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-03 05:51:28 +01:00
Rewrote transactions for storing extension table data
Affects issues: - Possibly fixed #1522 - Possibly fixed #1838
This commit is contained in:
parent
53120ad65a
commit
a8716e533e
@ -35,6 +35,7 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
||||||
@ -79,42 +80,60 @@ public class StorePlayerTableResultTransaction extends ThrowawayTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Integer tableID = query(tableID());
|
Integer tableID = query(tableID());
|
||||||
deleteOldValues(tableID).execute(connection);
|
|
||||||
insertNewValues(tableID).execute(connection);
|
List<Object[]> rows = table.getRows();
|
||||||
|
Integer oldRowCount = query(currentRowCount(tableID));
|
||||||
|
int newRowCount = rows.size();
|
||||||
|
|
||||||
|
if (oldRowCount < newRowCount) {
|
||||||
|
updateRows(tableID, oldRowCount, rows);
|
||||||
|
insertNewRows(tableID, oldRowCount, rows);
|
||||||
|
} else if (oldRowCount == newRowCount) {
|
||||||
|
// No need to delete or insert rows
|
||||||
|
updateRows(tableID, oldRowCount, rows);
|
||||||
|
} else {
|
||||||
|
// oldRowCount > newRowCount
|
||||||
|
updateRows(tableID, newRowCount, rows);
|
||||||
|
deleteOldRows(tableID, newRowCount);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Executable deleteOldValues(int tableID) {
|
private void deleteOldRows(Integer tableID, int afterRow) {
|
||||||
String sql = DELETE_FROM + TABLE_NAME +
|
String sql = DELETE_FROM + TABLE_NAME +
|
||||||
WHERE + TABLE_ID + "=?" +
|
WHERE + TABLE_ID + "=?" +
|
||||||
AND + USER_UUID + "=?";
|
AND + USER_UUID + "=?" +
|
||||||
|
AND + ROW_NUMBER + ">=?"; // Since row count is zero indexed and afterRow is size the value should be removed.
|
||||||
|
|
||||||
return new ExecStatement(sql) {
|
execute(new ExecStatement(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
statement.setInt(1, tableID);
|
statement.setInt(1, tableID);
|
||||||
statement.setString(2, playerUUID.toString());
|
statement.setString(2, playerUUID.toString());
|
||||||
|
statement.setInt(3, afterRow);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Executable insertNewValues(int tableID) {
|
private void insertNewRows(Integer tableID, Integer afterRow, List<Object[]> rows) {
|
||||||
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
||||||
TABLE_ID + ',' +
|
TABLE_ID + ',' +
|
||||||
USER_UUID + ',' +
|
USER_UUID + ',' +
|
||||||
VALUE_1 + ',' +
|
VALUE_1 + ',' +
|
||||||
VALUE_2 + ',' +
|
VALUE_2 + ',' +
|
||||||
VALUE_3 + ',' +
|
VALUE_3 + ',' +
|
||||||
VALUE_4 +
|
VALUE_4 + ',' +
|
||||||
") VALUES (?,?,?,?,?,?)";
|
ROW_NUMBER +
|
||||||
|
") VALUES (?,?,?,?,?,?,?)";
|
||||||
|
|
||||||
return new ExecBatchStatement(sql) {
|
execute(new ExecBatchStatement(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
int maxColumnSize = Math.min(table.getMaxColumnSize(), 4); // Limit to maximum 4 columns, or how many column names there are.
|
int maxColumnSize = Math.min(table.getMaxColumnSize(), 4); // Limit to maximum 4 columns, or how many column names there are.
|
||||||
|
|
||||||
for (Object[] row : table.getRows()) {
|
for (int rowNumber = afterRow; rowNumber < rows.size(); rowNumber++) {
|
||||||
|
Object[] row = rows.get(rowNumber);
|
||||||
statement.setInt(1, tableID);
|
statement.setInt(1, tableID);
|
||||||
statement.setString(2, playerUUID.toString());
|
statement.setString(2, playerUUID.toString());
|
||||||
for (int i = 0; i < maxColumnSize; i++) {
|
for (int i = 0; i < maxColumnSize; i++) {
|
||||||
@ -126,9 +145,67 @@ public class StorePlayerTableResultTransaction extends ThrowawayTransaction {
|
|||||||
statement.setNull(3 + i, Types.VARCHAR);
|
statement.setNull(3 + i, Types.VARCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statement.setInt(7, rowNumber);
|
||||||
|
|
||||||
statement.addBatch();
|
statement.addBatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRows(Integer tableID, Integer untilRow, List<Object[]> rows) {
|
||||||
|
String sql = "UPDATE " + TABLE_NAME + " SET " +
|
||||||
|
VALUE_1 + "=?," +
|
||||||
|
VALUE_2 + "=?," +
|
||||||
|
VALUE_3 + "=?," +
|
||||||
|
VALUE_4 + "=?" +
|
||||||
|
WHERE + TABLE_ID + "=?" +
|
||||||
|
AND + USER_UUID + "=?" +
|
||||||
|
AND + ROW_NUMBER + "=?";
|
||||||
|
execute(new ExecBatchStatement(sql) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
int maxColumnSize = Math.min(table.getMaxColumnSize(), 4); // Limit to maximum 4 columns, or how many column names there are.
|
||||||
|
|
||||||
|
for (int rowNumber = 0; rowNumber < untilRow; rowNumber++) {
|
||||||
|
Object[] row = rows.get(rowNumber);
|
||||||
|
|
||||||
|
for (int valueIndex = 0; valueIndex < maxColumnSize; valueIndex++) {
|
||||||
|
Object value = row[valueIndex];
|
||||||
|
setStringOrNull(statement, 1 + valueIndex, value != null ? StringUtils.truncate(value.toString(), 250) : null);
|
||||||
|
}
|
||||||
|
// Rest are set null if not 4 columns wide.
|
||||||
|
for (int valueIndex = maxColumnSize; valueIndex < 4; valueIndex++) {
|
||||||
|
statement.setNull(1 + valueIndex, Types.VARCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.setInt(5, tableID);
|
||||||
|
statement.setString(6, playerUUID.toString());
|
||||||
|
statement.setInt(7, rowNumber);
|
||||||
|
|
||||||
|
statement.addBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Query<Integer> currentRowCount(Integer tableID) {
|
||||||
|
String sql = SELECT + "COALESCE(MAX(" + ROW_NUMBER + "), -1) as m" +
|
||||||
|
FROM + TABLE_NAME +
|
||||||
|
WHERE + TABLE_ID + "=?" +
|
||||||
|
AND + USER_UUID + "=?";
|
||||||
|
return new QueryStatement<Integer>(sql) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
statement.setInt(1, tableID);
|
||||||
|
statement.setString(2, playerUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer processResults(ResultSet set) throws SQLException {
|
||||||
|
// add one to the row number, which is 0 indexed
|
||||||
|
return set.next() ? set.getInt("m") + 1 : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
|
||||||
import static com.djrapitops.plan.storage.database.sql.tables.ExtensionServerTableValueTable.*;
|
import static com.djrapitops.plan.storage.database.sql.tables.ExtensionServerTableValueTable.*;
|
||||||
@ -76,27 +77,43 @@ public class StoreServerTableResultTransaction extends ThrowawayTransaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Integer tableID = query(tableID());
|
Integer tableID = query(tableID());
|
||||||
deleteOldValues(tableID).execute(connection);
|
|
||||||
insertNewValues(tableID).execute(connection);
|
List<Object[]> rows = table.getRows();
|
||||||
|
Integer oldRowCount = query(currentRowCount(tableID));
|
||||||
|
int newRowCount = rows.size();
|
||||||
|
|
||||||
|
if (oldRowCount < newRowCount) {
|
||||||
|
updateRows(tableID, oldRowCount, rows);
|
||||||
|
insertNewRows(tableID, oldRowCount, rows);
|
||||||
|
} else if (oldRowCount == newRowCount) {
|
||||||
|
// No need to delete or insert rows
|
||||||
|
updateRows(tableID, oldRowCount, rows);
|
||||||
|
} else {
|
||||||
|
// oldRowCount > newRowCount
|
||||||
|
updateRows(tableID, newRowCount, rows);
|
||||||
|
deleteOldRows(tableID, newRowCount);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Executable deleteOldValues(int tableID) {
|
private void deleteOldRows(Integer tableID, int afterRow) {
|
||||||
String sql = DELETE_FROM + TABLE_NAME +
|
String sql = DELETE_FROM + TABLE_NAME +
|
||||||
WHERE + TABLE_ID + "=?" +
|
WHERE + TABLE_ID + "=?" +
|
||||||
AND + SERVER_UUID + "=?";
|
AND + SERVER_UUID + "=?" +
|
||||||
|
AND + ROW_NUMBER + ">=?"; // Since row count is zero indexed and afterRow is size the value should be removed.
|
||||||
|
|
||||||
return new ExecStatement(sql) {
|
execute(new ExecStatement(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
statement.setInt(1, tableID);
|
statement.setInt(1, tableID);
|
||||||
statement.setString(2, serverUUID.toString());
|
statement.setString(2, serverUUID.toString());
|
||||||
|
statement.setInt(3, afterRow);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Executable insertNewValues(int tableID) {
|
private void insertNewRows(Integer tableID, Integer afterRow, List<Object[]> rows) {
|
||||||
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
String sql = "INSERT INTO " + TABLE_NAME + '(' +
|
||||||
TABLE_ID + ',' +
|
TABLE_ID + ',' +
|
||||||
SERVER_UUID + ',' +
|
SERVER_UUID + ',' +
|
||||||
@ -104,15 +121,17 @@ public class StoreServerTableResultTransaction extends ThrowawayTransaction {
|
|||||||
VALUE_2 + ',' +
|
VALUE_2 + ',' +
|
||||||
VALUE_3 + ',' +
|
VALUE_3 + ',' +
|
||||||
VALUE_4 + ',' +
|
VALUE_4 + ',' +
|
||||||
VALUE_5 +
|
VALUE_5 + ',' +
|
||||||
") VALUES (?,?,?,?,?,?, ?)";
|
ROW_NUMBER +
|
||||||
|
") VALUES (?,?,?,?,?,?,?,?)";
|
||||||
|
|
||||||
return new ExecBatchStatement(sql) {
|
execute(new ExecBatchStatement(sql) {
|
||||||
@Override
|
@Override
|
||||||
public void prepare(PreparedStatement statement) throws SQLException {
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
int maxColumnSize = Math.min(table.getMaxColumnSize(), 5); // Limit to maximum 5 columns, or how many column names there are.
|
int maxColumnSize = Math.min(table.getMaxColumnSize(), 5); // Limit to maximum 5 columns, or how many column names there are.
|
||||||
|
|
||||||
for (Object[] row : table.getRows()) {
|
for (int rowNumber = afterRow; rowNumber < rows.size(); rowNumber++) {
|
||||||
|
Object[] row = rows.get(rowNumber);
|
||||||
statement.setInt(1, tableID);
|
statement.setInt(1, tableID);
|
||||||
statement.setString(2, serverUUID.toString());
|
statement.setString(2, serverUUID.toString());
|
||||||
for (int i = 0; i < maxColumnSize; i++) {
|
for (int i = 0; i < maxColumnSize; i++) {
|
||||||
@ -124,9 +143,68 @@ public class StoreServerTableResultTransaction extends ThrowawayTransaction {
|
|||||||
statement.setNull(3 + i, Types.VARCHAR);
|
statement.setNull(3 + i, Types.VARCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
statement.setInt(8, rowNumber);
|
||||||
|
|
||||||
statement.addBatch();
|
statement.addBatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRows(Integer tableID, Integer untilRow, List<Object[]> rows) {
|
||||||
|
String sql = "UPDATE " + TABLE_NAME + " SET " +
|
||||||
|
VALUE_1 + "=?," +
|
||||||
|
VALUE_2 + "=?," +
|
||||||
|
VALUE_3 + "=?," +
|
||||||
|
VALUE_4 + "=?," +
|
||||||
|
VALUE_5 + "=?" +
|
||||||
|
WHERE + TABLE_ID + "=?" +
|
||||||
|
AND + SERVER_UUID + "=?" +
|
||||||
|
AND + ROW_NUMBER + "=?";
|
||||||
|
execute(new ExecBatchStatement(sql) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
int maxColumnSize = Math.min(table.getMaxColumnSize(), 5); // Limit to maximum 5 columns, or how many column names there are.
|
||||||
|
|
||||||
|
for (int rowNumber = 0; rowNumber < untilRow; rowNumber++) {
|
||||||
|
Object[] row = rows.get(rowNumber);
|
||||||
|
|
||||||
|
for (int valueIndex = 0; valueIndex < maxColumnSize; valueIndex++) {
|
||||||
|
Object value = row[valueIndex];
|
||||||
|
setStringOrNull(statement, 1 + valueIndex, value != null ? StringUtils.truncate(value.toString(), 250) : null);
|
||||||
|
}
|
||||||
|
// Rest are set null if not 5 columns wide.
|
||||||
|
for (int valueIndex = maxColumnSize; valueIndex < 5; valueIndex++) {
|
||||||
|
statement.setNull(1 + valueIndex, Types.VARCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
statement.setInt(6, tableID);
|
||||||
|
statement.setString(7, serverUUID.toString());
|
||||||
|
statement.setInt(8, rowNumber);
|
||||||
|
|
||||||
|
statement.addBatch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Query<Integer> currentRowCount(Integer tableID) {
|
||||||
|
String sql = SELECT + "COALESCE(MAX(" + ROW_NUMBER + "), -1) as m" +
|
||||||
|
FROM + TABLE_NAME +
|
||||||
|
WHERE + TABLE_ID + "=?" +
|
||||||
|
AND + SERVER_UUID + "=?";
|
||||||
|
return new QueryStatement<Integer>(sql) {
|
||||||
|
@Override
|
||||||
|
public void prepare(PreparedStatement statement) throws SQLException {
|
||||||
|
statement.setInt(1, tableID);
|
||||||
|
statement.setString(2, serverUUID.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer processResults(ResultSet set) throws SQLException {
|
||||||
|
// add one to the row number, which is 0 indexed
|
||||||
|
return set.next() ? set.getInt("m") + 1 : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,9 @@ public abstract class SQLDB extends AbstractDatabase {
|
|||||||
new LitebansTableHeaderPatch(),
|
new LitebansTableHeaderPatch(),
|
||||||
new UserInfoHostnamePatch(),
|
new UserInfoHostnamePatch(),
|
||||||
new ServerIsProxyPatch(),
|
new ServerIsProxyPatch(),
|
||||||
new UserInfoHostnameAllowNullPatch()
|
new UserInfoHostnameAllowNullPatch(),
|
||||||
|
new ServerTableValuesRowNumberPatch(),
|
||||||
|
new PlayerTableValuesRowNumberPatch()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ public class ExtensionPlayerTableValueTable {
|
|||||||
public static final String TABLE_ID = "table_id";
|
public static final String TABLE_ID = "table_id";
|
||||||
public static final String USER_UUID = "uuid";
|
public static final String USER_UUID = "uuid";
|
||||||
|
|
||||||
|
public static final String ROW_NUMBER = "row_number";
|
||||||
// All values can be null
|
// All values can be null
|
||||||
public static final String VALUE_1 = "col_1_value";
|
public static final String VALUE_1 = "col_1_value";
|
||||||
public static final String VALUE_2 = "col_2_value";
|
public static final String VALUE_2 = "col_2_value";
|
||||||
@ -49,6 +50,7 @@ public class ExtensionPlayerTableValueTable {
|
|||||||
return CreateTableBuilder.create(TABLE_NAME, dbType)
|
return CreateTableBuilder.create(TABLE_NAME, dbType)
|
||||||
.column(ID, INT).primaryKey()
|
.column(ID, INT).primaryKey()
|
||||||
.column(USER_UUID, Sql.varchar(36)).notNull()
|
.column(USER_UUID, Sql.varchar(36)).notNull()
|
||||||
|
.column(ROW_NUMBER, INT).notNull()
|
||||||
.column(VALUE_1, Sql.varchar(250))
|
.column(VALUE_1, Sql.varchar(250))
|
||||||
.column(VALUE_2, Sql.varchar(250))
|
.column(VALUE_2, Sql.varchar(250))
|
||||||
.column(VALUE_3, Sql.varchar(250))
|
.column(VALUE_3, Sql.varchar(250))
|
||||||
|
@ -35,6 +35,7 @@ public class ExtensionServerTableValueTable {
|
|||||||
public static final String TABLE_ID = "table_id";
|
public static final String TABLE_ID = "table_id";
|
||||||
public static final String SERVER_UUID = "uuid";
|
public static final String SERVER_UUID = "uuid";
|
||||||
|
|
||||||
|
public static final String ROW_NUMBER = "row_number";
|
||||||
// All values can be null
|
// All values can be null
|
||||||
public static final String VALUE_1 = "col_1_value";
|
public static final String VALUE_1 = "col_1_value";
|
||||||
public static final String VALUE_2 = "col_2_value";
|
public static final String VALUE_2 = "col_2_value";
|
||||||
@ -50,6 +51,7 @@ public class ExtensionServerTableValueTable {
|
|||||||
return CreateTableBuilder.create(TABLE_NAME, dbType)
|
return CreateTableBuilder.create(TABLE_NAME, dbType)
|
||||||
.column(ID, INT).primaryKey()
|
.column(ID, INT).primaryKey()
|
||||||
.column(SERVER_UUID, Sql.varchar(36)).notNull()
|
.column(SERVER_UUID, Sql.varchar(36)).notNull()
|
||||||
|
.column(ROW_NUMBER, INT).notNull()
|
||||||
.column(VALUE_1, Sql.varchar(250))
|
.column(VALUE_1, Sql.varchar(250))
|
||||||
.column(VALUE_2, Sql.varchar(250))
|
.column(VALUE_2, Sql.varchar(250))
|
||||||
.column(VALUE_3, Sql.varchar(250))
|
.column(VALUE_3, Sql.varchar(250))
|
||||||
|
Loading…
Reference in New Issue
Block a user