mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-31 16:01:00 +01:00
Fix exception related to CONCAT on SQLite in Extension boolean storage
Affects issues: - Fixed #3514
This commit is contained in:
parent
9fa1a94301
commit
7463d4e440
@ -155,7 +155,7 @@ public class StorePlayerBooleanResultTransaction extends ThrowawayTransaction {
|
|||||||
"FROM plan_extension_providers indb " +
|
"FROM plan_extension_providers indb " +
|
||||||
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
|
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
|
||||||
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
||||||
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
|
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
|
||||||
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
||||||
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
||||||
" AND indb.provided_condition IS NOT NULL";
|
" AND indb.provided_condition IS NOT NULL";
|
||||||
@ -181,7 +181,7 @@ public class StorePlayerBooleanResultTransaction extends ThrowawayTransaction {
|
|||||||
"FROM plan_extension_providers indb " +
|
"FROM plan_extension_providers indb " +
|
||||||
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
|
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
|
||||||
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
||||||
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
|
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
|
||||||
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
||||||
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
||||||
" AND indb.provided_condition IS NOT NULL";
|
" AND indb.provided_condition IS NOT NULL";
|
||||||
|
@ -134,7 +134,7 @@ public class StoreServerBooleanResultTransaction extends ThrowawayTransaction {
|
|||||||
"FROM plan_extension_providers indb " +
|
"FROM plan_extension_providers indb " +
|
||||||
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
|
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
|
||||||
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
||||||
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
|
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
|
||||||
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
||||||
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
||||||
" AND indb.provided_condition IS NOT NULL";
|
" AND indb.provided_condition IS NOT NULL";
|
||||||
@ -166,7 +166,7 @@ public class StoreServerBooleanResultTransaction extends ThrowawayTransaction {
|
|||||||
"FROM plan_extension_providers indb " +
|
"FROM plan_extension_providers indb " +
|
||||||
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
|
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
|
||||||
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
|
||||||
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
|
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
|
||||||
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
" AND indb.plugin_id=unfulfilled.plugin_id" +
|
||||||
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
|
||||||
" AND indb.provided_condition IS NOT NULL";
|
" AND indb.provided_condition IS NOT NULL";
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.djrapitops.plan.storage.database.sql.building;
|
package com.djrapitops.plan.storage.database.sql.building;
|
||||||
|
|
||||||
|
import com.djrapitops.plan.storage.database.DBType;
|
||||||
import org.apache.commons.text.TextStringBuilder;
|
import org.apache.commons.text.TextStringBuilder;
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
@ -96,6 +97,15 @@ public abstract class Sql {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String concat(DBType dbType, String one, String two) {
|
||||||
|
if (dbType == DBType.MYSQL) {
|
||||||
|
return "CONCAT(" + one + ',' + two + ")";
|
||||||
|
} else if (dbType == DBType.SQLITE) {
|
||||||
|
return one + " || " + two;
|
||||||
|
}
|
||||||
|
return one + two;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract String epochSecondToDate(String sql);
|
public abstract String epochSecondToDate(String sql);
|
||||||
|
|
||||||
public abstract String dateToEpochSecond(String sql);
|
public abstract String dateToEpochSecond(String sql);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package com.djrapitops.plan.storage.database.transactions.patches;
|
package com.djrapitops.plan.storage.database.transactions.patches;
|
||||||
|
|
||||||
import com.djrapitops.plan.exceptions.database.DBOpException;
|
import com.djrapitops.plan.exceptions.database.DBOpException;
|
||||||
import com.djrapitops.plan.storage.database.DBType;
|
import com.djrapitops.plan.storage.database.sql.building.Sql;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.webuser.SecurityTable;
|
import com.djrapitops.plan.storage.database.sql.tables.webuser.SecurityTable;
|
||||||
import com.djrapitops.plan.storage.database.sql.tables.webuser.WebGroupTable;
|
import com.djrapitops.plan.storage.database.sql.tables.webuser.WebGroupTable;
|
||||||
|
|
||||||
@ -71,7 +71,7 @@ public class SecurityTableGroupPatch extends Patch {
|
|||||||
SecurityTable.USERNAME + ',' +
|
SecurityTable.USERNAME + ',' +
|
||||||
SecurityTable.LINKED_TO + ',' +
|
SecurityTable.LINKED_TO + ',' +
|
||||||
SecurityTable.SALT_PASSWORD_HASH + ',' +
|
SecurityTable.SALT_PASSWORD_HASH + ',' +
|
||||||
"(" + SELECT + WebGroupTable.ID + FROM + WebGroupTable.TABLE_NAME + WHERE + WebGroupTable.NAME + "=" + (dbType == DBType.SQLITE ? "'legacy_level_' || permission_level" : "CONCAT('legacy_level_', permission_level)") + ")" +
|
"(" + SELECT + WebGroupTable.ID + FROM + WebGroupTable.TABLE_NAME + WHERE + WebGroupTable.NAME + "=" + Sql.concat(dbType, "'legacy_level_'", "permission_level") + ")" +
|
||||||
FROM + tempTableName
|
FROM + tempTableName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -234,6 +234,58 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
|
|||||||
checkThatPlayerDataExists(ConditionalExtension.condition);
|
checkThatPlayerDataExists(ConditionalExtension.condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
default void unsatisfiedPlayerConditionalResultsAreCleanedCompletely() {
|
||||||
|
db().executeTransaction(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
|
||||||
|
|
||||||
|
ExtensionSvc extensionService = extensionService();
|
||||||
|
|
||||||
|
extensionService.register(new RemovingConditionalExtension());
|
||||||
|
|
||||||
|
RemovingConditionalExtension.condition = true;
|
||||||
|
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
|
||||||
|
|
||||||
|
List<ExtensionData> ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
|
||||||
|
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
|
||||||
|
ExtensionTabData tabData = ofServer.get(0).getTabs().get(0);
|
||||||
|
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
|
||||||
|
|
||||||
|
// Reverse condition
|
||||||
|
RemovingConditionalExtension.condition = false;
|
||||||
|
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
|
||||||
|
|
||||||
|
ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
|
||||||
|
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
|
||||||
|
tabData = ofServer.get(0).getTabs().get(0);
|
||||||
|
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
default void unsatisfiedServerConditionalResultsAreCleanedCompletely() {
|
||||||
|
db().executeTransaction(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
|
||||||
|
|
||||||
|
ExtensionSvc extensionService = extensionService();
|
||||||
|
|
||||||
|
extensionService.register(new RemovingConditionalExtension());
|
||||||
|
|
||||||
|
RemovingConditionalExtension.condition = true;
|
||||||
|
extensionService.updateServerValues(CallEvents.MANUAL);
|
||||||
|
|
||||||
|
List<ExtensionData> ofServer = db().query(new ExtensionServerDataQuery(serverUUID()));
|
||||||
|
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
|
||||||
|
ExtensionTabData tabData = ofServer.get(0).getTabs().get(0);
|
||||||
|
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
|
||||||
|
|
||||||
|
// Reverse condition
|
||||||
|
RemovingConditionalExtension.condition = false;
|
||||||
|
extensionService.updateServerValues(CallEvents.MANUAL);
|
||||||
|
|
||||||
|
ofServer = db().query(new ExtensionServerDataQuery(serverUUID()));
|
||||||
|
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
|
||||||
|
tabData = ofServer.get(0).getTabs().get(0);
|
||||||
|
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
|
||||||
|
}
|
||||||
|
|
||||||
default void checkThatPlayerDataExists(boolean condition) {
|
default void checkThatPlayerDataExists(boolean condition) {
|
||||||
if (condition) { // Condition is true, conditional values exist
|
if (condition) { // Condition is true, conditional values exist
|
||||||
List<ExtensionData> ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
|
List<ExtensionData> ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
|
||||||
@ -437,6 +489,34 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PluginInfo(name = "ConditionalExtension")
|
||||||
|
class RemovingConditionalExtension implements DataExtension {
|
||||||
|
|
||||||
|
static boolean condition = true;
|
||||||
|
|
||||||
|
@BooleanProvider(text = "a boolean", conditionName = "condition")
|
||||||
|
public boolean isCondition(UUID playerUUID) {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@StringProvider(text = "Conditional Value")
|
||||||
|
@Conditional("condition")
|
||||||
|
public String conditionalValue(UUID playerUUID) {
|
||||||
|
return "Conditional";
|
||||||
|
}
|
||||||
|
|
||||||
|
@BooleanProvider(text = "a boolean", conditionName = "condition")
|
||||||
|
public boolean isCondition() {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@StringProvider(text = "Conditional Value")
|
||||||
|
@Conditional("condition")
|
||||||
|
public String conditionalValue() {
|
||||||
|
return "Conditional";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PluginInfo(name = "ServerExtension")
|
@PluginInfo(name = "ServerExtension")
|
||||||
class ServerExtension implements DataExtension {
|
class ServerExtension implements DataExtension {
|
||||||
@NumberProvider(text = "a number")
|
@NumberProvider(text = "a number")
|
||||||
|
Loading…
Reference in New Issue
Block a user