From 86e65043e1baf0b85dec7d2fbc085a347400810d Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 14 Jul 2023 13:39:20 +0200 Subject: [PATCH] feat(persistence): delete --- .../items/settings/LanguageCyclingItem.java | 1 + .../java/xyz/atnrch/nicko/storage/Cache.java | 2 ++ .../xyz/atnrch/nicko/storage/Storage.java | 2 ++ .../nicko/storage/json/JSONStorage.java | 10 ++++++++ .../atnrch/nicko/storage/map/MapCache.java | 7 ++++++ .../nicko/storage/redis/RedisCache.java | 10 +++++++- .../atnrch/nicko/storage/sql/SQLStorage.java | 21 ++++++++++++++-- .../test/storage/redis/RedisCacheTest.java | 25 ++++++++++++++----- 8 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java index 01a3c41..d15b8b7 100644 --- a/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/atnrch/nicko/gui/items/settings/LanguageCyclingItem.java @@ -32,6 +32,7 @@ public class LanguageCyclingItem { return CycleItem.withStateChangeHandler((observer, integer) -> { nickoProfile.setLocale(Locale.values()[integer]); observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C + // TODO (Ineanto, 7/14/23): This checks a 2nd time for the profile. if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) { final I18N i18n = new I18N(player); player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR)); diff --git a/src/main/java/xyz/atnrch/nicko/storage/Cache.java b/src/main/java/xyz/atnrch/nicko/storage/Cache.java index cf48f79..e771324 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Cache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Cache.java @@ -17,6 +17,8 @@ public abstract class Cache { public abstract Optional retrieve(UUID uuid); + public abstract ActionResult delete(UUID uuid); + public boolean isError() { return error; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/Storage.java b/src/main/java/xyz/atnrch/nicko/storage/Storage.java index ed1d0a9..d9c6743 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/Storage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/Storage.java @@ -17,6 +17,8 @@ public abstract class Storage { public abstract Optional retrieve(UUID uuid); + public abstract ActionResult delete(UUID uuid); + public boolean isError() { return error; } diff --git a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java index 22e27c3..747a739 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/json/JSONStorage.java @@ -74,6 +74,16 @@ public class JSONStorage extends Storage { } } + @Override + public ActionResult delete(UUID uuid) { + final File directory = new File(NickoBukkit.getInstance().getDataFolder() + "/players/"); + final File file = new File(directory, uuid.toString() + ".json"); + if (file.delete() || !file.exists()) { + return ActionResult.ok(); + } + return ActionResult.error(I18NDict.Error.JSON_ERROR); + } + private boolean checkFileExists(File file) throws IOException { if (!file.exists()) { return file.createNewFile(); diff --git a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java index 7b566e5..c573457 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/map/MapCache.java @@ -41,4 +41,11 @@ public class MapCache extends Cache { } return Optional.empty(); } + + @Override + public ActionResult delete(UUID uuid) { + final HashMap profiles = provider.getMap(); + profiles.remove(uuid); + return ActionResult.ok(); + } } diff --git a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java index 642fb9b..a8d532c 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java +++ b/src/main/java/xyz/atnrch/nicko/storage/redis/RedisCache.java @@ -4,8 +4,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import redis.clients.jedis.Jedis; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.config.Configuration; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Cache; import xyz.atnrch.nicko.storage.CacheProvider; @@ -56,4 +56,12 @@ public class RedisCache extends Cache { return Optional.of(profile); } } + + @Override + public ActionResult delete(UUID uuid) { + try (Jedis jedis = provider.getJedis()) { + jedis.del("nicko:" + uuid.toString()); + return ActionResult.ok(); + } + } } diff --git a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java index 36c67e3..27abb9a 100644 --- a/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java +++ b/src/main/java/xyz/atnrch/nicko/storage/sql/SQLStorage.java @@ -1,10 +1,10 @@ package xyz.atnrch.nicko.storage.sql; -import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.appearance.ActionResult; -import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.i18n.I18NDict; import xyz.atnrch.nicko.i18n.Locale; +import xyz.atnrch.nicko.profile.NickoProfile; import xyz.atnrch.nicko.storage.Storage; import java.io.ByteArrayInputStream; @@ -101,6 +101,23 @@ public class SQLStorage extends Storage { } } + @Override + public ActionResult delete(UUID uuid) { + final Connection connection = getProvider().getConnection(); + if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR); + + try { + final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?"; + final PreparedStatement statement = connection.prepareStatement(sql); + statement.setBinaryStream(1, uuidToBin(uuid)); + statement.executeUpdate(); + return ActionResult.ok(); + } catch (SQLException e) { + logger.warning("Couldn't fetch profile: " + e.getMessage()); + return ActionResult.error(I18NDict.Error.SQL_ERROR); + } + } + private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException { final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `bungeecord`) VALUES (?, ?, ?, ?, ?)"; final PreparedStatement statement = connection.prepareStatement(sql); diff --git a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java b/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java index 524e2c2..b8bf8b7 100644 --- a/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java +++ b/src/test/java/xyz/atnrch/nicko/test/storage/redis/RedisCacheTest.java @@ -3,17 +3,17 @@ package xyz.atnrch.nicko.test.storage.redis; import be.seeseemelk.mockbukkit.MockBukkit; import be.seeseemelk.mockbukkit.ServerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import xyz.atnrch.nicko.NickoBukkit; +import xyz.atnrch.nicko.appearance.AppearanceManager; import xyz.atnrch.nicko.config.Configuration; import xyz.atnrch.nicko.config.DataSourceConfiguration; import xyz.atnrch.nicko.profile.NickoProfile; +import xyz.atnrch.nicko.storage.PlayerDataStore; import java.util.Optional; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; public class RedisCacheTest { @@ -34,13 +34,26 @@ public class RedisCacheTest { } @Test - @DisplayName("Cache Player Data") - public void cachePlayerData() { + @DisplayName("Cache Profile") + public void cacheProfile() { final Optional optionalProfile = plugin.getDataStore().getData(player.getUniqueId()); assertTrue(optionalProfile.isPresent()); assertTrue(plugin.getDataStore().getCache().isCached(player.getUniqueId())); } + @Test + @DisplayName("Update Cache Profile") + public void updatePlayerCache() { + final PlayerDataStore dataStore = plugin.getDataStore(); + final AppearanceManager appearanceManager = AppearanceManager.get(player); + appearanceManager.setName("Notch"); + dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile()); + final Optional retrieve = dataStore.getCache().retrieve(player.getUniqueId()); + assertTrue(retrieve.isPresent()); + final NickoProfile retrieved = retrieve.get(); + assertEquals(retrieved.getName(), "Notch"); + } + @AfterAll public static void shutdown() { MockBukkit.unmock();