mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-24 03:25:19 +01:00
Refactor storage system
This commit is contained in:
parent
8b97439ffc
commit
8115fbaa98
@ -27,7 +27,7 @@ package me.lucko.luckperms.common.api;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
|
||||
public final class ApiUtils {
|
||||
|
||||
|
@ -33,7 +33,7 @@ import me.lucko.luckperms.common.command.abstraction.CommandException;
|
||||
import me.lucko.luckperms.common.commands.user.UserMainCommand;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.DateParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,7 +45,7 @@ import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -46,7 +46,7 @@ import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -36,7 +36,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -39,7 +39,7 @@ import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -39,7 +39,7 @@ import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.NodeMapType;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -38,7 +38,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.DurationFormatter;
|
||||
import me.lucko.luckperms.common.utils.Paginated;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
@ -38,7 +38,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.DurationFormatter;
|
||||
import me.lucko.luckperms.common.utils.Paginated;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
@ -25,9 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.common.commands.misc;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.LookupSetting;
|
||||
import me.lucko.luckperms.api.caching.MetaContexts;
|
||||
@ -50,6 +47,7 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.processors.PermissionProcessor;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
import me.lucko.luckperms.common.utils.gson.JArray;
|
||||
import me.lucko.luckperms.common.utils.gson.JObject;
|
||||
import me.lucko.luckperms.common.web.Pastebin;
|
||||
@ -70,8 +68,6 @@ import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DebugCommand extends SingleCommand {
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
|
||||
public DebugCommand(LocaleManager locale) {
|
||||
super(CommandSpec.DEBUG.localize(locale), "Debug", CommandPermission.DEBUG, Predicates.alwaysFalse());
|
||||
}
|
||||
@ -85,7 +81,7 @@ public class DebugCommand extends SingleCommand {
|
||||
|
||||
BiConsumer<String, JObject> builder = (name, content) -> {
|
||||
sb.append("-- ").append(name).append(" --\n");
|
||||
sb.append(GSON.toJson(content.toJson()));
|
||||
sb.append(GsonProvider.prettyPrinting().toJson(content.toJson()));
|
||||
sb.append("\n\n");
|
||||
};
|
||||
|
||||
@ -124,7 +120,7 @@ public class DebugCommand extends SingleCommand {
|
||||
return new JObject()
|
||||
.add("storage", new JObject()
|
||||
.add("name", plugin.getStorage().getName())
|
||||
.add("type", plugin.getStorage().getDao().getClass().getName())
|
||||
.add("type", plugin.getStorage().getImplementation().getClass().getName())
|
||||
.add("meta", () -> {
|
||||
JObject metaObject = new JObject();
|
||||
Map<String, String> meta = plugin.getStorage().getMeta();
|
||||
|
@ -36,7 +36,7 @@ import me.lucko.luckperms.common.locale.command.CommandSpec;
|
||||
import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -41,7 +41,7 @@ import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -37,7 +37,7 @@ import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -41,7 +41,7 @@ import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -40,7 +40,7 @@ import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -38,7 +38,7 @@ import me.lucko.luckperms.common.locale.message.Message;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,7 +45,7 @@ import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,7 +45,7 @@ import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.model.UserIdentifier;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Uuids;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -45,7 +45,7 @@ import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -43,8 +43,8 @@ import me.lucko.luckperms.common.primarygroup.AllParentsByWeightHolder;
|
||||
import me.lucko.luckperms.common.primarygroup.ParentsByWeightHolder;
|
||||
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
||||
import me.lucko.luckperms.common.primarygroup.StoredHolder;
|
||||
import me.lucko.luckperms.common.storage.SplitStorageType;
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.implementation.split.SplitStorageType;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -25,12 +25,12 @@
|
||||
|
||||
package me.lucko.luckperms.common.config;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
@ -70,7 +70,7 @@ public class ContextsFile {
|
||||
|
||||
boolean save = false;
|
||||
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
|
||||
JsonObject data = new Gson().fromJson(reader, JsonObject.class);
|
||||
JsonObject data = GsonProvider.normal().fromJson(reader, JsonObject.class);
|
||||
|
||||
if (data.has("context")) {
|
||||
this.staticContexts = ContextSetJsonSerializer.deserializeContextSet(data.get("context").getAsJsonObject()).makeImmutable();
|
||||
|
@ -25,8 +25,6 @@
|
||||
|
||||
package me.lucko.luckperms.common.messaging;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
@ -46,6 +44,7 @@ import me.lucko.luckperms.common.messaging.message.UpdateMessageImpl;
|
||||
import me.lucko.luckperms.common.messaging.message.UserUpdateMessageImpl;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
import me.lucko.luckperms.common.utils.gson.JObject;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -59,8 +58,6 @@ import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class LuckPermsMessagingService implements InternalMessagingService, IncomingMessageConsumer {
|
||||
private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Set<UUID> receivedMessages;
|
||||
private final PushUpdateBuffer updateBuffer;
|
||||
@ -169,7 +166,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
|
||||
@Override
|
||||
public boolean consumeIncomingMessageAsString(@NonNull String encodedString) {
|
||||
Objects.requireNonNull(encodedString, "encodedString");
|
||||
JsonObject decodedObject = GSON.fromJson(encodedString, JsonObject.class).getAsJsonObject();
|
||||
JsonObject decodedObject = GsonProvider.normal().fromJson(encodedString, JsonObject.class).getAsJsonObject();
|
||||
|
||||
// extract id
|
||||
JsonElement idElement = decodedObject.get("id");
|
||||
@ -226,7 +223,7 @@ public class LuckPermsMessagingService implements InternalMessagingService, Inco
|
||||
})
|
||||
.toJson();
|
||||
|
||||
return GSON.toJson(json);
|
||||
return GsonProvider.normal().toJson(json);
|
||||
}
|
||||
|
||||
private void processIncomingMessage(Message message) {
|
||||
|
@ -34,9 +34,9 @@ import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.messaging.redis.RedisMessenger;
|
||||
import me.lucko.luckperms.common.messaging.sql.SqlMessenger;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.SqlDao;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.MariaDbConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.MySqlConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MariaDbConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MySqlConnectionFactory;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
@ -57,9 +57,9 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
|
||||
messagingType = "redis";
|
||||
}
|
||||
|
||||
if (messagingType.equals("none") && this.plugin.getStorage().getDao() instanceof SqlDao) {
|
||||
SqlDao dao = (SqlDao) this.plugin.getStorage().getDao();
|
||||
if (dao.getProvider() instanceof MySqlConnectionFactory || dao.getProvider() instanceof MariaDbConnectionFactory) {
|
||||
if (messagingType.equals("none") && this.plugin.getStorage().getImplementation() instanceof SqlStorage) {
|
||||
SqlStorage dao = (SqlStorage) this.plugin.getStorage().getImplementation();
|
||||
if (dao.getConnectionFactory() instanceof MySqlConnectionFactory || dao.getConnectionFactory() instanceof MariaDbConnectionFactory) {
|
||||
messagingType = "sql";
|
||||
}
|
||||
}
|
||||
@ -125,8 +125,8 @@ public class MessagingFactory<P extends LuckPermsPlugin> {
|
||||
|
||||
@Override
|
||||
public @NonNull Messenger obtain(@NonNull IncomingMessageConsumer incomingMessageConsumer) {
|
||||
SqlDao dao = (SqlDao) getPlugin().getStorage().getDao();
|
||||
Preconditions.checkState(dao.getProvider() instanceof MySqlConnectionFactory || dao.getProvider() instanceof MariaDbConnectionFactory, "not a supported sql type");
|
||||
SqlStorage dao = (SqlStorage) getPlugin().getStorage().getImplementation();
|
||||
Preconditions.checkState(dao.getConnectionFactory() instanceof MySqlConnectionFactory || dao.getConnectionFactory() instanceof MariaDbConnectionFactory, "not a supported sql type");
|
||||
|
||||
SqlMessenger sql = new SqlMessenger(getPlugin(), dao, incomingMessageConsumer);
|
||||
sql.init();
|
||||
|
@ -29,7 +29,7 @@ import me.lucko.luckperms.api.messenger.IncomingMessageConsumer;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.plugin.scheduler.SchedulerAdapter;
|
||||
import me.lucko.luckperms.common.plugin.scheduler.SchedulerTask;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.SqlDao;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
@ -37,15 +37,15 @@ import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class SqlMessenger extends AbstractSqlMessenger {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final SqlDao sqlDao;
|
||||
private final SqlStorage sqlStorage;
|
||||
|
||||
private SchedulerTask pollTask;
|
||||
private SchedulerTask housekeepingTask;
|
||||
|
||||
public SqlMessenger(LuckPermsPlugin plugin, SqlDao sqlDao, IncomingMessageConsumer consumer) {
|
||||
public SqlMessenger(LuckPermsPlugin plugin, SqlStorage sqlStorage, IncomingMessageConsumer consumer) {
|
||||
super(consumer);
|
||||
this.plugin = plugin;
|
||||
this.sqlDao = sqlDao;
|
||||
this.sqlStorage = sqlStorage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -81,11 +81,11 @@ public class SqlMessenger extends AbstractSqlMessenger {
|
||||
|
||||
@Override
|
||||
protected Connection getConnection() throws SQLException {
|
||||
return this.sqlDao.getProvider().getConnection();
|
||||
return this.sqlStorage.getConnectionFactory().getConnection();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTableName() {
|
||||
return this.sqlDao.getStatementProcessor().apply("{prefix}messenger");
|
||||
return this.sqlStorage.getStatementProcessor().apply("{prefix}messenger");
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.StorageFactory;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.FileWatcher;
|
||||
import me.lucko.luckperms.common.tasks.SyncTask;
|
||||
import me.lucko.luckperms.common.treeview.PermissionRegistry;
|
||||
import me.lucko.luckperms.common.verbose.VerboseHandler;
|
||||
|
@ -49,7 +49,7 @@ import me.lucko.luckperms.common.plugin.logging.PluginLogger;
|
||||
import me.lucko.luckperms.common.plugin.util.AbstractConnectionListener;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
import me.lucko.luckperms.common.storage.dao.file.FileWatcher;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.FileWatcher;
|
||||
import me.lucko.luckperms.common.tasks.SyncTask;
|
||||
import me.lucko.luckperms.common.treeview.PermissionRegistry;
|
||||
import me.lucko.luckperms.common.verbose.VerboseHandler;
|
||||
|
@ -31,7 +31,7 @@ import me.lucko.luckperms.common.assignments.AssignmentRule;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
@ -1,304 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.PlayerSaveResult;
|
||||
import me.lucko.luckperms.api.event.cause.CreationCause;
|
||||
import me.lucko.luckperms.api.event.cause.DeletionCause;
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.api.delegates.model.ApiStorage;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparisons.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.wrappings.PhasedStorage;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
/**
|
||||
* Implements {@link Storage} using an {@link AbstractDao}.
|
||||
*/
|
||||
public class AbstractStorage implements Storage {
|
||||
public static Storage create(LuckPermsPlugin plugin, AbstractDao backing) {
|
||||
// make a base implementation
|
||||
Storage base = new AbstractStorage(plugin, backing);
|
||||
// wrap with a phaser
|
||||
return PhasedStorage.wrap(base);
|
||||
}
|
||||
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final AbstractDao dao;
|
||||
|
||||
private final ApiStorage apiDelegate;
|
||||
|
||||
private AbstractStorage(LuckPermsPlugin plugin, AbstractDao dao) {
|
||||
this.plugin = plugin;
|
||||
this.dao = dao;
|
||||
this.apiDelegate = new ApiStorage(plugin, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDao getDao() {
|
||||
return this.dao;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiStorage getApiDelegate() {
|
||||
return this.apiDelegate;
|
||||
}
|
||||
|
||||
private <T> CompletableFuture<T> makeFuture(Callable<T> supplier) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return supplier.call();
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
Throwables.propagateIfPossible(e);
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, this.dao.getPlugin().getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
private interface ThrowingRunnable {
|
||||
void run() throws Exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.dao.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
try {
|
||||
this.dao.init();
|
||||
} catch (Exception e) {
|
||||
this.plugin.getLogger().severe("Failed to init storage dao");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
try {
|
||||
this.dao.shutdown();
|
||||
} catch (Exception e) {
|
||||
this.plugin.getLogger().severe("Failed to shutdown storage dao");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMeta() {
|
||||
return this.dao.getMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> logAction(LogEntry entry) {
|
||||
return makeFuture(() -> this.dao.logAction(entry));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Log> getLog() {
|
||||
return makeFuture(this.dao::getLog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> applyBulkUpdate(BulkUpdate bulkUpdate) {
|
||||
return makeFuture(() -> this.dao.applyBulkUpdate(bulkUpdate));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<User> loadUser(UUID uuid, String username) {
|
||||
return makeFuture(() -> {
|
||||
User user = this.dao.loadUser(uuid, username);
|
||||
if (user != null) {
|
||||
this.plugin.getEventFactory().handleUserLoad(user);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> saveUser(User user) {
|
||||
return makeFuture(() -> this.dao.saveUser(user));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Set<UUID>> getUniqueUsers() {
|
||||
return makeFuture(this.dao::getUniqueUsers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(Constraint constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldPermission<UUID>> result = this.dao.getUsersWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.asNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Group> createAndLoadGroup(String name, CreationCause cause) {
|
||||
return makeFuture(() -> {
|
||||
Group group = this.dao.createAndLoadGroup(name);
|
||||
if (group != null) {
|
||||
this.plugin.getEventFactory().handleGroupCreate(group, cause);
|
||||
}
|
||||
return group;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Optional<Group>> loadGroup(String name) {
|
||||
return makeFuture(() -> {
|
||||
Optional<Group> group = this.dao.loadGroup(name);
|
||||
if (group.isPresent()) {
|
||||
this.plugin.getEventFactory().handleGroupLoad(group.get());
|
||||
}
|
||||
return group;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> loadAllGroups() {
|
||||
return makeFuture(() -> {
|
||||
this.dao.loadAllGroups();
|
||||
this.plugin.getEventFactory().handleGroupLoadAll();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> saveGroup(Group group) {
|
||||
return makeFuture(() -> this.dao.saveGroup(group));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteGroup(Group group, DeletionCause cause) {
|
||||
return makeFuture(() -> {
|
||||
this.dao.deleteGroup(group);
|
||||
this.plugin.getEventFactory().handleGroupDelete(group, cause);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(Constraint constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldPermission<String>> result = this.dao.getGroupsWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.asNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Track> createAndLoadTrack(String name, CreationCause cause) {
|
||||
return makeFuture(() -> {
|
||||
Track track = this.dao.createAndLoadTrack(name);
|
||||
if (track != null) {
|
||||
this.plugin.getEventFactory().handleTrackCreate(track, cause);
|
||||
}
|
||||
return track;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Optional<Track>> loadTrack(String name) {
|
||||
return makeFuture(() -> {
|
||||
Optional<Track> track = this.dao.loadTrack(name);
|
||||
if (track.isPresent()) {
|
||||
this.plugin.getEventFactory().handleTrackLoad(track.get());
|
||||
}
|
||||
return track;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> loadAllTracks() {
|
||||
return makeFuture(() -> {
|
||||
this.dao.loadAllTracks();
|
||||
this.plugin.getEventFactory().handleTrackLoadAll();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> saveTrack(Track track) {
|
||||
return makeFuture(() -> this.dao.saveTrack(track));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> deleteTrack(Track track, DeletionCause cause) {
|
||||
return makeFuture(() -> {
|
||||
this.dao.deleteTrack(track);
|
||||
this.plugin.getEventFactory().handleTrackDelete(track, cause);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<PlayerSaveResult> savePlayerData(UUID uuid, String username) {
|
||||
return makeFuture(() -> {
|
||||
PlayerSaveResult result = this.dao.savePlayerData(uuid, username);
|
||||
if (result != null) {
|
||||
this.plugin.getEventFactory().handlePlayerDataSave(uuid, username, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<UUID> getPlayerUuid(String username) {
|
||||
return makeFuture(() -> this.dao.getPlayerUuid(username));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<String> getPlayerName(UUID uuid) {
|
||||
return makeFuture(() -> this.dao.getPlayerName(uuid));
|
||||
}
|
||||
}
|
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.PlayerSaveResult;
|
||||
@ -37,71 +39,231 @@ import me.lucko.luckperms.common.bulkupdate.comparisons.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.utils.ThrowingRunnable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.CompletionException;
|
||||
|
||||
/**
|
||||
* Main interface for all Storage providers.
|
||||
* Provides a {@link CompletableFuture} based API for interacting with a {@link StorageImplementation}.
|
||||
*/
|
||||
public interface Storage {
|
||||
public class Storage {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final StorageImplementation implementation;
|
||||
|
||||
ApiStorage getApiDelegate();
|
||||
private final ApiStorage apiDelegate;
|
||||
|
||||
AbstractDao getDao();
|
||||
public Storage(LuckPermsPlugin plugin, StorageImplementation implementation) {
|
||||
this.plugin = plugin;
|
||||
this.implementation = implementation;
|
||||
this.apiDelegate = new ApiStorage(plugin, this);
|
||||
}
|
||||
|
||||
String getName();
|
||||
public StorageImplementation getImplementation() {
|
||||
return this.implementation;
|
||||
}
|
||||
|
||||
void init();
|
||||
public ApiStorage getApiDelegate() {
|
||||
return this.apiDelegate;
|
||||
}
|
||||
|
||||
void shutdown();
|
||||
private <T> CompletableFuture<T> makeFuture(Callable<T> supplier) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
return supplier.call();
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, this.plugin.getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
Map<String, String> getMeta();
|
||||
private CompletableFuture<Void> makeFuture(ThrowingRunnable runnable) {
|
||||
return CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
throw new CompletionException(e);
|
||||
}
|
||||
}, this.plugin.getBootstrap().getScheduler().async());
|
||||
}
|
||||
|
||||
CompletableFuture<Void> logAction(LogEntry entry);
|
||||
public String getName() {
|
||||
return this.implementation.getImplementationName();
|
||||
}
|
||||
|
||||
CompletableFuture<Log> getLog();
|
||||
public void init() {
|
||||
try {
|
||||
this.implementation.init();
|
||||
} catch (Exception e) {
|
||||
this.plugin.getLogger().severe("Failed to init storage dao");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<Void> applyBulkUpdate(BulkUpdate bulkUpdate);
|
||||
public void shutdown() {
|
||||
try {
|
||||
this.implementation.shutdown();
|
||||
} catch (Exception e) {
|
||||
this.plugin.getLogger().severe("Failed to shutdown storage dao");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
CompletableFuture<User> loadUser(UUID uuid, String username);
|
||||
public Map<String, String> getMeta() {
|
||||
return this.implementation.getMeta();
|
||||
}
|
||||
|
||||
CompletableFuture<Void> saveUser(User user);
|
||||
public CompletableFuture<Void> logAction(LogEntry entry) {
|
||||
return makeFuture(() -> this.implementation.logAction(entry));
|
||||
}
|
||||
|
||||
CompletableFuture<Set<UUID>> getUniqueUsers();
|
||||
public CompletableFuture<Log> getLog() {
|
||||
return makeFuture(this.implementation::getLog);
|
||||
}
|
||||
|
||||
CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(Constraint constraint);
|
||||
public CompletableFuture<Void> applyBulkUpdate(BulkUpdate bulkUpdate) {
|
||||
return makeFuture(() -> this.implementation.applyBulkUpdate(bulkUpdate));
|
||||
}
|
||||
|
||||
CompletableFuture<Group> createAndLoadGroup(String name, CreationCause cause);
|
||||
public CompletableFuture<User> loadUser(UUID uuid, String username) {
|
||||
return makeFuture(() -> {
|
||||
User user = this.implementation.loadUser(uuid, username);
|
||||
if (user != null) {
|
||||
this.plugin.getEventFactory().handleUserLoad(user);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Optional<Group>> loadGroup(String name);
|
||||
public CompletableFuture<Void> saveUser(User user) {
|
||||
return makeFuture(() -> this.implementation.saveUser(user));
|
||||
}
|
||||
|
||||
CompletableFuture<Void> loadAllGroups();
|
||||
public CompletableFuture<Set<UUID>> getUniqueUsers() {
|
||||
return makeFuture(this.implementation::getUniqueUsers);
|
||||
}
|
||||
|
||||
CompletableFuture<Void> saveGroup(Group group);
|
||||
public CompletableFuture<List<HeldPermission<UUID>>> getUsersWithPermission(Constraint constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldPermission<UUID>> result = this.implementation.getUsersWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.asNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Void> deleteGroup(Group group, DeletionCause cause);
|
||||
public CompletableFuture<Group> createAndLoadGroup(String name, CreationCause cause) {
|
||||
return makeFuture(() -> {
|
||||
Group group = this.implementation.createAndLoadGroup(name);
|
||||
if (group != null) {
|
||||
this.plugin.getEventFactory().handleGroupCreate(group, cause);
|
||||
}
|
||||
return group;
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(Constraint constraint);
|
||||
public CompletableFuture<Optional<Group>> loadGroup(String name) {
|
||||
return makeFuture(() -> {
|
||||
Optional<Group> group = this.implementation.loadGroup(name);
|
||||
if (group.isPresent()) {
|
||||
this.plugin.getEventFactory().handleGroupLoad(group.get());
|
||||
}
|
||||
return group;
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Track> createAndLoadTrack(String name, CreationCause cause);
|
||||
public CompletableFuture<Void> loadAllGroups() {
|
||||
return makeFuture(() -> {
|
||||
this.implementation.loadAllGroups();
|
||||
this.plugin.getEventFactory().handleGroupLoadAll();
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Optional<Track>> loadTrack(String name);
|
||||
public CompletableFuture<Void> saveGroup(Group group) {
|
||||
return makeFuture(() -> this.implementation.saveGroup(group));
|
||||
}
|
||||
|
||||
CompletableFuture<Void> loadAllTracks();
|
||||
public CompletableFuture<Void> deleteGroup(Group group, DeletionCause cause) {
|
||||
return makeFuture(() -> {
|
||||
this.implementation.deleteGroup(group);
|
||||
this.plugin.getEventFactory().handleGroupDelete(group, cause);
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Void> saveTrack(Track track);
|
||||
public CompletableFuture<List<HeldPermission<String>>> getGroupsWithPermission(Constraint constraint) {
|
||||
return makeFuture(() -> {
|
||||
List<HeldPermission<String>> result = this.implementation.getGroupsWithPermission(constraint);
|
||||
result.removeIf(entry -> entry.asNode().hasExpired());
|
||||
return ImmutableList.copyOf(result);
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<Void> deleteTrack(Track track, DeletionCause cause);
|
||||
public CompletableFuture<Track> createAndLoadTrack(String name, CreationCause cause) {
|
||||
return makeFuture(() -> {
|
||||
Track track = this.implementation.createAndLoadTrack(name);
|
||||
if (track != null) {
|
||||
this.plugin.getEventFactory().handleTrackCreate(track, cause);
|
||||
}
|
||||
return track;
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<PlayerSaveResult> savePlayerData(UUID uuid, String username);
|
||||
public CompletableFuture<Optional<Track>> loadTrack(String name) {
|
||||
return makeFuture(() -> {
|
||||
Optional<Track> track = this.implementation.loadTrack(name);
|
||||
if (track.isPresent()) {
|
||||
this.plugin.getEventFactory().handleTrackLoad(track.get());
|
||||
}
|
||||
return track;
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<UUID> getPlayerUuid(String username);
|
||||
public CompletableFuture<Void> loadAllTracks() {
|
||||
return makeFuture(() -> {
|
||||
this.implementation.loadAllTracks();
|
||||
this.plugin.getEventFactory().handleTrackLoadAll();
|
||||
});
|
||||
}
|
||||
|
||||
CompletableFuture<String> getPlayerName(UUID uuid);
|
||||
public CompletableFuture<Void> saveTrack(Track track) {
|
||||
return makeFuture(() -> this.implementation.saveTrack(track));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> deleteTrack(Track track, DeletionCause cause) {
|
||||
return makeFuture(() -> {
|
||||
this.implementation.deleteTrack(track);
|
||||
this.plugin.getEventFactory().handleTrackDelete(track, cause);
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<PlayerSaveResult> savePlayerData(UUID uuid, String username) {
|
||||
return makeFuture(() -> {
|
||||
PlayerSaveResult result = this.implementation.savePlayerData(uuid, username);
|
||||
if (result != null) {
|
||||
this.plugin.getEventFactory().handlePlayerDataSave(uuid, username, result);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
public CompletableFuture<UUID> getPlayerUuid(String username) {
|
||||
return makeFuture(() -> this.implementation.getPlayerUuid(username));
|
||||
}
|
||||
|
||||
public CompletableFuture<String> getPlayerName(UUID uuid) {
|
||||
return makeFuture(() -> this.implementation.getPlayerName(uuid));
|
||||
}
|
||||
}
|
||||
|
@ -30,22 +30,23 @@ import com.google.common.collect.Maps;
|
||||
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.dao.SplitStorageDao;
|
||||
import me.lucko.luckperms.common.storage.dao.file.CombinedConfigurateDao;
|
||||
import me.lucko.luckperms.common.storage.dao.file.SeparatedConfigurateDao;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.HoconLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.JsonLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.TomlLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.YamlLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.mongodb.MongoDao;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.SqlDao;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.file.H2ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.file.SQLiteConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.MariaDbConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.MySqlConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.PostgreConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.provider.StorageProviders;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.implementation.custom.CustomStorageProviders;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.CombinedConfigurateStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.SeparatedConfigurateStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.HoconLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.JsonLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.TomlLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.YamlLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.mongodb.MongoStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.split.SplitStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.split.SplitStorageType;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.SqlStorage;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.file.H2ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.file.SQLiteConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MariaDbConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.MySqlConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.PostgreConnectionFactory;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
|
||||
import java.util.Map;
|
||||
@ -97,11 +98,12 @@ public class StorageFactory {
|
||||
})
|
||||
.collect(ImmutableCollectors.toEnumMap(SplitStorageType.class, Map.Entry::getKey, Map.Entry::getValue));
|
||||
|
||||
Map<StorageType, AbstractDao> backing = mappedTypes.values().stream()
|
||||
Map<StorageType, StorageImplementation> backing = mappedTypes.values().stream()
|
||||
.distinct()
|
||||
.collect(ImmutableCollectors.toEnumMap(StorageType.class, e -> e, this::makeDao));
|
||||
.collect(ImmutableCollectors.toEnumMap(StorageType.class, e -> e, this::createNewImplementation));
|
||||
|
||||
storage = AbstractStorage.create(this.plugin, new SplitStorageDao(this.plugin, backing, mappedTypes));
|
||||
// make a base implementation
|
||||
storage = new Storage(this.plugin, new SplitStorage(this.plugin, backing, mappedTypes));
|
||||
|
||||
} else {
|
||||
String method = this.plugin.getConfiguration().get(ConfigKeys.STORAGE_METHOD);
|
||||
@ -119,66 +121,67 @@ public class StorageFactory {
|
||||
}
|
||||
|
||||
private Storage makeInstance(StorageType type) {
|
||||
return AbstractStorage.create(this.plugin, makeDao(type));
|
||||
// make a base implementation
|
||||
return new Storage(this.plugin, createNewImplementation(type));
|
||||
}
|
||||
|
||||
private AbstractDao makeDao(StorageType method) {
|
||||
private StorageImplementation createNewImplementation(StorageType method) {
|
||||
switch (method) {
|
||||
case CUSTOM:
|
||||
return StorageProviders.getProvider().provide(this.plugin);
|
||||
return CustomStorageProviders.getProvider().provide(this.plugin);
|
||||
case MARIADB:
|
||||
return new SqlDao(
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new MariaDbConnectionFactory(this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES)),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case MYSQL:
|
||||
return new SqlDao(
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new MySqlConnectionFactory(this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES)),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case SQLITE:
|
||||
return new SqlDao(
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new SQLiteConnectionFactory(this.plugin, this.plugin.getBootstrap().getDataDirectory().resolve("luckperms-sqlite.db")),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case H2:
|
||||
return new SqlDao(
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new H2ConnectionFactory(this.plugin, this.plugin.getBootstrap().getDataDirectory().resolve("luckperms-h2")),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case POSTGRESQL:
|
||||
return new SqlDao(
|
||||
return new SqlStorage(
|
||||
this.plugin,
|
||||
new PostgreConnectionFactory(this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES)),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.SQL_TABLE_PREFIX)
|
||||
);
|
||||
case MONGODB:
|
||||
return new MongoDao(
|
||||
return new MongoStorage(
|
||||
this.plugin,
|
||||
this.plugin.getConfiguration().get(ConfigKeys.DATABASE_VALUES),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.MONGODB_COLLECTION_PREFIX),
|
||||
this.plugin.getConfiguration().get(ConfigKeys.MONGODB_CONNECTION_URI)
|
||||
);
|
||||
case YAML:
|
||||
return new SeparatedConfigurateDao(this.plugin, new YamlLoader(), "YAML", ".yml", "yaml-storage");
|
||||
return new SeparatedConfigurateStorage(this.plugin, "YAML", new YamlLoader(), ".yml", "yaml-storage");
|
||||
case JSON:
|
||||
return new SeparatedConfigurateDao(this.plugin, new JsonLoader(), "JSON", ".json", "json-storage");
|
||||
return new SeparatedConfigurateStorage(this.plugin, "JSON", new JsonLoader(), ".json", "json-storage");
|
||||
case HOCON:
|
||||
return new SeparatedConfigurateDao(this.plugin, new HoconLoader(), "HOCON", ".conf", "hocon-storage");
|
||||
return new SeparatedConfigurateStorage(this.plugin, "HOCON", new HoconLoader(), ".conf", "hocon-storage");
|
||||
case TOML:
|
||||
return new SeparatedConfigurateDao(this.plugin, new TomlLoader(), "TOML", ".toml", "toml-storage");
|
||||
return new SeparatedConfigurateStorage(this.plugin, "TOML", new TomlLoader(), ".toml", "toml-storage");
|
||||
case YAML_COMBINED:
|
||||
return new CombinedConfigurateDao(this.plugin, new YamlLoader(), "YAML Combined", ".yml", "yaml-storage");
|
||||
return new CombinedConfigurateStorage(this.plugin, "YAML Combined", new YamlLoader(), ".yml", "yaml-storage");
|
||||
case JSON_COMBINED:
|
||||
return new CombinedConfigurateDao(this.plugin, new JsonLoader(), "JSON Combined", ".json", "json-storage");
|
||||
return new CombinedConfigurateStorage(this.plugin, "JSON Combined", new JsonLoader(), ".json", "json-storage");
|
||||
case HOCON_COMBINED:
|
||||
return new CombinedConfigurateDao(this.plugin, new HoconLoader(), "HOCON Combined", ".conf", "hocon-storage");
|
||||
return new CombinedConfigurateStorage(this.plugin, "HOCON Combined", new HoconLoader(), ".conf", "hocon-storage");
|
||||
case TOML_COMBINED:
|
||||
return new CombinedConfigurateDao(this.plugin, new TomlLoader(), "TOML Combined", ".toml", "toml-storage");
|
||||
return new CombinedConfigurateStorage(this.plugin, "TOML Combined", new TomlLoader(), ".toml", "toml-storage");
|
||||
default:
|
||||
throw new RuntimeException("Unknown method: " + method);
|
||||
}
|
||||
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.PlayerSaveResult;
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparisons.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractDao {
|
||||
|
||||
protected final LuckPermsPlugin plugin;
|
||||
public final String name;
|
||||
|
||||
protected AbstractDao(LuckPermsPlugin plugin, String name) {
|
||||
this.plugin = plugin;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public LuckPermsPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public abstract void init() throws Exception;
|
||||
|
||||
public abstract void shutdown();
|
||||
|
||||
public Map<String, String> getMeta() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public abstract void logAction(LogEntry entry) throws Exception;
|
||||
|
||||
public abstract Log getLog() throws Exception;
|
||||
|
||||
public abstract void applyBulkUpdate(BulkUpdate bulkUpdate) throws Exception;
|
||||
|
||||
public abstract User loadUser(UUID uuid, String username) throws Exception;
|
||||
|
||||
public abstract void saveUser(User user) throws Exception;
|
||||
|
||||
public abstract Set<UUID> getUniqueUsers() throws Exception;
|
||||
|
||||
public abstract List<HeldPermission<UUID>> getUsersWithPermission(Constraint constraint) throws Exception;
|
||||
|
||||
public abstract Group createAndLoadGroup(String name) throws Exception;
|
||||
|
||||
public abstract Optional<Group> loadGroup(String name) throws Exception;
|
||||
|
||||
public abstract void loadAllGroups() throws Exception;
|
||||
|
||||
public abstract void saveGroup(Group group) throws Exception;
|
||||
|
||||
public abstract void deleteGroup(Group group) throws Exception;
|
||||
|
||||
public abstract List<HeldPermission<String>> getGroupsWithPermission(Constraint constraint) throws Exception;
|
||||
|
||||
public abstract Track createAndLoadTrack(String name) throws Exception;
|
||||
|
||||
public abstract Optional<Track> loadTrack(String name) throws Exception;
|
||||
|
||||
public abstract void loadAllTracks() throws Exception;
|
||||
|
||||
public abstract void saveTrack(Track track) throws Exception;
|
||||
|
||||
public abstract void deleteTrack(Track track) throws Exception;
|
||||
|
||||
public abstract PlayerSaveResult savePlayerData(UUID uuid, String username) throws Exception;
|
||||
|
||||
public abstract @Nullable UUID getPlayerUuid(String username) throws Exception;
|
||||
|
||||
public abstract @Nullable String getPlayerName(UUID uuid) throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.implementation;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.api.LogEntry;
|
||||
import me.lucko.luckperms.api.PlayerSaveResult;
|
||||
import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparisons.Constraint;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface StorageImplementation {
|
||||
LuckPermsPlugin getPlugin();
|
||||
|
||||
String getImplementationName();
|
||||
|
||||
void init() throws Exception;
|
||||
|
||||
void shutdown();
|
||||
|
||||
default Map<String, String> getMeta() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
void logAction(LogEntry entry) throws Exception;
|
||||
|
||||
Log getLog() throws Exception;
|
||||
|
||||
void applyBulkUpdate(BulkUpdate bulkUpdate) throws Exception;
|
||||
|
||||
User loadUser(UUID uuid, String username) throws Exception;
|
||||
|
||||
void saveUser(User user) throws Exception;
|
||||
|
||||
Set<UUID> getUniqueUsers() throws Exception;
|
||||
|
||||
List<HeldPermission<UUID>> getUsersWithPermission(Constraint constraint) throws Exception;
|
||||
|
||||
Group createAndLoadGroup(String name) throws Exception;
|
||||
|
||||
Optional<Group> loadGroup(String name) throws Exception;
|
||||
|
||||
void loadAllGroups() throws Exception;
|
||||
|
||||
void saveGroup(Group group) throws Exception;
|
||||
|
||||
void deleteGroup(Group group) throws Exception;
|
||||
|
||||
List<HeldPermission<String>> getGroupsWithPermission(Constraint constraint) throws Exception;
|
||||
|
||||
Track createAndLoadTrack(String name) throws Exception;
|
||||
|
||||
Optional<Track> loadTrack(String name) throws Exception;
|
||||
|
||||
void loadAllTracks() throws Exception;
|
||||
|
||||
void saveTrack(Track track) throws Exception;
|
||||
|
||||
void deleteTrack(Track track) throws Exception;
|
||||
|
||||
PlayerSaveResult savePlayerData(UUID uuid, String username) throws Exception;
|
||||
|
||||
@Nullable UUID getPlayerUuid(String username) throws Exception;
|
||||
|
||||
@Nullable String getPlayerName(UUID uuid) throws Exception;
|
||||
}
|
@ -23,17 +23,17 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.provider;
|
||||
package me.lucko.luckperms.common.storage.implementation.custom;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
|
||||
/**
|
||||
* A storage provider
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StorageProvider {
|
||||
public interface CustomStorageProvider {
|
||||
|
||||
AbstractDao provide(LuckPermsPlugin plugin);
|
||||
StorageImplementation provide(LuckPermsPlugin plugin);
|
||||
|
||||
}
|
@ -23,19 +23,19 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.provider;
|
||||
package me.lucko.luckperms.common.storage.implementation.custom;
|
||||
|
||||
/**
|
||||
* Hook to allow external code to provide a storage dao
|
||||
*/
|
||||
public final class StorageProviders {
|
||||
private static StorageProvider provider = null;
|
||||
public final class CustomStorageProviders {
|
||||
private static CustomStorageProvider provider = null;
|
||||
|
||||
public static void register(StorageProvider provider) {
|
||||
StorageProviders.provider = provider;
|
||||
public static void register(CustomStorageProvider provider) {
|
||||
CustomStorageProviders.provider = provider;
|
||||
}
|
||||
|
||||
public static StorageProvider getProvider() {
|
||||
public static CustomStorageProvider getProvider() {
|
||||
if (provider == null) {
|
||||
throw new IllegalStateException("Provider not present.");
|
||||
}
|
||||
@ -43,6 +43,6 @@ public final class StorageProviders {
|
||||
return provider;
|
||||
}
|
||||
|
||||
private StorageProviders() {}
|
||||
private CustomStorageProviders() {}
|
||||
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -46,10 +46,10 @@ import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||
import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.node.utils.MetaType;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.JsonLoader;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.YamlLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.JsonLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.YamlLoader;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.common.utils.MoreFiles;
|
||||
|
||||
@ -77,7 +77,10 @@ import java.util.stream.Collectors;
|
||||
* Abstract implementation using configurate {@link ConfigurationNode}s to serialize and deserialize
|
||||
* data.
|
||||
*/
|
||||
public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
public abstract class AbstractConfigurateStorage implements StorageImplementation {
|
||||
|
||||
protected final LuckPermsPlugin plugin;
|
||||
private final String implementationName;
|
||||
|
||||
// the loader responsible for i/o
|
||||
protected final ConfigurateLoader loader;
|
||||
@ -95,13 +98,24 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
// the file used to store uuid data
|
||||
private Path uuidDataFile;
|
||||
|
||||
protected AbstractConfigurateDao(LuckPermsPlugin plugin, ConfigurateLoader loader, String name, String dataDirectoryName) {
|
||||
super(plugin, name);
|
||||
protected AbstractConfigurateStorage(LuckPermsPlugin plugin, String implementationName, ConfigurateLoader loader, String dataDirectoryName) {
|
||||
this.plugin = plugin;
|
||||
this.implementationName = implementationName;
|
||||
this.loader = loader;
|
||||
this.dataDirectoryName = dataDirectoryName;
|
||||
this.actionLogger = new FileActionLogger(plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckPermsPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return this.implementationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a configuration node from the given location
|
||||
*
|
||||
@ -217,7 +231,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
saveFile(StorageLocation.USER, user.getUuid().toString(), null);
|
||||
} else {
|
||||
ConfigurationNode data = SimpleConfigurationNode.root();
|
||||
if (this instanceof SeparatedConfigurateDao) {
|
||||
if (this instanceof SeparatedConfigurateStorage) {
|
||||
data.getNode("uuid").setValue(user.getUuid().toString());
|
||||
}
|
||||
data.getNode("name").setValue(user.getName().orElse("null"));
|
||||
@ -247,7 +261,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
group.setNodes(NodeMapType.ENDURING, nodes);
|
||||
} else {
|
||||
ConfigurationNode data = SimpleConfigurationNode.root();
|
||||
if (this instanceof SeparatedConfigurateDao) {
|
||||
if (this instanceof SeparatedConfigurateStorage) {
|
||||
data.getNode("name").setValue(group.getName());
|
||||
}
|
||||
|
||||
@ -304,7 +318,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
ConfigurationNode data = SimpleConfigurationNode.root();
|
||||
if (this instanceof SeparatedConfigurateDao) {
|
||||
if (this instanceof SeparatedConfigurateStorage) {
|
||||
data.getNode("name").setValue(group.getName());
|
||||
}
|
||||
|
||||
@ -347,7 +361,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
track.setGroups(groups);
|
||||
} else {
|
||||
ConfigurationNode data = SimpleConfigurationNode.root();
|
||||
if (this instanceof SeparatedConfigurateDao) {
|
||||
if (this instanceof SeparatedConfigurateStorage) {
|
||||
data.getNode("name").setValue(name);
|
||||
}
|
||||
data.getNode("groups").setValue(track.getGroups());
|
||||
@ -402,7 +416,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
ConfigurationNode data = SimpleConfigurationNode.root();
|
||||
if (this instanceof SeparatedConfigurateDao) {
|
||||
if (this instanceof SeparatedConfigurateStorage) {
|
||||
data.getNode("name").setValue(track.getName());
|
||||
}
|
||||
data.getNode("groups").setValue(track.getGroups());
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
@ -33,7 +33,7 @@ import me.lucko.luckperms.common.managers.track.TrackManager;
|
||||
import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.node.model.NodeHeldPermission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
||||
@ -49,7 +49,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CombinedConfigurateDao extends AbstractConfigurateDao {
|
||||
public class CombinedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
private final String fileExtension;
|
||||
|
||||
private Path usersFile;
|
||||
@ -69,13 +69,13 @@ public class CombinedConfigurateDao extends AbstractConfigurateDao {
|
||||
|
||||
private CachedLoader(Path path) {
|
||||
this.path = path;
|
||||
this.loader = CombinedConfigurateDao.super.loader.loader(path);
|
||||
this.loader = CombinedConfigurateStorage.super.loader.loader(path);
|
||||
reload();
|
||||
}
|
||||
|
||||
private void recordChange() {
|
||||
if (CombinedConfigurateDao.this.watcher != null) {
|
||||
CombinedConfigurateDao.this.watcher.recordChange(this.path.getFileName().toString());
|
||||
if (CombinedConfigurateStorage.this.watcher != null) {
|
||||
CombinedConfigurateStorage.this.watcher.recordChange(this.path.getFileName().toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,14 +145,13 @@ public class CombinedConfigurateDao extends AbstractConfigurateDao {
|
||||
|
||||
/**
|
||||
* Creates a new configurate dao
|
||||
*
|
||||
* @param plugin the plugin instance
|
||||
* @param name the name of this dao
|
||||
* @param implementationName the name of this dao
|
||||
* @param fileExtension the file extension used by this instance, including a "." at the start
|
||||
* @param dataFolderName the name of the folder used to store data
|
||||
*/
|
||||
public CombinedConfigurateDao(LuckPermsPlugin plugin, ConfigurateLoader loader, String name, String fileExtension, String dataFolderName) {
|
||||
super(plugin, loader, name, dataFolderName);
|
||||
public CombinedConfigurateStorage(LuckPermsPlugin plugin, String implementationName, ConfigurateLoader loader, String fileExtension, String dataFolderName) {
|
||||
super(plugin, implementationName, loader, dataFolderName);
|
||||
this.fileExtension = fileExtension;
|
||||
}
|
||||
|
@ -23,12 +23,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
@ -37,6 +35,7 @@ import me.lucko.luckperms.common.actionlog.Log;
|
||||
import me.lucko.luckperms.common.actionlog.LogEntryJsonSerializer;
|
||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -48,8 +47,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class FileActionLogger {
|
||||
private static final JsonParser JSON_PARSER = new JsonParser();
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
/**
|
||||
* The path to save logger content to
|
||||
@ -95,7 +92,7 @@ public class FileActionLogger {
|
||||
|
||||
if (Files.exists(this.contentFile)) {
|
||||
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
array = JSON_PARSER.parse(reader).getAsJsonArray();
|
||||
array = GsonProvider.parser().parse(reader).getAsJsonArray();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
array = new JsonArray();
|
||||
@ -112,7 +109,7 @@ public class FileActionLogger {
|
||||
// write the full content back to the file
|
||||
try (JsonWriter writer = new JsonWriter(Files.newBufferedWriter(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
writer.setIndent(" ");
|
||||
GSON.toJson(array, writer);
|
||||
GsonProvider.normal().toJson(array, writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
@ -125,7 +122,7 @@ public class FileActionLogger {
|
||||
public Log getLog() throws IOException {
|
||||
Log.Builder log = Log.builder();
|
||||
try (JsonReader reader = new JsonReader(Files.newBufferedReader(this.contentFile, StandardCharsets.UTF_8))) {
|
||||
JsonArray array = JSON_PARSER.parse(reader).getAsJsonArray();
|
||||
JsonArray array = GsonProvider.parser().parse(reader).getAsJsonArray();
|
||||
for (JsonElement element : array) {
|
||||
log.add(LogEntryJsonSerializer.deserialize(element));
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -31,7 +31,7 @@ import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import me.lucko.luckperms.api.PlayerSaveResult;
|
||||
import me.lucko.luckperms.common.storage.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.utils.Uuids;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.utils.Iterators;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
|
||||
@ -34,7 +34,7 @@ import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.node.model.NodeHeldPermission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.dao.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.storage.implementation.file.loader.ConfigurateLoader;
|
||||
import me.lucko.luckperms.common.utils.MoreFiles;
|
||||
import me.lucko.luckperms.common.utils.Uuids;
|
||||
|
||||
@ -51,7 +51,7 @@ import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class SeparatedConfigurateDao extends AbstractConfigurateDao {
|
||||
public class SeparatedConfigurateStorage extends AbstractConfigurateStorage {
|
||||
private final String fileExtension;
|
||||
|
||||
private Path usersDirectory;
|
||||
@ -64,14 +64,13 @@ public class SeparatedConfigurateDao extends AbstractConfigurateDao {
|
||||
|
||||
/**
|
||||
* Creates a new configurate dao
|
||||
*
|
||||
* @param plugin the plugin instance
|
||||
* @param name the name of this dao
|
||||
* @param implementationName the name of this dao
|
||||
* @param fileExtension the file extension used by this instance, including a "." at the start
|
||||
* @param dataFolderName the name of the folder used to store data
|
||||
*/
|
||||
public SeparatedConfigurateDao(LuckPermsPlugin plugin, ConfigurateLoader loader, String name, String fileExtension, String dataFolderName) {
|
||||
super(plugin, loader, name, dataFolderName);
|
||||
public SeparatedConfigurateStorage(LuckPermsPlugin plugin, String implementationName, ConfigurateLoader loader, String fileExtension, String dataFolderName) {
|
||||
super(plugin, implementationName, loader, dataFolderName);
|
||||
this.fileExtension = fileExtension;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.file;
|
||||
|
||||
public enum StorageLocation {
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file.loader;
|
||||
package me.lucko.luckperms.common.storage.implementation.file.loader;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file.loader;
|
||||
package me.lucko.luckperms.common.storage.implementation.file.loader;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file.loader;
|
||||
package me.lucko.luckperms.common.storage.implementation.file.loader;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file.loader;
|
||||
package me.lucko.luckperms.common.storage.implementation.file.loader;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.file.loader;
|
||||
package me.lucko.luckperms.common.storage.implementation.file.loader;
|
||||
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.mongodb;
|
||||
package me.lucko.luckperms.common.storage.implementation.mongodb;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.mongodb.MongoClient;
|
||||
@ -60,9 +60,9 @@ import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||
import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.node.model.NodeHeldPermission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
import org.bson.Document;
|
||||
|
||||
@ -77,7 +77,8 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class MongoDao extends AbstractDao {
|
||||
public class MongoStorage implements StorageImplementation {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
private final StorageCredentials configuration;
|
||||
private MongoClient mongoClient;
|
||||
@ -85,13 +86,23 @@ public class MongoDao extends AbstractDao {
|
||||
private final String prefix;
|
||||
private final String connectionUri;
|
||||
|
||||
public MongoDao(LuckPermsPlugin plugin, StorageCredentials configuration, String prefix, String connectionUri) {
|
||||
super(plugin, "MongoDB");
|
||||
public MongoStorage(LuckPermsPlugin plugin, StorageCredentials configuration, String prefix, String connectionUri) {
|
||||
this.plugin = plugin;
|
||||
this.configuration = configuration;
|
||||
this.prefix = prefix;
|
||||
this.connectionUri = connectionUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckPermsPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "MongoDB";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
if (!Strings.isNullOrEmpty(this.connectionUri)) {
|
||||
@ -215,7 +226,7 @@ public class MongoDao extends AbstractDao {
|
||||
|
||||
if (!nodes.equals(results)) {
|
||||
List<Document> newNodes = results.stream()
|
||||
.map(MongoDao::nodeToDoc)
|
||||
.map(MongoStorage::nodeToDoc)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
d.append("permissions", newNodes).remove("perms");
|
||||
@ -240,7 +251,7 @@ public class MongoDao extends AbstractDao {
|
||||
|
||||
if (!nodes.equals(results)) {
|
||||
List<Document> newNodes = results.stream()
|
||||
.map(MongoDao::nodeToDoc)
|
||||
.map(MongoStorage::nodeToDoc)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
d.append("permissions", newNodes).remove("perms");
|
||||
@ -628,7 +639,7 @@ public class MongoDao extends AbstractDao {
|
||||
private static Document userToDoc(User user) {
|
||||
List<Document> nodes = user.enduringData().immutable().values().stream()
|
||||
.map(NodeDataContainer::fromNode)
|
||||
.map(MongoDao::nodeToDoc)
|
||||
.map(MongoStorage::nodeToDoc)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new Document("_id", user.getUuid())
|
||||
@ -666,7 +677,7 @@ public class MongoDao extends AbstractDao {
|
||||
private static Document groupToDoc(Group group) {
|
||||
List<Document> nodes = group.enduringData().immutable().values().stream()
|
||||
.map(NodeDataContainer::fromNode)
|
||||
.map(MongoDao::nodeToDoc)
|
||||
.map(MongoStorage::nodeToDoc)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new Document("_id", group.getName()).append("permissions", nodes);
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao;
|
||||
package me.lucko.luckperms.common.storage.implementation.split;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
@ -37,8 +37,8 @@ import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.Track;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.SplitStorageType;
|
||||
import me.lucko.luckperms.common.storage.StorageType;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
@ -47,20 +47,31 @@ import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SplitStorageDao extends AbstractDao {
|
||||
private final Map<StorageType, AbstractDao> backing;
|
||||
public class SplitStorage implements StorageImplementation {
|
||||
private final LuckPermsPlugin plugin;
|
||||
private final Map<StorageType, StorageImplementation> backing;
|
||||
private final Map<SplitStorageType, StorageType> types;
|
||||
|
||||
public SplitStorageDao(LuckPermsPlugin plugin, Map<StorageType, AbstractDao> backing, Map<SplitStorageType, StorageType> types) {
|
||||
super(plugin, "Split Storage");
|
||||
public SplitStorage(LuckPermsPlugin plugin, Map<StorageType, StorageImplementation> backing, Map<SplitStorageType, StorageType> types) {
|
||||
this.plugin = plugin;
|
||||
this.backing = ImmutableMap.copyOf(backing);
|
||||
this.types = ImmutableMap.copyOf(types);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LuckPermsPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "Split Storage";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
boolean failed = false;
|
||||
for (AbstractDao ds : this.backing.values()) {
|
||||
for (StorageImplementation ds : this.backing.values()) {
|
||||
try {
|
||||
ds.init();
|
||||
} catch (Exception ex) {
|
||||
@ -75,7 +86,7 @@ public class SplitStorageDao extends AbstractDao {
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
for (AbstractDao ds : this.backing.values()) {
|
||||
for (StorageImplementation ds : this.backing.values()) {
|
||||
try {
|
||||
ds.shutdown();
|
||||
} catch (Exception e) {
|
||||
@ -88,7 +99,7 @@ public class SplitStorageDao extends AbstractDao {
|
||||
public Map<String, String> getMeta() {
|
||||
Map<String, String> ret = new LinkedHashMap<>();
|
||||
ret.put("Types", this.types.toString());
|
||||
for (AbstractDao backing : this.backing.values()) {
|
||||
for (StorageImplementation backing : this.backing.values()) {
|
||||
ret.putAll(backing.getMeta());
|
||||
}
|
||||
return ret;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
package me.lucko.luckperms.common.storage.implementation.split;
|
||||
|
||||
public enum SplitStorageType {
|
||||
LOG, USER, GROUP, TRACK, UUID
|
@ -23,10 +23,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import me.lucko.luckperms.api.HeldPermission;
|
||||
@ -50,11 +49,12 @@ import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||
import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.node.model.NodeHeldPermission;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.storage.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.storage.dao.AbstractDao;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.AbstractConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.file.SQLiteConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.hikari.PostgreConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.StorageImplementation;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.file.SQLiteConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.hikari.PostgreConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.misc.PlayerSaveResultImpl;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
@ -76,7 +76,7 @@ import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class SqlDao extends AbstractDao {
|
||||
public class SqlStorage implements StorageImplementation {
|
||||
private static final Type LIST_STRING_TYPE = new TypeToken<List<String>>(){}.getType();
|
||||
|
||||
private static final String USER_PERMISSIONS_SELECT = "SELECT permission, value, server, world, expiry, contexts FROM {prefix}user_permissions WHERE uuid=?";
|
||||
@ -118,23 +118,29 @@ public class SqlDao extends AbstractDao {
|
||||
private static final String ACTION_INSERT = "INSERT INTO {prefix}actions(time, actor_uuid, actor_name, type, acted_uuid, acted_name, action) VALUES(?, ?, ?, ?, ?, ?, ?)";
|
||||
private static final String ACTION_SELECT_ALL = "SELECT * FROM {prefix}actions";
|
||||
|
||||
private final Gson gson;
|
||||
private final AbstractConnectionFactory provider;
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
private final ConnectionFactory connectionFactory;
|
||||
private final Function<String, String> statementProcessor;
|
||||
|
||||
public SqlDao(LuckPermsPlugin plugin, AbstractConnectionFactory provider, String tablePrefix) {
|
||||
super(plugin, provider.getName());
|
||||
this.provider = provider;
|
||||
this.statementProcessor = provider.getStatementProcessor().compose(s -> s.replace("{prefix}", tablePrefix));
|
||||
this.gson = new Gson();
|
||||
public SqlStorage(LuckPermsPlugin plugin, ConnectionFactory connectionFactory, String tablePrefix) {
|
||||
this.plugin = plugin;
|
||||
this.connectionFactory = connectionFactory;
|
||||
this.statementProcessor = connectionFactory.getStatementProcessor().compose(s -> s.replace("{prefix}", tablePrefix));
|
||||
}
|
||||
|
||||
public Gson getGson() {
|
||||
return this.gson;
|
||||
@Override
|
||||
public LuckPermsPlugin getPlugin() {
|
||||
return this.plugin;
|
||||
}
|
||||
|
||||
public AbstractConnectionFactory getProvider() {
|
||||
return this.provider;
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return this.connectionFactory.getImplementationName();
|
||||
}
|
||||
|
||||
public ConnectionFactory getConnectionFactory() {
|
||||
return this.connectionFactory;
|
||||
}
|
||||
|
||||
public Function<String, String> getStatementProcessor() {
|
||||
@ -142,7 +148,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
|
||||
private boolean tableExists(String table) throws SQLException {
|
||||
try (Connection connection = this.provider.getConnection()) {
|
||||
try (Connection connection = this.connectionFactory.getConnection()) {
|
||||
try (ResultSet rs = connection.getMetaData().getTables(null, null, "%", null)) {
|
||||
while (rs.next()) {
|
||||
if (rs.getString(3).equalsIgnoreCase(table)) {
|
||||
@ -156,18 +162,18 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
@Override
|
||||
public void init() throws Exception {
|
||||
this.provider.init();
|
||||
this.connectionFactory.init();
|
||||
|
||||
// Init tables
|
||||
if (!tableExists(this.statementProcessor.apply("{prefix}user_permissions"))) {
|
||||
String schemaFileName = "me/lucko/luckperms/schema/" + this.provider.getName().toLowerCase() + ".sql";
|
||||
String schemaFileName = "me/lucko/luckperms/schema/" + this.connectionFactory.getImplementationName().toLowerCase() + ".sql";
|
||||
try (InputStream is = this.plugin.getBootstrap().getResourceStream(schemaFileName)) {
|
||||
if (is == null) {
|
||||
throw new Exception("Couldn't locate schema file for " + this.provider.getName());
|
||||
throw new Exception("Couldn't locate schema file for " + this.connectionFactory.getImplementationName());
|
||||
}
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8))) {
|
||||
try (Connection connection = this.provider.getConnection()) {
|
||||
try (Connection connection = this.connectionFactory.getConnection()) {
|
||||
try (Statement s = connection.createStatement()) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line;
|
||||
@ -196,8 +202,8 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
// migrations
|
||||
try {
|
||||
if (!(this.provider instanceof SQLiteConnectionFactory) && !(this.provider instanceof PostgreConnectionFactory)) {
|
||||
try (Connection connection = this.provider.getConnection()) {
|
||||
if (!(this.connectionFactory instanceof SQLiteConnectionFactory) && !(this.connectionFactory instanceof PostgreConnectionFactory)) {
|
||||
try (Connection connection = this.connectionFactory.getConnection()) {
|
||||
try (Statement s = connection.createStatement()) {
|
||||
s.execute(this.statementProcessor.apply("ALTER TABLE {prefix}actions MODIFY COLUMN actor_name VARCHAR(100)"));
|
||||
s.execute(this.statementProcessor.apply("ALTER TABLE {prefix}actions MODIFY COLUMN action VARCHAR(300)"));
|
||||
@ -212,7 +218,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public void shutdown() {
|
||||
try {
|
||||
this.provider.shutdown();
|
||||
this.connectionFactory.shutdown();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -220,12 +226,12 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMeta() {
|
||||
return this.provider.getMeta();
|
||||
return this.connectionFactory.getMeta();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logAction(LogEntry entry) throws SQLException {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(ACTION_INSERT))) {
|
||||
ps.setLong(1, entry.getTimestamp());
|
||||
ps.setString(2, entry.getActor().toString());
|
||||
@ -242,7 +248,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public Log getLog() throws SQLException {
|
||||
final Log.Builder log = Log.builder();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(ACTION_SELECT_ALL))) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -267,7 +273,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
@Override
|
||||
public void applyBulkUpdate(BulkUpdate bulkUpdate) throws SQLException {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
if (bulkUpdate.getDataType().isIncludingUsers()) {
|
||||
String table = this.statementProcessor.apply("{prefix}user_permissions");
|
||||
try (PreparedStatement ps = bulkUpdate.buildAsSql().build(c, q -> q.replace("{table}", table))) {
|
||||
@ -294,7 +300,7 @@ public class SqlDao extends AbstractDao {
|
||||
String userName = null;
|
||||
|
||||
// Collect user permissions
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_SELECT))) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
|
||||
@ -313,7 +319,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
|
||||
// Collect user meta (username & primary group)
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_BY_UUID))) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
|
||||
@ -367,7 +373,7 @@ public class SqlDao extends AbstractDao {
|
||||
try {
|
||||
// Empty data - just delete from the DB.
|
||||
if (!this.plugin.getUserManager().shouldSave(user)) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_DELETE))) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
ps.execute();
|
||||
@ -383,7 +389,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
// Get a snapshot of current data.
|
||||
Set<NodeDataContainer> remote = new HashSet<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_SELECT))) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
|
||||
@ -409,7 +415,7 @@ public class SqlDao extends AbstractDao {
|
||||
Set<NodeDataContainer> toRemove = diff.getValue();
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_DELETE_SPECIFIC))) {
|
||||
for (NodeDataContainer nd : toRemove) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
@ -418,7 +424,7 @@ public class SqlDao extends AbstractDao {
|
||||
ps.setString(4, nd.getServer());
|
||||
ps.setString(5, nd.getWorld());
|
||||
ps.setLong(6, nd.getExpiry());
|
||||
ps.setString(7, this.gson.toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.setString(7, GsonProvider.normal().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
@ -427,7 +433,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
|
||||
if (!toAdd.isEmpty()) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_INSERT))) {
|
||||
for (NodeDataContainer nd : toAdd) {
|
||||
ps.setString(1, user.getUuid().toString());
|
||||
@ -436,7 +442,7 @@ public class SqlDao extends AbstractDao {
|
||||
ps.setString(4, nd.getServer());
|
||||
ps.setString(5, nd.getWorld());
|
||||
ps.setLong(6, nd.getExpiry());
|
||||
ps.setString(7, this.gson.toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.setString(7, GsonProvider.normal().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
@ -444,7 +450,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
}
|
||||
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
boolean hasPrimaryGroupSaved;
|
||||
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_PRIMARY_GROUP_BY_UUID))) {
|
||||
@ -480,7 +486,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public Set<UUID> getUniqueUsers() throws SQLException {
|
||||
Set<UUID> uuids = new HashSet<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(USER_PERMISSIONS_SELECT_DISTINCT))) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -499,7 +505,7 @@ public class SqlDao extends AbstractDao {
|
||||
constraint.appendSql(builder, "permission");
|
||||
|
||||
List<HeldPermission<UUID>> held = new ArrayList<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = builder.build(c, this.statementProcessor)) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -523,7 +529,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public Group createAndLoadGroup(String name) throws SQLException {
|
||||
String query;
|
||||
switch (this.provider.getName()) {
|
||||
switch (this.connectionFactory.getImplementationName()) {
|
||||
case "H2":
|
||||
query = H2_GROUP_INSERT;
|
||||
break;
|
||||
@ -538,7 +544,7 @@ public class SqlDao extends AbstractDao {
|
||||
break;
|
||||
}
|
||||
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(query))) {
|
||||
ps.setString(1, name);
|
||||
ps.execute();
|
||||
@ -552,7 +558,7 @@ public class SqlDao extends AbstractDao {
|
||||
public Optional<Group> loadGroup(String name) throws SQLException {
|
||||
// Check the group actually exists
|
||||
List<String> groups = new ArrayList<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_SELECT_ALL))) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -572,7 +578,7 @@ public class SqlDao extends AbstractDao {
|
||||
try {
|
||||
List<NodeDataContainer> data = new ArrayList<>();
|
||||
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_SELECT))) {
|
||||
ps.setString(1, group.getName());
|
||||
|
||||
@ -606,7 +612,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public void loadAllGroups() throws SQLException {
|
||||
List<String> groups = new ArrayList<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_SELECT_ALL))) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -642,7 +648,7 @@ public class SqlDao extends AbstractDao {
|
||||
try {
|
||||
// Empty data, just delete.
|
||||
if (group.enduringData().immutable().isEmpty()) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_DELETE))) {
|
||||
ps.setString(1, group.getName());
|
||||
ps.execute();
|
||||
@ -653,7 +659,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
// Get a snapshot of current data
|
||||
Set<NodeDataContainer> remote = new HashSet<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_SELECT))) {
|
||||
ps.setString(1, group.getName());
|
||||
|
||||
@ -679,7 +685,7 @@ public class SqlDao extends AbstractDao {
|
||||
Set<NodeDataContainer> toRemove = diff.getValue();
|
||||
|
||||
if (!toRemove.isEmpty()) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_DELETE_SPECIFIC))) {
|
||||
for (NodeDataContainer nd : toRemove) {
|
||||
ps.setString(1, group.getName());
|
||||
@ -688,7 +694,7 @@ public class SqlDao extends AbstractDao {
|
||||
ps.setString(4, nd.getServer());
|
||||
ps.setString(5, nd.getWorld());
|
||||
ps.setLong(6, nd.getExpiry());
|
||||
ps.setString(7, this.gson.toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.setString(7, GsonProvider.normal().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
@ -697,7 +703,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
|
||||
if (!toAdd.isEmpty()) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_INSERT))) {
|
||||
for (NodeDataContainer nd : toAdd) {
|
||||
ps.setString(1, group.getName());
|
||||
@ -706,7 +712,7 @@ public class SqlDao extends AbstractDao {
|
||||
ps.setString(4, nd.getServer());
|
||||
ps.setString(5, nd.getWorld());
|
||||
ps.setLong(6, nd.getExpiry());
|
||||
ps.setString(7, this.gson.toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.setString(7, GsonProvider.normal().toJson(ContextSetJsonSerializer.serializeContextSet(nd.getContexts())));
|
||||
ps.addBatch();
|
||||
}
|
||||
ps.executeBatch();
|
||||
@ -722,7 +728,7 @@ public class SqlDao extends AbstractDao {
|
||||
public void deleteGroup(Group group) throws SQLException {
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(GROUP_PERMISSIONS_DELETE))) {
|
||||
ps.setString(1, group.getName());
|
||||
ps.execute();
|
||||
@ -746,7 +752,7 @@ public class SqlDao extends AbstractDao {
|
||||
constraint.appendSql(builder, "permission");
|
||||
|
||||
List<HeldPermission<String>> held = new ArrayList<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = builder.build(c, this.statementProcessor)) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -774,7 +780,7 @@ public class SqlDao extends AbstractDao {
|
||||
try {
|
||||
boolean exists = false;
|
||||
String groups = null;
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_SELECT))) {
|
||||
ps.setString(1, track.getName());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
@ -788,10 +794,10 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
if (exists) {
|
||||
// Track exists, let's load.
|
||||
track.setGroups(this.gson.fromJson(groups, LIST_STRING_TYPE));
|
||||
track.setGroups(GsonProvider.normal().fromJson(groups, LIST_STRING_TYPE));
|
||||
} else {
|
||||
String json = this.gson.toJson(track.getGroups());
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
String json = GsonProvider.normal().toJson(track.getGroups());
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_INSERT))) {
|
||||
ps.setString(1, track.getName());
|
||||
ps.setString(2, json);
|
||||
@ -813,7 +819,7 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
try {
|
||||
String groups;
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_SELECT))) {
|
||||
ps.setString(1, name);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
@ -831,7 +837,7 @@ public class SqlDao extends AbstractDao {
|
||||
track.getIoLock().lock();
|
||||
}
|
||||
|
||||
track.setGroups(this.gson.fromJson(groups, LIST_STRING_TYPE));
|
||||
track.setGroups(GsonProvider.normal().fromJson(groups, LIST_STRING_TYPE));
|
||||
return Optional.of(track);
|
||||
|
||||
} finally {
|
||||
@ -844,7 +850,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public void loadAllTracks() throws SQLException {
|
||||
List<String> tracks = new ArrayList<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_SELECT_ALL))) {
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
@ -878,8 +884,8 @@ public class SqlDao extends AbstractDao {
|
||||
public void saveTrack(Track track) throws SQLException {
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
String s = this.gson.toJson(track.getGroups());
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
String s = GsonProvider.normal().toJson(track.getGroups());
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_UPDATE))) {
|
||||
ps.setString(1, s);
|
||||
ps.setString(2, track.getName());
|
||||
@ -895,7 +901,7 @@ public class SqlDao extends AbstractDao {
|
||||
public void deleteTrack(Track track) throws SQLException {
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(TRACK_DELETE))) {
|
||||
ps.setString(1, track.getName());
|
||||
ps.execute();
|
||||
@ -917,7 +923,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
// do the insert
|
||||
if (!username.equals(oldUsername)) {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
if (oldUsername != null) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_UPDATE_USERNAME_FOR_UUID))) {
|
||||
ps.setString(1, username);
|
||||
@ -938,7 +944,7 @@ public class SqlDao extends AbstractDao {
|
||||
PlayerSaveResultImpl result = PlayerSaveResultImpl.determineBaseResult(username, oldUsername);
|
||||
|
||||
Set<UUID> conflicting = new HashSet<>();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_ALL_UUIDS_BY_USERNAME))) {
|
||||
ps.setString(1, username);
|
||||
ps.setString(2, uuid.toString());
|
||||
@ -952,7 +958,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
if (!conflicting.isEmpty()) {
|
||||
// remove the mappings for conflicting uuids
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_DELETE_ALL_UUIDS_BY_USERNAME))) {
|
||||
ps.setString(1, username);
|
||||
ps.setString(2, uuid.toString());
|
||||
@ -968,7 +974,7 @@ public class SqlDao extends AbstractDao {
|
||||
@Override
|
||||
public UUID getPlayerUuid(String username) throws SQLException {
|
||||
username = username.toLowerCase();
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_UUID_BY_USERNAME))) {
|
||||
ps.setString(1, username);
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
@ -983,7 +989,7 @@ public class SqlDao extends AbstractDao {
|
||||
|
||||
@Override
|
||||
public String getPlayerName(UUID uuid) throws SQLException {
|
||||
try (Connection c = this.provider.getConnection()) {
|
||||
try (Connection c = this.connectionFactory.getConnection()) {
|
||||
try (PreparedStatement ps = c.prepareStatement(this.statementProcessor.apply(PLAYER_SELECT_USERNAME_BY_UUID))) {
|
||||
ps.setString(1, uuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
@ -1016,6 +1022,6 @@ public class SqlDao extends AbstractDao {
|
||||
}
|
||||
|
||||
private NodeDataContainer deserializeNode(String permission, boolean value, String server, String world, long expiry, String contexts) {
|
||||
return NodeDataContainer.of(permission, value, server, world, expiry, ContextSetJsonSerializer.deserializeContextSet(this.gson, contexts).makeImmutable());
|
||||
return NodeDataContainer.of(permission, value, server, world, expiry, ContextSetJsonSerializer.deserializeContextSet(GsonProvider.normal(), contexts).makeImmutable());
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
@ -31,28 +31,20 @@ import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public abstract class AbstractConnectionFactory {
|
||||
public interface ConnectionFactory {
|
||||
|
||||
private final String name;
|
||||
String getImplementationName();
|
||||
|
||||
public AbstractConnectionFactory(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
void init();
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
void shutdown() throws Exception;
|
||||
|
||||
public abstract void init();
|
||||
|
||||
public abstract void shutdown() throws Exception;
|
||||
|
||||
public Map<String, String> getMeta() {
|
||||
default Map<String, String> getMeta() {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
public abstract Function<String, String> getStatementProcessor();
|
||||
Function<String, String> getStatementProcessor();
|
||||
|
||||
public abstract Connection getConnection() throws SQLException;
|
||||
Connection getConnection() throws SQLException;
|
||||
|
||||
}
|
@ -23,9 +23,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.file;
|
||||
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.AbstractConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@ -34,13 +34,12 @@ import java.text.DecimalFormat;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
abstract class FlatfileConnectionFactory extends AbstractConnectionFactory {
|
||||
abstract class FlatfileConnectionFactory implements ConnectionFactory {
|
||||
protected static final DecimalFormat DF = new DecimalFormat("#.##");
|
||||
|
||||
protected final Path file;
|
||||
|
||||
FlatfileConnectionFactory(String name, Path file) {
|
||||
super(name);
|
||||
FlatfileConnectionFactory(Path file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.file;
|
||||
|
||||
import me.lucko.luckperms.common.dependencies.Dependency;
|
||||
import me.lucko.luckperms.common.dependencies.classloader.IsolatedClassLoader;
|
||||
@ -49,7 +49,7 @@ public class H2ConnectionFactory extends FlatfileConnectionFactory {
|
||||
private NonClosableConnection connection;
|
||||
|
||||
public H2ConnectionFactory(LuckPermsPlugin plugin, Path file) {
|
||||
super("H2", file);
|
||||
super(file);
|
||||
|
||||
// backwards compat
|
||||
Path data = file.getParent().resolve("luckperms.db.mv.db");
|
||||
@ -72,6 +72,11 @@ public class H2ConnectionFactory extends FlatfileConnectionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "H2";
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Connection getConnection() throws SQLException {
|
||||
if (this.connection == null || this.connection.isClosed()) {
|
@ -23,8 +23,10 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.file;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.sql.Connection;
|
||||
|
||||
@ -43,22 +45,7 @@ public interface NonClosableConnection extends Connection {
|
||||
return (NonClosableConnection) Proxy.newProxyInstance(
|
||||
NonClosableConnection.class.getClassLoader(),
|
||||
new Class[]{NonClosableConnection.class},
|
||||
(proxy, method, args) -> {
|
||||
|
||||
// block calls directly to #close
|
||||
if (method.getName().equals("close")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// proxy calls to #shutdown to the real #close method
|
||||
if (method.getName().equals("shutdown")) {
|
||||
connection.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
// delegate all other calls
|
||||
return method.invoke(connection, args);
|
||||
}
|
||||
new Handler(connection)
|
||||
);
|
||||
}
|
||||
|
||||
@ -66,4 +53,29 @@ public interface NonClosableConnection extends Connection {
|
||||
* Actually {@link #close() closes} the underlying connection.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
final class Handler implements InvocationHandler {
|
||||
private final Connection connection;
|
||||
|
||||
Handler(Connection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
// block calls directly to #close
|
||||
if (method.getName().equals("close")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// proxy calls to #shutdown to the real #close method
|
||||
if (method.getName().equals("shutdown")) {
|
||||
this.connection.close();
|
||||
return null;
|
||||
}
|
||||
|
||||
// delegate all other calls
|
||||
return method.invoke(this.connection, args);
|
||||
}
|
||||
}
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.file;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.file;
|
||||
|
||||
import me.lucko.luckperms.common.dependencies.Dependency;
|
||||
import me.lucko.luckperms.common.dependencies.classloader.IsolatedClassLoader;
|
||||
@ -48,7 +48,7 @@ public class SQLiteConnectionFactory extends FlatfileConnectionFactory {
|
||||
private NonClosableConnection connection;
|
||||
|
||||
public SQLiteConnectionFactory(LuckPermsPlugin plugin, Path file) {
|
||||
super("SQLite", file);
|
||||
super(file);
|
||||
|
||||
// backwards compat
|
||||
Path data = file.getParent().resolve("luckperms.sqlite");
|
||||
@ -70,6 +70,11 @@ public class SQLiteConnectionFactory extends FlatfileConnectionFactory {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "SQLite";
|
||||
}
|
||||
|
||||
private Connection createConnection(String url) throws SQLException {
|
||||
try {
|
||||
return (Connection) this.createConnectionMethod.invoke(null, url, new Properties());
|
@ -23,13 +23,13 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.hikari;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.dao.sql.connection.AbstractConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.implementation.sql.connection.ConnectionFactory;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
@ -37,13 +37,12 @@ import java.sql.Statement;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class HikariConnectionFactory extends AbstractConnectionFactory {
|
||||
public abstract class HikariConnectionFactory implements ConnectionFactory {
|
||||
|
||||
protected final StorageCredentials configuration;
|
||||
private HikariDataSource hikari;
|
||||
|
||||
public HikariConnectionFactory(String name, StorageCredentials configuration) {
|
||||
super(name);
|
||||
public HikariConnectionFactory(StorageCredentials configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
@ -23,11 +23,11 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.hikari;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -36,7 +36,12 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class MariaDbConnectionFactory extends HikariConnectionFactory {
|
||||
public MariaDbConnectionFactory(StorageCredentials configuration) {
|
||||
super("MariaDB", configuration);
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "MariaDB";
|
||||
}
|
||||
|
||||
@Override
|
@ -23,17 +23,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.hikari;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class MySqlConnectionFactory extends HikariConnectionFactory {
|
||||
public MySqlConnectionFactory(StorageCredentials configuration) {
|
||||
super("MySQL", configuration);
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "MySQL";
|
||||
}
|
||||
|
||||
@Override
|
@ -23,17 +23,22 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.dao.sql.connection.hikari;
|
||||
package me.lucko.luckperms.common.storage.implementation.sql.connection.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
|
||||
import me.lucko.luckperms.common.storage.StorageCredentials;
|
||||
import me.lucko.luckperms.common.storage.misc.StorageCredentials;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class PostgreConnectionFactory extends HikariConnectionFactory {
|
||||
public PostgreConnectionFactory(StorageCredentials configuration) {
|
||||
super("PostgreSQL", configuration);
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImplementationName() {
|
||||
return "PostgreSQL";
|
||||
}
|
||||
|
||||
@Override
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
package me.lucko.luckperms.common.storage.misc;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
package me.lucko.luckperms.common.storage.misc;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
@ -23,7 +23,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage;
|
||||
package me.lucko.luckperms.common.storage.misc;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
* This file is part of LuckPerms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.storage.wrappings;
|
||||
|
||||
import me.lucko.luckperms.common.storage.Storage;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.concurrent.Phaser;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* A storage wrapping that ensures all tasks are completed before {@link Storage#shutdown()} is called.
|
||||
*/
|
||||
public interface PhasedStorage extends Storage {
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@link PhasedStorage} which delegates called to the given
|
||||
* {@link Storage} instance.
|
||||
*
|
||||
* @param delegate the delegate storage impl
|
||||
* @return the new phased storage instance
|
||||
*/
|
||||
static PhasedStorage wrap(Storage delegate) {
|
||||
// create a new phaser to be used by the instance
|
||||
Phaser phaser = new Phaser();
|
||||
|
||||
// create and return a proxy instance which directs save calls through the phaser
|
||||
return (PhasedStorage) Proxy.newProxyInstance(
|
||||
PhasedStorage.class.getClassLoader(),
|
||||
new Class[]{PhasedStorage.class},
|
||||
(proxy, method, args) -> {
|
||||
|
||||
// direct delegation
|
||||
switch (method.getName()) {
|
||||
case "getDao":
|
||||
case "getApiDelegate":
|
||||
case "getName":
|
||||
case "init":
|
||||
case "getMeta":
|
||||
return method.invoke(delegate, args);
|
||||
}
|
||||
|
||||
// await the phaser on shutdown
|
||||
if (method.getName().equals("shutdown")) {
|
||||
try {
|
||||
phaser.awaitAdvanceInterruptibly(phaser.getPhase(), 10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | TimeoutException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
delegate.shutdown();
|
||||
return null;
|
||||
}
|
||||
|
||||
// for all other methods, run the call via the phaser
|
||||
phaser.register();
|
||||
try {
|
||||
return method.invoke(delegate, args);
|
||||
} finally {
|
||||
phaser.arriveAndDeregister();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -29,6 +29,8 @@ import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Translates unix timestamps / durations into a readable format
|
||||
@ -37,7 +39,7 @@ import java.util.regex.Pattern;
|
||||
* see: https://github.com/drtshock/Essentials/blob/2.x/Essentials/src/com/earth2me/essentials/utils/DateUtil.java
|
||||
*/
|
||||
public final class DateParser {
|
||||
private static final Pattern TIME_PATTERN = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?" + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
|
||||
private static final Pattern TIME_PATTERN = Pattern.compile(Stream.of("y", "mo", "w", "d", "h", "m").map(i -> "(?:([0-9]+)\\s*" + i + "[a-z]*[,\\s]*)?").collect(Collectors.joining()) + "(?:([0-9]+)\\s*(?:s[a-z]*)?)?", Pattern.CASE_INSENSITIVE);
|
||||
private static final int MAX_YEARS = 100000;
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils;
|
||||
|
||||
public interface ThrowingRunnable {
|
||||
|
||||
void run() throws Exception;
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This file is part of luckperms, licensed under the MIT License.
|
||||
*
|
||||
* Copyright (c) lucko (Luck) <luck@lucko.me>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.common.utils.gson;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public final class GsonProvider {
|
||||
|
||||
private static final Gson NORMAL = new GsonBuilder().disableHtmlEscaping().create();
|
||||
private static final Gson PRETTY_PRINTING = new GsonBuilder().disableHtmlEscaping().setPrettyPrinting().create();
|
||||
private static final JsonParser NORMAL_PARSER = new JsonParser();
|
||||
|
||||
public static Gson normal() {
|
||||
return NORMAL;
|
||||
}
|
||||
|
||||
public static Gson prettyPrinting() {
|
||||
return PRETTY_PRINTING;
|
||||
}
|
||||
|
||||
public static JsonParser parser() {
|
||||
return NORMAL_PARSER;
|
||||
}
|
||||
|
||||
private GsonProvider() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
}
|
@ -25,11 +25,11 @@
|
||||
|
||||
package me.lucko.luckperms.common.web;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
@ -60,7 +60,7 @@ public enum StandardPastebin implements Pastebin {
|
||||
|
||||
@Override
|
||||
protected String parseIdFromResult(BufferedReader reader) {
|
||||
JsonObject object = GSON.fromJson(reader, JsonObject.class);
|
||||
JsonObject object = GsonProvider.prettyPrinting().fromJson(reader, JsonObject.class);
|
||||
return object.get("key").getAsString();
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ public enum StandardPastebin implements Pastebin {
|
||||
|
||||
@Override
|
||||
protected String parseIdFromResult(BufferedReader reader) {
|
||||
JsonObject object = GSON.fromJson(reader, JsonObject.class);
|
||||
JsonObject object = GsonProvider.prettyPrinting().fromJson(reader, JsonObject.class);
|
||||
return object.get("key").getAsString();
|
||||
}
|
||||
|
||||
@ -92,7 +92,6 @@ public enum StandardPastebin implements Pastebin {
|
||||
}
|
||||
};
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
|
||||
private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");
|
||||
private static final MediaType PLAIN_TYPE = MediaType.parse("text/plain; charset=utf-8");
|
||||
|
||||
@ -115,7 +114,7 @@ public enum StandardPastebin implements Pastebin {
|
||||
}
|
||||
|
||||
try (Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
|
||||
GSON.toJson(content, writer);
|
||||
GsonProvider.prettyPrinting().toJson(content, writer);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
package me.lucko.luckperms.common.web;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@ -41,6 +40,7 @@ import me.lucko.luckperms.common.node.model.NodeDataContainer;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.common.sender.Sender;
|
||||
import me.lucko.luckperms.common.utils.Uuids;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
import me.lucko.luckperms.common.utils.gson.JArray;
|
||||
import me.lucko.luckperms.common.utils.gson.JObject;
|
||||
|
||||
@ -63,8 +63,6 @@ import java.util.stream.Stream;
|
||||
* Utility methods for interacting with the LuckPerms web permission editor.
|
||||
*/
|
||||
public final class WebEditor {
|
||||
private static final Gson GSON = new Gson();
|
||||
|
||||
private static final String USER_ID_PATTERN = "user/";
|
||||
private static final String GROUP_ID_PATTERN = "group/";
|
||||
|
||||
@ -159,7 +157,7 @@ public final class WebEditor {
|
||||
|
||||
try (InputStream inputStream = responseBody.byteStream()) {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
|
||||
return GSON.fromJson(reader, JsonObject.class);
|
||||
return GsonProvider.normal().fromJson(reader, JsonObject.class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ import me.lucko.luckperms.api.event.cause.CreationCause;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparisons.Constraint;
|
||||
import me.lucko.luckperms.common.bulkupdate.comparisons.StandardComparison;
|
||||
import me.lucko.luckperms.common.managers.group.AbstractGroupManager;
|
||||
import me.lucko.luckperms.common.storage.DataConstraints;
|
||||
import me.lucko.luckperms.common.storage.misc.DataConstraints;
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||
|
@ -26,12 +26,11 @@
|
||||
package me.lucko.luckperms.sponge.service.persisted;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
||||
import me.lucko.luckperms.common.utils.MoreFiles;
|
||||
import me.lucko.luckperms.common.utils.gson.GsonProvider;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
@ -56,11 +55,6 @@ public class SubjectStorage {
|
||||
*/
|
||||
private final LPPermissionService service;
|
||||
|
||||
/**
|
||||
* Gson instance
|
||||
*/
|
||||
private final Gson gson;
|
||||
|
||||
/**
|
||||
* The root directory used to store files
|
||||
*/
|
||||
@ -68,7 +62,6 @@ public class SubjectStorage {
|
||||
|
||||
public SubjectStorage(LPPermissionService service, Path container) {
|
||||
this.service = service;
|
||||
this.gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
@ -131,7 +124,7 @@ public class SubjectStorage {
|
||||
public void saveToFile(SubjectDataContainer container, Path file) throws IOException {
|
||||
MoreFiles.createDirectoriesIfNotExists(file.getParent());
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(file, StandardCharsets.UTF_8)) {
|
||||
this.gson.toJson(container.serialize(), writer);
|
||||
GsonProvider.prettyPrinting().toJson(container.serialize(), writer);
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
@ -201,7 +194,7 @@ public class SubjectStorage {
|
||||
String subjectName = fileName.substring(0, fileName.length() - ".json".length());
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
|
||||
JsonObject data = this.gson.fromJson(reader, JsonObject.class);
|
||||
JsonObject data = GsonProvider.prettyPrinting().fromJson(reader, JsonObject.class);
|
||||
SubjectDataContainer model = SubjectDataContainer.deserialize(this.service, data);
|
||||
return new LoadedSubject(subjectName, model);
|
||||
} catch (Exception e) {
|
||||
|
Loading…
Reference in New Issue
Block a user