Refactored SettingsTable#storeConfig to a transaction

This commit is contained in:
Rsl1122 2019-02-14 17:59:35 +02:00
parent edcd7bd53a
commit 1cf8daf6c2
8 changed files with 124 additions and 92 deletions

View File

@ -0,0 +1,100 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.db.access.transactions;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.access.Executable;
import com.djrapitops.plan.db.access.HasMoreThanZeroQueryStatement;
import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.sql.tables.SettingsTable;
import com.djrapitops.plan.system.settings.config.Config;
import com.djrapitops.plan.system.settings.config.ConfigWriter;
import org.apache.commons.text.TextStringBuilder;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.UUID;
/**
* Transaction to store a server's configuration file in the database.
*
* @author Rsl1122
*/
public class StoreConfigTransaction extends Transaction {
private final UUID serverUUID;
private final long lastModified;
private final String configSettings;
public StoreConfigTransaction(UUID serverUUID, Config config, long lastModified) {
this.serverUUID = serverUUID;
this.configSettings = extractConfigSettingLines(config);
this.lastModified = lastModified;
}
private String extractConfigSettingLines(Config config) {
TextStringBuilder configTextBuilder = new TextStringBuilder();
List<String> lines = new ConfigWriter().parseLines(config);
configTextBuilder.appendWithSeparators(lines, "\n");
return configTextBuilder.toString();
}
@Override
protected void performOperations() {
if (query(isConfigStored())) {
execute(updateConfig());
} else {
execute(insertConfig());
}
}
private Query<Boolean> isConfigStored() {
String sql = "SELECT COUNT(1) as c FROM " + SettingsTable.TABLE_NAME +
" WHERE " + SettingsTable.SERVER_UUID + "=? LIMIT 1";
return new HasMoreThanZeroQueryStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
};
}
private Executable updateConfig() {
return new ExecStatement(SettingsTable.UPDATE_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, configSettings);
statement.setLong(2, lastModified);
statement.setString(3, serverUUID.toString());
statement.setString(4, configSettings);
}
};
}
private Executable insertConfig() {
return new ExecStatement(SettingsTable.INSERT_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
statement.setLong(2, lastModified);
statement.setString(3, configSettings);
}
};
}
}

View File

@ -18,19 +18,15 @@ package com.djrapitops.plan.db.sql.tables;
import com.djrapitops.plan.db.DBType;
import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.ExecStatement;
import com.djrapitops.plan.db.access.QueryStatement;
import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
import com.djrapitops.plan.db.sql.parsing.Sql;
import com.djrapitops.plan.system.settings.config.Config;
import com.djrapitops.plan.system.settings.config.ConfigReader;
import com.djrapitops.plan.system.settings.config.ConfigWriter;
import org.apache.commons.text.TextStringBuilder;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.Scanner;
import java.util.UUID;
@ -49,6 +45,16 @@ public class SettingsTable extends Table {
public static final String UPDATED = "updated";
public static final String CONFIG_CONTENT = "content";
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" +
SERVER_UUID + ", " +
UPDATED + ", " +
CONFIG_CONTENT + ") VALUES (?,?,?)";
public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET " +
CONFIG_CONTENT + "=?," +
UPDATED + "=? WHERE " +
SERVER_UUID + "=? AND " +
CONFIG_CONTENT + "!=?";
public SettingsTable(SQLDB db) {
super(TABLE_NAME, db);
}
@ -62,76 +68,6 @@ public class SettingsTable extends Table {
.toString();
}
/**
* Place a config in the database for this server.
* <p>
* Only one config is stored per server uuid.
*
* @param serverUUID UUID of the server.
* @param config Config of the server.
* @param lastModified Epoch ms the config file was last modified.
*/
public void storeConfig(UUID serverUUID, Config config, long lastModified) {
TextStringBuilder configTextBuilder = new TextStringBuilder();
List<String> lines = new ConfigWriter().parseLines(config);
configTextBuilder.appendWithSeparators(lines, "\n");
String configSettings = configTextBuilder.toString();
if (isConfigStored(serverUUID)) {
updateConfig(serverUUID, configSettings, lastModified);
} else {
insertConfig(serverUUID, configSettings, lastModified);
}
}
private void insertConfig(UUID serverUUID, String configSettings, long lastModified) {
String sql = "INSERT INTO " + tableName + " (" +
SERVER_UUID + ", " +
UPDATED + ", " +
CONFIG_CONTENT + ") VALUES (?,?,?)";
execute(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
statement.setLong(2, lastModified);
statement.setString(3, configSettings);
}
});
}
private void updateConfig(UUID serverUUID, String configSettings, long lastModified) {
String sql = "UPDATE " + tableName + " SET " +
CONFIG_CONTENT + "=?," +
UPDATED + "=? WHERE " +
SERVER_UUID + "=? AND " +
CONFIG_CONTENT + "!=?";
execute(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, configSettings);
statement.setLong(2, lastModified);
statement.setString(3, serverUUID.toString());
statement.setString(4, configSettings);
}
});
}
private boolean isConfigStored(UUID serverUUID) {
String sql = "SELECT " + SERVER_UUID + " FROM " + tableName + " WHERE " + SERVER_UUID + "=? LIMIT 1";
return query(new QueryStatement<Boolean>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Boolean processResults(ResultSet set) throws SQLException {
return set.next() && set.getString(SERVER_UUID).equals(serverUUID.toString());
}
});
}
/**
* Fetch a config that was placed into the database after a certain epoch ms.
*

View File

@ -22,7 +22,6 @@ import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.data.store.objects.Nickname;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
import java.util.List;
import java.util.Map;
@ -84,6 +83,4 @@ public interface SaveOperations {
@Deprecated
void setAsUninstalled(UUID serverUUID);
@Deprecated
void saveConfig(UUID serverUUID, Config config, long lastModified);
}

View File

@ -24,7 +24,6 @@ import com.djrapitops.plan.db.access.queries.LargeStoreQueries;
import com.djrapitops.plan.db.access.transactions.Transaction;
import com.djrapitops.plan.system.database.databases.operation.SaveOperations;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
import java.util.Collection;
import java.util.List;
@ -161,8 +160,4 @@ public class SQLSaveOps extends SQLOps implements SaveOperations {
serverTable.setAsUninstalled(serverUUID);
}
@Override
public void saveConfig(UUID serverUUID, Config config, long lastModified) {
settingsTable.storeConfig(serverUUID, config, lastModified);
}
}

View File

@ -19,6 +19,7 @@ package com.djrapitops.plan.system.settings.network;
import com.djrapitops.plan.api.exceptions.EnableException;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.file.PlanFiles;
@ -204,7 +205,7 @@ public class NetworkSettingManager implements SubSystem {
try (ConfigReader reader = new ConfigReader(file.toPath())) {
Config config = reader.read();
database.save().saveConfig(serverUUID, config, file.lastModified());
database.executeTransaction(new StoreConfigTransaction(serverUUID, config, file.lastModified()));
String serverName = config.getNode(PluginSettings.SERVER_NAME.getPath()).map(ConfigNode::getString).orElse("Unknown");
logger.debug("Server config '" + serverName + "' in db now up to date.");
} catch (IOException e) {

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.system.settings.network;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction;
import com.djrapitops.plan.system.SubSystem;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.file.PlanFiles;
@ -109,7 +110,7 @@ public class ServerSettingsManager implements SubSystem {
try (ConfigReader reader = new ConfigReader(file.toPath())) {
Config config = reader.read();
database.save().saveConfig(serverInfo.getServerUUID(), config, file.lastModified());
database.executeTransaction(new StoreConfigTransaction(serverInfo.getServerUUID(), config, file.lastModified()));
logger.debug("Server config saved to database.");
} catch (IOException e) {
throw new UncheckedIOException(e);

View File

@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.system.tasks.server;
import com.djrapitops.plan.db.access.transactions.StoreConfigTransaction;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.file.PlanFiles;
import com.djrapitops.plan.system.info.server.ServerInfo;
@ -58,7 +59,7 @@ public class ConfigStoreTask extends AbsRunnable {
@Override
public void run() {
long lastModified = files.getConfigFile().lastModified();
dbSystem.getDatabase().save().saveConfig(serverInfo.getServerUUID(), config, lastModified);
dbSystem.getDatabase().executeTransaction(new StoreConfigTransaction(serverInfo.getServerUUID(), config, lastModified));
logger.debug("Config Store Task - Config in db now up to date.");
cancel();
}

View File

@ -37,7 +37,10 @@ import com.djrapitops.plan.db.access.queries.objects.*;
import com.djrapitops.plan.db.access.transactions.*;
import com.djrapitops.plan.db.access.transactions.events.*;
import com.djrapitops.plan.db.patches.Patch;
import com.djrapitops.plan.db.sql.tables.*;
import com.djrapitops.plan.db.sql.tables.ServerTable;
import com.djrapitops.plan.db.sql.tables.SessionsTable;
import com.djrapitops.plan.db.sql.tables.TPSTable;
import com.djrapitops.plan.db.sql.tables.UsersTable;
import com.djrapitops.plan.system.PlanSystem;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.info.server.Server;
@ -951,10 +954,9 @@ public abstract class CommonDBTest {
public void configIsStoredInTheDatabase() {
PlanConfig config = system.getConfigSystem().getConfig();
SettingsTable settingsTable = db.getSettingsTable();
settingsTable.storeConfig(serverUUID, config, System.currentTimeMillis());
db.executeTransaction(new StoreConfigTransaction(serverUUID, config, System.currentTimeMillis()));
Optional<Config> foundConfig = settingsTable.fetchNewerConfig(0, serverUUID);
Optional<Config> foundConfig = db.getSettingsTable().fetchNewerConfig(0, serverUUID);
assertTrue(foundConfig.isPresent());
assertEquals(config, foundConfig.get());
}
@ -966,10 +968,9 @@ public abstract class CommonDBTest {
PlanConfig config = system.getConfigSystem().getConfig();
SettingsTable settingsTable = db.getSettingsTable();
settingsTable.storeConfig(serverUUID, config, System.currentTimeMillis());
db.executeTransaction(new StoreConfigTransaction(serverUUID, config, System.currentTimeMillis()));
assertFalse(settingsTable.fetchNewerConfig(savedMs, serverUUID).isPresent());
assertFalse(db.getSettingsTable().fetchNewerConfig(savedMs, serverUUID).isPresent());
}
@Test