9
0
mirror of https://github.com/WiIIiam278/HuskSync.git synced 2025-12-30 20:29:28 +00:00

Implement compression via DataAdapter, add option to disable compression, better exception handling

This commit is contained in:
William
2022-07-04 23:44:45 +01:00
parent f2d4bec138
commit 1829526aa7
23 changed files with 227 additions and 83 deletions

View File

@@ -1,5 +1,6 @@
package net.william278.husksync.database;
import net.william278.husksync.data.DataAdapter;
import net.william278.husksync.data.UserData;
import net.william278.husksync.data.VersionedUserData;
import net.william278.husksync.player.User;
@@ -36,6 +37,20 @@ public abstract class Database {
*/
protected final int maxUserDataRecords;
/**
* {@link DataAdapter} implementation used for adapting {@link UserData} to and from JSON
*/
private final DataAdapter dataAdapter;
/**
* Returns the {@link DataAdapter} used to adapt {@link UserData} to and from JSON
*
* @return instance of the {@link DataAdapter} implementation
*/
protected DataAdapter getDataAdapter() {
return dataAdapter;
}
/**
* Logger instance used for database error logging
*/
@@ -56,11 +71,12 @@ public abstract class Database {
private final ResourceReader resourceReader;
protected Database(@NotNull String playerTableName, @NotNull String dataTableName, final int maxUserDataRecords,
@NotNull ResourceReader resourceReader, @NotNull Logger logger) {
@NotNull ResourceReader resourceReader, @NotNull DataAdapter dataAdapter, @NotNull Logger logger) {
this.playerTableName = playerTableName;
this.dataTableName = dataTableName;
this.maxUserDataRecords = maxUserDataRecords;
this.resourceReader = resourceReader;
this.dataAdapter = dataAdapter;
this.logger = logger;
}

View File

@@ -2,6 +2,8 @@ package net.william278.husksync.database;
import com.zaxxer.hikari.HikariDataSource;
import net.william278.husksync.config.Settings;
import net.william278.husksync.data.DataAdapter;
import net.william278.husksync.data.DataAdaptionException;
import net.william278.husksync.data.UserData;
import net.william278.husksync.data.VersionedUserData;
import net.william278.husksync.player.User;
@@ -52,22 +54,23 @@ public class MySqlDatabase extends Database {
*/
private HikariDataSource connectionPool;
public MySqlDatabase(@NotNull Settings settings, @NotNull ResourceReader resourceReader, @NotNull Logger logger) {
public MySqlDatabase(@NotNull Settings settings, @NotNull ResourceReader resourceReader, @NotNull Logger logger,
@NotNull DataAdapter dataAdapter) {
super(settings.getStringValue(Settings.ConfigOption.DATABASE_PLAYERS_TABLE_NAME),
settings.getStringValue(Settings.ConfigOption.DATABASE_DATA_TABLE_NAME),
settings.getIntegerValue(Settings.ConfigOption.SYNCHRONIZATION_MAX_USER_DATA_RECORDS),
resourceReader, logger);
mySqlHost = settings.getStringValue(Settings.ConfigOption.DATABASE_HOST);
mySqlPort = settings.getIntegerValue(Settings.ConfigOption.DATABASE_PORT);
mySqlDatabaseName = settings.getStringValue(Settings.ConfigOption.DATABASE_NAME);
mySqlUsername = settings.getStringValue(Settings.ConfigOption.DATABASE_USERNAME);
mySqlPassword = settings.getStringValue(Settings.ConfigOption.DATABASE_PASSWORD);
mySqlConnectionParameters = settings.getStringValue(Settings.ConfigOption.DATABASE_CONNECTION_PARAMS);
hikariMaximumPoolSize = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_SIZE);
hikariMinimumIdle = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MIN_IDLE);
hikariMaximumLifetime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_LIFETIME);
hikariKeepAliveTime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_KEEPALIVE);
hikariConnectionTimeOut = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_TIMEOUT);
resourceReader, dataAdapter, logger);
this.mySqlHost = settings.getStringValue(Settings.ConfigOption.DATABASE_HOST);
this.mySqlPort = settings.getIntegerValue(Settings.ConfigOption.DATABASE_PORT);
this.mySqlDatabaseName = settings.getStringValue(Settings.ConfigOption.DATABASE_NAME);
this.mySqlUsername = settings.getStringValue(Settings.ConfigOption.DATABASE_USERNAME);
this.mySqlPassword = settings.getStringValue(Settings.ConfigOption.DATABASE_PASSWORD);
this.mySqlConnectionParameters = settings.getStringValue(Settings.ConfigOption.DATABASE_CONNECTION_PARAMS);
this.hikariMaximumPoolSize = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_SIZE);
this.hikariMinimumIdle = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MIN_IDLE);
this.hikariMaximumLifetime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_MAX_LIFETIME);
this.hikariKeepAliveTime = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_KEEPALIVE);
this.hikariConnectionTimeOut = settings.getIntegerValue(Settings.ConfigOption.DATABASE_CONNECTION_POOL_TIMEOUT);
}
/**
@@ -219,16 +222,15 @@ public class MySqlDatabase extends Database {
final ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
final Blob blob = resultSet.getBlob("data");
final byte[] compressedDataJson = blob.getBytes(1, (int) blob.length());
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
blob.free();
return Optional.of(new VersionedUserData(
UUID.fromString(resultSet.getString("version_uuid")),
Date.from(resultSet.getTimestamp("timestamp").toInstant()),
UserData.fromJson(new String(Snappy.uncompress(compressedDataJson),
StandardCharsets.UTF_8))));
getDataAdapter().fromBytes(dataByteArray)));
}
}
} catch (SQLException | IOException e) {
} catch (SQLException | DataAdaptionException e) {
getLogger().log(Level.SEVERE, "Failed to fetch a user's current user data from the database", e);
}
return Optional.empty();
@@ -249,18 +251,17 @@ public class MySqlDatabase extends Database {
final ResultSet resultSet = statement.executeQuery();
while (resultSet.next()) {
final Blob blob = resultSet.getBlob("data");
final byte[] compressedDataJson = blob.getBytes(1, (int) blob.length());
final byte[] dataByteArray = blob.getBytes(1, (int) blob.length());
blob.free();
final VersionedUserData data = new VersionedUserData(
UUID.fromString(resultSet.getString("version_uuid")),
Date.from(resultSet.getTimestamp("timestamp").toInstant()),
UserData.fromJson(new String(Snappy.uncompress(compressedDataJson),
StandardCharsets.UTF_8)));
getDataAdapter().fromBytes(dataByteArray));
retrievedData.add(data);
}
return retrievedData;
}
} catch (SQLException | IOException e) {
} catch (SQLException | DataAdaptionException e) {
getLogger().log(Level.SEVERE, "Failed to fetch a user's current user data from the database", e);
}
return retrievedData;
@@ -297,11 +298,11 @@ public class MySqlDatabase extends Database {
(`player_uuid`,`version_uuid`,`timestamp`,`data`)
VALUES (?,UUID(),NOW(),?);"""))) {
statement.setString(1, user.uuid.toString());
statement.setBlob(2, new ByteArrayInputStream(Snappy
.compress(userData.toJson().getBytes(StandardCharsets.UTF_8))));
statement.setBlob(2, new ByteArrayInputStream(
getDataAdapter().toBytes(userData)));
statement.executeUpdate();
}
} catch (SQLException | IOException e) {
} catch (SQLException | DataAdaptionException e) {
getLogger().log(Level.SEVERE, "Failed to set user data in the database", e);
}
}).thenRun(() -> pruneUserDataRecords(user).join());