Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

database fixes #275

Merged
merged 4 commits into from
Aug 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions build-logic/src/main/kotlin/WriteDependencies.kt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ abstract class WriteDependencies : DefaultTask() {
private fun MutableSet<ResolvedDependencyResult>.addFrom(dependencies: Set<DependencyResult>) {
for (dependency in dependencies) {
dependency as ResolvedDependencyResult
if (dependency.resolvedVariant.attributes.toString().contains("org.gradle.category=platform")) {
continue
}
add(dependency)
if (transitive.get()) {
addFrom(dependency.selected.dependencies)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ dependencies {
runtimeDownload(libs.assistedInject) {
isTransitive = false
}
runtimeDownload(libs.flyway) {
exclude("com.google", "gson")
}
runtimeDownload(libs.flywayMysql) {
isTransitive = false
}
}

tasks {
Expand Down
3 changes: 2 additions & 1 deletion build-logic/src/main/kotlin/extensions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ fun Task.standardRuntimeRelocations() {
relocateDependency("org.mariadb.jdbc")
relocateDependency("org.postgresql")
relocateDependency("redis.clients.jedis")
relocateDependency("org.flywaydb")
relocateDependency("com.fasterxml")
}

/**
Expand All @@ -77,7 +79,6 @@ fun Task.standardRelocations() {
relocateDependency("ninja.egg82.messenger")
relocateDependency("org.antlr")
relocateDependency("com.electronwill")
relocateDependency("org.flywaydb")
}

fun Task.relocateCloud() {
Expand Down
8 changes: 6 additions & 2 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ dependencies {
compileOnlyApi(libs.jdbiObject)
compileOnlyApi(libs.jdbiPostgres)
api(libs.hikariCP)
api(libs.flyway)
api(libs.flywayMysql)
compileOnlyApi(libs.flyway) {
exclude("com.google", "gson")
}
compileOnlyApi(libs.flywayMysql) {
isTransitive = false
}

// Messaging
api(libs.messenger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import net.draycia.carbon.common.messaging.packets.PacketFactory;
import net.draycia.carbon.common.users.db.DatabaseUserManager;
import net.draycia.carbon.common.util.ConcurrentUtil;
import net.draycia.carbon.common.util.PlayerUtils;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
Expand Down Expand Up @@ -75,7 +76,14 @@ protected CachingUserManager(
protected abstract void saveSync(CarbonPlayerCommon player);

private CompletableFuture<Void> save(final CarbonPlayerCommon player) {
return CompletableFuture.runAsync(() -> this.saveSync(player), this.executor);
return CompletableFuture.runAsync(() -> {
this.saveSync(player);
player.saved();
this.messagingManager.get().withPacketService(packetService -> {
packetService.queuePacket(this.packetFactory.saveCompletedPacket(player.uuid()));
packetService.flushQueue();
});
}, this.executor);
}

@Override
Expand All @@ -93,13 +101,7 @@ public CompletableFuture<Void> saveIfNeeded(final CarbonPlayerCommon player) {
if (!player.needsSave()) {
return CompletableFuture.completedFuture(null);
}
return this.save(player).whenComplete(($, $$) -> {
player.saved();
this.messagingManager.get().withPacketService(packetService -> {
packetService.queuePacket(this.packetFactory.saveCompletedPacket(player.uuid()));
packetService.flushQueue();
});
});
return this.save(player);
}

@Override
Expand All @@ -111,7 +113,8 @@ public CompletableFuture<CarbonPlayerCommon> user(final UUID uuid) {
final CarbonPlayerCommon player = this.loadOrCreate(uuid);
this.playerInjector.injectMembers(player);
if (this instanceof DatabaseUserManager) {
player.registerPropertyUpdateListener(() -> this.save(player));
player.registerPropertyUpdateListener(() ->
this.save(player).exceptionally(PlayerUtils.saveExceptionHandler(this.logger, player.username, uuid)));
}
return player;
}, this.executor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public CarbonPlayerCommon(
final boolean muted,
final boolean deafened,
final @Nullable Key selectedChannel,
final String username,
final @Nullable String username, // will be resolved when requested
final UUID uuid,
final @Nullable Component displayName,
final @Nullable UUID lastWhisperTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

import com.google.inject.MembersInjector;
import com.google.inject.Provider;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import net.draycia.carbon.api.channels.ChannelRegistry;
import net.draycia.carbon.common.messaging.MessagingManager;
Expand All @@ -34,7 +36,6 @@
import org.checkerframework.framework.qual.DefaultQualifier;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.statement.PreparedBatch;
import org.jdbi.v3.core.statement.Update;

@DefaultQualifier(NonNull.class)
public abstract class DatabaseUserManager extends CachingUserManager {
Expand Down Expand Up @@ -67,33 +68,46 @@ protected DatabaseUserManager(

@Override
public final void saveSync(final CarbonPlayerCommon player) {
this.jdbi.withHandle(handle -> {
this.bindPlayerArguments(handle.createUpdate(this.locator.query("save-player")), player)
this.jdbi.useTransaction(handle -> {
handle.createUpdate(this.locator.query("insert-player"))
.bind("id", player.uuid())
.bind("muted", player.muted())
.bind("deafened", player.deafened())
.bind("selectedchannel", player.selectedChannelKey())
.bind("username", player.username()) // todo remove from db?
.bind("displayname", player.displayNameRaw())
.bind("lastwhispertarget", player.lastWhisperTarget())
.bind("whisperreplytarget", player.whisperReplyTarget())
.bind("spying", player.spying())
.execute();

if (!player.ignoredPlayers().isEmpty()) {
final PreparedBatch batch = handle.prepareBatch(this.locator.query("save-ignores"));
handle.createUpdate(this.locator.query("clear-ignores"))
.bind("id", player.uuid())
.execute();
handle.createUpdate(this.locator.query("clear-leftchannels"))
.bind("id", player.uuid())
.execute();

for (final UUID ignoredPlayer : player.ignoredPlayers()) {
final Set<UUID> ignored = player.ignoredPlayers();
if (!ignored.isEmpty()) {
final PreparedBatch batch = handle.prepareBatch(this.locator.query("save-ignores"));
for (final UUID ignoredPlayer : ignored) {
batch.bind("id", player.uuid()).bind("ignoredplayer", ignoredPlayer).add();
}

batch.execute();
}
if (!player.leftChannels().isEmpty()) {
final PreparedBatch batch = handle.prepareBatch(this.locator.query("save-leftchannels"));

for (final Key leftChannel : player.leftChannels()) {
final List<Key> left = player.leftChannels();
if (!left.isEmpty()) {
final PreparedBatch batch = handle.prepareBatch(this.locator.query("save-leftchannels"));
for (final Key leftChannel : left) {
batch.bind("id", player.uuid()).bind("channel", leftChannel).add();
}

batch.execute();
}
// TODO: save ignoredplayers
return null;

handle.commit();
});
}

abstract protected Update bindPlayerArguments(final Update update, final CarbonPlayerCommon player);

}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public CarbonPlayerCommon map(final ResultSet rs, final StatementContext ctx) th
rs.getBoolean("muted"),
rs.getBoolean("deafened"),
selectedChannel == null ? null : Key.key(selectedChannel),
Strings.trim(rs.getString("username")),
null,
UUID.fromString(id),
displayName == null ? null : GsonComponentSerializer.gson().deserialize(displayName),
lastWhisperTarget == null ? null : UUID.fromString(lastWhisperTarget),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.checkerframework.framework.qual.DefaultQualifier;
import org.flywaydb.core.Flyway;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.statement.Update;
import org.jdbi.v3.sqlobject.SqlObjectPlugin;

@DefaultQualifier(NonNull.class)
Expand Down Expand Up @@ -110,20 +109,6 @@ protected CarbonPlayerCommon loadOrCreate(final UUID uuid) {
});
}

@Override
protected Update bindPlayerArguments(final Update update, final CarbonPlayerCommon player) {
return update
.bind("id", player.uuid())
.bind("muted", player.muted())
.bind("deafened", player.deafened())
.bind("selectedchannel", player.selectedChannelKey())
.bind("username", player.username())
.bind("displayname", player.displayNameRaw())
.bind("lastwhispertarget", player.lastWhisperTarget())
.bind("whisperreplytarget", player.whisperReplyTarget())
.bind("spying", player.spying());
}

public static final class Factory {

private final DatabaseSettings databaseSettings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public CarbonPlayerCommon map(final ResultSet rs, final StatementContext ctx) th
rs.getBoolean("muted"),
rs.getBoolean("deafened"),
selectedChannel == null ? null : Key.key(selectedChannel),
Strings.trim(rs.getString("username")),
null,
rs.getObject("id", UUID.class),
displayName == null ? null : GsonComponentSerializer.gson().deserialize(displayName),
rs.getObject("lastwhispertarget", UUID.class),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.internal.database.postgresql.PostgreSQLDatabaseType;
import org.flywaydb.core.internal.plugin.PluginRegister;
import org.jdbi.v3.core.Jdbi;
import org.jdbi.v3.core.statement.Update;
import org.jdbi.v3.postgres.PostgresPlugin;
import org.jdbi.v3.sqlobject.SqlObjectPlugin;

Expand Down Expand Up @@ -113,20 +110,6 @@ protected CarbonPlayerCommon loadOrCreate(final UUID uuid) {
});
}

@Override
protected Update bindPlayerArguments(final Update update, final CarbonPlayerCommon player) {
return update
.bind("id", player.uuid())
.bind("muted", player.muted())
.bind("deafened", player.deafened())
.bind("selectedchannel", player.selectedChannelKey())
.bind("username", player.username())
.bind("displayname", player.displayNameRaw())
.bind("lastwhispertarget", player.lastWhisperTarget())
.bind("whisperreplytarget", player.whisperReplyTarget())
.bind("spying", player.spying());
}

public static final class Factory {

private final DatabaseSettings databaseSettings;
Expand Down Expand Up @@ -158,7 +141,6 @@ private Factory(

public PostgreSQLUserManager create() {
SQLDrivers.loadFrom(this.getClass().getClassLoader());
PluginRegister.REGISTERED_PLUGINS.add(new PostgreSQLDatabaseType());

final HikariConfig hikariConfig = new HikariConfig();
hikariConfig.setMaximumPoolSize(20);
Expand All @@ -169,15 +151,17 @@ public PostgreSQLUserManager create() {

final DataSource dataSource = new HikariDataSource(hikariConfig);

Flyway.configure(CarbonChat.class.getClassLoader())
final Flyway flyway = Flyway.configure(CarbonChat.class.getClassLoader())
.baselineVersion("0")
.baselineOnMigrate(true)
.locations("queries/migrations/postgresql")
.dataSource(dataSource)
.validateMigrationNaming(true)
.validateOnMigrate(true)
.load()
.migrate();
.load();

flyway.repair();
flyway.migrate();

final Jdbi jdbi = Jdbi.create(dataSource)
.registerArgument(new ComponentArgumentFactory())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static <C extends CarbonPlayer> CompletableFuture<Void> savePlayer(

public static Function<Throwable, @Nullable Void> saveExceptionHandler(final Logger logger, final String username, final UUID uuid) {
return thr -> {
logger.warn("Exception saving data for player {} with uuid {}", username, uuid);
logger.warn("Exception saving data for player {} with uuid {}", username, uuid, thr);
return null;
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ CREATE TABLE carbon_users (
`id` BINARY(16) NOT NULL PRIMARY KEY,
`muted` BOOLEAN,
`deafened` BOOLEAN,
`selectedchannel` varchar(256),
`username` varchar(20),
`displayname` varchar(1024),
`selectedchannel` VARCHAR(256),
`username` VARCHAR(20),
`displayname` VARCHAR(1024),
`lastwhispertarget` BINARY(16),
`whisperreplytarget` BINARY(16),
`spying` BOOLEAN
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DROP TABLE carbon_leftchannels;
CREATE TABLE carbon_leftchannels (
`id` BINARY(16) NOT NULL,
`channel` VARCHAR(256) NOT NULL,
PRIMARY KEY (id, channel)
);
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CREATE TABLE IF NOT EXISTS carbon_users (
CREATE TABLE carbon_users (
id uuid NOT NULL PRIMARY KEY,
muted BOOLEAN,
deafened BOOLEAN,
Expand All @@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS carbon_users (
spying BOOLEAN
);

CREATE TABLE IF NOT EXISTS carbon_ignores (
CREATE TABLE carbon_ignores (
id uuid NOT NULL,
ignoredplayer uuid NOT NULL,
PRIMARY KEY (id, ignoredplayer)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
CREATE TABLE IF NOT EXISTS carbon_leftchannels (
CREATE TABLE carbon_leftchannels (
id uuid NOT NULL,
channel varchar(100) NOT NULL,
channel VARCHAR(100) NOT NULL,
PRIMARY KEY (id, channel)
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE carbon_leftchannels ALTER COLUMN channel TYPE VARCHAR(256) NOT NULL;
1 change: 1 addition & 0 deletions common/src/main/resources/queries/mysql/clear-ignores.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM carbon_ignores WHERE (id = UNHEX(REPLACE(:id, '-', '')));
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM carbon_leftchannels WHERE (id = UNHEX(REPLACE(:id, '-', '')));
32 changes: 21 additions & 11 deletions common/src/main/resources/queries/mysql/insert-player.sql
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
INSERT INTO carbon_users VALUES (
UNHEX(REPLACE(:id, '-', '')),
:muted,
:deafened,
:selectedchannel,
:username,
:displayname,
UNHEX(REPLACE(:lastwhispertarget, '-', '')),
UNHEX(REPLACE(:whisperreplytarget, '-', '')),
:spying
);
INSERT INTO carbon_users SET
id = UNHEX(REPLACE(:id, '-', '')),
muted = :muted,
deafened = :deafened,
selectedchannel = :selectedchannel,
username= :username,
displayname = :displayname,
lastwhispertarget = UNHEX(REPLACE(:lastwhispertarget, '-', '')),
whisperreplytarget = UNHEX(REPLACE(:whisperreplytarget, '-', '')),
spying = :spying
ON DUPLICATE KEY UPDATE
id = UNHEX(REPLACE(:id, '-', '')),
muted = :muted,
deafened = :deafened,
selectedchannel = :selectedchannel,
username= :username,
displayname = :displayname,
lastwhispertarget = UNHEX(REPLACE(:lastwhispertarget, '-', '')),
whisperreplytarget = UNHEX(REPLACE(:whisperreplytarget, '-', '')),
spying = :spying
;