Sonar fixes (#3510)

* Remove deprecated code

- RemoveUnsatisfiedConditionalPlayerResultsTransaction.java
- RemoveUnsatisfiedConditionalServerResultsTransaction.java

* Fix apache compress deprecations

- Use org.apache.commons.io.IOUtils instead of org.apache.commons.compress.utils.IOUtils
- Use TarArchiveInputStream#getNextEntry instead of getNextTarEntry

* Rename variable in BukkitPingCounter

* Extract ApiServices from PlanSystem
This commit is contained in:
Aurora Lahtela 2024-03-09 14:43:41 +02:00 committed by GitHub
parent 670ef2aff3
commit de9f9ec5b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 143 additions and 421 deletions

View File

@ -89,9 +89,9 @@ public class BukkitPingCounter extends TaskSystem.Task implements Listener {
startRecording = new ConcurrentHashMap<>(); startRecording = new ConcurrentHashMap<>();
playerHistory = new HashMap<>(); playerHistory = new HashMap<>();
Optional<PingMethod> pingMethod = loadPingMethod(); Optional<PingMethod> loaded = loadPingMethod();
if (pingMethod.isPresent()) { if (loaded.isPresent()) {
this.pingMethod = pingMethod.get(); this.pingMethod = loaded.get();
pingMethodAvailable = true; pingMethodAvailable = true;
} else { } else {
pingMethodAvailable = false; pingMethodAvailable = false;

View File

@ -0,0 +1,119 @@
/*
* 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;
import com.djrapitops.plan.component.ComponentSvc;
import com.djrapitops.plan.delivery.web.ResolverSvc;
import com.djrapitops.plan.delivery.web.ResourceSvc;
import com.djrapitops.plan.extension.ExtensionSvc;
import com.djrapitops.plan.query.QuerySvc;
import com.djrapitops.plan.settings.ListenerSvc;
import com.djrapitops.plan.settings.SchedulerSvc;
import com.djrapitops.plan.settings.SettingsSvc;
import javax.inject.Inject;
import javax.inject.Singleton;
/**
* Breaks up {@link PlanSystem} to be a smaller class.
*
* @author AuroraLS3
*/
@Singleton
public class ApiServices {
private final ComponentSvc componentService;
private final ResolverSvc resolverService;
private final ResourceSvc resourceService;
private final ExtensionSvc extensionService;
private final QuerySvc queryService;
private final ListenerSvc listenerService;
private final SettingsSvc settingsService;
private final SchedulerSvc schedulerService;
@Inject
public ApiServices(
ComponentSvc componentService,
ResolverSvc resolverService,
ResourceSvc resourceService,
ExtensionSvc extensionService,
QuerySvc queryService,
ListenerSvc listenerService,
SettingsSvc settingsService,
SchedulerSvc schedulerService
) {
this.componentService = componentService;
this.resolverService = resolverService;
this.resourceService = resourceService;
this.extensionService = extensionService;
this.queryService = queryService;
this.listenerService = listenerService;
this.settingsService = settingsService;
this.schedulerService = schedulerService;
}
public void register() {
extensionService.register();
componentService.register();
resolverService.register();
resourceService.register();
listenerService.register();
settingsService.register();
schedulerService.register();
queryService.register();
}
public void registerExtensions() {
extensionService.registerExtensions();
}
public void disableExtensionDataUpdates() {
extensionService.disableUpdates();
}
public ComponentSvc getComponentService() {
return componentService;
}
public ResolverSvc getResolverService() {
return resolverService;
}
public ResourceSvc getResourceService() {
return resourceService;
}
public ExtensionSvc getExtensionService() {
return extensionService;
}
public QuerySvc getQueryService() {
return queryService;
}
public ListenerSvc getListenerService() {
return listenerService;
}
public SettingsSvc getSettingsService() {
return settingsService;
}
public SchedulerSvc getSchedulerService() {
return schedulerService;
}
}

View File

@ -17,25 +17,17 @@
package com.djrapitops.plan; package com.djrapitops.plan;
import com.djrapitops.plan.api.PlanAPI; import com.djrapitops.plan.api.PlanAPI;
import com.djrapitops.plan.component.ComponentSvc;
import com.djrapitops.plan.delivery.DeliveryUtilities; import com.djrapitops.plan.delivery.DeliveryUtilities;
import com.djrapitops.plan.delivery.export.ExportSystem; import com.djrapitops.plan.delivery.export.ExportSystem;
import com.djrapitops.plan.delivery.formatting.Formatters; import com.djrapitops.plan.delivery.formatting.Formatters;
import com.djrapitops.plan.delivery.web.ResolverSvc;
import com.djrapitops.plan.delivery.web.ResourceSvc;
import com.djrapitops.plan.delivery.webserver.NonProxyWebserverDisableChecker; import com.djrapitops.plan.delivery.webserver.NonProxyWebserverDisableChecker;
import com.djrapitops.plan.delivery.webserver.WebServerSystem; import com.djrapitops.plan.delivery.webserver.WebServerSystem;
import com.djrapitops.plan.extension.ExtensionSvc;
import com.djrapitops.plan.gathering.cache.CacheSystem; import com.djrapitops.plan.gathering.cache.CacheSystem;
import com.djrapitops.plan.gathering.importing.ImportSystem; import com.djrapitops.plan.gathering.importing.ImportSystem;
import com.djrapitops.plan.gathering.listeners.ListenerSystem; import com.djrapitops.plan.gathering.listeners.ListenerSystem;
import com.djrapitops.plan.identification.ServerInfo; import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.processing.Processing; import com.djrapitops.plan.processing.Processing;
import com.djrapitops.plan.query.QuerySvc;
import com.djrapitops.plan.settings.ConfigSystem; import com.djrapitops.plan.settings.ConfigSystem;
import com.djrapitops.plan.settings.ListenerSvc;
import com.djrapitops.plan.settings.SchedulerSvc;
import com.djrapitops.plan.settings.SettingsSvc;
import com.djrapitops.plan.settings.locale.LocaleSystem; import com.djrapitops.plan.settings.locale.LocaleSystem;
import com.djrapitops.plan.storage.database.DBSystem; import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.PlanFiles;
@ -77,14 +69,7 @@ public class PlanSystem implements SubSystem {
private final ImportSystem importSystem; private final ImportSystem importSystem;
private final ExportSystem exportSystem; private final ExportSystem exportSystem;
private final DeliveryUtilities deliveryUtilities; private final DeliveryUtilities deliveryUtilities;
private final ComponentSvc componentService; private final ApiServices apiServices;
private final ResolverSvc resolverService;
private final ResourceSvc resourceService;
private final ExtensionSvc extensionService;
private final QuerySvc queryService;
private final ListenerSvc listenerService;
private final SettingsSvc settingsService;
private final SchedulerSvc schedulerService;
private final PluginLogger logger; private final PluginLogger logger;
private final ErrorLogger errorLogger; private final ErrorLogger errorLogger;
@ -104,16 +89,9 @@ public class PlanSystem implements SubSystem {
ImportSystem importSystem, ImportSystem importSystem,
ExportSystem exportSystem, ExportSystem exportSystem,
DeliveryUtilities deliveryUtilities, DeliveryUtilities deliveryUtilities,
ComponentSvc componentService,
ResolverSvc resolverService,
ResourceSvc resourceService,
ExtensionSvc extensionService,
QuerySvc queryService,
ListenerSvc listenerService,
SettingsSvc settingsService,
SchedulerSvc schedulerService,
PluginLogger logger, PluginLogger logger,
ErrorLogger errorLogger, ErrorLogger errorLogger,
ApiServices apiServices, // API v5
@SuppressWarnings("deprecation") PlanAPI.PlanAPIHolder apiHolder // Deprecated PlanAPI, backwards compatibility @SuppressWarnings("deprecation") PlanAPI.PlanAPIHolder apiHolder // Deprecated PlanAPI, backwards compatibility
) { ) {
this.files = files; this.files = files;
@ -130,16 +108,9 @@ public class PlanSystem implements SubSystem {
this.importSystem = importSystem; this.importSystem = importSystem;
this.exportSystem = exportSystem; this.exportSystem = exportSystem;
this.deliveryUtilities = deliveryUtilities; this.deliveryUtilities = deliveryUtilities;
this.componentService = componentService;
this.resolverService = resolverService;
this.resourceService = resourceService;
this.extensionService = extensionService;
this.queryService = queryService;
this.listenerService = listenerService;
this.settingsService = settingsService;
this.schedulerService = schedulerService;
this.logger = logger; this.logger = logger;
this.errorLogger = errorLogger; this.errorLogger = errorLogger;
this.apiServices = apiServices;
logger.info("§2"); logger.info("§2");
logger.info("§2 ██▌"); logger.info("§2 ██▌");
@ -162,14 +133,7 @@ public class PlanSystem implements SubSystem {
* Enables the rest of the systems that are not enabled in {@link #enableForCommands()}. * Enables the rest of the systems that are not enabled in {@link #enableForCommands()}.
*/ */
public void enableOtherThanCommands() { public void enableOtherThanCommands() {
extensionService.register(); apiServices.register();
componentService.register();
resolverService.register();
resourceService.register();
listenerService.register();
settingsService.register();
schedulerService.register();
queryService.register();
enableSystems( enableSystems(
processing, processing,
@ -193,7 +157,7 @@ public class PlanSystem implements SubSystem {
)); ));
} }
extensionService.registerExtensions(); apiServices.registerExtensions();
enabled = true; enabled = true;
String javaVersion = System.getProperty("java.specification.version"); String javaVersion = System.getProperty("java.specification.version");
@ -223,7 +187,7 @@ public class PlanSystem implements SubSystem {
enabled = false; enabled = false;
Formatters.clearSingleton(); Formatters.clearSingleton();
extensionService.disableUpdates(); apiServices.disableExtensionDataUpdates();
disableSystems( disableSystems(
taskSystem, taskSystem,
@ -316,12 +280,8 @@ public class PlanSystem implements SubSystem {
return enabled; return enabled;
} }
public ExtensionSvc getExtensionService() { public ApiServices getApiServices() {
return extensionService; return apiServices;
}
public ComponentSvc getComponentService() {
return componentService;
} }
public static long getServerEnableTime() { public static long getServerEnableTime() {

View File

@ -1,195 +0,0 @@
/*
* 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.extension.implementation.storage.transactions.results;
import com.djrapitops.plan.storage.database.DBType;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.sql.tables.extension.*;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
/**
* Transaction to remove older results that violate an updated condition value.
* <p>
* How it works:
* - Select all fulfilled conditions for all players (conditionName when true and not_conditionName when false)
* - Left join with player value and provider tables when uuids match, and when condition matches a condition in the query above.
* - Filter the join query for values where the condition did not match any provided condition in the join (Is null)
* - Delete all player values with IDs that are returned by the left join query after filtering
*
* @author AuroraLS3
* @deprecated Cleanup is now done as part of {@link StorePlayerBooleanResultTransaction}.
*/
@Deprecated(since = "2024-03-02")
public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends ThrowawayTransaction {
private final String providerTable;
private final String playerValueTable;
private final String playerTableValueTable;
private final String tableTable;
private final String groupTable;
public RemoveUnsatisfiedConditionalPlayerResultsTransaction() {
providerTable = ExtensionProviderTable.TABLE_NAME;
playerValueTable = ExtensionPlayerValueTable.TABLE_NAME;
tableTable = ExtensionTableProviderTable.TABLE_NAME;
groupTable = ExtensionGroupsTable.TABLE_NAME;
playerTableValueTable = ExtensionPlayerTableValueTable.TABLE_NAME;
}
@Override
protected void performOperations() {
String selectSatisfiedConditions = getSatisfiedConditionsSQL();
execute(deleteUnsatisfiedValues(selectSatisfiedConditions));
execute(deleteUnsatisfiedGroupValues(selectSatisfiedConditions));
execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions));
}
private String getSatisfiedConditionsSQL() {
String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')';
String selectSatisfiedPositiveConditions = SELECT +
ExtensionProviderTable.PROVIDED_CONDITION + ',' +
ExtensionProviderTable.PLUGIN_ID + ',' +
"u." + UsersTable.ID + " as user_id" +
FROM + providerTable +
INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=" + playerValueTable + "." + ExtensionPlayerTableValueTable.USER_UUID +
WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" +
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
String selectSatisfiedNegativeConditions = SELECT +
reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' +
ExtensionProviderTable.PLUGIN_ID + ',' +
"u." + UsersTable.ID + " as user_id" +
FROM + providerTable +
INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=" + playerValueTable + "." + ExtensionPlayerTableValueTable.USER_UUID +
WHERE + ExtensionPlayerValueTable.BOOLEAN_VALUE + "=?" +
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
// Query contents: Set of provided_conditions
return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1";
}
private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) {
// Query contents:
// id | uuid | q1.uuid | condition | q1.provided_condition
// -- | ---- | ------- | --------- | ---------------------
// 1 | ... | ... | A | A Satisfied condition
// 2 | ... | ... | not_B | not_B Satisfied condition
// 3 | ... | ... | NULL | NULL Satisfied condition
// 4 | ... | ... | B | NULL Unsatisfied condition, filtered to these in WHERE clause.
// 5 | ... | ... | not_C | NULL Unsatisfied condition
String selectUnsatisfiedValueIDs = SELECT + playerValueTable + '.' + ExtensionPlayerValueTable.ID +
FROM + providerTable +
INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=" + playerValueTable + "." + ExtensionPlayerTableValueTable.USER_UUID +
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
" on (" + // Join when uuid and plugin_id match and condition for the group provider is satisfied
"u." + UsersTable.ID + "=q1.user_id" +
AND + ExtensionProviderTable.CONDITION + "=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID + "=q1." + ExtensionProviderTable.PLUGIN_ID +
')' +
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
// Nested query here is required because MySQL limits update statements with nested queries:
// The nested query creates a temporary table that bypasses the same table query-update limit.
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
String sql = DELETE_FROM + playerValueTable +
WHERE + ExtensionPlayerValueTable.ID + " IN (" + SELECT + ExtensionPlayerValueTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true); // Select provided conditions with 'true' value
statement.setBoolean(2, false); // Select negated conditions with 'false' value
}
};
}
private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) {
String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID +
FROM + tableTable +
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
" on (" + // Join when plugin_id matches and condition for the group provider is satisfied
tableTable + '.' + ExtensionTableProviderTable.CONDITION +
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID +
"=q1." + ExtensionProviderTable.PLUGIN_ID +
')' +
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
// Nested query here is required because MySQL limits update statements with nested queries:
// The nested query creates a temporary table that bypasses the same table query-update limit.
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
String deleteValuesSQL = DELETE_FROM + playerTableValueTable +
WHERE + ExtensionPlayerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
return new ExecStatement(deleteValuesSQL) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true); // Select provided conditions with 'true' value
statement.setBoolean(2, false); // Select negated conditions with 'false' value
}
};
}
private Executable deleteUnsatisfiedGroupValues(String selectSatisfiedConditions) {
// plan_extensions_player_groups.id is needed for removal of the correct row.
// The id is known if group_id & uuid are known
// -
// Conditions are in plan_extensions_providers
// selectSatisfiedConditions lists 'provided_condition' Strings
String selectUnsatisfiedIDs = SELECT + groupTable + '.' + ID +
FROM + groupTable +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=" + groupTable + "." + ExtensionGroupsTable.USER_UUID +
INNER_JOIN + providerTable + " on " + providerTable + '.' + ID + '=' + groupTable + '.' + ExtensionGroupsTable.PROVIDER_ID +
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
" on (" + // Join when uuid and plugin_id match and condition for the group provider is satisfied
"u." + UsersTable.ID + "=q1.user_id" +
AND + ExtensionProviderTable.CONDITION +
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID +
"=q1." + ExtensionProviderTable.PLUGIN_ID +
')' +
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
// Nested query here is required because MySQL limits update statements with nested queries:
// The nested query creates a temporary table that bypasses the same table query-update limit.
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
String deleteValuesSQL = DELETE_FROM + groupTable +
WHERE + ID + " IN (" + SELECT + ID + FROM + '(' + selectUnsatisfiedIDs + ") as ids)";
return new ExecStatement(deleteValuesSQL) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true); // Select provided conditions with 'true' value
statement.setBoolean(2, false); // Select negated conditions with 'false' value
}
};
}
}

View File

@ -1,152 +0,0 @@
/*
* 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.extension.implementation.storage.transactions.results;
import com.djrapitops.plan.storage.database.DBType;
import com.djrapitops.plan.storage.database.sql.tables.extension.ExtensionProviderTable;
import com.djrapitops.plan.storage.database.sql.tables.extension.ExtensionServerTableValueTable;
import com.djrapitops.plan.storage.database.sql.tables.extension.ExtensionServerValueTable;
import com.djrapitops.plan.storage.database.sql.tables.extension.ExtensionTableProviderTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
/**
* Transaction to remove older results that violate an updated condition value.
* <p>
* How it works:
* - Select all fulfilled conditions for all servers (conditionName when true and not_conditionName when false)
* - Left join with server value and provider tables when plugin_ids match, and when condition matches a condition in the
* query above. (plugin_ids can be linked to servers)
* - Filter the join query for values where the condition did not match any provided condition in the join (Is null)
* - Delete all server values with IDs that are returned by the left join query after filtering
*
* @author AuroraLS3
* @deprecated Cleanup is now done in {@link StoreServerBooleanResultTransaction}.
*/
@Deprecated(since = "2024-03-02")
public class RemoveUnsatisfiedConditionalServerResultsTransaction extends ThrowawayTransaction {
private final String providerTable;
private final String serverValueTable;
private final String serverTableValueTable;
private final String tableTable;
public RemoveUnsatisfiedConditionalServerResultsTransaction() {
providerTable = ExtensionProviderTable.TABLE_NAME;
serverValueTable = ExtensionServerValueTable.TABLE_NAME;
tableTable = ExtensionTableProviderTable.TABLE_NAME;
serverTableValueTable = ExtensionServerTableValueTable.TABLE_NAME;
}
@Override
protected void performOperations() {
String selectSatisfiedConditions = getSatisfiedConditionsSQL();
execute(deleteUnsatisfiedValues(selectSatisfiedConditions));
execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions));
}
private Executable deleteUnsatisfiedValues(String selectSatisfiedConditions) {
// Query contents:
// id | provider_id | q1.provider_id | condition | q1.provided_condition
// -- | ----------- | -------------- | --------- | ---------------------
// 1 | ... | ... | A | A Satisfied condition
// 2 | ... | ... | not_B | not_B Satisfied condition
// 3 | ... | ... | NULL | NULL Satisfied condition
// 4 | ... | ... | B | NULL Unsatisfied condition, filtered to these in WHERE clause.
// 5 | ... | ... | not_C | NULL Unsatisfied condition
String selectUnsatisfiedValueIDs = SELECT + serverValueTable + '.' + ExtensionServerValueTable.ID +
FROM + providerTable +
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
" on (" +
ExtensionProviderTable.CONDITION + "=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
AND + providerTable + '.' + ExtensionProviderTable.PLUGIN_ID + "=q1." + ExtensionProviderTable.PLUGIN_ID +
')' +
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
// Nested query here is required because MySQL limits update statements with nested queries:
// The nested query creates a temporary table that bypasses the same table query-update limit.
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
String sql = DELETE_FROM + serverValueTable +
WHERE + ExtensionServerValueTable.ID + " IN (" + SELECT + ExtensionServerValueTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true); // Select provided conditions with 'true' value
statement.setBoolean(2, false); // Select negated conditions with 'false' value
}
};
}
private String getSatisfiedConditionsSQL() {
String reversedCondition = dbType == DBType.SQLITE ? "'not_' || " + ExtensionProviderTable.PROVIDED_CONDITION : "CONCAT('not_'," + ExtensionProviderTable.PROVIDED_CONDITION + ')';
String selectSatisfiedPositiveConditions = SELECT +
ExtensionProviderTable.PROVIDED_CONDITION + ',' +
ExtensionProviderTable.PLUGIN_ID +
FROM + providerTable +
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" +
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
String selectSatisfiedNegativeConditions = SELECT +
reversedCondition + " as " + ExtensionProviderTable.PROVIDED_CONDITION + ',' +
ExtensionProviderTable.PLUGIN_ID +
FROM + providerTable +
INNER_JOIN + serverValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionServerValueTable.PROVIDER_ID +
WHERE + ExtensionServerValueTable.BOOLEAN_VALUE + "=?" +
AND + ExtensionProviderTable.PROVIDED_CONDITION + IS_NOT_NULL;
// Query contents: Set of provided_conditions
return '(' + selectSatisfiedPositiveConditions + " UNION " + selectSatisfiedNegativeConditions + ") q1";
}
private Executable deleteUnsatisfiedTableValues(String selectSatisfiedConditions) {
String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID +
FROM + tableTable +
LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled
" on (" +
tableTable + '.' + ExtensionTableProviderTable.CONDITION +
"=q1." + ExtensionProviderTable.PROVIDED_CONDITION +
AND + tableTable + '.' + ExtensionTableProviderTable.PLUGIN_ID +
"=q1." + ExtensionProviderTable.PLUGIN_ID +
')' +
WHERE + "q1." + ExtensionProviderTable.PROVIDED_CONDITION + IS_NULL + // Conditions that were not in the satisfied condition query
AND + ExtensionProviderTable.CONDITION + IS_NOT_NULL; // Ignore values that don't need condition
// Nested query here is required because MySQL limits update statements with nested queries:
// The nested query creates a temporary table that bypasses the same table query-update limit.
// Note: MySQL versions 5.6.7+ might optimize this nested query away leading to an exception.
String deleteValuesSQL = DELETE_FROM + serverTableValueTable +
WHERE + ExtensionServerTableValueTable.TABLE_ID + " IN (" + SELECT + ExtensionTableProviderTable.ID + FROM + '(' + selectUnsatisfiedValueIDs + ") as ids)";
return new ExecStatement(deleteValuesSQL) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, true); // Select provided conditions with 'true' value
statement.setBoolean(2, false); // Select negated conditions with 'false' value
}
};
}
}

View File

@ -26,7 +26,7 @@ import com.maxmind.geoip2.model.CountryResponse;
import com.maxmind.geoip2.record.Country; import com.maxmind.geoip2.record.Country;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.IOUtils;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -119,7 +119,7 @@ public class GeoLite2Geolocator implements Geolocator {
private void findAndCopyFromTar(TarArchiveInputStream tarIn, FileOutputStream fos) throws IOException { private void findAndCopyFromTar(TarArchiveInputStream tarIn, FileOutputStream fos) throws IOException {
// Breadth first search // Breadth first search
Queue<TarArchiveEntry> entries = new ArrayDeque<>(); Queue<TarArchiveEntry> entries = new ArrayDeque<>();
entries.add(tarIn.getNextTarEntry()); entries.add(tarIn.getNextEntry());
while (!entries.isEmpty()) { while (!entries.isEmpty()) {
TarArchiveEntry entry = entries.poll(); TarArchiveEntry entry = entries.poll();
if (entry.isDirectory()) { if (entry.isDirectory()) {
@ -132,7 +132,7 @@ public class GeoLite2Geolocator implements Geolocator {
break; // Found it break; // Found it
} }
TarArchiveEntry next = tarIn.getNextTarEntry(); TarArchiveEntry next = tarIn.getNextEntry();
if (next != null) entries.add(next); if (next != null) entries.add(next);
} }
} }

View File

@ -16,7 +16,7 @@
*/ */
package com.djrapitops.plan.storage.file; package com.djrapitops.plan.storage.file;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.IOUtils;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;

View File

@ -110,8 +110,6 @@ public class DBCleanTask extends TaskSystem.Task {
config.get(TimeSettings.DELETE_PING_DATA_AFTER) config.get(TimeSettings.DELETE_PING_DATA_AFTER)
)); ));
database.executeTransaction(new RemoveDuplicateUserInfoTransaction()); database.executeTransaction(new RemoveDuplicateUserInfoTransaction());
// database.executeTransaction(new RemoveUnsatisfiedConditionalPlayerResultsTransaction());
// database.executeTransaction(new RemoveUnsatisfiedConditionalServerResultsTransaction());
int removed = cleanOldPlayers(database); int removed = cleanOldPlayers(database);
if (removed > 0) { if (removed > 0) {
logger.info(locale.getString(PluginLang.DB_NOTIFY_CLEAN, removed)); logger.info(locale.getString(PluginLang.DB_NOTIFY_CLEAN, removed));

View File

@ -33,7 +33,7 @@ import com.djrapitops.plan.storage.database.transactions.commands.StoreWebUserTr
import com.djrapitops.plan.utilities.PassEncryptUtil; import com.djrapitops.plan.utilities.PassEncryptUtil;
import com.google.gson.Gson; import com.google.gson.Gson;
import extension.FullSystemExtension; import extension.FullSystemExtension;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;

View File

@ -31,7 +31,7 @@ import com.djrapitops.plan.storage.database.transactions.commands.StoreWebUserTr
import com.djrapitops.plan.storage.database.transactions.events.PlayerRegisterTransaction; import com.djrapitops.plan.storage.database.transactions.events.PlayerRegisterTransaction;
import com.djrapitops.plan.storage.database.transactions.webuser.StoreWebGroupTransaction; import com.djrapitops.plan.storage.database.transactions.webuser.StoreWebGroupTransaction;
import com.djrapitops.plan.utilities.PassEncryptUtil; import com.djrapitops.plan.utilities.PassEncryptUtil;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeAll;
@ -201,7 +201,7 @@ class AccessControlTest {
address, address,
TestConstants.VERSION))); TestConstants.VERSION)));
Caller caller = system.getExtensionService().register(new ExtensionsDatabaseTest.PlayerExtension()) Caller caller = system.getApiServices().getExtensionService().register(new ExtensionsDatabaseTest.PlayerExtension())
.orElseThrow(AssertionError::new); .orElseThrow(AssertionError::new);
caller.updatePlayerData(TestConstants.PLAYER_ONE_UUID, TestConstants.PLAYER_ONE_NAME); caller.updatePlayerData(TestConstants.PLAYER_ONE_UUID, TestConstants.PLAYER_ONE_NAME);

View File

@ -70,7 +70,7 @@ class HttpAccessControlTest {
ADDRESS, ADDRESS,
TestConstants.VERSION))); TestConstants.VERSION)));
Caller caller = system.getExtensionService().register(new ExtensionsDatabaseTest.PlayerExtension()) Caller caller = system.getApiServices().getExtensionService().register(new ExtensionsDatabaseTest.PlayerExtension())
.orElseThrow(AssertionError::new); .orElseThrow(AssertionError::new);
caller.updatePlayerData(TestConstants.PLAYER_ONE_UUID, TestConstants.PLAYER_ONE_NAME); caller.updatePlayerData(TestConstants.PLAYER_ONE_UUID, TestConstants.PLAYER_ONE_NAME);

View File

@ -17,7 +17,7 @@
package com.djrapitops.plan.delivery.webserver; package com.djrapitops.plan.delivery.webserver;
import com.djrapitops.plan.delivery.webserver.http.WebServer; import com.djrapitops.plan.delivery.webserver.http.WebServer;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import utilities.HTTPConnector; import utilities.HTTPConnector;
@ -73,13 +73,13 @@ interface HttpsServerTest {
default -> throw new IllegalStateException(address + "| Wrong response code " + responseCode); default -> throw new IllegalStateException(address + "| Wrong response code " + responseCode);
} }
} finally { } finally {
connection.disconnect(); if (connection != null) connection.disconnect();
} }
} }
default String login(String address) throws IOException, KeyManagementException, NoSuchAlgorithmException { default String login(String address) throws IOException, KeyManagementException, NoSuchAlgorithmException {
HttpURLConnection connection = null; HttpURLConnection connection = null;
String cookie = ""; String cookie;
try { try {
connection = connector.getConnection("POST", address + "/auth/login"); connection = connector.getConnection("POST", address + "/auth/login");
connection.setDoOutput(true); connection.setDoOutput(true);

View File

@ -64,9 +64,9 @@ public interface DatabaseTestPreparer {
return system().getDeliveryUtilities(); return system().getDeliveryUtilities();
} }
default ExtensionSvc extensionService() {return system().getExtensionService();} default ExtensionSvc extensionService() {return system().getApiServices().getExtensionService();}
default ComponentSvc componentService() {return system().getComponentService();} default ComponentSvc componentService() {return system().getApiServices().getComponentService();}
QueryFilters queryFilters(); QueryFilters queryFilters();

View File

@ -223,8 +223,6 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
ConditionalExtension.condition = false; ConditionalExtension.condition = false;
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL); extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
// db().executeTransaction(new RemoveUnsatisfiedConditionalPlayerResultsTransaction());
// Check that the wanted data exists // Check that the wanted data exists
checkThatPlayerDataExists(ConditionalExtension.condition); checkThatPlayerDataExists(ConditionalExtension.condition);
@ -232,8 +230,6 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
ConditionalExtension.condition = false; ConditionalExtension.condition = false;
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL); extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
// db().executeTransaction(new RemoveUnsatisfiedConditionalPlayerResultsTransaction());
// Check that the wanted data exists // Check that the wanted data exists
checkThatPlayerDataExists(ConditionalExtension.condition); checkThatPlayerDataExists(ConditionalExtension.condition);
} }
@ -276,8 +272,6 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
ConditionalExtension.condition = false; ConditionalExtension.condition = false;
extensionService.updateServerValues(CallEvents.MANUAL); extensionService.updateServerValues(CallEvents.MANUAL);
// db().executeTransaction(new RemoveUnsatisfiedConditionalServerResultsTransaction());
// Check that the wanted data exists // Check that the wanted data exists
checkThatServerDataExists(ConditionalExtension.condition); checkThatServerDataExists(ConditionalExtension.condition);
@ -285,8 +279,6 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
ConditionalExtension.condition = false; ConditionalExtension.condition = false;
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL); extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
// db().executeTransaction(new RemoveUnsatisfiedConditionalServerResultsTransaction());
// Check that the wanted data exists // Check that the wanted data exists
checkThatServerDataExists(ConditionalExtension.condition); checkThatServerDataExists(ConditionalExtension.condition);
} }