Removal of unsatisfied conditional groups

This commit is contained in:
Rsl1122 2019-08-26 16:33:51 +03:00
parent 49f7286923
commit ca8b89338e
3 changed files with 56 additions and 10 deletions

View File

@ -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";

View File

@ -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
}
};
}
}

View File

@ -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<ExtensionPlayerData> 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";