mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-28 13:45:14 +01:00
Added AbstractJSONDatabaseHandler<T>
This commit is contained in:
parent
f0c4cb710c
commit
77258b2770
@ -0,0 +1,52 @@
|
|||||||
|
package world.bentobox.bentobox.database;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.api.flags.Flag;
|
||||||
|
import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter;
|
||||||
|
import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter;
|
||||||
|
import world.bentobox.bentobox.database.mysql.adapters.PotionEffectTypeAdapter;
|
||||||
|
import world.bentobox.bentobox.database.mysql.adapters.WorldAdapter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class that handles insert/select-operations into/from a database.
|
||||||
|
* It also provides {@link #getGson()}.
|
||||||
|
*
|
||||||
|
* @author Poslovitch
|
||||||
|
*
|
||||||
|
* @param <T>
|
||||||
|
*/
|
||||||
|
public abstract class AbstractJSONDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param plugin
|
||||||
|
* @param type The type of the objects that should be created and filled with
|
||||||
|
* values from the database or inserted into the database
|
||||||
|
* @param databaseConnector Contains the settings to create a connection to the database
|
||||||
|
*/
|
||||||
|
protected AbstractJSONDatabaseHandler(BentoBox plugin, Class<T> type, DatabaseConnector databaseConnector) {
|
||||||
|
super(plugin, type, databaseConnector);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Gson getGson() {
|
||||||
|
// excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose
|
||||||
|
// enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys
|
||||||
|
GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
|
||||||
|
// Register adapters
|
||||||
|
builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ;
|
||||||
|
builder.registerTypeAdapter(World.class, new WorldAdapter(plugin));
|
||||||
|
builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin));
|
||||||
|
builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter());
|
||||||
|
// Keep null in the database
|
||||||
|
builder.serializeNulls();
|
||||||
|
// Allow characters like < or > without escaping them
|
||||||
|
builder.disableHtmlEscaping();
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
}
|
@ -5,12 +5,8 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.conversions.Bson;
|
import org.bson.conversions.Bson;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.potion.PotionEffectType;
|
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.mongodb.client.MongoCollection;
|
import com.mongodb.client.MongoCollection;
|
||||||
import com.mongodb.client.MongoDatabase;
|
import com.mongodb.client.MongoDatabase;
|
||||||
import com.mongodb.client.model.FindOneAndReplaceOptions;
|
import com.mongodb.client.model.FindOneAndReplaceOptions;
|
||||||
@ -19,13 +15,8 @@ import com.mongodb.client.model.Indexes;
|
|||||||
import com.mongodb.util.JSON;
|
import com.mongodb.util.JSON;
|
||||||
|
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.flags.Flag;
|
import world.bentobox.bentobox.database.AbstractJSONDatabaseHandler;
|
||||||
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
|
|
||||||
import world.bentobox.bentobox.database.DatabaseConnector;
|
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter;
|
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter;
|
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.PotionEffectTypeAdapter;
|
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.WorldAdapter;
|
|
||||||
import world.bentobox.bentobox.database.objects.DataObject;
|
import world.bentobox.bentobox.database.objects.DataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -37,7 +28,7 @@ import world.bentobox.bentobox.database.objects.DataObject;
|
|||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public class MongoDBDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
public class MongoDBDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
|
||||||
|
|
||||||
private static final String UNIQUEID = "uniqueId";
|
private static final String UNIQUEID = "uniqueId";
|
||||||
private static final String MONGO_ID = "_id";
|
private static final String MONGO_ID = "_id";
|
||||||
@ -56,36 +47,18 @@ public class MongoDBDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
public MongoDBDatabaseHandler(BentoBox plugin, Class<T> type, DatabaseConnector dbConnecter) {
|
public MongoDBDatabaseHandler(BentoBox plugin, Class<T> type, DatabaseConnector dbConnecter) {
|
||||||
super(plugin, type, dbConnecter);
|
super(plugin, type, dbConnecter);
|
||||||
this.dbConnecter = dbConnecter;
|
this.dbConnecter = dbConnecter;
|
||||||
/*
|
|
||||||
Connection to the database
|
// Connection to the database
|
||||||
*/
|
|
||||||
MongoDatabase database = (MongoDatabase) dbConnecter.createConnection();
|
MongoDatabase database = (MongoDatabase) dbConnecter.createConnection();
|
||||||
collection = database.getCollection(dataObject.getCanonicalName());
|
collection = database.getCollection(dataObject.getCanonicalName());
|
||||||
IndexOptions indexOptions = new IndexOptions().unique(true);
|
IndexOptions indexOptions = new IndexOptions().unique(true);
|
||||||
collection.createIndex(Indexes.text(UNIQUEID), indexOptions);
|
collection.createIndex(Indexes.text(UNIQUEID), indexOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the GSON builder
|
|
||||||
private Gson getGSON() {
|
|
||||||
// excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose
|
|
||||||
// enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys
|
|
||||||
GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
|
|
||||||
// Register adapters
|
|
||||||
builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ;
|
|
||||||
builder.registerTypeAdapter(World.class, new WorldAdapter(plugin));
|
|
||||||
builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin));
|
|
||||||
builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter());
|
|
||||||
// Keep null in the database
|
|
||||||
builder.serializeNulls();
|
|
||||||
// Allow characters like < or > without escaping them
|
|
||||||
builder.disableHtmlEscaping();
|
|
||||||
return builder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<T> loadObjects() {
|
public List<T> loadObjects() {
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
for (Document document : collection.find(new Document())) {
|
for (Document document : collection.find(new Document())) {
|
||||||
// The deprecated serialize option does not have a viable alternative without involving a huge amount of custom code
|
// The deprecated serialize option does not have a viable alternative without involving a huge amount of custom code
|
||||||
String json = JSON.serialize(document);
|
String json = JSON.serialize(document);
|
||||||
@ -98,7 +71,7 @@ public class MongoDBDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
@Override
|
@Override
|
||||||
public T loadObject(String uniqueId) {
|
public T loadObject(String uniqueId) {
|
||||||
Document doc = collection.find(new Document(MONGO_ID, uniqueId)).limit(1).first();
|
Document doc = collection.find(new Document(MONGO_ID, uniqueId)).limit(1).first();
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
String json = JSON.serialize(doc).replaceFirst(MONGO_ID, UNIQUEID);
|
String json = JSON.serialize(doc).replaceFirst(MONGO_ID, UNIQUEID);
|
||||||
// load single object
|
// load single object
|
||||||
return gson.fromJson(json, dataObject);
|
return gson.fromJson(json, dataObject);
|
||||||
@ -112,7 +85,7 @@ public class MongoDBDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
}
|
}
|
||||||
DataObject dataObj = (DataObject)instance;
|
DataObject dataObj = (DataObject)instance;
|
||||||
try {
|
try {
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
String toStore = gson.toJson(instance);
|
String toStore = gson.toJson(instance);
|
||||||
// Change uniqueId to _id
|
// Change uniqueId to _id
|
||||||
toStore = toStore.replaceFirst(UNIQUEID, MONGO_ID);
|
toStore = toStore.replaceFirst(UNIQUEID, MONGO_ID);
|
||||||
|
@ -19,6 +19,7 @@ import com.google.gson.GsonBuilder;
|
|||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.api.flags.Flag;
|
import world.bentobox.bentobox.api.flags.Flag;
|
||||||
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
|
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
|
||||||
|
import world.bentobox.bentobox.database.AbstractJSONDatabaseHandler;
|
||||||
import world.bentobox.bentobox.database.DatabaseConnector;
|
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter;
|
import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter;
|
||||||
import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter;
|
import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter;
|
||||||
@ -34,7 +35,7 @@ import world.bentobox.bentobox.database.objects.DataObject;
|
|||||||
*
|
*
|
||||||
* @param <T>
|
* @param <T>
|
||||||
*/
|
*/
|
||||||
public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connection to the database
|
* Connection to the database
|
||||||
@ -71,23 +72,6 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the GSON builder
|
|
||||||
private Gson getGSON() {
|
|
||||||
// excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose
|
|
||||||
// enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys
|
|
||||||
GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization();
|
|
||||||
// Register adapters
|
|
||||||
builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ;
|
|
||||||
builder.registerTypeAdapter(World.class, new WorldAdapter(plugin));
|
|
||||||
builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin));
|
|
||||||
builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter());
|
|
||||||
// Keep null in the database
|
|
||||||
builder.serializeNulls();
|
|
||||||
// Allow characters like < or > without escaping them
|
|
||||||
builder.disableHtmlEscaping();
|
|
||||||
return builder.create();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<T> loadObjects() {
|
public List<T> loadObjects() {
|
||||||
List<T> list = new ArrayList<>();
|
List<T> list = new ArrayList<>();
|
||||||
@ -98,7 +82,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
try (Statement preparedStatement = connection.createStatement()) {
|
try (Statement preparedStatement = connection.createStatement()) {
|
||||||
try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) {
|
try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) {
|
||||||
// Load all the results
|
// Load all the results
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
list.add(gson.fromJson(resultSet.getString("json"), dataObject));
|
list.add(gson.fromJson(resultSet.getString("json"), dataObject));
|
||||||
}
|
}
|
||||||
@ -120,7 +104,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
try (ResultSet resultSet = preparedStatement.executeQuery()) {
|
||||||
if (resultSet.next()) {
|
if (resultSet.next()) {
|
||||||
// If there is a result, we only want/need the first one
|
// If there is a result, we only want/need the first one
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
return gson.fromJson(resultSet.getString("json"), dataObject);
|
return gson.fromJson(resultSet.getString("json"), dataObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +127,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
|||||||
// Replace into is used so that any data in the table will be replaced with updated data
|
// 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
|
// 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)) {
|
try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) {
|
||||||
Gson gson = getGSON();
|
Gson gson = getGson();
|
||||||
String toStore = gson.toJson(instance);
|
String toStore = gson.toJson(instance);
|
||||||
preparedStatement.setString(1, toStore);
|
preparedStatement.setString(1, toStore);
|
||||||
preparedStatement.setString(2, toStore);
|
preparedStatement.setString(2, toStore);
|
||||||
|
Loading…
Reference in New Issue
Block a user