From ca8b89338e575ece1230a3ae30d19d7a74841055 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 26 Aug 2019 16:33:51 +0300 Subject: [PATCH] Removal of unsatisfied conditional groups --- .../djrapitops/plan/db/sql/parsing/Sql.java | 3 ++ ...edConditionalPlayerResultsTransaction.java | 51 ++++++++++++++++--- .../com/djrapitops/plan/db/DatabaseTest.java | 12 +++-- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java index 5e48e3c6e..36911b499 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/parsing/Sql.java @@ -22,6 +22,9 @@ import java.util.concurrent.TimeUnit; * Duplicate String reducing utility class for SQL language Strings. */ public interface Sql { + String ID = "id"; + String P_UUID = "uuid"; + String INT = "integer"; String DOUBLE = "double"; String LONG = "bigint"; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java index 8bbda64c4..d223917db 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/RemoveUnsatisfiedConditionalPlayerResultsTransaction.java @@ -20,10 +20,7 @@ import com.djrapitops.plan.db.DBType; import com.djrapitops.plan.db.access.ExecStatement; import com.djrapitops.plan.db.access.Executable; import com.djrapitops.plan.db.access.transactions.Transaction; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerTableValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionPlayerValueTable; -import com.djrapitops.plan.db.sql.tables.ExtensionProviderTable; -import com.djrapitops.plan.db.sql.tables.ExtensionTableProviderTable; +import com.djrapitops.plan.db.sql.tables.*; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -47,11 +44,15 @@ public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transa private final String playerValueTable; private final String playerTableValueTable; private final String tableTable; + private final String groupTable; + private final String playerGroupTable; public RemoveUnsatisfiedConditionalPlayerResultsTransaction() { providerTable = ExtensionProviderTable.TABLE_NAME; playerValueTable = ExtensionPlayerValueTable.TABLE_NAME; tableTable = ExtensionTableProviderTable.TABLE_NAME; + groupTable = ExtensionGroupsTable.TABLE_NAME; + playerGroupTable = ExtensionPlayerGroupsTable.TABLE_NAME; playerTableValueTable = ExtensionPlayerTableValueTable.TABLE_NAME; } @@ -60,6 +61,7 @@ public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transa String selectSatisfiedConditions = getSatisfiedConditionsSQL(); execute(deleteUnsatisfiedValues(selectSatisfiedConditions)); + execute(deleteUnsatisfiedGroupValues(selectSatisfiedConditions)); execute(deleteUnsatisfiedTableValues(selectSatisfiedConditions)); } @@ -100,7 +102,7 @@ public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transa FROM + providerTable + INNER_JOIN + playerValueTable + " on " + providerTable + '.' + ExtensionProviderTable.ID + "=" + ExtensionPlayerValueTable.PROVIDER_ID + LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + + " on (" + // Join when uuid and plugin_id match and condition for the group provider is satisfied playerValueTable + '.' + ExtensionPlayerValueTable.USER_UUID + "=q1." + ExtensionPlayerValueTable.USER_UUID + AND + ExtensionProviderTable.CONDITION + @@ -130,7 +132,7 @@ public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transa String selectUnsatisfiedValueIDs = SELECT + ExtensionTableProviderTable.ID + FROM + tableTable + LEFT_JOIN + selectSatisfiedConditions + // Left join to preserve values that don't have their condition fulfilled - " on (" + + " 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 + @@ -153,4 +155,41 @@ public class RemoveUnsatisfiedConditionalPlayerResultsTransaction extends Transa } }; } + + 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 + playerGroupTable + '.' + ID + + FROM + playerGroupTable + + INNER_JOIN + groupTable + " on " + groupTable + '.' + ID + '=' + playerGroupTable + '.' + ExtensionPlayerGroupsTable.GROUP_ID + + 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 + playerGroupTable + '.' + P_UUID + + "=q1." + P_UUID + + 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 " + playerGroupTable + + 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 + } + }; + } } \ No newline at end of file diff --git a/Plan/common/src/test/java/com/djrapitops/plan/db/DatabaseTest.java b/Plan/common/src/test/java/com/djrapitops/plan/db/DatabaseTest.java index 5d233efca..428b28942 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/db/DatabaseTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/db/DatabaseTest.java @@ -51,10 +51,7 @@ import com.djrapitops.plan.db.access.transactions.init.RemoveDuplicateUserInfoTr import com.djrapitops.plan.db.patches.Patch; import com.djrapitops.plan.db.sql.parsing.Sql; import com.djrapitops.plan.db.tasks.DBCleanTask; -import com.djrapitops.plan.extension.CallEvents; -import com.djrapitops.plan.extension.DataExtension; -import com.djrapitops.plan.extension.ExtensionService; -import com.djrapitops.plan.extension.ExtensionServiceImplementation; +import com.djrapitops.plan.extension.*; import com.djrapitops.plan.extension.annotation.*; import com.djrapitops.plan.extension.icon.Color; import com.djrapitops.plan.extension.icon.Icon; @@ -1275,6 +1272,7 @@ public interface DatabaseTest { } default void checkThatPlayerDataExists(boolean condition) { + // TODO Add Group data to this test if (condition) { // Condition is true, conditional values exist List ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID()); assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left"); @@ -1463,6 +1461,12 @@ public interface DatabaseTest { return "Reversed"; } + @GroupProvider(text = "Conditional Group") + @Conditional("condition") + public Group[] conditionalGroups(UUID playerUUID) { + return new Group[]{() -> "Group"}; + } + @StringProvider(text = "Unconditional") public String unconditional() { return "unconditional";