From 6be730f747111e033acc31dc2d82c0f4603f5fab Mon Sep 17 00:00:00 2001 From: tastybento Date: Sat, 27 May 2017 16:38:32 -0700 Subject: [PATCH] MySQL database will now store Collections in additional tables. --- .../database/mysql/MySQLDatabaseHandler.java | 72 ++++++++++++++++--- 1 file changed, 63 insertions(+), 9 deletions(-) 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 b0704933c..ccb1c231c 100644 --- a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java @@ -5,6 +5,9 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.lang.reflect.TypeVariable; import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; @@ -64,14 +67,16 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // Bukkit Mappings mySQLmapping.put(Location.class.getTypeName(), "VARCHAR(254)"); mySQLmapping.put(World.class.getTypeName(), "VARCHAR(254)"); - + // TODO: Collections - these need to create another table and link to it - mySQLmapping.put(Set.class.getTypeName(), "VARCHAR(254)"); - mySQLmapping.put(Map.class.getTypeName(), "VARCHAR(254)"); - mySQLmapping.put(HashMap.class.getTypeName(), "VARCHAR(254)"); - mySQLmapping.put(ArrayList.class.getTypeName(), "VARCHAR(254)"); - - } + // Collections are stored as additional tables. The boolean indicates whether there + // is any data in it or not (maybe) + mySQLmapping.put(Set.class.getTypeName(), "BOOL"); + mySQLmapping.put(Map.class.getTypeName(), "BOOL"); + mySQLmapping.put(HashMap.class.getTypeName(), "BOOL"); + mySQLmapping.put(ArrayList.class.getTypeName(), "BOOL"); + + } public MySQLDatabaseHandler(BSkyBlock plugin, Class type, DatabaseConnecter databaseConnecter) { super(plugin, type, databaseConnecter); @@ -108,7 +113,18 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { String mapping = mySQLmapping.get(propertyDescriptor.getPropertyType().getTypeName()); if (mapping != null) { sql += "`" + field.getName() + "` " + mapping + ","; - // TODO: Create set and map tables. + // Create set and map tables. + if (propertyDescriptor.getPropertyType().equals(Set.class) || + propertyDescriptor.getPropertyType().equals(Map.class) || + propertyDescriptor.getPropertyType().equals(HashMap.class) || + propertyDescriptor.getPropertyType().equals(ArrayList.class)) { + String setSql = "CREATE TABLE IF NOT EXISTS " + type.getSimpleName() + "_" + field.getName() + " ("; + // Get the type + setSql += getMethodParameterTypes(propertyDescriptor.getWriteMethod()); + plugin.getLogger().info(setSql); + PreparedStatement collections = connection.prepareStatement(setSql); + collections.executeUpdate(); + } } else { sql += field.getName() + " VARCHAR(254),"; plugin.getLogger().severe("Unknown type! Hoping it'll fit in a string!"); @@ -116,7 +132,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { } //plugin.getLogger().info("DEBUG: SQL before trim string = " + sql); sql = sql.substring(0,(sql.length()-1)) + ")"; - //plugin.getLogger().info("DEBUG: SQL string = " + sql); + plugin.getLogger().info("DEBUG: SQL string = " + sql); pstmt = connection.prepareStatement(sql.toString()); pstmt.executeUpdate(); } catch (Exception e) { @@ -127,6 +143,44 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { } } + /** + * Gets the types for parameters in a method + * @param writeMethod + * @return List of strings with the SQL for parameter and type set + */ + private String getMethodParameterTypes(Method method) { + String result = ""; + // Get the return type + Type[] genericParameterTypes = method.getGenericParameterTypes(); + for (int i = 0; i < genericParameterTypes.length; i++) { + if( genericParameterTypes[i] instanceof ParameterizedType ) { + Type[] parameters = ((ParameterizedType)genericParameterTypes[i]).getActualTypeArguments(); + //parameters[0] contains java.lang.String for method like "method(List value)" + int index = 0; + String firstColumn = ""; + for (Type type : parameters) { + plugin.getLogger().info("DEBUG: set type = " + type.getTypeName()); + String setMapping = mySQLmapping.get(type.getTypeName()); + String notNull = ""; + if (index == 0) { + firstColumn = "`" + type.getTypeName() + "_" + index + "`"; + notNull = " NOT NULL"; + } + if (setMapping != null) { + result += "`" + type.getTypeName() + "_" + index + "` " + setMapping + notNull + ","; + } else { + result += "`" + type.getTypeName() + "_" + index + "` VARCHAR(254)" + notNull + ","; + plugin.getLogger().severe("Unknown type! Hoping it'll fit in a string!"); + } + index++; + } + // Add primary key + result += " PRIMARY KEY (" + firstColumn + "))"; + } + } + return result; + } + @Override protected String createSelectQuery() {