Skip to content

Commit 7463d4e

Browse files
committed
Fix exception related to CONCAT on SQLite in Extension boolean storage
Affects issues: - Fixed #3514
1 parent 9fa1a94 commit 7463d4e

File tree

5 files changed

+96
-6
lines changed

5 files changed

+96
-6
lines changed

Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StorePlayerBooleanResultTransaction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private List<Integer> selectUnfulfilledProviderIds() {
155155
"FROM plan_extension_providers indb " +
156156
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
157157
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
158-
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
158+
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
159159
" AND indb.plugin_id=unfulfilled.plugin_id" +
160160
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
161161
" AND indb.provided_condition IS NOT NULL";
@@ -181,7 +181,7 @@ private List<Integer> selectUnfulfilledTableIds() {
181181
"FROM plan_extension_providers indb " +
182182
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
183183
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
184-
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
184+
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
185185
" AND indb.plugin_id=unfulfilled.plugin_id" +
186186
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
187187
" AND indb.provided_condition IS NOT NULL";

Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/transactions/results/StoreServerBooleanResultTransaction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ private List<Integer> selectUnfulfilledProviderIds() {
134134
"FROM plan_extension_providers indb " +
135135
"JOIN plan_extension_providers unfulfilled ON unfulfilled.condition_name=" +
136136
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
137-
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
137+
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
138138
" AND indb.plugin_id=unfulfilled.plugin_id" +
139139
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
140140
" AND indb.provided_condition IS NOT NULL";
@@ -166,7 +166,7 @@ private List<Integer> selectUnfulfilledTableIds() {
166166
"FROM plan_extension_providers indb " +
167167
"JOIN plan_extension_tables unfulfilled ON unfulfilled.condition_name=" +
168168
// This gives the unfulfilled condition, eg. if value is true not_condition is unfulfilled.
169-
(value ? "CONCAT('not_', " : "") + "indb.provided_condition" + (value ? ")" : "") +
169+
(value ? Sql.concat(dbType, "'not_'", "indb.provided_condition") : "indb.provided_condition") +
170170
" AND indb.plugin_id=unfulfilled.plugin_id" +
171171
" WHERE indb.id=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
172172
" AND indb.provided_condition IS NOT NULL";

Plan/common/src/main/java/com/djrapitops/plan/storage/database/sql/building/Sql.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package com.djrapitops.plan.storage.database.sql.building;
1818

19+
import com.djrapitops.plan.storage.database.DBType;
1920
import org.apache.commons.text.TextStringBuilder;
2021

2122
import java.sql.PreparedStatement;
@@ -96,6 +97,15 @@ public static void setStringOrNull(PreparedStatement statement, int index, Strin
9697
}
9798
}
9899

100+
public static String concat(DBType dbType, String one, String two) {
101+
if (dbType == DBType.MYSQL) {
102+
return "CONCAT(" + one + ',' + two + ")";
103+
} else if (dbType == DBType.SQLITE) {
104+
return one + " || " + two;
105+
}
106+
return one + two;
107+
}
108+
99109
public abstract String epochSecondToDate(String sql);
100110

101111
public abstract String dateToEpochSecond(String sql);

Plan/common/src/main/java/com/djrapitops/plan/storage/database/transactions/patches/SecurityTableGroupPatch.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
package com.djrapitops.plan.storage.database.transactions.patches;
1818

1919
import com.djrapitops.plan.exceptions.database.DBOpException;
20-
import com.djrapitops.plan.storage.database.DBType;
20+
import com.djrapitops.plan.storage.database.sql.building.Sql;
2121
import com.djrapitops.plan.storage.database.sql.tables.webuser.SecurityTable;
2222
import com.djrapitops.plan.storage.database.sql.tables.webuser.WebGroupTable;
2323

@@ -71,7 +71,7 @@ protected void applyPatch() {
7171
SecurityTable.USERNAME + ',' +
7272
SecurityTable.LINKED_TO + ',' +
7373
SecurityTable.SALT_PASSWORD_HASH + ',' +
74-
"(" + SELECT + WebGroupTable.ID + FROM + WebGroupTable.TABLE_NAME + WHERE + WebGroupTable.NAME + "=" + (dbType == DBType.SQLITE ? "'legacy_level_' || permission_level" : "CONCAT('legacy_level_', permission_level)") + ")" +
74+
"(" + SELECT + WebGroupTable.ID + FROM + WebGroupTable.TABLE_NAME + WHERE + WebGroupTable.NAME + "=" + Sql.concat(dbType, "'legacy_level_'", "permission_level") + ")" +
7575
FROM + tempTableName
7676
);
7777

Plan/common/src/test/java/com/djrapitops/plan/storage/database/queries/ExtensionsDatabaseTest.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,58 @@ default void unsatisfiedPlayerConditionalResultsAreCleaned() {
234234
checkThatPlayerDataExists(ConditionalExtension.condition);
235235
}
236236

237+
@Test
238+
default void unsatisfiedPlayerConditionalResultsAreCleanedCompletely() {
239+
db().executeTransaction(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
240+
241+
ExtensionSvc extensionService = extensionService();
242+
243+
extensionService.register(new RemovingConditionalExtension());
244+
245+
RemovingConditionalExtension.condition = true;
246+
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
247+
248+
List<ExtensionData> ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
249+
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
250+
ExtensionTabData tabData = ofServer.get(0).getTabs().get(0);
251+
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
252+
253+
// Reverse condition
254+
RemovingConditionalExtension.condition = false;
255+
extensionService.updatePlayerValues(playerUUID, TestConstants.PLAYER_ONE_NAME, CallEvents.MANUAL);
256+
257+
ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
258+
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
259+
tabData = ofServer.get(0).getTabs().get(0);
260+
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
261+
}
262+
263+
@Test
264+
default void unsatisfiedServerConditionalResultsAreCleanedCompletely() {
265+
db().executeTransaction(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
266+
267+
ExtensionSvc extensionService = extensionService();
268+
269+
extensionService.register(new RemovingConditionalExtension());
270+
271+
RemovingConditionalExtension.condition = true;
272+
extensionService.updateServerValues(CallEvents.MANUAL);
273+
274+
List<ExtensionData> ofServer = db().query(new ExtensionServerDataQuery(serverUUID()));
275+
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
276+
ExtensionTabData tabData = ofServer.get(0).getTabs().get(0);
277+
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
278+
279+
// Reverse condition
280+
RemovingConditionalExtension.condition = false;
281+
extensionService.updateServerValues(CallEvents.MANUAL);
282+
283+
ofServer = db().query(new ExtensionServerDataQuery(serverUUID()));
284+
assertTrue(ofServer != null && !ofServer.isEmpty() && !ofServer.get(0).getTabs().isEmpty(), "There was no data left");
285+
tabData = ofServer.get(0).getTabs().get(0);
286+
assertEquals(RemovingConditionalExtension.condition, tabData.getString("conditionalValue").isPresent());
287+
}
288+
237289
default void checkThatPlayerDataExists(boolean condition) {
238290
if (condition) { // Condition is true, conditional values exist
239291
List<ExtensionData> ofServer = db().query(new ExtensionPlayerDataQuery(playerUUID)).get(serverUUID());
@@ -437,6 +489,34 @@ public String unconditional() {
437489
}
438490
}
439491

492+
@PluginInfo(name = "ConditionalExtension")
493+
class RemovingConditionalExtension implements DataExtension {
494+
495+
static boolean condition = true;
496+
497+
@BooleanProvider(text = "a boolean", conditionName = "condition")
498+
public boolean isCondition(UUID playerUUID) {
499+
return condition;
500+
}
501+
502+
@StringProvider(text = "Conditional Value")
503+
@Conditional("condition")
504+
public String conditionalValue(UUID playerUUID) {
505+
return "Conditional";
506+
}
507+
508+
@BooleanProvider(text = "a boolean", conditionName = "condition")
509+
public boolean isCondition() {
510+
return condition;
511+
}
512+
513+
@StringProvider(text = "Conditional Value")
514+
@Conditional("condition")
515+
public String conditionalValue() {
516+
return "Conditional";
517+
}
518+
}
519+
440520
@PluginInfo(name = "ServerExtension")
441521
class ServerExtension implements DataExtension {
442522
@NumberProvider(text = "a number")

0 commit comments

Comments
 (0)