From fe6159e87b939037ab27a63a477d3c3864aad28f Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 26 Aug 2017 18:21:42 -0700 Subject: [PATCH] Fixed MySQL bug for loading individual objects. The code was not loading the uniqueId object. Added a lot of debug code in to help debug. --- .../api/commands/AbstractCommand.java | 14 +++ .../bskyblock/commands/IslandCommand.java | 2 + .../database/managers/IslandsManager.java | 12 ++- .../database/managers/PlayersManager.java | 19 +++- .../database/mysql/MySQLDatabaseHandler.java | 97 ++++++++++++++----- .../bskyblock/database/objects/Island.java | 1 + .../bskyblock/database/objects/Players.java | 4 - .../listeners/JoinLeaveListener.java | 1 - .../bskyblock/schematics/SchematicsMgr.java | 8 +- 9 files changed, 119 insertions(+), 39 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/api/commands/AbstractCommand.java b/src/main/java/us/tastybento/bskyblock/api/commands/AbstractCommand.java index 026b3b1fc..e771c190b 100644 --- a/src/main/java/us/tastybento/bskyblock/api/commands/AbstractCommand.java +++ b/src/main/java/us/tastybento/bskyblock/api/commands/AbstractCommand.java @@ -46,6 +46,8 @@ public abstract class AbstractCommand implements CommandExecutor, TabCompleter { private final boolean help; private static final int MAX_PER_PAGE = 7; + private static final boolean DEBUG = false; + protected AbstractCommand(BSkyBlock plugin, String label, String[] aliases, boolean help) { this.plugin = plugin; this.argumentsMap = new LinkedHashMap<>(); @@ -252,6 +254,8 @@ public abstract class AbstractCommand implements CommandExecutor, TabCompleter { * @param sender */ private void checkForPlayer(CommandSender sender) { + if (DEBUG) + plugin.getLogger().info("DEBUG: checkForPlayer"); // Check if the command sender is a player or not if (sender instanceof Player) { isPlayer = true; @@ -262,9 +266,19 @@ public abstract class AbstractCommand implements CommandExecutor, TabCompleter { } // Check if the player is in a team or not and if so, grab the team leader's UUID if (plugin.getPlayers().inTeam(playerUUID)) { + if (DEBUG) + plugin.getLogger().info("DEBUG: player in team"); inTeam = true; teamLeaderUUID = plugin.getIslands().getTeamLeader(playerUUID); + if (DEBUG) + plugin.getLogger().info("DEBUG: team leader UUID = " + teamLeaderUUID); teamMembers = plugin.getIslands().getMembers(teamLeaderUUID); + if (DEBUG) { + plugin.getLogger().info("DEBUG: teammembers = "); + for (UUID member: teamMembers) { + plugin.getLogger().info("DEBUG: " + member); + } + } } else { inTeam = false; } diff --git a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java index e503e236f..bf43a5670 100755 --- a/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java +++ b/src/main/java/us/tastybento/bskyblock/commands/IslandCommand.java @@ -501,6 +501,8 @@ public class IslandCommand extends AbstractCommand { Util.sendMessage(player, getLocale(sender).get("team.listingMembers")); // Display members in the list for (UUID m : teamMembers) { + if (DEBUG) + plugin.getLogger().info("DEBUG: member " + m); if (teamLeaderUUID.equals(m)) { Util.sendMessage(player, getLocale(sender).get("team.leader-color") + getPlayers().getName(m) + getLocale(sender).get("team.leader")); } else { diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java index 2f744b59f..1ac99e6e1 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/IslandsManager.java @@ -49,7 +49,7 @@ import us.tastybento.bskyblock.util.Util; */ public class IslandsManager { - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; private static final boolean DEBUG2 = false; private BSkyBlock plugin; private BSBDatabase database; @@ -92,10 +92,20 @@ public class IslandsManager { islandsByUUID.clear(); spawn = null; try { + if (DEBUG) + plugin.getLogger().info("DEBUG: loading grid"); for (Island island : handler.loadObjects()) { + if (DEBUG) + plugin.getLogger().info("DEBUG: addin island at "+ island.getCenter()); islandsByLocation.put(island.getCenter(), island); + if (DEBUG) + plugin.getLogger().info("DEBUG: owner = " + island.getOwner()); islandsByUUID.put(island.getOwner(), island); + if (DEBUG) + plugin.getLogger().info("DEBUG: island has " + island.getMembers().size() + " members"); for (UUID member: island.getMembers()) { + if (DEBUG) + plugin.getLogger().info("DEBUG: " + member); islandsByUUID.put(member, island); } addToGrid(island); diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java index e0d41c491..2f0a87d78 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/PlayersManager.java @@ -66,8 +66,12 @@ public class PlayersManager{ * @param async - if true, save async */ public void save(boolean async){ + if (DEBUG) + plugin.getLogger().info("DEBUG: saving " + async); Runnable save = () -> { for(Players player : playerCache.values()){ + if (DEBUG) + plugin.getLogger().info("DEBUG: saving player " + player.getPlayerName() + " "+ player.getUniqueId()); try { handler.saveObject(player); } catch (Exception e) { @@ -331,8 +335,10 @@ public class PlayersManager{ * @param name */ public void setPlayerName(UUID uniqueId, String name) { + if (DEBUG) + plugin.getLogger().info("DEBUG: Setting player name to " + name + " for " + uniqueId); addPlayer(uniqueId); - playerCache.get(uniqueId).setPlayerN(name); + playerCache.get(uniqueId).setPlayerName(name); //database.savePlayerName(name, uniqueId); } @@ -344,10 +350,14 @@ public class PlayersManager{ * @return String - playerName */ public String getName(UUID playerUUID) { + if (DEBUG) + plugin.getLogger().info("DEBUG: Geting player name"); if (playerUUID == null) { return ""; } addPlayer(playerUUID); + if (DEBUG) + plugin.getLogger().info("DEBUG: name is " + playerCache.get(playerUUID).getPlayerName()); return playerCache.get(playerUUID).getPlayerName(); } @@ -595,11 +605,12 @@ public class PlayersManager{ */ public void save(UUID playerUUID) { if (playerCache.containsKey(playerUUID)) { - Players player = playerCache.get(playerUUID); + final Players player = playerCache.get(playerUUID); try { - handler.saveObject(player); if (DEBUG) - plugin.getLogger().info("DEBUG: " + playerUUID + " saved"); + plugin.getLogger().info("DEBUG: saving player by uuid " + player.getPlayerName() + " " + playerUUID + " saved"); + handler.saveObject(player); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException | InstantiationException | NoSuchMethodException diff --git a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java index d07fff865..7b13d3a39 100644 --- a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java @@ -45,6 +45,7 @@ import us.tastybento.bskyblock.util.Util; */ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { + private static final boolean DEBUG = false; /** * Connection to the database */ @@ -84,6 +85,9 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { mySQLmapping.put(Map.class.getTypeName(), "BOOL"); mySQLmapping.put(HashMap.class.getTypeName(), "BOOL"); mySQLmapping.put(ArrayList.class.getTypeName(), "BOOL"); + + // Enums + mySQLmapping.put(Enum.class.getTypeName(), "VARCHAR(254)"); } @@ -132,7 +136,11 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // The SQL column name is the name of the field String columnName = field.getName(); // Get the mapping for this field from the hashmap - String mapping = mySQLmapping.get(propertyDescriptor.getPropertyType().getTypeName()); + String typeName = propertyDescriptor.getPropertyType().getTypeName(); + if (propertyDescriptor.getPropertyType().isEnum()) { + typeName = "Enum"; + } + String mapping = mySQLmapping.get(typeName); // If it exists, then create the SQL if (mapping != null) { // Note that the column name must be enclosed in `'s because it may include reserved words. @@ -153,6 +161,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { //plugin.getLogger().info(setSql); // Execute the statement PreparedStatement collections = connection.prepareStatement(setSql); + if (DEBUG) + plugin.getLogger().info("DEBUG: collections prepared statement = " + collections.toString()); collections.executeUpdate(); } } else { @@ -160,6 +170,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // This should NOT be used in general because every type should be in the hashmap sql += field.getName() + " VARCHAR(254),"; plugin.getLogger().severe("Unknown type! Hoping it'll fit in a string!"); + plugin.getLogger().severe(propertyDescriptor.getPropertyType().getTypeName()); } } //plugin.getLogger().info("DEBUG: SQL before trim string = " + sql); @@ -168,6 +179,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { //plugin.getLogger().info("DEBUG: SQL string = " + sql); // Prepare and execute the database statements pstmt = connection.prepareStatement(sql); + if (DEBUG) + plugin.getLogger().info("DEBUG: pstmt = " + pstmt.toString()); pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); @@ -234,7 +247,6 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { if (createSchema) { // If this is the schema, then guess the mapping type columns += " VARCHAR(254)"; - plugin.getLogger().warning("Unknown type! Hoping it'll fit in a string!"); } } } @@ -318,33 +330,40 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { Connection connection = null; PreparedStatement preparedStatement = null; - + if (DEBUG) + plugin.getLogger().info("DEBUG: saveObject "); try { // Try to connect to the database connection = databaseConnecter.createConnection(); // insertQuery is created in super from the createInsertQuery() method preparedStatement = connection.prepareStatement(insertQuery); // Get the uniqueId. As each class extends DataObject, it must have this method in it. - Method getUniqueId = type.getMethod("getUniqueId"); - String uniqueId = (String) getUniqueId.invoke(instance); - //plugin.getLogger().info("DEBUG: Unique Id = " + uniqueId); + PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", type); + Method getUniqueId = propertyDescriptor.getReadMethod(); + final String uniqueId = (String) getUniqueId.invoke(instance); + if (DEBUG) { + plugin.getLogger().info("DEBUG: Unique Id = " + uniqueId); + } if (uniqueId.isEmpty()) { throw new SQLException("uniqueId is blank"); } // Create the insertion int i = 0; - //plugin.getLogger().info("DEBUG: insert Query " + insertQuery); + if (DEBUG) + plugin.getLogger().info("DEBUG: insert Query " + insertQuery); // Run through the fields in the class using introspection for (Field field : type.getDeclaredFields()) { // Get the field's property descriptor - PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type); + propertyDescriptor = new PropertyDescriptor(field.getName(), type); // Get the read method for this field Method method = propertyDescriptor.getReadMethod(); - //plugin.getLogger().info("DEBUG: Field = " + field.getName() + "(" + propertyDescriptor.getPropertyType().getTypeName() + ")"); + if (DEBUG) + plugin.getLogger().info("DEBUG: Field = " + field.getName() + "(" + propertyDescriptor.getPropertyType().getTypeName() + ")"); //sql += "`" + field.getName() + "` " + mapping + ","; // Invoke the read method to obtain the value from the class - this is the value we need to store in the database Object value = method.invoke(instance); - + if (DEBUG) + plugin.getLogger().info("DEBUG: value = " + value); // Create set and map table inserts if this is a Collection if (propertyDescriptor.getPropertyType().equals(Set.class) || propertyDescriptor.getPropertyType().equals(Map.class) || @@ -356,6 +375,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { PreparedStatement collStatement = connection.prepareStatement(clearTableSql); collStatement.setString(1, uniqueId); collStatement.execute(); + if (DEBUG) + plugin.getLogger().info("DEBUG: collStatement " + collStatement.toString()); // Insert into the table String setSql = "INSERT INTO `" + type.getCanonicalName() + "." + field.getName() + "` (uniqueId, "; // Get the columns we are going to insert, just the names of them @@ -364,7 +385,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { setSql += "VALUES ('" + uniqueId + "'," + getCollectionColumns(propertyDescriptor.getWriteMethod(), true, false) + ")"; // Prepare the statement collStatement = connection.prepareStatement(setSql); - //plugin.getLogger().info("DEBUG: collection insert =" + setSql); + if (DEBUG) + plugin.getLogger().info("DEBUG: collection insert =" + setSql); // Do single dimension types (set and list) if (propertyDescriptor.getPropertyType().equals(Set.class) || propertyDescriptor.getPropertyType().equals(ArrayList.class)) { @@ -381,7 +403,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { //} // Set the value from ? to whatever it is collStatement.setObject(1, setValue); - //plugin.getLogger().info("DEBUG: " + collStatement.toString()); + if (DEBUG) + plugin.getLogger().info("DEBUG: " + collStatement.toString()); // Execute the SQL in the database collStatement.execute(); } @@ -400,7 +423,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // Write the objects into prepared statement collStatement.setObject(1, key); collStatement.setObject(2, mapValue); - //plugin.getLogger().info("DEBUG: " + collStatement.toString()); + if (DEBUG) + plugin.getLogger().info("DEBUG: " + collStatement.toString()); // Write to database collStatement.execute(); } @@ -419,6 +443,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // Add the statements to a batch preparedStatement.addBatch(); // Execute + if (DEBUG) + plugin.getLogger().info("DEBUG: prepared statement = " + preparedStatement.toString()); preparedStatement.executeBatch(); } finally { @@ -497,6 +523,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { try { connection = databaseConnecter.createConnection(); statement = connection.createStatement(); + if (DEBUG) + plugin.getLogger().info("DEBUG: selectQuery = " + selectQuery); resultSet = statement.executeQuery(selectQuery); return createObjects(resultSet); @@ -518,11 +546,16 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { Connection connection = null; Statement statement = null; ResultSet resultSet = null; - + if (DEBUG) + plugin.getLogger().info("DEBUG: loading object for " + uniqueId); try { connection = databaseConnecter.createConnection(); - statement = connection.createStatement(); - resultSet = statement.executeQuery(selectQuery); + String query = "SELECT " + super.getColumns(false) + " FROM `" + type.getCanonicalName() + "` WHERE uniqueId = ? LIMIT 1"; + PreparedStatement preparedStatement = connection.prepareStatement(query); + preparedStatement.setString(1, uniqueId); + if (DEBUG) + plugin.getLogger().info("DEBUG: load Object query = " + preparedStatement.toString()); + resultSet = preparedStatement.executeQuery(); List result = createObjects(resultSet); if (!result.isEmpty()) { @@ -605,22 +638,25 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { PreparedStatement collStatement = connection.prepareStatement(setSql); // Set the unique ID collStatement.setObject(1, uniqueId); - //plugin.getLogger().info("DEBUG: collStatement = " + collStatement.toString()); + if (DEBUG) + plugin.getLogger().info("DEBUG: collStatement = " + collStatement.toString()); ResultSet collectionResultSet = collStatement.executeQuery(); //plugin.getLogger().info("DEBUG: collectionResultSet = " + collectionResultSet.toString()); // Do single dimension types (set and list) if (propertyDescriptor.getPropertyType().equals(Set.class)) { - //plugin.getLogger().info("DEBUG: adding a set"); + if (DEBUG) + plugin.getLogger().info("DEBUG: adding a set"); // Loop through the collection resultset // Note that we have no idea what type this is List collectionTypes = Util.getCollectionParameterTypes(method); // collectionTypes should be only 1 long Type setType = collectionTypes.get(0); value = new HashSet(); - //plugin.getLogger().info("DEBUG: collection type argument = " + collectionTypes); - //plugin.getLogger().info("DEBUG: setType = " + setType.getTypeName()); + if (DEBUG) { + plugin.getLogger().info("DEBUG: collection type argument = " + collectionTypes); + plugin.getLogger().info("DEBUG: setType = " + setType.getTypeName()); + } while (collectionResultSet.next()) { - //plugin.getLogger().info("DEBUG: collectionResultSet size = " + collectionResultSet.getFetchSize()); ((Set) value).add(deserialize(collectionResultSet.getObject(1),Class.forName(setType.getTypeName()))); } } else if (propertyDescriptor.getPropertyType().equals(ArrayList.class)) { @@ -750,7 +786,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // Second is the unique ID preparedStatement.setString(1, uniqueId); preparedStatement.addBatch(); - plugin.getLogger().info("DEBUG: DELETE Query " + preparedStatement.toString()); + if (DEBUG) + plugin.getLogger().info("DEBUG: DELETE Query " + preparedStatement.toString()); preparedStatement.executeBatch(); // Delete from any sub tables created from the object // Run through the fields in the class using introspection @@ -768,7 +805,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { preparedStatement.setString(1, uniqueId); preparedStatement.addBatch(); // Execute - plugin.getLogger().info("DEBUG: " + preparedStatement.toString()); + if (DEBUG) + plugin.getLogger().info("DEBUG: " + preparedStatement.toString()); preparedStatement.executeBatch(); } } @@ -784,16 +822,25 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { */ @Override public boolean objectExits(String key) { + if (DEBUG) + plugin.getLogger().info("DEBUG: checking if " + key + " exists in the database"); Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; - String query = "SELECT * FROM `" + type.getCanonicalName() + "` WHERE uniqueId = ?"; + String query = "SELECT IF ( EXISTS( SELECT * FROM `" + type.getCanonicalName() + "` WHERE `uniqueId` = ?), 1, 0)"; + //String query = "SELECT * FROM `" + type.getCanonicalName() + "` WHERE uniqueId = ?"; try { connection = databaseConnecter.createConnection(); preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, key); resultSet = preparedStatement.executeQuery(); - return resultSet.next(); + if (DEBUG) + plugin.getLogger().info("DEBUG: object exists sql " + preparedStatement.toString()); + if (resultSet.next()) { + if (DEBUG) + plugin.getLogger().info("DEBUG: result is " + resultSet.getBoolean(1)); + return resultSet.getBoolean(1); + } } catch (SQLException e) { e.printStackTrace(); } finally { diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index b5a4903c2..5dbffff52 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -680,6 +680,7 @@ public class Island extends DataObject { * @param members - the members to set */ public void setMembers(Set members){ + //Bukkit.getLogger().info("DEBUG: members size = " + members.size()); this.members = members; } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java index 0df819822..e3e5cd2f7 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Players.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Players.java @@ -135,10 +135,6 @@ public class Players extends DataObject { return playerName; } - public void setPlayerN(String playerName) { - this.playerName = playerName; - } - /** * @return the resetsLeft */ diff --git a/src/main/java/us/tastybento/bskyblock/listeners/JoinLeaveListener.java b/src/main/java/us/tastybento/bskyblock/listeners/JoinLeaveListener.java index 99f43f8cf..6ea42c6ca 100644 --- a/src/main/java/us/tastybento/bskyblock/listeners/JoinLeaveListener.java +++ b/src/main/java/us/tastybento/bskyblock/listeners/JoinLeaveListener.java @@ -2,7 +2,6 @@ package us.tastybento.bskyblock.listeners; import java.util.UUID; -import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; diff --git a/src/main/java/us/tastybento/bskyblock/schematics/SchematicsMgr.java b/src/main/java/us/tastybento/bskyblock/schematics/SchematicsMgr.java index 8aff7bee4..6dd0ead6f 100644 --- a/src/main/java/us/tastybento/bskyblock/schematics/SchematicsMgr.java +++ b/src/main/java/us/tastybento/bskyblock/schematics/SchematicsMgr.java @@ -65,12 +65,12 @@ public class SchematicsMgr { // built-in island generation schematics.put("default",new Schematic(plugin)); } - plugin.getLogger().info("Loaded default nether schematic"); + //plugin.getLogger().info("Loaded default nether schematic"); } else { // It exists, so load it try { schematics.put("default",new Schematic(plugin, schematicFile)); - plugin.getLogger().info("Loaded default island schematic."); + //plugin.getLogger().info("Loaded default island schematic."); } catch (IOException e) { plugin.getLogger().severe("Could not load default schematic!"); e.printStackTrace(); @@ -86,7 +86,7 @@ public class SchematicsMgr { Schematic netherIsland = new Schematic(plugin, netherFile); netherIsland.setVisible(false); schematics.put("nether", netherIsland); - plugin.getLogger().info("Loaded default nether schematic."); + //plugin.getLogger().info("Loaded default nether schematic."); } catch (IOException e) { plugin.getLogger().severe("Could not load default nether schematic!"); e.printStackTrace(); @@ -100,7 +100,7 @@ public class SchematicsMgr { Schematic netherIsland = new Schematic(plugin, netherFile); netherIsland.setVisible(false); schematics.put("nether", netherIsland); - plugin.getLogger().info("Loaded default nether schematic."); + //plugin.getLogger().info("Loaded default nether schematic."); } catch (IOException e) { plugin.getLogger().severe("Could not load default nether schematic!"); e.printStackTrace();