From 997210a16ffbd60a6ee3c900b3ec0077b01e56c3 Mon Sep 17 00:00:00 2001 From: Paul Reilly Date: Fri, 31 Mar 2023 00:52:53 -0500 Subject: [PATCH] Retrieving ResultSets correctly --- .../totalfreedommod/admin/Admin.java | 49 ++++---- .../totalfreedommod/admin/AdminList.java | 32 ++--- .../totalfreedommod/banning/BanManager.java | 56 ++++----- .../totalfreedommod/player/PlayerData.java | 5 +- .../totalfreedommod/player/PlayerList.java | 23 ++-- .../sql/ResultSetProvider.java | 114 ++++++++++++++++++ .../totalfreedommod/sql/SQLite.java | 66 +++++----- 7 files changed, 216 insertions(+), 129 deletions(-) create mode 100644 commons/src/main/java/me/totalfreedom/totalfreedommod/sql/ResultSetProvider.java diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java index 0b5fdc95..3d0eae5f 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/Admin.java @@ -4,15 +4,13 @@ import me.totalfreedom.totalfreedommod.TotalFreedomMod; import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.rank.DisplayableGroup; import me.totalfreedom.totalfreedommod.rank.GroupProvider; -import me.totalfreedom.totalfreedommod.util.FLog; +import me.totalfreedom.totalfreedommod.sql.ResultSetProvider; import me.totalfreedom.totalfreedommod.util.FUtil; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.entity.Player; -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.*; public class Admin @@ -32,23 +30,22 @@ public class Admin this.ips.add(FUtil.getIp(player)); } - public Admin(ResultSet resultSet) + public Admin(ResultSetProvider resultSet) { - try + if (resultSet.getString("uuid") == null) { - this.uuid = UUID.fromString(resultSet.getString("uuid")); - this.active = resultSet.getBoolean("active"); - this.rank = GroupProvider.fromArgument(resultSet.getString("rank")).getGroup(); - this.ips.clear(); - this.ips.addAll(FUtil.stringToList(resultSet.getString("ips"))); - this.lastLogin = new Date(resultSet.getLong("last_login")); - this.commandSpy = resultSet.getBoolean("command_spy"); - this.potionSpy = resultSet.getBoolean("potion_spy"); - this.acFormat = resultSet.getString("ac_format"); - } catch (SQLException e) - { - FLog.severe("Failed to load admin: " + e.getMessage()); + throw new IllegalArgumentException("Failed to load admin, as the UUID is null."); } + + this.uuid = UUID.fromString(resultSet.getString("uuid")); + this.active = resultSet.getBoolean("active"); + this.rank = GroupProvider.fromArgument(resultSet.getString("rank")).getGroup(); + this.ips.clear(); + this.ips.addAll(FUtil.stringToList(resultSet.getString("ips"))); + this.lastLogin = new Date(resultSet.getLong("last_login")); + this.commandSpy = resultSet.getBoolean("command_spy"); + this.potionSpy = resultSet.getBoolean("potion_spy"); + this.acFormat = resultSet.getString("ac_format"); } @Override @@ -70,15 +67,15 @@ public class Admin public Map toSQLStorable() { HashMap map = new HashMap<>(); - map.put("uuid", uuid.toString()); - map.put("active", active); - map.put("rank", rank.toString()); - map.put("ips", FUtil.listToString(ips)); - map.put("last_login", lastLogin.getTime()); - map.put("command_spy", commandSpy); - map.put("potion_spy", potionSpy); - map.put("ac_format", acFormat); - return map; + map.put("uuid", uuid.toString()); + map.put("active", active); + map.put("rank", rank.toString()); + map.put("ips", FUtil.listToString(ips)); + map.put("last_login", lastLogin.getTime()); + map.put("command_spy", commandSpy); + map.put("potion_spy", potionSpy); + map.put("ac_format", acFormat); + return map; } diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java index 10bf705e..c9ef00c9 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/admin/AdminList.java @@ -5,6 +5,7 @@ import com.google.common.collect.Sets; import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.rank.GroupProvider; +import me.totalfreedom.totalfreedommod.sql.ResultSetProvider; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import net.kyori.adventure.text.Component; @@ -12,10 +13,10 @@ import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; public class AdminList extends FreedomService { @@ -45,11 +46,19 @@ public class AdminList extends FreedomService allAdmins.clear(); try { - ResultSet adminSet = plugin.sql.getAdminList(); - while (adminSet.next()) - { - tryAddAdmin(adminSet); - } + ResultSetProvider adminList = plugin.sql.getAdminList(); + AtomicInteger row = new AtomicInteger(1); + adminList.getAllRowsResultSet().forEach(adminSet -> { + try + { + tryAddAdmin(ResultSetProvider.fromRow(adminSet)); + row.set(row.get() + 1); + } catch (Throwable e) + { + FLog.warning("An error occurred whilst reading the admin entry at row #" + row.get()); + FLog.warning(e); + } + }); } catch (SQLException e) { FLog.severe("Failed to load admin list: " + e.getMessage()); @@ -59,17 +68,10 @@ public class AdminList extends FreedomService FLog.info("Loaded " + allAdmins.size() + " admins (" + uuidTable.size() + " active, " + ipTable.size() + " IPs)"); } - private void tryAddAdmin(ResultSet adminSet) throws SQLException + private void tryAddAdmin(ResultSetProvider adminSet) { - try - { Admin admin = new Admin(adminSet); allAdmins.add(admin); - } catch (Throwable ex) - { - FLog.warning("An error occurred whilst reading the admin entry at row #" + adminSet.getRow()); - FLog.warning(ex); - } } public void messageAllAdmins(Component message) @@ -263,7 +265,7 @@ public class AdminList extends FreedomService { try { - ResultSet currentSave = plugin.sql.getAdminByUuid(admin.getUuid()); + ResultSetProvider currentSave = plugin.sql.getAdminByUuid(admin.getUuid()); for (Map.Entry entry : admin.toSQLStorable().entrySet()) { Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java index c308d34c..b261a2e5 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/banning/BanManager.java @@ -2,17 +2,8 @@ package me.totalfreedom.totalfreedommod.banning; import com.google.common.collect.Maps; import com.google.common.collect.Sets; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; import me.totalfreedom.totalfreedommod.FreedomService; +import me.totalfreedom.totalfreedommod.sql.ResultSetProvider; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import org.bukkit.entity.Player; @@ -21,6 +12,9 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerLoginEvent; +import java.sql.SQLException; +import java.util.*; + public class BanManager extends FreedomService { @@ -36,28 +30,24 @@ public class BanManager extends FreedomService bans.clear(); try { - ResultSet banSet = plugin.sql.getBanList(); - { - while (banSet.next()) + plugin.sql.getBanList().getAllRowsResultSet().forEach(row -> { + ResultSetProvider banSet = ResultSetProvider.fromRow(row); + String name = banSet.getString("name"); + UUID uuid = null; + String strUUID = banSet.getString("uuid"); + if (strUUID != null) { - String name = banSet.getString("name"); - UUID uuid = null; - String strUUID = banSet.getString("uuid"); - if (strUUID != null) - { - uuid = UUID.fromString(strUUID); - } - List ips = FUtil.stringToList(banSet.getString("ips")); - String by = banSet.getString("by"); - Date at = new Date(banSet.getLong("at")); - Date expires = new Date(banSet.getLong("expires")); - String reason = banSet.getString("reason"); - Ban ban = new Ban(name, uuid, ips, by, at, expires, reason); - bans.add(ban); + uuid = UUID.fromString(strUUID); } - } - } - catch (SQLException e) + List ips = FUtil.stringToList(banSet.getString("ips")); + String by = banSet.getString("by"); + Date at = new Date(banSet.getLong("at")); + Date expires = new Date(banSet.getLong("expires")); + String reason = banSet.getString("reason"); + Ban ban = new Ban(name, uuid, ips, by, at, expires, reason); + bans.add(ban); + }); + } catch (SQLException e) { FLog.severe("Failed to load ban list: " + e.getMessage()); } @@ -186,8 +176,7 @@ public class BanManager extends FreedomService if (ban.getUsername() != null && getByUsername(ban.getUsername()) != null) { removeBan(ban); - } - else + } else { for (String ip : ban.getIps()) @@ -267,8 +256,7 @@ public class BanManager extends FreedomService if (ban != null) { removeBan(ban); - } - else + } else { ban = getByIp(FUtil.getIp(player)); if (ban != null) diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java index 2872a2f8..452e087a 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerData.java @@ -4,6 +4,7 @@ import com.google.common.base.Strings; import com.google.common.collect.Lists; import me.totalfreedom.totalfreedommod.api.ShopItem; import me.totalfreedom.totalfreedommod.util.FConverter; +import me.totalfreedom.totalfreedommod.sql.ResultSetProvider; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import net.kyori.adventure.text.Component; @@ -44,7 +45,7 @@ public class PlayerData private Boolean inspect = false; - public PlayerData(ResultSet resultSet) + public PlayerData(ResultSetProvider resultSet) { try { @@ -71,7 +72,7 @@ public class PlayerData loginMessage = tempLoginMessage; //-- inspect = resultSet.getBoolean("inspect"); - } catch (SQLException e) + } catch (Throwable e) { FLog.severe("Failed to load player: " + e.getMessage()); e.printStackTrace(); diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java index d0487111..ea9b8d31 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/player/PlayerList.java @@ -5,6 +5,7 @@ import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.rank.GroupProvider; +import me.totalfreedom.totalfreedommod.sql.ResultSetProvider; import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FUtil; import org.bukkit.OfflinePlayer; @@ -42,24 +43,17 @@ public class PlayerList extends FreedomService public void loadMasterBuilders() { - ResultSet resultSet = plugin.sql.getMasterBuilders(); + ResultSetProvider resultSet = plugin.sql.getMasterBuilders(); if (resultSet == null) { return; } - try - { - while (resultSet.next()) - { - PlayerData playerData = load(resultSet); - dataMap.put(playerData.getUuid(), playerData); - } - } catch (SQLException e) - { - FLog.severe("Failed to parse master builders: " + e.getMessage()); - } + resultSet.getAllRowsResultSet().forEach(row -> { + PlayerData playerData = load(ResultSetProvider.fromRow(row)); + dataMap.put(playerData.getUuid(), playerData); + }); } public String getIp(OfflinePlayer player) @@ -128,12 +122,13 @@ public class PlayerList extends FreedomService return load(plugin.sql.getPlayerByIp(ip)); } - public PlayerData load(ResultSet resultSet) + public PlayerData load(ResultSetProvider resultSet) { if (resultSet == null) { return null; } + return new PlayerData(resultSet); } @@ -149,7 +144,7 @@ public class PlayerList extends FreedomService { try { - ResultSet currentSave = plugin.sql.getPlayerByUuid(player.getUuid()); + ResultSetProvider currentSave = plugin.sql.getPlayerByUuid(player.getUuid()); for (Map.Entry entry : player.toSQLStorable().entrySet()) { Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/ResultSetProvider.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/ResultSetProvider.java new file mode 100644 index 00000000..b3cb7373 --- /dev/null +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/ResultSetProvider.java @@ -0,0 +1,114 @@ +package me.totalfreedom.totalfreedommod.sql; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Wrapper; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +public class ResultSetProvider +{ + List> allRowsResultSet = new ArrayList<>(); + + Map singularResultMap = new HashMap<>(); + + private ResultSetProvider(Map singularResultMap) + { + this.singularResultMap = singularResultMap; + } + + private ResultSetProvider(ResultSet resultSet, boolean allRows) throws SQLException + { + if (allRows) + { + while (resultSet.next()) + { + allRowsResultSet.add(mapResultSet(resultSet)); + } + } else + { + if (resultSet.next()) + { + this.singularResultMap = mapResultSet(resultSet); + } + } + } + + public static CompletableFuture provideAllRows(ResultSet resultSet) + { + return CompletableFuture.supplyAsync(() -> + { + try + { + return new ResultSetProvider(resultSet, true); + } catch (SQLException e) + { + return null; + } + }); + } + + public static CompletableFuture provideSpecificRow(ResultSet resultSet) throws SQLException + { + return CompletableFuture.supplyAsync(() -> { + try + { + return new ResultSetProvider(resultSet, false); + } catch (SQLException e) + { + throw new RuntimeException(e); // We don't want to handle this exception, we want the delegate to handle it instead. + } + }); + } + + public static ResultSetProvider fromRow(Map row) { + return new ResultSetProvider(row); + } + + public List> getAllRowsResultSet() + { + return allRowsResultSet; + } + + private Map mapResultSet(ResultSet rs) throws SQLException + { + Map result = new HashMap<>(); + while (rs.next()) + { + int columns = rs.getMetaData().getColumnCount(); + for (int i = 1; i <= columns; i++) + { + String columnName = rs.getMetaData().getColumnName(i); + Object columnValue = rs.getObject(i); + result.put(columnName, columnValue); + } + } + return result; + } + + public String getString(String key) + { + return (String) singularResultMap.get(key); + } + + public int getInt(String key) + { + return (int) singularResultMap.get(key); + } + + public boolean getBoolean(String key) + { + return (boolean) singularResultMap.get(key); + } + + public long getLong(String key) + { + return (long) singularResultMap.get(key); + } +} diff --git a/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java b/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java index 5c4b200d..e595edea 100644 --- a/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java +++ b/commons/src/main/java/me/totalfreedom/totalfreedommod/sql/SQLite.java @@ -125,14 +125,20 @@ public class SQLite extends FreedomService } } - public ResultSet getBanList() throws SQLException + public ResultSetProvider getBanList() throws SQLException { - return connection.prepareStatement("SELECT * FROM bans").executeQuery(); + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans")) + { + return ResultSetProvider.provideAllRows(statement.executeQuery()).join(); + } } - public ResultSet getAdminList() throws SQLException + public ResultSetProvider getAdminList() throws SQLException { - return connection.prepareStatement("SELECT * FROM admins").executeQuery(); + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM bans")) + { + return ResultSetProvider.provideAllRows(statement.executeQuery()).join(); + } } public void setAdminValue(Admin admin, String key, Object value) @@ -191,21 +197,21 @@ public class SQLite extends FreedomService return statement; } - public Object getValue(ResultSet resultSet, String key, Object value) throws SQLException + public Object getValue(ResultSetProvider provider, String key, Object value) throws SQLException { Object result = null; if (value instanceof String) { - result = resultSet.getString(key); + result = provider.getString(key); } else if (value instanceof Integer) { - result = resultSet.getInt(key); + result = provider.getInt(key); } else if (value instanceof Boolean) { - result = resultSet.getObject(key); + result = provider.getBoolean(key); } else if (value instanceof Long) { - result = resultSet.getLong(key); + result = provider.getLong(key); } return result; } @@ -256,17 +262,12 @@ public class SQLite extends FreedomService } } - public ResultSet getAdminByUuid(UUID uuid) + public ResultSetProvider getAdminByUuid(UUID uuid) { - try + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM admins WHERE uuid=?")) { - PreparedStatement statement = connection.prepareStatement("SELECT * FROM admins WHERE uuid=?"); statement.setString(1, uuid.toString()); - ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) - { - return resultSet; - } + return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join(); } catch (SQLException e) { FLog.severe("Failed to get admin by name:"); @@ -276,18 +277,12 @@ public class SQLite extends FreedomService return null; } - public ResultSet getPlayerByUuid(UUID uuid) + public ResultSetProvider getPlayerByUuid(UUID uuid) { - try + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM players WHERE uuid=?")) { - PreparedStatement statement = connection.prepareStatement("SELECT * FROM players WHERE uuid=?"); - statement.setString(1, uuid.toString()); - ResultSet resultSet = statement.executeQuery(); - - if (resultSet.next()) - { - return resultSet; - } + statement.setString(1, uuid.toString()); + return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join(); } catch (SQLException e) { FLog.severe("Failed to get player by UUID:"); @@ -297,11 +292,11 @@ public class SQLite extends FreedomService return null; } - public ResultSet getMasterBuilders() + public ResultSetProvider getMasterBuilders() { - try + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM players WHERE master_builder=true")) { - return connection.prepareStatement("SELECT * FROM players WHERE master_builder=true").executeQuery(); + return ResultSetProvider.provideAllRows(statement.executeQuery()).join(); } catch (SQLException e) { FLog.severe("Failed to get Master Builders:"); @@ -311,17 +306,12 @@ public class SQLite extends FreedomService return null; } - public ResultSet getPlayerByIp(String ip) + public ResultSetProvider getPlayerByIp(String ip) { - try + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM players WHERE ips LIKE %?%")) { - PreparedStatement statement = connection.prepareStatement("SELECT * FROM players WHERE ips LIKE %?%"); statement.setString(1, ip); - ResultSet resultSet = statement.executeQuery(); - if (resultSet.next()) - { - return resultSet; - } + return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join(); } catch (SQLException e) { FLog.severe("Failed to get player by ip:");