From 9677de701a10209ab75de41607511ebcfc345405 Mon Sep 17 00:00:00 2001 From: Rsl1122 Date: Mon, 26 Aug 2019 18:15:15 +0300 Subject: [PATCH] Query for groups on player page --- .../results/ExtensionStringData.java | 7 +- .../results/ExtensionTabData.java | 7 + .../queries/ExtensionPlayerDataQuery.java | 4 +- .../queries/ExtensionPlayerGroupsQuery.java | 179 ++++++++++++++++++ .../ExtensionServerPlayerDataTableQuery.java | 4 +- .../com/djrapitops/plan/db/DatabaseTest.java | 6 +- 6 files changed, 199 insertions(+), 8 deletions(-) create mode 100644 Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerGroupsQuery.java diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java index c2e3274f0..71dbd6df9 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionStringData.java @@ -28,7 +28,7 @@ public class ExtensionStringData implements ExtensionData { private final ExtensionDescriptive descriptive; private final boolean playerName; - private final String value; + private String value; public ExtensionStringData(ExtensionDescriptive descriptive, boolean playerName, String value) { this.descriptive = descriptive; @@ -44,4 +44,9 @@ public class ExtensionStringData implements ExtensionData { String withColors = Html.swapColorCodesToSpan(value); return !playerName ? withColors : Html.LINK.parse(PlanAPI.getInstance().getPlayerInspectPageLink(value), withColors); } + + ExtensionStringData concatenate(ExtensionStringData other) { + value += ", " + other.value; + return this; + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java index b46624713..b8a1b3de7 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/results/ExtensionTabData.java @@ -176,6 +176,13 @@ public class ExtensionTabData implements Comparable { return this; } + public Factory putGroupData(ExtensionStringData extensionStringData) { + String name = extensionStringData.getDescriptive().getName(); + ExtensionStringData previous = data.stringData.get(name); + data.stringData.put(name, previous != null ? previous.concatenate(extensionStringData) : extensionStringData); + return this; + } + public Factory putTableData(ExtensionTableData extensionTableData) { data.tableData.add(extensionTableData); return this; diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java index d1140ab49..a2617903f 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerDataQuery.java @@ -68,8 +68,8 @@ public class ExtensionPlayerDataQuery implements Query> extensionsByServerUUID = db.query(ExtensionInformationQueries.allExtensions()); Map extensionDataByPluginID = db.query(fetchIncompletePlayerDataByPluginID()); - Map tableDataByPluginID = db.query(new ExtensionPlayerTablesQuery(playerUUID)); - combine(extensionDataByPluginID, tableDataByPluginID); + combine(extensionDataByPluginID, db.query(new ExtensionPlayerTablesQuery(playerUUID))); + combine(extensionDataByPluginID, db.query(new ExtensionPlayerGroupsQuery(playerUUID))); return flatMapByServerUUID(extensionsByServerUUID, extensionDataByPluginID); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerGroupsQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerGroupsQuery.java new file mode 100644 index 000000000..65df1095b --- /dev/null +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionPlayerGroupsQuery.java @@ -0,0 +1,179 @@ +/* + * 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 . + */ +package com.djrapitops.plan.extension.implementation.storage.queries; + +import com.djrapitops.plan.db.SQLDB; +import com.djrapitops.plan.db.access.Query; +import com.djrapitops.plan.db.access.QueryStatement; +import com.djrapitops.plan.db.sql.tables.*; +import com.djrapitops.plan.extension.ElementOrder; +import com.djrapitops.plan.extension.icon.Color; +import com.djrapitops.plan.extension.icon.Family; +import com.djrapitops.plan.extension.icon.Icon; +import com.djrapitops.plan.extension.implementation.TabInformation; +import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; +import com.djrapitops.plan.extension.implementation.results.ExtensionStringData; +import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; +import com.djrapitops.plan.extension.implementation.results.player.ExtensionPlayerData; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; + +import static com.djrapitops.plan.db.sql.parsing.Sql.*; + +/** + * Query player's Groups by Plugin ID inside ExtensionPlayerData objects. + *

+ * - Group names are represented as a String value, concatenated to a single one. + * - String values are placed into Tabs they belong to + * - Tabs are placed to plugin they belong to + * - The map is returned + * + * @author Rsl1122 + */ +public class ExtensionPlayerGroupsQuery implements Query> { + + private final UUID playerUUID; + + public ExtensionPlayerGroupsQuery(UUID playerUUID) { + this.playerUUID = playerUUID; + } + + @Override + public Map executeQuery(SQLDB db) { + return db.query(fetchGroupsByPluginID()); + } + + private Query> fetchGroupsByPluginID() { + String sql = SELECT + + "v1." + ExtensionGroupsTable.GROUP_NAME + " as group_name," + + "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + + "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + + "p1." + ExtensionProviderTable.TEXT + " as text," + + "t1." + ExtensionTabTable.TAB_NAME + " as tab_name," + + "t1." + ExtensionTabTable.TAB_PRIORITY + " as tab_priority," + + "t1." + ExtensionTabTable.ELEMENT_ORDER + " as element_order," + + "i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," + + "i1." + ExtensionIconTable.FAMILY + " as provider_icon_family," + + "i1." + ExtensionIconTable.COLOR + " as provider_icon_color," + + "i2." + ExtensionIconTable.ICON_NAME + " as tab_icon_name," + + "i2." + ExtensionIconTable.FAMILY + " as tab_icon_family," + + "i2." + ExtensionIconTable.COLOR + " as tab_icon_color" + + FROM + ExtensionGroupsTable.TABLE_NAME + " v1" + + INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionPlayerValueTable.PROVIDER_ID + + LEFT_JOIN + ExtensionTabTable.TABLE_NAME + " t1 on t1." + ExtensionTabTable.ID + "=p1." + ExtensionProviderTable.TAB_ID + + LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID + + LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i2 on i2." + ExtensionIconTable.ID + "=p1." + ExtensionTabTable.ICON_ID + + WHERE + ExtensionGroupsTable.USER_UUID + "=?" + + AND + "p1." + ExtensionProviderTable.HIDDEN + "=?" + + ORDER_BY + ExtensionGroupsTable.GROUP_NAME + " ASC"; + + return new QueryStatement>(sql, 1000) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setString(1, playerUUID.toString()); + statement.setBoolean(2, false); // Don't select hidden values + } + + @Override + public Map processResults(ResultSet set) throws SQLException { + Map> tabDataByPluginID = extractTabDataByPluginID(set); + return flatMapToPlayerData(tabDataByPluginID); + } + }; + } + + private Map flatMapToPlayerData(Map> tabDataByPluginID) { + Map dataByPluginID = new HashMap<>(); + for (Map.Entry> entry : tabDataByPluginID.entrySet()) { + Integer pluginID = entry.getKey(); + ExtensionPlayerData.Factory data = dataByPluginID.getOrDefault(pluginID, new ExtensionPlayerData.Factory(pluginID)); + for (ExtensionTabData.Factory tabData : entry.getValue().values()) { + data.addTab(tabData.build()); + } + dataByPluginID.put(pluginID, data); + } + return dataByPluginID; + } + + private Map> extractTabDataByPluginID(ResultSet set) throws SQLException { + Map> tabDataByPluginID = new HashMap<>(); + + while (set.next()) { + int pluginID = set.getInt("plugin_id"); + Map tabData = tabDataByPluginID.getOrDefault(pluginID, new HashMap<>()); + + String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); + ExtensionTabData.Factory inMap = tabData.get(tabName); + ExtensionTabData.Factory extensionTab = inMap != null ? inMap : extractTab(tabName, set, tabData); + + ExtensionDescriptive extensionDescriptive = extractDescriptive(set); + + String groupName = set.getString(ExtensionGroupsTable.GROUP_NAME); + extensionTab.putGroupData(new ExtensionStringData(extensionDescriptive, false, groupName)); + + tabData.put(tabName, extensionTab); + tabDataByPluginID.put(pluginID, tabData); + } + return tabDataByPluginID; + } + + private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { + String name = set.getString("provider_name"); + String text = set.getString(ExtensionProviderTable.TEXT); + + String iconName = set.getString("provider_icon_name"); + Family family = Family.getByName(set.getString("provider_icon_family")).orElse(Family.SOLID); + Color color = Color.getByName(set.getString("provider_icon_color")).orElse(Color.NONE); + Icon icon = new Icon(family, iconName, color); + + return new ExtensionDescriptive(name, text, null, icon, 0); + } + + private ExtensionTabData.Factory extractTab(String tabName, ResultSet set, Map tabData) throws SQLException { + Optional tabPriority = Optional.of(set.getInt("tab_priority")); + if (set.wasNull()) { + tabPriority = Optional.empty(); + } + Optional elementOrder = Optional.ofNullable(set.getString(ExtensionTabTable.ELEMENT_ORDER)).map(ElementOrder::deserialize); + + Icon tabIcon = extractTabIcon(set); + + return tabData.getOrDefault(tabName, new ExtensionTabData.Factory(new TabInformation( + tabName, + tabIcon, + elementOrder.orElse(ElementOrder.values()), + tabPriority.orElse(100) + ))); + } + + private Icon extractTabIcon(ResultSet set) throws SQLException { + Optional iconName = Optional.ofNullable(set.getString("tab_icon_name")); + if (iconName.isPresent()) { + Family iconFamily = Family.getByName(set.getString("tab_icon_family")).orElse(Family.SOLID); + Color iconColor = Color.getByName(set.getString("tab_icon_color")).orElse(Color.NONE); + return new Icon(iconFamily, iconName.get(), iconColor); + } else { + return TabInformation.defaultIcon(); + } + } +} \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java index 8a4954064..fa7d25b45 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/extension/implementation/storage/queries/ExtensionServerPlayerDataTableQuery.java @@ -55,10 +55,10 @@ public class ExtensionServerPlayerDataTableQuery implements Query executeQuery(SQLDB db) { - return db.query(fetchIncompletePlayerDataByPluginID()); + return db.query(fetchPlayerData()); } - private Query> fetchIncompletePlayerDataByPluginID() { + private Query> fetchPlayerData() { String selectLimitedNumberOfPlayerUUIDsByLastSeenDate = SELECT + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID + ",MAX(" + SessionsTable.SESSION_END + ") as last_seen" + 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 b99815cae..294403092 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 @@ -1166,6 +1166,7 @@ public interface DatabaseTest { OptionalAssert.equals("0.5", tabData.getDouble("doubleVal").map(data -> data.getFormattedValue(Object::toString))); OptionalAssert.equals("0.5", tabData.getPercentage("percentageVal").map(data -> data.getFormattedValue(Object::toString))); OptionalAssert.equals("Something", tabData.getString("stringVal").map(ExtensionStringData::getFormattedValue)); + OptionalAssert.equals("Group", tabData.getString("groupVal").map(ExtensionStringData::getFormattedValue)); } @Test @@ -1238,7 +1239,6 @@ public interface DatabaseTest { OptionalAssert.equals("0.5", tabData.getDouble("doubleVal_total").map(data -> data.getFormattedValue(Objects::toString))); OptionalAssert.equals("5", tabData.getNumber("value_avg").map(data -> data.getFormattedValue(Objects::toString))); OptionalAssert.equals("5", tabData.getNumber("value_total").map(data -> data.getFormattedValue(Objects::toString))); - // TODO Add test that group exists } @Test @@ -1530,8 +1530,8 @@ public interface DatabaseTest { } @GroupProvider(text = "a group") - public Group[] group(UUID playerUUID) { - return new Group[]{() -> "group"}; + public Group[] groupVal(UUID playerUUID) { + return new Group[]{() -> "Group"}; } }