mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-30 22:53:39 +01:00
MariaDB 10.2.3+ support.
This commit is contained in:
parent
2b0ccb4099
commit
961ca02fa1
@ -2,6 +2,7 @@ package world.bentobox.bentobox.database;
|
|||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.database.json.JSONDatabase;
|
import world.bentobox.bentobox.database.json.JSONDatabase;
|
||||||
|
import world.bentobox.bentobox.database.mariadb.MariaDBDatabase;
|
||||||
import world.bentobox.bentobox.database.mongodb.MongoDBDatabase;
|
import world.bentobox.bentobox.database.mongodb.MongoDBDatabase;
|
||||||
import world.bentobox.bentobox.database.mysql.MySQLDatabase;
|
import world.bentobox.bentobox.database.mysql.MySQLDatabase;
|
||||||
import world.bentobox.bentobox.database.yaml.YamlDatabase;
|
import world.bentobox.bentobox.database.yaml.YamlDatabase;
|
||||||
@ -10,7 +11,7 @@ public interface DatabaseSetup {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of database being used.
|
* Gets the type of database being used.
|
||||||
* Currently supported options are YAML, JSON, MYSQL and MONGODB.
|
* Currently supported options are YAML, JSON, MYSQL, MARIADB and MONGODB.
|
||||||
* Default is YAML.
|
* Default is YAML.
|
||||||
* @return Database type
|
* @return Database type
|
||||||
*/
|
*/
|
||||||
@ -28,8 +29,8 @@ public interface DatabaseSetup {
|
|||||||
YAML(new YamlDatabase()),
|
YAML(new YamlDatabase()),
|
||||||
JSON(new JSONDatabase()),
|
JSON(new JSONDatabase()),
|
||||||
MYSQL(new MySQLDatabase()),
|
MYSQL(new MySQLDatabase()),
|
||||||
|
MARIADB(new MariaDBDatabase()),
|
||||||
MONGODB(new MongoDBDatabase());
|
MONGODB(new MongoDBDatabase());
|
||||||
|
|
||||||
DatabaseSetup database;
|
DatabaseSetup database;
|
||||||
|
|
||||||
DatabaseType(DatabaseSetup database){
|
DatabaseType(DatabaseSetup database){
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package world.bentobox.bentobox.database.mariadb;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
|
||||||
|
import world.bentobox.bentobox.database.DatabaseConnectionSettingsImpl;
|
||||||
|
import world.bentobox.bentobox.database.DatabaseSetup;
|
||||||
|
|
||||||
|
public class MariaDBDatabase implements DatabaseSetup {
|
||||||
|
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see world.bentobox.bentobox.database.BSBDbSetup#getHandler(java.lang.Class)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public <T> AbstractDatabaseHandler<T> getHandler(Class<T> type) {
|
||||||
|
BentoBox plugin = BentoBox.getInstance();
|
||||||
|
return new MariaDBDatabaseHandler<>(plugin, type, new MariaDBDatabaseConnector(new DatabaseConnectionSettingsImpl(
|
||||||
|
plugin.getSettings().getDatabaseHost(),
|
||||||
|
plugin.getSettings().getDatabasePort(),
|
||||||
|
plugin.getSettings().getDatabaseName(),
|
||||||
|
plugin.getSettings().getDatabaseUsername(),
|
||||||
|
plugin.getSettings().getDatabasePassword()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package world.bentobox.bentobox.database.mariadb;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import world.bentobox.bentobox.database.DatabaseConnectionSettingsImpl;
|
||||||
|
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
public class MariaDBDatabaseConnector implements DatabaseConnector {
|
||||||
|
|
||||||
|
private String connectionUrl;
|
||||||
|
private DatabaseConnectionSettingsImpl dbSettings;
|
||||||
|
private Connection connection = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for MariaDB database connections using the settings provided
|
||||||
|
* @param dbSettings - database settings
|
||||||
|
*/
|
||||||
|
MariaDBDatabaseConnector(DatabaseConnectionSettingsImpl dbSettings) {
|
||||||
|
this.dbSettings = dbSettings;
|
||||||
|
connectionUrl = "jdbc:mysql://" + dbSettings.getHost() + ":" + dbSettings.getPort() + "/" + dbSettings.getDatabaseName()
|
||||||
|
+ "?autoReconnect=true&useSSL=false&allowMultiQueries=true";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection createConnection() {
|
||||||
|
try {
|
||||||
|
connection = DriverManager.getConnection(connectionUrl, dbSettings.getUsername(), dbSettings.getPassword());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Bukkit.getLogger().severe("Could not connect to the database! " + e.getMessage());
|
||||||
|
}
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getConnectionUrl() {
|
||||||
|
return connectionUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUniqueId(String tableName) {
|
||||||
|
// Not used
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean uniqueIdExists(String tableName, String key) {
|
||||||
|
// Not used
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeConnection() {
|
||||||
|
if (connection != null) {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Bukkit.getLogger().severe("Could not close MariaDB database connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,186 @@
|
|||||||
|
package world.bentobox.bentobox.database.mariadb;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonSyntaxException;
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||||
|
import world.bentobox.bentobox.database.json.AbstractJSONDatabaseHandler;
|
||||||
|
import world.bentobox.bentobox.database.objects.DataObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Class that inserts a <T> into the corresponding database-table.
|
||||||
|
*
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public class MariaDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connection to the database
|
||||||
|
*/
|
||||||
|
private Connection connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the connection to the database and creation of the initial database schema (tables) for
|
||||||
|
* the class that will be stored.
|
||||||
|
* @param plugin - plugin object
|
||||||
|
* @param type - the type of class to be stored in the database. Must inherit DataObject
|
||||||
|
* @param dbConnecter - authentication details for the database
|
||||||
|
*/
|
||||||
|
MariaDBDatabaseHandler(BentoBox plugin, Class<T> type, DatabaseConnector dbConnecter) {
|
||||||
|
super(plugin, type, dbConnecter);
|
||||||
|
connection = (Connection)dbConnecter.createConnection();
|
||||||
|
// Check if the table exists in the database and if not, create it
|
||||||
|
createSchema();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the table in the database if it doesn't exist already
|
||||||
|
*/
|
||||||
|
private void createSchema() {
|
||||||
|
String sql = "CREATE TABLE IF NOT EXISTS `" +
|
||||||
|
dataObject.getCanonicalName() +
|
||||||
|
"` (json JSON, uniqueId VARCHAR(255) GENERATED ALWAYS AS (JSON_EXTRACT(json, \"$.uniqueId\")), UNIQUE INDEX i (uniqueId))";
|
||||||
|
// Prepare and execute the database statements
|
||||||
|
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
|
||||||
|
pstmt.executeUpdate();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Problem trying to create schema for data object " + dataObject.getCanonicalName() + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<T> loadObjects() {
|
||||||
|
List<T> list = new ArrayList<>();
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("SELECT `json` FROM `");
|
||||||
|
sb.append(dataObject.getCanonicalName());
|
||||||
|
sb.append("`");
|
||||||
|
try (Statement preparedStatement = connection.createStatement()) {
|
||||||
|
try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) {
|
||||||
|
// Load all the results
|
||||||
|
Gson gson = getGson();
|
||||||
|
while (resultSet.next()) {
|
||||||
|
String json = resultSet.getString("json");
|
||||||
|
if (json != null) {
|
||||||
|
try {
|
||||||
|
T gsonResult = gson.fromJson(json, dataObject);
|
||||||
|
if (gsonResult != null) {
|
||||||
|
list.add(gsonResult);
|
||||||
|
}
|
||||||
|
} catch (JsonSyntaxException ex) {
|
||||||
|
plugin.logError("Could not load object " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Could not load objects " + e.getMessage());
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T loadObject(String uniqueId) {
|
||||||
|
String sb = "SELECT `json` FROM `" +
|
||||||
|
dataObject.getCanonicalName() +
|
||||||
|
"` WHERE uniqueId = ? LIMIT 1";
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) {
|
||||||
|
// UniqueId needs to be placed in quotes
|
||||||
|
preparedStatement.setString(1, "\"" + uniqueId + "\"");
|
||||||
|
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
// If there is a result, we only want/need the first one
|
||||||
|
Gson gson = getGson();
|
||||||
|
return gson.fromJson(resultSet.getString("json"), dataObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Could not load object " + uniqueId + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveObject(T instance) {
|
||||||
|
if (!(instance instanceof DataObject)) {
|
||||||
|
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String sb = "INSERT INTO " +
|
||||||
|
"`" +
|
||||||
|
dataObject.getCanonicalName() +
|
||||||
|
"` (json) VALUES (?) ON DUPLICATE KEY UPDATE json = ?";
|
||||||
|
// Replace into is used so that any data in the table will be replaced with updated data
|
||||||
|
// The table name is the canonical name, so that add-ons can be sure of a unique table in the database
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) {
|
||||||
|
Gson gson = getGson();
|
||||||
|
String toStore = gson.toJson(instance);
|
||||||
|
preparedStatement.setString(1, toStore);
|
||||||
|
preparedStatement.setString(2, toStore);
|
||||||
|
preparedStatement.execute();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Could not save object " + instance.getClass().getName() + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteObject(T instance) {
|
||||||
|
if (!(instance instanceof DataObject)) {
|
||||||
|
plugin.logError("This class is not a DataObject: " + instance.getClass().getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String sb = "DELETE FROM `" +
|
||||||
|
dataObject.getCanonicalName() +
|
||||||
|
"` WHERE uniqueId = ?";
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) {
|
||||||
|
Method getUniqueId = dataObject.getMethod("getUniqueId");
|
||||||
|
String uniqueId = (String) getUniqueId.invoke(instance);
|
||||||
|
// UniqueId needs to be placed in quotes
|
||||||
|
preparedStatement.setString(1, "\"" + uniqueId + "\"");
|
||||||
|
preparedStatement.execute();
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.logError("Could not delete object " + instance.getClass().getName() + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean objectExists(String uniqueId) {
|
||||||
|
// Create the query to see if this key exists
|
||||||
|
String query = "SELECT IF ( EXISTS( SELECT * FROM `" +
|
||||||
|
dataObject.getCanonicalName() +
|
||||||
|
"` WHERE `uniqueId` = ?), 1, 0)";
|
||||||
|
|
||||||
|
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
|
||||||
|
// UniqueId needs to be placed in quotes
|
||||||
|
preparedStatement.setString(1, "\"" + uniqueId + "\"");
|
||||||
|
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
||||||
|
if (resultSet.next()) {
|
||||||
|
return resultSet.getBoolean(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Could not check if key exists in database! " + uniqueId + " " + e.getMessage());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
if (connection != null) {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
plugin.logError("Could not close database for some reason");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user