Retrieving ResultSets correctly

This commit is contained in:
Paul Reilly 2023-03-31 00:52:53 -05:00
parent f53ba1bd76
commit 997210a16f
7 changed files with 216 additions and 129 deletions

View File

@ -4,15 +4,13 @@ import me.totalfreedom.totalfreedommod.TotalFreedomMod;
import me.totalfreedom.totalfreedommod.player.FPlayer; import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.rank.DisplayableGroup; import me.totalfreedom.totalfreedommod.rank.DisplayableGroup;
import me.totalfreedom.totalfreedommod.rank.GroupProvider; 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 me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*; import java.util.*;
public class Admin public class Admin
@ -32,23 +30,22 @@ public class Admin
this.ips.add(FUtil.getIp(player)); 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")); throw new IllegalArgumentException("Failed to load admin, as the UUID is null.");
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());
} }
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 @Override
@ -70,15 +67,15 @@ public class Admin
public Map<String, Object> toSQLStorable() public Map<String, Object> toSQLStorable()
{ {
HashMap<String, Object> map = new HashMap<>(); HashMap<String, Object> map = new HashMap<>();
map.put("uuid", uuid.toString()); map.put("uuid", uuid.toString());
map.put("active", active); map.put("active", active);
map.put("rank", rank.toString()); map.put("rank", rank.toString());
map.put("ips", FUtil.listToString(ips)); map.put("ips", FUtil.listToString(ips));
map.put("last_login", lastLogin.getTime()); map.put("last_login", lastLogin.getTime());
map.put("command_spy", commandSpy); map.put("command_spy", commandSpy);
map.put("potion_spy", potionSpy); map.put("potion_spy", potionSpy);
map.put("ac_format", acFormat); map.put("ac_format", acFormat);
return map; return map;
} }

View File

@ -5,6 +5,7 @@ import com.google.common.collect.Sets;
import me.totalfreedom.totalfreedommod.FreedomService; import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.GroupProvider; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.sql.ResultSetProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -12,10 +13,10 @@ import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class AdminList extends FreedomService public class AdminList extends FreedomService
{ {
@ -45,11 +46,19 @@ public class AdminList extends FreedomService
allAdmins.clear(); allAdmins.clear();
try try
{ {
ResultSet adminSet = plugin.sql.getAdminList(); ResultSetProvider adminList = plugin.sql.getAdminList();
while (adminSet.next()) AtomicInteger row = new AtomicInteger(1);
{ adminList.getAllRowsResultSet().forEach(adminSet -> {
tryAddAdmin(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) } catch (SQLException e)
{ {
FLog.severe("Failed to load admin list: " + e.getMessage()); 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)"); 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); Admin admin = new Admin(adminSet);
allAdmins.add(admin); 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) public void messageAllAdmins(Component message)
@ -263,7 +265,7 @@ public class AdminList extends FreedomService
{ {
try try
{ {
ResultSet currentSave = plugin.sql.getAdminByUuid(admin.getUuid()); ResultSetProvider currentSave = plugin.sql.getAdminByUuid(admin.getUuid());
for (Map.Entry<String, Object> entry : admin.toSQLStorable().entrySet()) for (Map.Entry<String, Object> entry : admin.toSQLStorable().entrySet())
{ {
Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue());

View File

@ -2,17 +2,8 @@ package me.totalfreedom.totalfreedommod.banning;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets; 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.FreedomService;
import me.totalfreedom.totalfreedommod.sql.ResultSetProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.entity.Player; 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.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import java.sql.SQLException;
import java.util.*;
public class BanManager extends FreedomService public class BanManager extends FreedomService
{ {
@ -36,28 +30,24 @@ public class BanManager extends FreedomService
bans.clear(); bans.clear();
try try
{ {
ResultSet banSet = plugin.sql.getBanList(); plugin.sql.getBanList().getAllRowsResultSet().forEach(row -> {
{ ResultSetProvider banSet = ResultSetProvider.fromRow(row);
while (banSet.next()) String name = banSet.getString("name");
UUID uuid = null;
String strUUID = banSet.getString("uuid");
if (strUUID != null)
{ {
String name = banSet.getString("name"); uuid = UUID.fromString(strUUID);
UUID uuid = null;
String strUUID = banSet.getString("uuid");
if (strUUID != null)
{
uuid = UUID.fromString(strUUID);
}
List<String> 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);
} }
} List<String> ips = FUtil.stringToList(banSet.getString("ips"));
} String by = banSet.getString("by");
catch (SQLException e) 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()); 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) if (ban.getUsername() != null && getByUsername(ban.getUsername()) != null)
{ {
removeBan(ban); removeBan(ban);
} } else
else
{ {
for (String ip : ban.getIps()) for (String ip : ban.getIps())
@ -267,8 +256,7 @@ public class BanManager extends FreedomService
if (ban != null) if (ban != null)
{ {
removeBan(ban); removeBan(ban);
} } else
else
{ {
ban = getByIp(FUtil.getIp(player)); ban = getByIp(FUtil.getIp(player));
if (ban != null) if (ban != null)

View File

@ -4,6 +4,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import me.totalfreedom.totalfreedommod.api.ShopItem; import me.totalfreedom.totalfreedommod.api.ShopItem;
import me.totalfreedom.totalfreedommod.util.FConverter; import me.totalfreedom.totalfreedommod.util.FConverter;
import me.totalfreedom.totalfreedommod.sql.ResultSetProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -44,7 +45,7 @@ public class PlayerData
private Boolean inspect = false; private Boolean inspect = false;
public PlayerData(ResultSet resultSet) public PlayerData(ResultSetProvider resultSet)
{ {
try try
{ {
@ -71,7 +72,7 @@ public class PlayerData
loginMessage = tempLoginMessage; loginMessage = tempLoginMessage;
//-- //--
inspect = resultSet.getBoolean("inspect"); inspect = resultSet.getBoolean("inspect");
} catch (SQLException e) } catch (Throwable e)
{ {
FLog.severe("Failed to load player: " + e.getMessage()); FLog.severe("Failed to load player: " + e.getMessage());
e.printStackTrace(); e.printStackTrace();

View File

@ -5,6 +5,7 @@ import me.totalfreedom.totalfreedommod.FreedomService;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.GroupProvider; import me.totalfreedom.totalfreedommod.rank.GroupProvider;
import me.totalfreedom.totalfreedommod.sql.ResultSetProvider;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil; import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
@ -42,24 +43,17 @@ public class PlayerList extends FreedomService
public void loadMasterBuilders() public void loadMasterBuilders()
{ {
ResultSet resultSet = plugin.sql.getMasterBuilders(); ResultSetProvider resultSet = plugin.sql.getMasterBuilders();
if (resultSet == null) if (resultSet == null)
{ {
return; return;
} }
try resultSet.getAllRowsResultSet().forEach(row -> {
{ PlayerData playerData = load(ResultSetProvider.fromRow(row));
while (resultSet.next()) dataMap.put(playerData.getUuid(), playerData);
{ });
PlayerData playerData = load(resultSet);
dataMap.put(playerData.getUuid(), playerData);
}
} catch (SQLException e)
{
FLog.severe("Failed to parse master builders: " + e.getMessage());
}
} }
public String getIp(OfflinePlayer player) public String getIp(OfflinePlayer player)
@ -128,12 +122,13 @@ public class PlayerList extends FreedomService
return load(plugin.sql.getPlayerByIp(ip)); return load(plugin.sql.getPlayerByIp(ip));
} }
public PlayerData load(ResultSet resultSet) public PlayerData load(ResultSetProvider resultSet)
{ {
if (resultSet == null) if (resultSet == null)
{ {
return null; return null;
} }
return new PlayerData(resultSet); return new PlayerData(resultSet);
} }
@ -149,7 +144,7 @@ public class PlayerList extends FreedomService
{ {
try try
{ {
ResultSet currentSave = plugin.sql.getPlayerByUuid(player.getUuid()); ResultSetProvider currentSave = plugin.sql.getPlayerByUuid(player.getUuid());
for (Map.Entry<String, Object> entry : player.toSQLStorable().entrySet()) for (Map.Entry<String, Object> entry : player.toSQLStorable().entrySet())
{ {
Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue()); Object storedValue = plugin.sql.getValue(currentSave, entry.getKey(), entry.getValue());

View File

@ -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<Map<String, Object>> allRowsResultSet = new ArrayList<>();
Map<String, Object> singularResultMap = new HashMap<>();
private ResultSetProvider(Map<String, Object> 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<ResultSetProvider> provideAllRows(ResultSet resultSet)
{
return CompletableFuture.supplyAsync(() ->
{
try
{
return new ResultSetProvider(resultSet, true);
} catch (SQLException e)
{
return null;
}
});
}
public static CompletableFuture<ResultSetProvider> 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<String, Object> row) {
return new ResultSetProvider(row);
}
public List<Map<String, Object>> getAllRowsResultSet()
{
return allRowsResultSet;
}
private Map<String, Object> mapResultSet(ResultSet rs) throws SQLException
{
Map<String, Object> 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);
}
}

View File

@ -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) public void setAdminValue(Admin admin, String key, Object value)
@ -191,21 +197,21 @@ public class SQLite extends FreedomService
return statement; 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; Object result = null;
if (value instanceof String) if (value instanceof String)
{ {
result = resultSet.getString(key); result = provider.getString(key);
} else if (value instanceof Integer) } else if (value instanceof Integer)
{ {
result = resultSet.getInt(key); result = provider.getInt(key);
} else if (value instanceof Boolean) } else if (value instanceof Boolean)
{ {
result = resultSet.getObject(key); result = provider.getBoolean(key);
} else if (value instanceof Long) } else if (value instanceof Long)
{ {
result = resultSet.getLong(key); result = provider.getLong(key);
} }
return result; 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()); statement.setString(1, uuid.toString());
ResultSet resultSet = statement.executeQuery(); return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join();
if (resultSet.next())
{
return resultSet;
}
} catch (SQLException e) } catch (SQLException e)
{ {
FLog.severe("Failed to get admin by name:"); FLog.severe("Failed to get admin by name:");
@ -276,18 +277,12 @@ public class SQLite extends FreedomService
return null; 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());
statement.setString(1, uuid.toString()); return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join();
ResultSet resultSet = statement.executeQuery();
if (resultSet.next())
{
return resultSet;
}
} catch (SQLException e) } catch (SQLException e)
{ {
FLog.severe("Failed to get player by UUID:"); FLog.severe("Failed to get player by UUID:");
@ -297,11 +292,11 @@ public class SQLite extends FreedomService
return null; 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) } catch (SQLException e)
{ {
FLog.severe("Failed to get Master Builders:"); FLog.severe("Failed to get Master Builders:");
@ -311,17 +306,12 @@ public class SQLite extends FreedomService
return null; 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); statement.setString(1, ip);
ResultSet resultSet = statement.executeQuery(); return ResultSetProvider.provideSpecificRow(statement.executeQuery()).join();
if (resultSet.next())
{
return resultSet;
}
} catch (SQLException e) } catch (SQLException e)
{ {
FLog.severe("Failed to get player by ip:"); FLog.severe("Failed to get player by ip:");