Added async saving to YAML and MYSQL

Both seem to work fine, but probably need more real-world testing.
This commit is contained in:
tastybento 2019-01-12 18:18:22 -08:00
parent 501c3257ed
commit 7854187448
3 changed files with 38 additions and 28 deletions

View File

@ -9,6 +9,8 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.Bukkit;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
@ -128,11 +130,18 @@ public class MySQLDatabaseHandler<T> extends AbstractJSONDatabaseHandler<T> {
"`" +
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
Gson gson = getGson();
String toStore = gson.toJson(instance);
if (plugin.isEnabled()) {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> store(instance, toStore, sb));
} else {
store(instance, toStore, sb);
}
}
private void store(T instance, String toStore, String sb) {
try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) {
Gson gson = getGson();
String toStore = gson.toJson(instance);
preparedStatement.setString(1, toStore);
preparedStatement.setString(2, toStore);
preparedStatement.execute();

View File

@ -6,8 +6,9 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
@ -18,6 +19,8 @@ import java.util.UUID;
import org.bukkit.configuration.file.YamlConfiguration;
import com.google.common.base.Charsets;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.DatabaseConnector;
@ -78,29 +81,21 @@ public class YamlDatabaseConnector implements DatabaseConnector {
return config;
}
public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName, Map<String, String> commentMap) {
if (!fileName.endsWith(YML)) {
fileName = fileName + YML;
}
public void saveYamlFile(String data, String tableName, String fileName, Map<String, String> commentMap) {
String name = fileName.endsWith(YML) ? fileName : fileName + YML;
File tableFolder = new File(plugin.getDataFolder(), tableName);
File file = new File(tableFolder, fileName);
File file = new File(tableFolder, name);
if (!tableFolder.exists()) {
tableFolder.mkdirs();
}
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);
}
yamlConfig.save(file.toPath().toString());
Files.deleteIfExists(tmpFile.toPath());
} catch (Exception e) {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) {
writer.write(data);
} catch (IOException e) {
plugin.logError("Could not save yml file: " + tableName + " " + fileName + " " + e.getMessage());
return;
}
if (commentMap != null && !commentMap.isEmpty()) {
commentFile(new File(tableFolder, fileName), commentMap);
commentFile(new File(tableFolder, name), commentMap);
}
}

View File

@ -22,6 +22,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.MemorySection;
@ -307,18 +308,14 @@ public class YamlDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
// This is the Yaml Configuration that will be used and saved at the end
YamlConfiguration config = new YamlConfiguration();
// The file name of the Yaml file.
String filename = "";
String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName();
// Comments for the file
Map<String, String> yamlComments = new HashMap<>();
// Only allow storing in an arbitrary place if it is a config object. Otherwise it is in the database
StoreAt storeAt = instance.getClass().getAnnotation(StoreAt.class);
if (storeAt != null) {
path = storeAt.path();
filename = storeAt.filename();
}
String path = storeAt == null ? DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName() : storeAt.path();
String filename = storeAt == null ? "" : storeAt.filename();
// See if there are any top-level comments
// See if there are multiple comments
ConfigComment.Line comments = instance.getClass().getAnnotation(ConfigComment.Line.class);
@ -443,7 +440,16 @@ public class YamlDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
throw new IllegalArgumentException("No uniqueId in class");
}
((YamlDatabaseConnector)databaseConnector).saveYamlFile(config, path, filename, yamlComments);
// Save
String name = filename;
String data = config.saveToString();
if (plugin.isEnabled()) {
// Async
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> ((YamlDatabaseConnector)databaseConnector).saveYamlFile(data, path, name, yamlComments));
} else {
// Sync for shutdown
((YamlDatabaseConnector)databaseConnector).saveYamlFile(data, path, name, yamlComments);
}
}
private void setComment(ConfigComment comment, YamlConfiguration config, Map<String, String> yamlComments, String parent) {