mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-24 11:45:31 +01:00
Added JSON (flatfile) database type
This commit is contained in:
parent
10000b71f6
commit
db5ac2d0e5
@ -2,6 +2,7 @@ package world.bentobox.bentobox.database;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.database.flatfile.FlatFileDatabase;
|
||||
import world.bentobox.bentobox.database.json.JSONDatabase;
|
||||
import world.bentobox.bentobox.database.mongodb.MongoDBDatabase;
|
||||
import world.bentobox.bentobox.database.mysql.MySQLDatabase;
|
||||
|
||||
@ -9,7 +10,7 @@ public interface DatabaseSetup {
|
||||
|
||||
/**
|
||||
* Gets the type of database being used.
|
||||
* Currently supported options are FLATFILE, MYSQL and MONGODB.
|
||||
* Currently supported options are FLATFILE, JSON, MYSQL and MONGODB.
|
||||
* Default is FLATFILE.
|
||||
* @return Database type
|
||||
*/
|
||||
@ -24,6 +25,7 @@ public interface DatabaseSetup {
|
||||
|
||||
enum DatabaseType {
|
||||
FLATFILE(new FlatFileDatabase()),
|
||||
JSON(new JSONDatabase()),
|
||||
MYSQL(new MySQLDatabase()),
|
||||
MONGODB(new MongoDBDatabase());
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
package world.bentobox.bentobox.database.json;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.database.AbstractDatabaseHandler;
|
||||
import world.bentobox.bentobox.database.DatabaseSetup;
|
||||
|
||||
public class JSONDatabase implements DatabaseSetup {
|
||||
|
||||
@Override
|
||||
public <T> AbstractDatabaseHandler<T> getHandler(Class<T> dataObjectClass) {
|
||||
return new JSONDatabaseHandler<>(BentoBox.getInstance(), dataObjectClass, new JSONDatabaseConnector(BentoBox.getInstance()));
|
||||
}
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package world.bentobox.bentobox.database.json;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.UUID;
|
||||
|
||||
public class JSONDatabaseConnector implements DatabaseConnector {
|
||||
|
||||
private static final int MAX_LOOPS = 100;
|
||||
private static final String DATABASE_FOLDER_NAME = "database";
|
||||
private final BentoBox plugin;
|
||||
private final File dataFolder;
|
||||
|
||||
public JSONDatabaseConnector(BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
dataFolder = new File(plugin.getDataFolder(), DATABASE_FOLDER_NAME);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUniqueId(String tableName) {
|
||||
UUID uuid = UUID.randomUUID();
|
||||
File file = new File(dataFolder, tableName + File.separator + uuid.toString() + ".json");
|
||||
int limit = 0;
|
||||
while (file.exists() && limit++ < MAX_LOOPS) {
|
||||
uuid = UUID.randomUUID();
|
||||
file = new File(dataFolder, tableName + File.separator + uuid.toString() + ".json");
|
||||
}
|
||||
return uuid.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean uniqueIdExists(String tableName, String key) {
|
||||
File file = new File(dataFolder, tableName + File.separator + key + ".json");
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object createConnection() {
|
||||
return null; // Not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionUrl() {
|
||||
return null; // Not used
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeConnection() {
|
||||
// Not used
|
||||
}
|
||||
}
|
@ -0,0 +1,153 @@
|
||||
package world.bentobox.bentobox.database.json;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.database.DatabaseConnector;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
public class JSONDatabaseHandler<T> extends AbstractJSONDatabaseHandler<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
|
||||
*/
|
||||
JSONDatabaseHandler(BentoBox plugin, Class<T> type, DatabaseConnector databaseConnector) {
|
||||
super(plugin, type, databaseConnector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<T> loadObjects() {
|
||||
// In this case, all the objects of a specific type are being loaded.
|
||||
List<T> list = new ArrayList<>();
|
||||
|
||||
// The path is the simple name of the class
|
||||
String path = dataObject.getSimpleName();
|
||||
|
||||
// The database folder name is in the plugin's data folder
|
||||
File dataFolder = new File(plugin.getDataFolder(), DATABASE_FOLDER_NAME);
|
||||
// The folder for the objects (tables in database terminology) is here
|
||||
File tableFolder = new File(dataFolder, path);
|
||||
if (!tableFolder.exists()) {
|
||||
// Nothing there...
|
||||
tableFolder.mkdirs();
|
||||
}
|
||||
// Load each object from the file system, filtered, non-null
|
||||
for (File file: Objects.requireNonNull(tableFolder.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(".json")))) {
|
||||
try {
|
||||
list.add(getGson().fromJson(new FileReader(file), dataObject));
|
||||
} catch (FileNotFoundException e) {
|
||||
plugin.logError("Could not load file '" + file.getName() + "': File not found.");
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T loadObject(String uniqueId) {
|
||||
// Objects are loaded from a folder named after the simple name of the class being stored
|
||||
String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName();
|
||||
|
||||
String fileName = path + File.separator + uniqueId;
|
||||
if (!fileName.endsWith(".json")) {
|
||||
fileName = fileName + ".json";
|
||||
}
|
||||
|
||||
T result = null;
|
||||
try {
|
||||
result = getGson().fromJson(new FileReader(new File(plugin.getDataFolder(), fileName)), dataObject);
|
||||
} catch (FileNotFoundException e) {
|
||||
plugin.logError("Could not load file '" + fileName + "': File not found.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
|
||||
String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName();
|
||||
|
||||
// Obtain the value of uniqueId within the instance (which must be a DataObject)
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
|
||||
Method method = propertyDescriptor.getReadMethod();
|
||||
String fileName = (String) method.invoke(instance);
|
||||
|
||||
File tableFolder = new File(plugin.getDataFolder(), path);
|
||||
File file = new File(tableFolder, fileName);
|
||||
if (!tableFolder.exists()) {
|
||||
tableFolder.mkdirs();
|
||||
}
|
||||
|
||||
String toStore = getGson().toJson(instance);
|
||||
|
||||
try {
|
||||
File tmpFile = new File(tableFolder, fileName + ".bak");
|
||||
if (file.exists()) {
|
||||
// Make a backup of file
|
||||
Files.copy(file.toPath(), tmpFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
FileWriter fileWriter = new FileWriter(file);
|
||||
fileWriter.write(toStore);
|
||||
fileWriter.close();
|
||||
Files.deleteIfExists(tmpFile.toPath());
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not save json file: " + path + " " + fileName + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteObject(T instance) throws IllegalAccessException, InvocationTargetException, IntrospectionException {
|
||||
// Obtain the value of uniqueId within the instance (which must be a DataObject)
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
|
||||
Method method = propertyDescriptor.getReadMethod();
|
||||
String fileName = (String) method.invoke(instance);
|
||||
|
||||
// The filename of the JSON file is the value of uniqueId field plus .json. Sometimes the .json is already appended.
|
||||
if (!fileName.endsWith(".json")) {
|
||||
fileName = fileName + ".json";
|
||||
}
|
||||
|
||||
// Get the database and table folders
|
||||
File dataFolder = new File(plugin.getDataFolder(), DATABASE_FOLDER_NAME);
|
||||
File tableFolder = new File(dataFolder, dataObject.getSimpleName());
|
||||
if (tableFolder.exists()) {
|
||||
// Obtain the file and delete it
|
||||
File file = new File(tableFolder, fileName);
|
||||
try {
|
||||
Files.delete(file.toPath());
|
||||
} catch (IOException e) {
|
||||
plugin.logError("Could not delete json database object! " + file.getName() + " - " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean objectExists(String uniqueId) {
|
||||
// Check if the uniqueId (key) exists in the file system
|
||||
return databaseConnector.uniqueIdExists(dataObject.getSimpleName(), uniqueId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
// Not used
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user