Added a lot of MySQL stuff. WIP, not tested at all. Beware test conde on

onEnable().
This commit is contained in:
tastybento 2017-05-25 22:54:04 -07:00
parent b5430c0aab
commit 19865969d2
11 changed files with 261 additions and 41 deletions

View File

@ -11,6 +11,7 @@ import us.tastybento.bskyblock.config.BSBLocale;
import us.tastybento.bskyblock.config.PluginConfig;
import us.tastybento.bskyblock.config.Settings;
import us.tastybento.bskyblock.database.BSBDatabase;
import us.tastybento.bskyblock.database.BSBDatabase.DatabaseType;
import us.tastybento.bskyblock.database.IslandsManager;
import us.tastybento.bskyblock.database.OfflineHistoryMessages;
import us.tastybento.bskyblock.database.PlayersManager;
@ -40,6 +41,14 @@ public class BSkyBlock extends JavaPlugin{
// Load configuration and locales. If there are no errors, load the plugin.
if(PluginConfig.loadPluginConfig(this)){
// TEMP DEBUG DATABASE
Settings.databaseType = DatabaseType.MYSQL;
Settings.dbHost = "localhost";
Settings.dbPort = 3306;
Settings.dbName = "ASkyBlock";
Settings.dbUsername = "user";
Settings.dbPassword = "password";
playersManager = new PlayersManager(this);
islandsManager = new IslandsManager(this);

View File

@ -33,7 +33,6 @@ public class Settings {
public static boolean purgeRemoveUserData;
// TODO Database
public static DatabaseType databaseType;
public static int databaseBackupPeriod;
public static boolean recoverSuperFlat;
@ -156,4 +155,12 @@ public class Settings {
// TODO added this just to avoid compilation errors, but will be changed in the future
public static List<HistoryMessageType> historyMessagesTypes;
// Database settings
public static DatabaseType databaseType;
public static String dbHost;
public static int dbPort;
public static String dbName;
public static String dbUsername;
public static String dbPassword;
}

View File

@ -7,7 +7,6 @@ import java.sql.SQLException;
import java.util.List;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.database.objects.Island;
/**
* An abstract class that handles insert/select-operations into/from a database
@ -19,11 +18,6 @@ import us.tastybento.bskyblock.database.objects.Island;
*
* @param <T>
*/
/**
* @author tastybento
*
* @param <T>
*/
public abstract class AbstractDatabaseHandler<T> {
/**
@ -45,7 +39,7 @@ public abstract class AbstractDatabaseHandler<T> {
protected BSkyBlock plugin;
/**
* Constructor
*
@ -56,8 +50,7 @@ public abstract class AbstractDatabaseHandler<T> {
* Contains the settings to create a connection to the database
* like host/port/database/user/password
*/
protected AbstractDatabaseHandler(BSkyBlock plugin, Class<T> type,
DatabaseConnecter databaseConnecter) {
protected AbstractDatabaseHandler(BSkyBlock plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
this.plugin = plugin;
this.databaseConnecter = databaseConnecter;
@ -103,7 +96,7 @@ public abstract class AbstractDatabaseHandler<T> {
return sb.toString();
}
/**
* Loads all the records in this table and returns a list of them
* @return list of <T>
@ -129,7 +122,7 @@ public abstract class AbstractDatabaseHandler<T> {
* @throws InstantiationException
*/
protected abstract T selectObject(String uniqueId) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException;
/**
* Inserts T into the corresponding database-table
*

View File

@ -8,6 +8,11 @@ import us.tastybento.bskyblock.database.sqlite.SQLiteDatabase;
public abstract class BSBDatabase {
/**
* Gets the type of database being used. Currently supported options are
* FLATFILE, MYSQL and SQLITE. Default is FLATFILE
* @return Database type
*/
public static BSBDatabase getDatabase(){
for(DatabaseType type : DatabaseType.values()){
if(type == Settings.databaseType) return type.database;
@ -31,7 +36,6 @@ public abstract class BSBDatabase {
* Gets a handler for this class type with this database connection
* @param plugin
* @param type
* @param databaseConnecter
* @return selector object
*/
public abstract AbstractDatabaseHandler<?> getHandler(BSkyBlock plugin, Class<?> type);

View File

@ -34,8 +34,20 @@ public interface DatabaseConnecter {
*/
public String getUniqueId(String tableName);
/**
* Loads a YAML file. Used by the flat file database
* @param string
* @param key
* @return Yaml Configuration
*/
public YamlConfiguration loadYamlFile(String string, String key);
/**
* Save the Yaml Config
* @param yamlFile
* @param tableName - analogous to a table in a database
* @param fileName - the name of the record. Must be unique.
*/
public void saveYamlFile(YamlConfiguration yamlFile, String tableName,
String fileName);
}

View File

@ -1,10 +1,96 @@
package us.tastybento.bskyblock.database;
import us.tastybento.bskyblock.config.Settings;
public class DatabaseConnectionSettingsImpl {
public DatabaseConnectionSettingsImpl(String string, int i, String string2,
String string3, String string4) {
// TODO Auto-generated constructor stub
private String host;
private int port;
private String databaseName;
private String username;
private String password;
/**
* Hosts database settings
* @param host
* @param port
* @param databaseName
* @param username
* @param password
*/
public DatabaseConnectionSettingsImpl(String host, int port,
String databaseName, String username, String password) {
this.host = host;
this.port = port;
this.databaseName = databaseName;
this.username = username;
this.password = password;
}
public DatabaseConnectionSettingsImpl() {
this.host = Settings.dbHost;
this.port = Settings.dbPort;
this.databaseName = Settings.dbName;
this.username = Settings.dbUsername;
this.password = Settings.dbPassword;
}
/**
* @return the host
*/
public String getHost() {
return host;
}
/**
* @param host the host to set
*/
public void setHost(String host) {
this.host = host;
}
/**
* @return the port
*/
public int getPort() {
return port;
}
/**
* @param port the port to set
*/
public void setPort(int port) {
this.port = port;
}
/**
* @return the databaseName
*/
public String getDatabaseName() {
return databaseName;
}
/**
* @param databaseName the databaseName to set
*/
public void setDatabaseName(String databaseName) {
this.databaseName = databaseName;
}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -13,6 +13,11 @@ import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.config.Settings;
import us.tastybento.bskyblock.database.objects.Island;
/**
* The job of this class is manage all island related data.
* @author tastybento
*
*/
public class IslandsManager {
private BSkyBlock plugin;
@ -23,12 +28,16 @@ public class IslandsManager {
// 2D islandGrid of islands, x,z
private TreeMap<Integer, TreeMap<Integer, Island>> islandGrid = new TreeMap<Integer, TreeMap<Integer, Island>>();
/**
* One island can be spawn, this is the one - otherwise, this value is null
*/
private Island spawn;
// Metrics data
private int metrics_createdcount = 0;
private AbstractDatabaseHandler<Island> handler;
@SuppressWarnings("unchecked")
public IslandsManager(BSkyBlock plugin){
this.plugin = plugin;
database = BSBDatabase.getDatabase();
@ -36,7 +45,6 @@ public class IslandsManager {
islands = new HashMap<Location, Island>();
islandsByUUID = new HashMap<UUID, Island>();
spawn = null;
//load();
}
public void load(){

View File

@ -3,14 +3,16 @@ package us.tastybento.bskyblock.database.mysql;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
import us.tastybento.bskyblock.database.BSBDatabase;
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabaseConnecter;
import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
import us.tastybento.bskyblock.database.objects.Island;
public class MySQLDatabase extends BSBDatabase{
@Override
public AbstractDatabaseHandler<?> getHandler(BSkyBlock plugin, Class<?> type) {
return new MySQLDatabaseHandler<Island>(plugin, Island.class, new FlatFileDatabaseConnecter(plugin, null));
return new MySQLDatabaseHandler<Island>(plugin, Island.class,
new MySqlDatabaseConnecter(new DatabaseConnectionSettingsImpl()));
}

View File

@ -5,13 +5,23 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.World;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.database.AbstractDatabaseHandler;
@ -27,11 +37,85 @@ import us.tastybento.bskyblock.database.DatabaseConnecter;
*/
public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
public MySQLDatabaseHandler(BSkyBlock plugin, Class<T> type,
DatabaseConnecter databaseConnecter) {
private Connection connection = null;
private static HashMap<String, String> mySQLmapping;
{
mySQLmapping = new HashMap<String, String>();
mySQLmapping.put(boolean.class.getTypeName(), "BOOL");
mySQLmapping.put(byte.class.getTypeName(), "TINYINT");
mySQLmapping.put(short.class.getTypeName(), "SMALLINT");
mySQLmapping.put(int.class.getTypeName(), "INTEGER");
mySQLmapping.put(long.class.getTypeName(), "BIGINT");
mySQLmapping.put(double.class.getTypeName(), "DOUBLE PRECISION");
mySQLmapping.put(Boolean.class.getTypeName(), "BOOL");
mySQLmapping.put(Byte.class.getTypeName(), "TINYINT");
mySQLmapping.put(Short.class.getTypeName(), "SMALLINT");
mySQLmapping.put(Integer.class.getTypeName(), "INTEGER");
mySQLmapping.put(Long.class.getTypeName(), "BIGINT");
mySQLmapping.put(Double.class.getTypeName(), "DOUBLE PRECISION");
mySQLmapping.put(BigDecimal.class.getTypeName(), "DECIMAL(13,0)");
mySQLmapping.put(String.class.getTypeName(), "VARCHAR(254)");
mySQLmapping.put(Date.class.getTypeName(), "DATE");
mySQLmapping.put(Time.class.getTypeName(), "TIME");
mySQLmapping.put(Timestamp.class.getTypeName(), "TIMESTAMP");
mySQLmapping.put(UUID.class.getTypeName(), "VARCHAR(32)"); // TODO: How long is a UUID to string?
// Bukkit Mappings
mySQLmapping.put(Location.class.getTypeName(), "VARCHAR(254)");
mySQLmapping.put(World.class.getTypeName(), "VARCHAR(254)");
// Sets - this stores just the name of the set which is another table
mySQLmapping.put(Set.class.getTypeName(), "VARCHAR(254)");
}
public MySQLDatabaseHandler(BSkyBlock plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
super(plugin, type, databaseConnecter);
// Check if the table exists in the database and if not, create it
try {
createSchema();
} catch (IntrospectionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* Creates the table in the database if it doesn't exist already
* @throws IntrospectionException
* @throws SQLException
*/
private void createSchema() throws IntrospectionException, SQLException {
PreparedStatement pstmt = null;
connection = databaseConnecter.createConnection();
try {
String sql = "CREATE TABLE IF NOT EXISTS " + type.getSimpleName() + "(";
for (Field field : type.getDeclaredFields()) {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
plugin.getLogger().info("DEBUG: Field = " + field.getName());
String mapping = mySQLmapping.get(propertyDescriptor.getPropertyType().getTypeName());
if (mapping != null) {
sql += field.getName() + " " + mapping + ",";
} else {
sql += field.getName() + " VARCHAR(254),";
plugin.getLogger().severe("Unknown type! Hoping it'll fit in a string!");
}
}
sql = sql.substring((sql.length()-1), sql.length()) + ")";
plugin.getLogger().info("DEBUG: SQL string = " + sql);
pstmt = connection.prepareStatement(sql.toString());
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
MySQLDatabaseResourceCloser.close(pstmt);
MySQLDatabaseResourceCloser.close(pstmt);
}
}
@Override
protected String createSelectQuery() {
@ -46,7 +130,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
return sb.toString();
}
@Override
protected String createInsertQuery() {
@ -130,9 +214,9 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
*/
@Override
public List<T> selectObjects() throws SQLException,
SecurityException, IllegalArgumentException,
InstantiationException, IllegalAccessException,
IntrospectionException, InvocationTargetException {
SecurityException, IllegalArgumentException,
InstantiationException, IllegalAccessException,
IntrospectionException, InvocationTargetException {
Connection connection = null;
Statement statement = null;
@ -154,13 +238,13 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
@Override
protected T selectObject(String uniqueId) throws InstantiationException,
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, IntrospectionException {
IllegalAccessException, IllegalArgumentException,
InvocationTargetException, IntrospectionException {
// TODO Auto-generated method stub
return null;
}
/**
*
* Creates a list of <T>s filled with values from the provided ResultSet

View File

@ -1,6 +1,7 @@
package us.tastybento.bskyblock.database.mysql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.bukkit.configuration.file.YamlConfiguration;
@ -10,39 +11,52 @@ import us.tastybento.bskyblock.database.DatabaseConnectionSettingsImpl;
public class MySqlDatabaseConnecter implements DatabaseConnecter {
private String connectionUrl;
private DatabaseConnectionSettingsImpl dbSettings;
private Connection connection = null;
/**
* Class for MySQL database connections using the settings provided
* @param dbSettings
*/
public MySqlDatabaseConnecter(
DatabaseConnectionSettingsImpl databaseConnectionSettingsImpl) {
// TODO Auto-generated constructor stub
DatabaseConnectionSettingsImpl dbSettings) {
this.dbSettings = dbSettings;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connectionUrl = "jdbc:mysql://" + dbSettings.getHost() + "/" + dbSettings.getDatabaseName();
}
@Override
public Connection createConnection() throws SQLException {
// TODO Auto-generated method stub
return null;
connection = DriverManager.getConnection(connectionUrl, dbSettings.getUsername(), dbSettings.getPassword());
return connection;
}
@Override
public String getConnectionUrl() {
// TODO Auto-generated method stub
return null;
return connectionUrl;
}
@Override
public String getUniqueId(String tableName) {
// TODO Auto-generated method stub
return null;
// Not used
return "";
}
@Override
public YamlConfiguration loadYamlFile(String string, String key) {
// TODO Auto-generated method stub
// Not used
return null;
}
@Override
public void saveYamlFile(YamlConfiguration yamlFile, String tableName,
String fileName) {
// TODO Auto-generated method stub
// Not used
}

View File

@ -801,4 +801,5 @@ public class Island extends DataObject {
this.uniqueId = uniqueId;
}
}