Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -301,15 +301,15 @@ private void loadCustomPlaceholders(Connection conn, ObjectCache cache, String p

@Override
public void updateData(ObjectCache cache, boolean quitServer) {
long saveVersion = cache.getModificationVersion();
ObjectCache.SaveRevision saveRevision = cache.captureSaveRevision(quitServer);
CompletableFuture.runAsync(() -> {
try {
boolean saved;
synchronized (cache.getSaveLock()) {
saved = saveAll(cache);
saved = saveSections(cache, saveRevision);
}
if (saved) {
cache.markSaved(saveVersion);
cache.markSaved(saveRevision);
}
} finally {
if (quitServer) {
Expand All @@ -321,24 +321,61 @@ public void updateData(ObjectCache cache, boolean quitServer) {
}, DatabaseExecutor.getExecutor());
}

private boolean saveAll(ObjectCache cache) {
boolean saved = saveUseTimes(cache);
saved &= saveFavourites(cache);
if (!UltimateShop.freeVersion) {
saved &= savePlaceholders(cache);
saved &= saveCustomPlaceholders(cache);
private boolean saveSections(ObjectCache cache, ObjectCache.SaveRevision saveRevision) {
if (!saveRevision.hasSections()) {
return true;
}

try (Connection conn = dataSource.getConnection()) {
boolean originalAutoCommit = conn.getAutoCommit();
try {
conn.setAutoCommit(false);
if (saveRevision.includes(ObjectCache.DirtySection.USE_TIMES)) {
saveUseTimes(conn, cache);
}
if (saveRevision.includes(ObjectCache.DirtySection.FAVOURITES)) {
saveFavourites(conn, cache);
}
if (!UltimateShop.freeVersion) {
if (saveRevision.includes(ObjectCache.DirtySection.RANDOM_PLACEHOLDERS)) {
savePlaceholders(conn, cache);
}
if (saveRevision.includes(ObjectCache.DirtySection.CUSTOM_PLACEHOLDERS)) {
saveCustomPlaceholders(conn, cache);
}
}
conn.commit();
return true;
} catch (SQLException | RuntimeException exception) {
try {
conn.rollback();
} catch (SQLException rollbackException) {
exception.addSuppressed(rollbackException);
}
exception.printStackTrace();
return false;
} finally {
try {
if (!conn.isClosed() && conn.getAutoCommit() != originalAutoCommit) {
conn.setAutoCommit(originalAutoCommit);
}
} catch (SQLException exception) {
exception.printStackTrace();
}
}
} catch (SQLException exception) {
exception.printStackTrace();
return false;
}
return saved;
}

private boolean saveFavourites(ObjectCache cache) {
private void saveFavourites(Connection conn, ObjectCache cache) throws SQLException {
if (cache.isServer()) {
return true;
return;
}
String playerUUID = cache.getPlayer().getUniqueId().toString();

try (Connection conn = dataSource.getConnection();
PreparedStatement deletePs = conn.prepareStatement(dialect.deleteFavourites());
try (PreparedStatement deletePs = conn.prepareStatement(dialect.deleteFavourites());
PreparedStatement insertPs = conn.prepareStatement(dialect.insertFavourite())) {

deletePs.setString(1, playerUUID);
Expand All @@ -364,22 +401,17 @@ private boolean saveFavourites(ObjectCache cache) {
if (dialect.supportBatch()) {
insertPs.executeBatch();
}
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}

private boolean saveUseTimes(ObjectCache cache) {
private void saveUseTimes(Connection conn, ObjectCache cache) throws SQLException {
String playerUUID = cache.isServer()
? "Global-Server"
: cache.getPlayer().getUniqueId().toString();

String sql = dialect.upsertUseTimes();

try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
try (PreparedStatement ps = conn.prepareStatement(sql)) {

for (Map.Entry<UseTimesStorageKey, ObjectUseTimesCache> entry : cache.getSharedUseTimesCache().entrySet()) {
writeUseTimesCache(ps, playerUUID, entry.getKey(), entry.getValue());
Expand All @@ -388,10 +420,6 @@ private boolean saveUseTimes(ObjectCache cache) {
if (dialect.supportBatch()) {
ps.executeBatch();
}
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}

Expand Down Expand Up @@ -465,15 +493,14 @@ private void fillUseTimes(PreparedStatement ps,
}
}

private boolean savePlaceholders(ObjectCache cache) {
private void savePlaceholders(Connection conn, ObjectCache cache) throws SQLException {
String playerUUID = cache.isServer()
? "Global-Server"
: cache.getPlayer().getUniqueId().toString();

String sql = dialect.upsertRandomPlaceholder();

try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
try (PreparedStatement ps = conn.prepareStatement(sql)) {

for (ObjectRandomPlaceholderCache ph
: cache.getRandomPlaceholderCache().values()) {
Expand All @@ -497,22 +524,17 @@ private boolean savePlaceholders(ObjectCache cache) {
if (dialect.supportBatch()) {
ps.executeBatch();
}
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}

private boolean saveCustomPlaceholders(ObjectCache cache) {
private void saveCustomPlaceholders(Connection conn, ObjectCache cache) throws SQLException {
String playerUUID = cache.isServer()
? "Global-Server"
: cache.getPlayer().getUniqueId().toString();

String sql = dialect.upsertCustomPlaceholder();

try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
try (PreparedStatement ps = conn.prepareStatement(sql)) {

for (Map.Entry<ObjectCustomPlaceholder, String> entry
: cache.getCustomPlaceholderCache().entrySet()) {
Expand All @@ -531,10 +553,6 @@ private boolean saveCustomPlaceholders(ObjectCache cache) {
if (dialect.supportBatch()) {
ps.executeBatch();
}
return true;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}

Expand Down Expand Up @@ -568,14 +586,14 @@ private void loadHistory(ObjectUseTimesCache cache, String sellHistoryJson, Stri

@Override
public void updateDataOnDisable(ObjectCache cache, boolean disable) {
long saveVersion = cache.getModificationVersion();
ObjectCache.SaveRevision saveRevision = cache.captureSaveRevision(true);
try {
boolean saved;
synchronized (cache.getSaveLock()) {
saved = saveAll(cache);
saved = saveSections(cache, saveRevision);
}
if (saved) {
cache.markSaved(saveVersion);
cache.markSaved(saveRevision);
}
} finally {
CacheManager.cacheManager.removeObjectCache(cache);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
Expand Down Expand Up @@ -44,7 +49,7 @@ private void loadData(ObjectCache cache) {
if (!file.exists()) {
YamlConfiguration config = new YamlConfiguration();
config.set("playerName", cache.isServer() ? "global" : cache.getPlayer().getName());
config.save(file);
writeAtomically(config, file);
}
} catch (IOException e) {
ErrorManager.errorManager.sendErrorMessage(
Expand Down Expand Up @@ -151,15 +156,15 @@ private void loadData(ObjectCache cache) {

@Override
public void updateData(ObjectCache cache, boolean quitServer) {
long saveVersion = cache.getModificationVersion();
ObjectCache.SaveRevision saveRevision = cache.captureSaveRevision(true);
CompletableFuture.runAsync(() -> {
try {
boolean saved;
synchronized (cache.getSaveLock()) {
saved = saveData(cache);
}
if (saved) {
cache.markSaved(saveVersion);
cache.markSaved(saveRevision);
}
} finally {
if (quitServer) {
Expand All @@ -173,14 +178,14 @@ public void updateData(ObjectCache cache, boolean quitServer) {

@Override
public void updateDataOnDisable(ObjectCache cache, boolean disable) {
long saveVersion = cache.getModificationVersion();
ObjectCache.SaveRevision saveRevision = cache.captureSaveRevision(true);
try {
boolean saved;
synchronized (cache.getSaveLock()) {
saved = saveData(cache);
}
if (saved) {
cache.markSaved(saveVersion);
cache.markSaved(saveRevision);
}
} finally {
CacheManager.cacheManager.removeObjectCache(cache);
Expand Down Expand Up @@ -232,14 +237,45 @@ private boolean saveData(ObjectCache cache) {
}

try {
config.save(file);
writeAtomically(config, file);
return true;
} catch (IOException e) {
ErrorManager.errorManager.sendErrorMessage("§cError: Can not save data file: " + file.getName() + "!");
return false;
}
}

private void writeAtomically(YamlConfiguration config, File file) throws IOException {
Path temporaryFile = Files.createTempFile(
dataDir.toPath(),
file.getName() + ".",
".tmp"
);
try {
Files.writeString(temporaryFile, config.saveToString(), StandardCharsets.UTF_8);
try {
Files.move(
temporaryFile,
file.toPath(),
StandardCopyOption.ATOMIC_MOVE,
StandardCopyOption.REPLACE_EXISTING
);
} catch (AtomicMoveNotSupportedException ignored) {
Files.move(
temporaryFile,
file.toPath(),
StandardCopyOption.REPLACE_EXISTING
);
}
} finally {
try {
Files.deleteIfExists(temporaryFile);
} catch (IOException ignored) {
// Keep the original write failure if cleanup also fails.
}
}
}

private void writeUseTimesCache(ConfigurationSection root,
UseTimesStorageKey key,
ObjectUseTimesCache cache) {
Expand Down
Loading
Loading