/* * 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.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.ExtensionData; import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive; import com.djrapitops.plan.extension.implementation.results.ExtensionDoubleData; import com.djrapitops.plan.extension.implementation.results.ExtensionTabData; import com.djrapitops.plan.storage.database.SQLDB; import com.djrapitops.plan.storage.database.queries.Query; import com.djrapitops.plan.storage.database.queries.QueryStatement; import com.djrapitops.plan.storage.database.sql.tables.*; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; import java.util.Optional; import java.util.UUID; import static com.djrapitops.plan.storage.database.sql.parsing.Sql.*; /** * Query aggregated boolean values from player value table. *

* Returns Map: PluginID - ExtensionServerData.Factory. *

* How it is done: * - Combines three queries, one that selects true boolean count, one that selects boolean value count and one that selects provider information. * - Data query is sorted into a multi-map: PluginID - Tab Name - Tab Data * - (Tab Name can be empty.) * - Multi-map is sorted into ExtensionPlayerData objects by PluginID, one per ID *

* There are multiple data extraction methods to make extracting the value query easier. * * @author Rsl1122 */ public class ExtensionAggregatePercentagesQuery implements Query> { private final UUID serverUUID; public ExtensionAggregatePercentagesQuery(UUID serverUUID) { this.serverUUID = serverUUID; } @Override public Map executeQuery(SQLDB db) { String selectPercentageAverage = SELECT + ExtensionPlayerValueTable.PROVIDER_ID + ",AVG(" + ExtensionPlayerValueTable.PERCENTAGE_VALUE + ") as average" + FROM + ExtensionPlayerValueTable.TABLE_NAME + WHERE + ExtensionPlayerValueTable.PERCENTAGE_VALUE + IS_NOT_NULL + GROUP_BY + ExtensionPlayerValueTable.PROVIDER_ID; String sql = SELECT + "b1.average as average," + "p1." + ExtensionProviderTable.PLUGIN_ID + " as plugin_id," + "p1." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," + "p1." + ExtensionProviderTable.TEXT + " as text," + "p1." + ExtensionProviderTable.DESCRIPTION + " as description," + "p1." + ExtensionProviderTable.PRIORITY + " as provider_priority," + "p1." + ExtensionProviderTable.IS_PLAYER_NAME + " as is_player_name," + "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 + '(' + selectPercentageAverage + ") b1" + INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=b1." + ExtensionPlayerValueTable.PROVIDER_ID + INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on p1." + ExtensionProviderTable.PLUGIN_ID + "=e1." + ExtensionPluginTable.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 + ExtensionPluginTable.SERVER_UUID + "=?" + AND + "p1." + ExtensionProviderTable.HIDDEN + "=?"; return db.query(new QueryStatement>(sql, 1000) { @Override public void prepare(PreparedStatement statement) throws SQLException { statement.setString(1, serverUUID.toString()); statement.setBoolean(2, false); // Don't select hidden values } @Override public Map processResults(ResultSet set) throws SQLException { return extractTabDataByPluginID(set).toExtensionDataByPluginID(); } }); } private QueriedTabData extractTabDataByPluginID(ResultSet set) throws SQLException { QueriedTabData tabData = new QueriedTabData(); while (set.next()) { int pluginID = set.getInt("plugin_id"); String tabName = Optional.ofNullable(set.getString("tab_name")).orElse(""); ExtensionTabData.Builder extensionTab = tabData.getTab(pluginID, tabName, () -> extractTabInformation(tabName, set)); ExtensionDescriptive extensionDescriptive = extractDescriptive(set); extractAndPutDataTo(extensionTab, extensionDescriptive, set); } return tabData; } private TabInformation extractTabInformation(String tabName, ResultSet set) 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 new TabInformation( tabName, tabIcon, elementOrder.orElse(ElementOrder.values()), tabPriority.orElse(100) ); } private void extractAndPutDataTo(ExtensionTabData.Builder extensionTab, ExtensionDescriptive descriptive, ResultSet set) throws SQLException { extensionTab.putPercentageData(new ExtensionDoubleData(modifiedDescriptive(descriptive, "_avg", "Average "), set.getDouble("average"))); } private ExtensionDescriptive modifiedDescriptive(ExtensionDescriptive descriptive, String appendToName, String appendToText) { return new ExtensionDescriptive(descriptive.getName() + appendToName, appendToText + descriptive.getText(), descriptive.getDescription().orElse(null), descriptive.getIcon(), descriptive.getPriority()); } private ExtensionDescriptive extractDescriptive(ResultSet set) throws SQLException { String name = set.getString("provider_name"); String text = set.getString(ExtensionProviderTable.TEXT); String description = set.getString(ExtensionProviderTable.DESCRIPTION); int priority = set.getInt("provider_priority"); 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, description, icon, priority); } 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(); } } }