Query optimizations (#2320)

* Optimized network ping table query
* Removed icon id selection subqueries

- Take the icon ID into memory when the icons are stored

* Fix typos in the optimized ping table query
* Optimize server ping table query
* Attempt to optimize /v1/servers tps data query
* Optimize ping and geolocations tables uuid -> user_id foreign key
* Prevent Plan from crashing if patching takes too long

- HikariCP auto commit was true for some reason even though all transactions have commit mechanism built-in.
- The setting was reset during connection recreation and that could cause an index out of bounds error.

* Reduce try-nesting in ExecStatement
* Use user_id and server_id instead of uuid for plan_world_times table
* Use user_id and server_id instead of uuid for plan_sessions and plan_user_info table
* Fix more issues and test queries used by Query Filters
* Use deferRender for data tables to load data into the table faster
* Swap uuids to user ids for query page filters

Fixes an issue where SQL is too big to execute

Affects issues:
- #2196
This commit is contained in:
Aurora Lahtela 2022-04-09 20:52:29 +03:00 committed by GitHub
parent 0e3339be6e
commit b74e338721
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
98 changed files with 1288 additions and 1351 deletions

View File

@ -25,6 +25,9 @@ package com.djrapitops.plan.extension.icon;
*/
public class Icon {
// Implementation detail, set during icon storage to optimize relation inserts.
int id;
private Family type;
private String name;
private Color color;

View File

@ -190,7 +190,12 @@ public class JSONFactory {
.findFirst()
.map(Server::getUuid).orElse(null);
Map<ServerUUID, List<TPS>> tpsData = db.query(
Map<ServerUUID, Integer> serverUuidToId = new HashMap<>();
for (Server server : serverInformation.values()) {
server.getId().ifPresent(serverId -> serverUuidToId.put(server.getUuid(), serverId));
}
Map<Integer, List<TPS>> tpsDataByServerId = db.query(
TPSQueries.fetchTPSDataOfAllServersBut(weekAgo, now, proxyUUID)
);
Map<ServerUUID, Integer> totalPlayerCounts = db.query(PlayerCountQueries.newPlayerCounts(0, now));
@ -214,7 +219,7 @@ public class JSONFactory {
server.put("last_peak_players", recentPeak.map(DateObj::getValue).orElse(0));
server.put("best_peak_players", allTimePeak.map(DateObj::getValue).orElse(0));
TPSMutator tpsMonth = new TPSMutator(tpsData.getOrDefault(serverUUID, Collections.emptyList()));
TPSMutator tpsMonth = new TPSMutator(tpsDataByServerId.getOrDefault(serverUuidToId.get(serverUUID), Collections.emptyList()));
server.put("playersOnline", tpsMonth.all().stream()
.map(tps -> new double[]{tps.getDate(), tps.getPlayers()})
.toArray(double[][]::new));

View File

@ -163,7 +163,7 @@ public class QueryJSONResolver implements Resolver {
.put("timestamp", timestamp)
.build();
if (!result.isEmpty()) {
json.put("data", getDataFor(result.getResultUUIDs(), view));
json.put("data", getDataFor(result.getResultUserIds(), view));
}
JSONStorage.StoredJSON stored = jsonStorage.storeJson("query", json, timestamp);
@ -177,22 +177,22 @@ public class QueryJSONResolver implements Resolver {
}
}
private Map<String, Object> getDataFor(Set<UUID> playerUUIDs, ViewDto view) throws ParseException {
private Map<String, Object> getDataFor(Set<Integer> userIds, ViewDto view) throws ParseException {
long after = view.getAfterEpochMs();
long before = view.getBeforeEpochMs();
List<ServerUUID> serverUUIDs = view.getServerUUIDs();
return Maps.builder(String.class, Object.class)
.put("players", getPlayersTableData(playerUUIDs, serverUUIDs, after, before))
.put("activity", getActivityGraphData(playerUUIDs, serverUUIDs, after, before))
.put("geolocation", getGeolocationData(playerUUIDs))
.put("sessions", getSessionSummaryData(playerUUIDs, serverUUIDs, after, before))
.put("players", getPlayersTableData(userIds, serverUUIDs, after, before))
.put("activity", getActivityGraphData(userIds, serverUUIDs, after, before))
.put("geolocation", getGeolocationData(userIds))
.put("sessions", getSessionSummaryData(userIds, serverUUIDs, after, before))
.build();
}
private Map<String, String> getSessionSummaryData(Set<UUID> playerUUIDs, List<ServerUUID> serverUUIDs, long after, long before) {
private Map<String, String> getSessionSummaryData(Set<Integer> userIds, List<ServerUUID> serverUUIDs, long after, long before) {
Database database = dbSystem.getDatabase();
Map<String, Long> summary = database.query(SessionQueries.summaryOfPlayers(playerUUIDs, serverUUIDs, after, before));
Map<String, Long> summary = database.query(SessionQueries.summaryOfPlayers(userIds, serverUUIDs, after, before));
Map<String, String> formattedSummary = new HashMap<>();
Formatter<Long> timeAmount = formatters.timeAmount();
for (Map.Entry<String, Long> entry : summary.entrySet()) {
@ -203,14 +203,14 @@ public class QueryJSONResolver implements Resolver {
return formattedSummary;
}
private Map<String, Object> getGeolocationData(Set<UUID> playerUUIDs) {
private Map<String, Object> getGeolocationData(Set<Integer> userIds) {
Database database = dbSystem.getDatabase();
return graphJSONCreator.createGeolocationJSON(
database.query(GeoInfoQueries.networkGeolocationCounts(playerUUIDs))
database.query(GeoInfoQueries.networkGeolocationCounts(userIds))
);
}
private Map<String, Object> getActivityGraphData(Set<UUID> playerUUIDs, List<ServerUUID> serverUUIDs, long after, long before) {
private Map<String, Object> getActivityGraphData(Set<Integer> userIds, List<ServerUUID> serverUUIDs, long after, long before) {
Database database = dbSystem.getDatabase();
Long threshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
@ -219,17 +219,17 @@ public class QueryJSONResolver implements Resolver {
DateMap<Map<String, Integer>> activityData = new DateMap<>();
for (long time = before; time >= stopDate; time -= TimeAmount.WEEK.toMillis(1L)) {
activityData.put(time, database.query(NetworkActivityIndexQueries.fetchActivityIndexGroupingsOn(time, threshold, playerUUIDs, serverUUIDs)));
activityData.put(time, database.query(NetworkActivityIndexQueries.fetchActivityIndexGroupingsOn(time, threshold, userIds, serverUUIDs)));
}
return graphJSONCreator.createActivityGraphJSON(activityData);
}
private Map<String, Object> getPlayersTableData(Set<UUID> playerUUIDs, List<ServerUUID> serverUUIDs, long after, long before) {
private Map<String, Object> getPlayersTableData(Set<Integer> userIds, List<ServerUUID> serverUUIDs, long after, long before) {
Database database = dbSystem.getDatabase();
return new PlayersTableJSONCreator(
database.query(new QueryTablePlayersQuery(playerUUIDs, serverUUIDs, after, before, config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD))),
database.query(new ExtensionQueryResultTableDataQuery(serverInfo.getServerUUID(), playerUUIDs)),
database.query(new QueryTablePlayersQuery(userIds, serverUUIDs, after, before, config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD))),
database.query(new ExtensionQueryResultTableDataQuery(serverInfo.getServerUUID(), userIds)),
config.get(DisplaySettings.OPEN_PLAYER_LINKS_IN_NEW_TAB),
formatters, locale
).toJSONMap();

View File

@ -0,0 +1,33 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.extension.icon;
public class IconAccessor {
private IconAccessor() {
/* Static access class for package private field */
}
public static Integer getId(Icon icon) {
return icon != null ? icon.id : null;
}
public static void setId(Icon icon, int id) {
icon.id = id;
}
}

View File

@ -49,11 +49,11 @@ import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
public class ExtensionQueryResultTableDataQuery implements Query<Map<UUID, ExtensionTabData>> {
private final ServerUUID serverUUID;
private final Collection<UUID> playerUUIDs;
private final Collection<Integer> userIds;
public ExtensionQueryResultTableDataQuery(ServerUUID serverUUID, Collection<UUID> playerUUIDs) {
public ExtensionQueryResultTableDataQuery(ServerUUID serverUUID, Collection<Integer> userIds) {
this.serverUUID = serverUUID;
this.playerUUIDs = playerUUIDs;
this.userIds = userIds;
}
@Override
@ -77,6 +77,9 @@ public class ExtensionQueryResultTableDataQuery implements Query<Map<UUID, Exten
}
private Query<Map<UUID, ExtensionTabData>> fetchPlayerData() {
String selectUuids = SELECT + UsersTable.USER_UUID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.ID + " IN (" + new TextStringBuilder().appendWithSeparators(userIds, ",") + ")";
String sql = SELECT +
"v1." + ExtensionPlayerValueTable.USER_UUID + " as uuid," +
@ -93,12 +96,11 @@ public class ExtensionQueryResultTableDataQuery implements Query<Map<UUID, Exten
"i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," +
"i1." + ExtensionIconTable.FAMILY + " as provider_icon_family" +
FROM + ExtensionPlayerValueTable.TABLE_NAME + " v1" +
INNER_JOIN + '(' + selectUuids + ") sel on sel." + UsersTable.USER_UUID + "=v1." + ExtensionPlayerValueTable.USER_UUID +
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionPlayerValueTable.PROVIDER_ID +
INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on e1." + ExtensionPluginTable.ID + "=p1." + ExtensionProviderTable.PLUGIN_ID +
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID +
WHERE + "v1." + ExtensionPlayerValueTable.USER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')" +
AND + "p1." + ExtensionProviderTable.SHOW_IN_PLAYERS_TABLE + "=?" +
WHERE + "p1." + ExtensionProviderTable.SHOW_IN_PLAYERS_TABLE + "=?" +
AND + "p1." + ExtensionProviderTable.IS_PLAYER_NAME + "=?" +
AND + "e1." + ExtensionPluginTable.SERVER_UUID + "=?";
@ -118,6 +120,10 @@ public class ExtensionQueryResultTableDataQuery implements Query<Map<UUID, Exten
}
private Query<Map<UUID, ExtensionTabData>> fetchPlayerGroups() {
String selectUuids = SELECT + UsersTable.USER_UUID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.ID + " IN (" + new TextStringBuilder().appendWithSeparators(userIds, ",") + ")";
String sql = SELECT +
"v1." + ExtensionGroupsTable.USER_UUID + " as uuid," +
"v1." + ExtensionGroupsTable.GROUP_NAME + " as group_value," +
@ -126,12 +132,11 @@ public class ExtensionQueryResultTableDataQuery implements Query<Map<UUID, Exten
"i1." + ExtensionIconTable.ICON_NAME + " as provider_icon_name," +
"i1." + ExtensionIconTable.FAMILY + " as provider_icon_family" +
FROM + ExtensionGroupsTable.TABLE_NAME + " v1" +
INNER_JOIN + '(' + selectUuids + ") sel on sel." + UsersTable.USER_UUID + "=v1." + ExtensionGroupsTable.USER_UUID +
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " p1 on p1." + ExtensionProviderTable.ID + "=v1." + ExtensionGroupsTable.PROVIDER_ID +
INNER_JOIN + ExtensionPluginTable.TABLE_NAME + " e1 on e1." + ExtensionPluginTable.ID + "=p1." + ExtensionProviderTable.PLUGIN_ID +
LEFT_JOIN + ExtensionIconTable.TABLE_NAME + " i1 on i1." + ExtensionIconTable.ID + "=p1." + ExtensionProviderTable.ICON_ID +
WHERE + "v1." + ExtensionPlayerValueTable.USER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')" +
AND + "e1." + ExtensionPluginTable.SERVER_UUID + "=?";
WHERE + "e1." + ExtensionPluginTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, ExtensionTabData>>(sql, 1000) {
@Override

View File

@ -76,10 +76,10 @@ public class ExtensionServerTableDataQuery implements Query<Map<UUID, ExtensionT
private Query<Map<UUID, ExtensionTabData>> fetchPlayerData() {
String selectLimitedNumberOfPlayerUUIDsByLastSeenDate = SELECT +
SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID +
",MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
UsersTable.USER_UUID + ",MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
FROM + SessionsTable.TABLE_NAME +
GROUP_BY + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_ID +
GROUP_BY + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_ID +
ORDER_BY + "last_seen DESC LIMIT ?";
String sql = SELECT +
@ -123,10 +123,10 @@ public class ExtensionServerTableDataQuery implements Query<Map<UUID, ExtensionT
private Query<Map<UUID, ExtensionTabData>> fetchPlayerGroups() {
String selectLimitedNumberOfPlayerUUIDsByLastSeenDate = SELECT +
SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID +
",MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
UsersTable.USER_UUID + ",MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
FROM + SessionsTable.TABLE_NAME +
GROUP_BY + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_ID +
GROUP_BY + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_ID +
ORDER_BY + "last_seen DESC LIMIT ?";
String sql = SELECT +

View File

@ -20,23 +20,27 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionGroupsTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import org.apache.commons.text.TextStringBuilder;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
public class ExtensionUUIDsInGroupQuery extends QueryStatement<Set<UUID>> {
public class ExtensionUserIdsInGroupQuery extends QueryStatement<Set<Integer>> {
private final String pluginName;
private final String groupProvider;
private final ServerUUID serverUUID;
private final List<String> inGroups;
public ExtensionUUIDsInGroupQuery(String pluginName, String groupProvider, ServerUUID serverUUID, List<String> inGroups) {
public ExtensionUserIdsInGroupQuery(String pluginName, String groupProvider, ServerUUID serverUUID, List<String> inGroups) {
super(buildSQL(inGroups), 100);
this.pluginName = pluginName;
this.groupProvider = groupProvider;
@ -47,8 +51,9 @@ public class ExtensionUUIDsInGroupQuery extends QueryStatement<Set<UUID>> {
private static String buildSQL(Collection<String> inGroups) {
TextStringBuilder dynamicInClauseAllocation = new TextStringBuilder();
dynamicInClauseAllocation.appendWithSeparators(inGroups.stream().map(group -> "?").toArray(), ",");
return SELECT + DISTINCT + ExtensionGroupsTable.USER_UUID +
FROM + ExtensionGroupsTable.TABLE_NAME +
return SELECT + DISTINCT + "u." + UsersTable.ID +
FROM + ExtensionGroupsTable.TABLE_NAME + " groups" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=groups." + ExtensionGroupsTable.USER_UUID +
WHERE + ExtensionGroupsTable.PROVIDER_ID + "=" + ExtensionProviderTable.STATEMENT_SELECT_PROVIDER_ID +
AND + ExtensionGroupsTable.GROUP_NAME + " IN (" + dynamicInClauseAllocation.build() + ")";
}
@ -64,11 +69,11 @@ public class ExtensionUUIDsInGroupQuery extends QueryStatement<Set<UUID>> {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString(ExtensionGroupsTable.USER_UUID)));
userIds.add(set.getInt(UsersTable.ID));
}
return uuids;
return userIds;
}
}

View File

@ -17,15 +17,17 @@
package com.djrapitops.plan.extension.implementation.storage.transactions;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plan.storage.database.queries.HasMoreThanZeroQueryStatement;
import com.djrapitops.plan.extension.icon.IconAccessor;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
@ -44,12 +46,16 @@ public class StoreIconTransaction extends ThrowawayTransaction {
@Override
protected void performOperations() {
if (Boolean.FALSE.equals(query(isIconStored()))) {
execute(insertIcon());
Optional<Integer> iconId = query(getIconId());
if (iconId.isPresent()) {
IconAccessor.setId(icon, iconId.get());
} else {
int id = executeReturningId(insertIcon());
IconAccessor.setId(icon, id);
}
}
private Executable insertIcon() {
private ExecStatement insertIcon() {
String sql = "INSERT INTO " + ExtensionIconTable.TABLE_NAME + "(" +
ExtensionIconTable.ICON_NAME + "," +
ExtensionIconTable.FAMILY + "," +
@ -63,17 +69,28 @@ public class StoreIconTransaction extends ThrowawayTransaction {
};
}
private Query<Boolean> isIconStored() {
String sql = SELECT + "COUNT(1) as c" +
private Query<Optional<Integer>> getIconId() {
String sql = SELECT + "id" +
FROM + ExtensionIconTable.TABLE_NAME +
WHERE + ExtensionIconTable.ICON_NAME + "=?" +
AND + ExtensionIconTable.FAMILY + "=?" +
AND + ExtensionIconTable.COLOR + "=?";
return new HasMoreThanZeroQueryStatement(sql) {
return new QueryStatement<Optional<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
ExtensionIconTable.set3IconValuesToStatement(statement, icon);
}
@Override
public Optional<Integer> processResults(ResultSet set) throws SQLException {
if (set.next()) {
int id = set.getInt(ExtensionIconTable.ID);
if (!set.wasNull()) {
return Optional.of(id);
}
}
return Optional.empty();
}
};
}
}

View File

@ -17,8 +17,8 @@
package com.djrapitops.plan.extension.implementation.storage.transactions;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plan.extension.icon.IconAccessor;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
@ -67,16 +67,16 @@ public class StorePluginTransaction extends ThrowawayTransaction {
String sql = "UPDATE " + ExtensionPluginTable.TABLE_NAME +
" SET " +
ExtensionPluginTable.LAST_UPDATED + "=?," +
ExtensionPluginTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID +
ExtensionPluginTable.ICON_ID + "=?" +
WHERE + ExtensionPluginTable.PLUGIN_NAME + "=?" +
AND + ExtensionPluginTable.SERVER_UUID + "=?";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, time);
ExtensionIconTable.set3IconValuesToStatement(statement, 2, icon);
statement.setString(5, pluginName);
statement.setString(6, serverUUID.toString());
statement.setInt(2, IconAccessor.getId(icon));
statement.setString(3, pluginName);
statement.setString(4, serverUUID.toString());
}
};
}
@ -87,14 +87,14 @@ public class StorePluginTransaction extends ThrowawayTransaction {
ExtensionPluginTable.LAST_UPDATED + "," +
ExtensionPluginTable.SERVER_UUID + "," +
ExtensionPluginTable.ICON_ID +
") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ")";
") VALUES (?,?,?,?)";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, pluginName);
statement.setLong(2, time);
statement.setString(3, serverUUID.toString());
ExtensionIconTable.set3IconValuesToStatement(statement, 4, icon);
statement.setInt(4, IconAccessor.getId(icon));
}
};
}

View File

@ -16,9 +16,9 @@
*/
package com.djrapitops.plan.extension.implementation.storage.transactions;
import com.djrapitops.plan.extension.icon.IconAccessor;
import com.djrapitops.plan.extension.implementation.TabInformation;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionTabTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
@ -67,7 +67,7 @@ public class StoreTabInformationTransaction extends ThrowawayTransaction {
" SET " +
ExtensionTabTable.TAB_PRIORITY + "=?," +
ExtensionTabTable.ELEMENT_ORDER + "=?," +
ExtensionTabTable.ICON_ID + "=" + ExtensionIconTable.STATEMENT_SELECT_ICON_ID +
ExtensionTabTable.ICON_ID + "=?" +
WHERE + ExtensionTabTable.PLUGIN_ID + "=" + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID +
AND + ExtensionTabTable.TAB_NAME + "=?";
return new ExecStatement(sql) {
@ -75,9 +75,9 @@ public class StoreTabInformationTransaction extends ThrowawayTransaction {
public void prepare(PreparedStatement statement) throws SQLException {
statement.setInt(1, tabInformation.getTabPriority());
statement.setString(2, tabInformation.getSerializedTabElementOrder());
ExtensionIconTable.set3IconValuesToStatement(statement, 3, tabInformation.getTabIcon());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 6, pluginName, serverUUID);
statement.setString(8, tabInformation.getTabName());
statement.setInt(3, IconAccessor.getId(tabInformation.getTabIcon()));
ExtensionPluginTable.set2PluginValuesToStatement(statement, 4, pluginName, serverUUID);
statement.setString(6, tabInformation.getTabName());
}
};
}
@ -89,15 +89,15 @@ public class StoreTabInformationTransaction extends ThrowawayTransaction {
ExtensionTabTable.TAB_PRIORITY + "," +
ExtensionTabTable.ICON_ID + "," +
ExtensionTabTable.PLUGIN_ID +
") VALUES (?,?,?," + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + "," + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")";
") VALUES (?,?,?,?," + ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ")";
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, tabInformation.getTabName());
statement.setString(2, tabInformation.getSerializedTabElementOrder());
statement.setInt(3, tabInformation.getTabPriority());
ExtensionIconTable.set3IconValuesToStatement(statement, 4, tabInformation.getTabIcon());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 7, pluginName, serverUUID);
statement.setInt(4, IconAccessor.getId(tabInformation.getTabIcon()));
ExtensionPluginTable.set2PluginValuesToStatement(statement, 5, pluginName, serverUUID);
}
};
}

View File

@ -17,12 +17,12 @@
package com.djrapitops.plan.extension.implementation.storage.transactions.providers;
import com.djrapitops.plan.extension.FormatType;
import com.djrapitops.plan.extension.icon.IconAccessor;
import com.djrapitops.plan.extension.implementation.ProviderInformation;
import com.djrapitops.plan.extension.implementation.providers.DataProvider;
import com.djrapitops.plan.extension.implementation.providers.Parameters;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.building.Sql;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionTabTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
@ -80,7 +80,7 @@ public class StoreProviderTransaction extends ThrowawayTransaction {
DESCRIPTION + "=?," +
PRIORITY + "=?," +
CONDITION + "=?," +
ICON_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_ID + "=?," +
TAB_ID + '=' + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
SHOW_IN_PLAYERS_TABLE + "=?," +
HIDDEN + "=?," +
@ -98,19 +98,19 @@ public class StoreProviderTransaction extends ThrowawayTransaction {
Sql.setStringOrNull(statement, 2, info.getDescription().orElse(null));
statement.setInt(3, info.getPriority());
Sql.setStringOrNull(statement, 4, info.getCondition().orElse(null));
ExtensionIconTable.set3IconValuesToStatement(statement, 5, info.getIcon());
ExtensionTabTable.set3TabValuesToStatement(statement, 8, info.getTab().orElse(null), info.getPluginName(), serverUUID);
statement.setBoolean(11, info.isShownInPlayersTable());
statement.setInt(5, IconAccessor.getId(info.getIcon()));
ExtensionTabTable.set3TabValuesToStatement(statement, 6, info.getTab().orElse(null), info.getPluginName(), serverUUID);
statement.setBoolean(9, info.isShownInPlayersTable());
// Specific provider cases
statement.setBoolean(12, info.isHidden());
Sql.setStringOrNull(statement, 13, info.getProvidedCondition());
Sql.setStringOrNull(statement, 14, info.getFormatType().map(FormatType::name).orElse(null));
statement.setBoolean(15, info.isPlayerName());
statement.setBoolean(10, info.isHidden());
Sql.setStringOrNull(statement, 11, info.getProvidedCondition());
Sql.setStringOrNull(statement, 12, info.getFormatType().map(FormatType::name).orElse(null));
statement.setBoolean(13, info.isPlayerName());
// Find appropriate provider
ExtensionPluginTable.set2PluginValuesToStatement(statement, 16, info.getPluginName(), serverUUID);
statement.setString(18, info.getName());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 14, info.getPluginName(), serverUUID);
statement.setString(16, info.getName());
}
};
}
@ -132,7 +132,7 @@ public class StoreProviderTransaction extends ThrowawayTransaction {
PLUGIN_ID +
") VALUES (?,?,?,?,?,?,?,?,?,?," +
ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
"?," +
ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ')';
return new ExecStatement(sql) {
@Override
@ -153,8 +153,8 @@ public class StoreProviderTransaction extends ThrowawayTransaction {
// Found for all providers
ExtensionTabTable.set3TabValuesToStatement(statement, 11, info.getTab().orElse(null), info.getPluginName(), serverUUID);
ExtensionIconTable.set3IconValuesToStatement(statement, 14, info.getIcon());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 17, info.getPluginName(), serverUUID);
statement.setInt(14, IconAccessor.getId(info.getIcon()));
ExtensionPluginTable.set2PluginValuesToStatement(statement, 15, info.getPluginName(), serverUUID);
}
};
}

View File

@ -17,13 +17,13 @@
package com.djrapitops.plan.extension.implementation.storage.transactions.providers;
import com.djrapitops.plan.extension.icon.Icon;
import com.djrapitops.plan.extension.icon.IconAccessor;
import com.djrapitops.plan.extension.implementation.MethodType;
import com.djrapitops.plan.extension.implementation.ProviderInformation;
import com.djrapitops.plan.extension.implementation.providers.Parameters;
import com.djrapitops.plan.extension.table.Table;
import com.djrapitops.plan.extension.table.TableColumnFormat;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionIconTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionTabTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
@ -89,11 +89,11 @@ public class StoreTableProviderTransaction extends ThrowawayTransaction {
COL_5 + "=?," +
CONDITION + "=?," +
TAB_ID + '=' + ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
ICON_1_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_2_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_3_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_4_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_5_ID + '=' + ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ICON_1_ID + "=?," +
ICON_2_ID + "=?," +
ICON_3_ID + "=?," +
ICON_4_ID + "=?," +
ICON_5_ID + "=?," +
FORMAT_1 + "=?," +
FORMAT_2 + "=?," +
FORMAT_3 + "=?," +
@ -114,23 +114,32 @@ public class StoreTableProviderTransaction extends ThrowawayTransaction {
setStringOrNull(statement, 6, columns[4]);
setStringOrNull(statement, 7, information.getCondition().orElse(null));
ExtensionTabTable.set3TabValuesToStatement(statement, 8, information.getTab().orElse("No Tab"), information.getPluginName(), serverUUID);
ExtensionIconTable.set3IconValuesToStatement(statement, 11, icons[0]);
ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[1]);
ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[2]);
ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[3]);
ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[4]);
setStringOrNull(statement, 26, formats[0] == TableColumnFormat.NONE ? null : formats[0].name());
setStringOrNull(statement, 27, formats[1] == TableColumnFormat.NONE ? null : formats[1].name());
setStringOrNull(statement, 28, formats[2] == TableColumnFormat.NONE ? null : formats[2].name());
setStringOrNull(statement, 29, formats[3] == TableColumnFormat.NONE ? null : formats[3].name());
setStringOrNull(statement, 30, formats[4] == TableColumnFormat.NONE ? null : formats[4].name());
statement.setInt(31, forPlayer ? VALUES_FOR_PLAYER : VALUES_FOR_SERVER);
statement.setString(32, information.getName());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 33, information.getPluginName(), serverUUID);
setIconId(statement, 11, 0, icons);
setIconId(statement, 12, 1, icons);
setIconId(statement, 13, 2, icons);
setIconId(statement, 14, 3, icons);
setIconId(statement, 15, 4, icons);
setStringOrNull(statement, 16, formats[0] == TableColumnFormat.NONE ? null : formats[0].name());
setStringOrNull(statement, 17, formats[1] == TableColumnFormat.NONE ? null : formats[1].name());
setStringOrNull(statement, 18, formats[2] == TableColumnFormat.NONE ? null : formats[2].name());
setStringOrNull(statement, 19, formats[3] == TableColumnFormat.NONE ? null : formats[3].name());
setStringOrNull(statement, 20, formats[4] == TableColumnFormat.NONE ? null : formats[4].name());
statement.setInt(21, forPlayer ? VALUES_FOR_PLAYER : VALUES_FOR_SERVER);
statement.setString(22, information.getName());
ExtensionPluginTable.set2PluginValuesToStatement(statement, 23, information.getPluginName(), serverUUID);
}
};
}
private void setIconId(PreparedStatement statement, int index, int iconIndex, Icon[] icons) throws SQLException {
Icon icon = icons[iconIndex];
if (icon == null) {
statement.setNull(index, Types.INTEGER);
} else {
statement.setInt(index, IconAccessor.getId(icon));
}
}
private Executable insertProvider() {
String[] columns = table.getColumns();
Icon[] icons = table.getIcons();
@ -161,12 +170,8 @@ public class StoreTableProviderTransaction extends ThrowawayTransaction {
") VALUES (?,?,?,?,?,?,?,?," +
ExtensionTabTable.STATEMENT_SELECT_TAB_ID + ',' +
ExtensionPluginTable.STATEMENT_SELECT_PLUGIN_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
ExtensionIconTable.STATEMENT_SELECT_ICON_ID + ',' +
"?,?,?,?,?," +
"?,?,?,?,?," + // 5 icons
"?,?,?,?,?," + // 5 formats
"?)";
return new ExecStatement(sql) {
@ -182,17 +187,17 @@ public class StoreTableProviderTransaction extends ThrowawayTransaction {
setStringOrNull(statement, 8, information.getCondition().orElse(null));
ExtensionTabTable.set3TabValuesToStatement(statement, 9, information.getTab().orElse("No Tab"), information.getPluginName(), serverUUID);
ExtensionPluginTable.set2PluginValuesToStatement(statement, 12, information.getPluginName(), serverUUID);
ExtensionIconTable.set3IconValuesToStatement(statement, 14, icons[0]);
ExtensionIconTable.set3IconValuesToStatement(statement, 17, icons[1]);
ExtensionIconTable.set3IconValuesToStatement(statement, 20, icons[2]);
ExtensionIconTable.set3IconValuesToStatement(statement, 23, icons[3]);
ExtensionIconTable.set3IconValuesToStatement(statement, 26, icons[4]);
setStringOrNull(statement, 29, formats[0] == TableColumnFormat.NONE ? null : formats[0].name());
setStringOrNull(statement, 30, formats[1] == TableColumnFormat.NONE ? null : formats[1].name());
setStringOrNull(statement, 31, formats[2] == TableColumnFormat.NONE ? null : formats[2].name());
setStringOrNull(statement, 32, formats[3] == TableColumnFormat.NONE ? null : formats[3].name());
setStringOrNull(statement, 33, formats[4] == TableColumnFormat.NONE ? null : formats[4].name());
statement.setInt(34, forPlayer ? VALUES_FOR_PLAYER : VALUES_FOR_SERVER);
setIconId(statement, 14, 0, icons);
setIconId(statement, 15, 1, icons);
setIconId(statement, 16, 2, icons);
setIconId(statement, 17, 3, icons);
setIconId(statement, 18, 4, icons);
setStringOrNull(statement, 19, formats[0] == TableColumnFormat.NONE ? null : formats[0].name());
setStringOrNull(statement, 20, formats[1] == TableColumnFormat.NONE ? null : formats[1].name());
setStringOrNull(statement, 21, formats[2] == TableColumnFormat.NONE ? null : formats[2].name());
setStringOrNull(statement, 22, formats[3] == TableColumnFormat.NONE ? null : formats[3].name());
setStringOrNull(statement, 23, formats[4] == TableColumnFormat.NONE ? null : formats[4].name());
statement.setInt(24, forPlayer ? VALUES_FOR_PLAYER : VALUES_FOR_SERVER);
}
};
}

View File

@ -84,7 +84,9 @@ public enum PluginLang implements Lang {
DB_NOTIFY_CLEAN("plugin.generic.dbNotifyClean", "Database Notify - Clean", "Removed data of ${0} players."),
DB_NOTIFY_SQLITE_WAL("plugin.generic.dbNotifySQLiteWAL", "Database Notify - SQLite No WAL", "SQLite WAL mode not supported on this server version, using default. This may or may not affect performance."),
DB_MYSQL_LAUNCH_OPTIONS_FAIL("plugin.generic.dbFaultyLaunchOptions", "Database MySQL - Launch Options Error", "Launch Options were faulty, using default (${0})"),
LOADING_SERVER_INFO("plugin.generic.loadingServerInfo", "ServerInfo - Loading", "Loading server identifying information");
LOADING_SERVER_INFO("plugin.generic.loadingServerInfo", "ServerInfo - Loading", "Loading server identifying information"),
DB_SCHEMA_PATCH("plugin.generic.dbSchemaPatch", "Database Notify - Patch", "Database: Making sure schema is up to date.."),
;
private final String key;
private final String identifier;

View File

@ -110,7 +110,7 @@ public class MySQLDB extends SQLDB {
String database = config.get(DatabaseSettings.MYSQL_DATABASE);
String launchOptions = config.get(DatabaseSettings.MYSQL_LAUNCH_OPTIONS);
// REGEX: match "?", match "word=word&" *-times, match "word=word"
if (launchOptions.isEmpty() || !launchOptions.matches("\\?(((\\w|[-])+=.+)&)*((\\w|[-])+=.+)")) {
if (launchOptions.isEmpty() || !launchOptions.matches("\\?((([\\w-])+=.+)&)*(([\\w-])+=.+)")) {
launchOptions = "?rewriteBatchedStatements=true&useSSL=false";
logger.error(locale.getString(PluginLang.DB_MYSQL_LAUNCH_OPTIONS_FAIL, launchOptions));
}
@ -127,7 +127,7 @@ public class MySQLDB extends SQLDB {
hikariConfig.setPoolName("Plan Connection Pool-" + increment);
increment();
hikariConfig.setAutoCommit(true);
hikariConfig.setAutoCommit(false);
try {
hikariConfig.setMaximumPoolSize(config.get(DatabaseSettings.MAX_CONNECTIONS));
} catch (IllegalStateException e) {

View File

@ -193,12 +193,8 @@ public abstract class SQLDB extends AbstractDatabase {
new VersionTableRemovalPatch(),
new DiskUsagePatch(),
new WorldsOptimizationPatch(),
new WorldTimesOptimizationPatch(),
new KillsOptimizationPatch(),
new SessionsOptimizationPatch(),
new PingOptimizationPatch(),
new NicknamesOptimizationPatch(),
new UserInfoOptimizationPatch(),
new GeoInfoOptimizationPatch(),
new TransferTableRemovalPatch(),
new BadAFKThresholdValuePatch(),
@ -206,20 +202,24 @@ public abstract class SQLDB extends AbstractDatabase {
new ExtensionShowInPlayersTablePatch(),
new ExtensionTableRowValueLengthPatch(),
new CommandUsageTableRemovalPatch(),
new RegisterDateMinimizationPatch(),
new BadNukkitRegisterValuePatch(),
new LinkedToSecurityTablePatch(),
new LinkUsersToPlayersSecurityTablePatch(),
new LitebansTableHeaderPatch(),
new UserInfoHostnamePatch(),
new ServerIsProxyPatch(),
new UserInfoHostnameAllowNullPatch(),
new ServerTableRowPatch(),
new PlayerTableRowPatch(),
new ExtensionTableProviderValuesForPatch(),
new RemoveIncorrectTebexPackageDataPatch(),
new ExtensionTableProviderFormattersPatch(),
new ServerPlanVersionPatch()
new ServerPlanVersionPatch(),
new PingOptimizationPatch(),
new UserInfoOptimizationPatch(),
new WorldTimesOptimizationPatch(),
new SessionsOptimizationPatch(),
new UserInfoHostnameAllowNullPatch(),
new RegisterDateMinimizationPatch(),
};
}
@ -230,18 +230,18 @@ public abstract class SQLDB extends AbstractDatabase {
*/
private void setupDatabase() {
executeTransaction(new CreateTablesTransaction());
logger.info("Database: Making sure schema is up to date..");
logger.info(locale.getString(PluginLang.DB_SCHEMA_PATCH));
for (Patch patch : patches()) {
executeTransaction(patch);
}
executeTransaction(new OperationCriticalTransaction() {
@Override
protected void performOperations() {
logger.info(locale.getString(PluginLang.DB_APPLIED_PATCHES));
if (getState() == State.PATCHING) setState(State.OPEN);
}
});
registerIndexCreationTask();
logger.info("Database: Ready for operation.");
}
private void registerIndexCreationTask() {
@ -382,4 +382,8 @@ public abstract class SQLDB extends AbstractDatabase {
public PluginLogger getLogger() {
return logger;
}
public Locale getLocale() {
return locale;
}
}

View File

@ -301,8 +301,8 @@ public class DataStoreQueries {
public static Executable updateJoinAddress(UUID playerUUID, ServerUUID serverUUID, String joinAddress) {
String sql = "UPDATE " + UserInfoTable.TABLE_NAME + " SET " +
UserInfoTable.JOIN_ADDRESS + "=?" +
WHERE + UserInfoTable.USER_UUID + "=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
WHERE + UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {

View File

@ -51,7 +51,7 @@ public class LargeFetchQueries {
* @return Map: Server UUID - List of TPS data
*/
public static Query<Map<ServerUUID, List<TPS>>> fetchAllTPSData() {
String serverIDColumn = ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_ID;
String serverIDColumn = ServerTable.TABLE_NAME + '.' + ServerTable.ID;
String serverUUIDColumn = ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_UUID + " as s_uuid";
String sql = SELECT +
TPSTable.DATE + ',' +

View File

@ -18,7 +18,9 @@ package com.djrapitops.plan.storage.database.queries;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.KillsTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -51,10 +53,11 @@ public class PerServerAggregateQueries {
*/
public static Query<Map<ServerUUID, Long>> lastSeenOnServers(UUID playerUUID) {
String sql = SELECT + "MAX(" + SessionsTable.SESSION_END + ") as last_seen, " +
SessionsTable.SERVER_UUID +
ServerTable.SERVER_UUID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.USER_UUID + "=?" +
GROUP_BY + SessionsTable.SERVER_UUID;
INNER_JOIN + ServerTable.TABLE_NAME + " se on se." + ServerTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + SessionsTable.SERVER_ID;
return new QueryStatement<Map<ServerUUID, Long>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -65,7 +68,7 @@ public class PerServerAggregateQueries {
public Map<ServerUUID, Long> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Long> lastSeenMap = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(SessionsTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
long lastSeen = set.getLong("last_seen");
lastSeenMap.put(serverUUID, lastSeen);
}
@ -81,7 +84,8 @@ public class PerServerAggregateQueries {
* @return Map: Server UUID - Player kill count
*/
public static Query<Map<ServerUUID, Integer>> playerKillCountOnServers(UUID playerUUID) {
String sql = SELECT + "COUNT(1) as kill_count, " + KillsTable.SERVER_UUID + FROM + KillsTable.TABLE_NAME +
String sql = SELECT + "COUNT(1) as kill_count, " + KillsTable.SERVER_UUID +
FROM + KillsTable.TABLE_NAME +
WHERE + KillsTable.KILLER_UUID + "=?" +
GROUP_BY + KillsTable.SERVER_UUID;
return getQueryForCountOf(playerUUID, sql, "kill_count");
@ -95,17 +99,21 @@ public class PerServerAggregateQueries {
*/
public static Query<Map<ServerUUID, Integer>> mobKillCountOnServers(UUID playerUUID) {
String sql = SELECT + "SUM(" + SessionsTable.MOB_KILLS + ") as kill_count, " +
SessionsTable.SERVER_UUID + FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.USER_UUID + "=?" +
GROUP_BY + SessionsTable.SERVER_UUID;
ServerTable.SERVER_UUID + " as server_uuid" +
FROM + SessionsTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " se on se." + ServerTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + SessionsTable.SERVER_ID;
return getQueryForCountOf(playerUUID, sql, "kill_count");
}
public static Query<Map<ServerUUID, Integer>> totalDeathCountOnServers(UUID playerUUID) {
String sql = SELECT + "SUM(" + SessionsTable.DEATHS + ") as death_count, " +
SessionsTable.SERVER_UUID + FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.USER_UUID + "=?" +
GROUP_BY + SessionsTable.SERVER_UUID;
ServerTable.SERVER_UUID + " as server_uuid" +
FROM + SessionsTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " se on se." + ServerTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + SessionsTable.SERVER_ID;
return getQueryForCountOf(playerUUID, sql, "death_count");
}
@ -121,7 +129,7 @@ public class PerServerAggregateQueries {
public Map<ServerUUID, Integer> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Integer> killCountMap = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(SessionsTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString("server_uuid"));
int count = set.getInt(column);
killCountMap.put(serverUUID, count);
}

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.storage.database.queries;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
@ -93,8 +94,8 @@ public class PlayerFetchQueries {
public static Query<Boolean> isPlayerRegisteredOnServer(UUID playerUUID, ServerUUID serverUUID) {
String sql = SELECT + "COUNT(1) as c" +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.USER_UUID + "=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
WHERE + UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return new HasMoreThanZeroQueryStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.storage.database.queries;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
@ -62,7 +63,7 @@ public class ServerAggregateQueries {
*/
public static Query<Integer> serverUserCount(ServerUUID serverUUID) {
String sql = SELECT + "COUNT(1) as c FROM " + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.SERVER_UUID + "=?";
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return new QueryStatement<Integer>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -85,14 +86,17 @@ public class ServerAggregateQueries {
* @return Map: Server UUID - Count of users registered to that server
*/
public static Query<Map<ServerUUID, Integer>> serverUserCounts() {
String sql = SELECT + "COUNT(1) as c, " + UserInfoTable.SERVER_UUID + FROM + UserInfoTable.TABLE_NAME +
GROUP_BY + UserInfoTable.SERVER_UUID;
String sql = SELECT + "COUNT(1) as c, " + ServerTable.SERVER_UUID +
FROM + UserInfoTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + '=' + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.SERVER_ID +
GROUP_BY + UserInfoTable.SERVER_ID;
return new QueryAllStatement<Map<ServerUUID, Integer>>(sql, 100) {
@Override
public Map<ServerUUID, Integer> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Integer> ofServer = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
int count = set.getInt("c");
ofServer.put(serverUUID, count);
}

View File

@ -20,8 +20,10 @@ import com.djrapitops.plan.delivery.domain.mutators.ActivityIndex;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -78,24 +80,26 @@ public class ActivityIndexQueries {
public static String selectActivityIndexSQL() {
String selectActivePlaytimeSQL = SELECT +
"ux." + UserInfoTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
"ux." + UserInfoTable.USER_ID + ",COALESCE(active_playtime,0) AS active_playtime" +
FROM + UserInfoTable.TABLE_NAME + " ux" +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_ID +
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
GROUP_BY + SessionsTable.USER_UUID +
") sx on sx.uuid=ux.uuid";
GROUP_BY + SessionsTable.USER_ID +
") sx on sx." + SessionsTable.USER_ID + "=ux." + UserInfoTable.USER_ID;
String selectThreeWeeks = selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL;
return SELECT +
"5.0 - 5.0 * AVG(1.0 / (?/2.0 * (q1.active_playtime*1.0/?) +1.0)) as activity_index," +
"q1." + SessionsTable.USER_UUID +
"u." + UsersTable.ID + " as " + SessionsTable.USER_ID + ',' +
"u." + UsersTable.USER_UUID +
FROM + '(' + selectThreeWeeks + ") q1" +
GROUP_BY + "q1." + SessionsTable.USER_UUID;
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=q1." + UserInfoTable.USER_ID +
GROUP_BY + "q1." + UserInfoTable.USER_ID;
}
public static void setSelectActivityIndexSQLParameters(PreparedStatement statement, int index, long playtimeThreshold, ServerUUID serverUUID, long date) throws SQLException {
@ -118,8 +122,8 @@ public class ActivityIndexQueries {
String selectIndexes = SELECT + "COALESCE(activity_index, 0) as activity_index" +
FROM + UserInfoTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectActivityIndex + ") q2 on q2." + SessionsTable.USER_UUID + "=u." + UserInfoTable.USER_UUID +
WHERE + "u." + UserInfoTable.SERVER_UUID + "=?" +
LEFT_JOIN + '(' + selectActivityIndex + ") q2 on q2." + SessionsTable.USER_ID + "=u." + UserInfoTable.USER_ID +
WHERE + "u." + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "u." + UserInfoTable.REGISTERED + "<=?";
String selectCount = SELECT + "COUNT(1) as count" +
@ -149,8 +153,8 @@ public class ActivityIndexQueries {
String selectIndexes = SELECT + "activity_index" +
FROM + UserInfoTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_UUID + "=u." + UserInfoTable.USER_UUID +
WHERE + "u." + UserInfoTable.SERVER_UUID + "=?" +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_ID + "=u." + UserInfoTable.USER_ID +
WHERE + "u." + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "u." + UserInfoTable.REGISTERED + "<=?";
return new QueryStatement<Map<String, Integer>>(selectIndexes) {
@ -179,8 +183,8 @@ public class ActivityIndexQueries {
String selectActivePlayerCount = SELECT + "COUNT(1) as count" +
FROM + '(' + selectActivityIndex + ") q2" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " u on u." + UserInfoTable.USER_UUID + "=q2." + SessionsTable.USER_UUID +
WHERE + "u." + UserInfoTable.SERVER_UUID + "=?" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " u on u." + UserInfoTable.USER_ID + "=q2." + SessionsTable.USER_ID +
WHERE + "u." + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "u." + UserInfoTable.REGISTERED + ">=?" +
AND + "u." + UserInfoTable.REGISTERED + "<=?" +
AND + "q2.activity_index>=?" +
@ -218,7 +222,7 @@ public class ActivityIndexQueries {
FROM + '(' + selectActivityIndex + ") q2" +
// Join two select activity index queries together to query Regular and Inactive players
INNER_JOIN + '(' + selectActivityIndex.replace("q1", "q3") + ") q4" +
" on q2." + SessionsTable.USER_UUID + "=q4." + SessionsTable.USER_UUID +
" on q2." + SessionsTable.USER_ID + "=q4." + SessionsTable.USER_ID +
WHERE + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
AND + "q4.activity_index>=?" +
@ -246,16 +250,16 @@ public class ActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectPlaytimePerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"SUM(p." + SessionsTable.SESSION_END + "-p." + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "p." + SessionsTable.SERVER_UUID + "=?" +
AND + "p." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
GROUP_BY + "p." + SessionsTable.USER_UUID;
GROUP_BY + "p." + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -281,13 +285,13 @@ public class ActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectSessionLengthPerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"p." + SessionsTable.SESSION_END + "-p." + SessionsTable.SESSION_START + " as length" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "p." + SessionsTable.SERVER_UUID + "=?" +
AND + "p." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?";
String selectAverage = SELECT + "AVG(length) as average" + FROM + '(' + selectSessionLengthPerPlayer + ") q1";
@ -315,16 +319,16 @@ public class ActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectPlaytimePerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"SUM(p." + SessionsTable.AFK_TIME + ") as afk" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "p." + SessionsTable.SERVER_UUID + "=?" +
AND + "p." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
GROUP_BY + "p." + SessionsTable.USER_UUID;
GROUP_BY + "p." + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(afk) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -347,15 +351,15 @@ public class ActivityIndexQueries {
}
public static Query<Collection<ActivityIndex>> activityIndexForNewPlayers(long after, long before, ServerUUID serverUUID, Long threshold) {
String selectNewUUIDs = SELECT + UserInfoTable.USER_UUID +
String selectNewUUIDs = SELECT + UserInfoTable.USER_ID +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String sql = SELECT + "activity_index" +
FROM + '(' + selectNewUUIDs + ") n" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID;
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_ID + "=a." + SessionsTable.USER_ID;
return new QueryStatement<Collection<ActivityIndex>>(sql) {
@Override
@ -378,22 +382,22 @@ public class ActivityIndexQueries {
}
public static Query<ActivityIndex> averageActivityIndexForRetainedPlayers(long after, long before, ServerUUID serverUUID, Long threshold) {
String selectNewUUIDs = SELECT + UserInfoTable.USER_UUID +
String selectNewUUIDs = SELECT + UserInfoTable.USER_ID +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_UUID +
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_ID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SERVER_UUID + "=?";
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String sql = SELECT + "AVG(activity_index) as average" +
FROM + '(' + selectNewUUIDs + ") n" +
INNER_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_UUID + "=u." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID;
INNER_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_ID + "=u." + SessionsTable.USER_ID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_ID + "=a." + SessionsTable.USER_ID;
return new QueryStatement<ActivityIndex>(sql) {
@Override
@ -418,23 +422,23 @@ public class ActivityIndexQueries {
}
public static Query<ActivityIndex> averageActivityIndexForNonRetainedPlayers(long after, long before, ServerUUID serverUUID, Long threshold) {
String selectNewUUIDs = SELECT + UserInfoTable.USER_UUID +
String selectNewUUIDs = SELECT + UserInfoTable.USER_ID +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_UUID +
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_ID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SERVER_UUID + "=?";
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String sql = SELECT + "AVG(activity_index) as average" +
FROM + '(' + selectNewUUIDs + ") n" +
LEFT_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_UUID + "=u." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID +
WHERE + "n." + SessionsTable.USER_UUID + IS_NULL;
LEFT_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_ID + "=u." + SessionsTable.USER_ID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_ID + "=a." + SessionsTable.USER_ID +
WHERE + "n." + SessionsTable.USER_ID + IS_NULL;
return new QueryStatement<ActivityIndex>(sql) {
@Override

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.delivery.domain.mutators.ActivityIndex;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import org.apache.commons.text.TextStringBuilder;
@ -79,25 +80,33 @@ public class NetworkActivityIndexQueries {
}
public static String selectActivityIndexSQL(Collection<ServerUUID> onServers) {
String selectServerIds = SELECT + ServerTable.ID +
FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(onServers, "','") + "')";
String selectActivePlaytimeSQL = SELECT +
"ux." + UsersTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
"ux." + UsersTable.ID + "," +
"ux." + UsersTable.USER_UUID + "," +
"COALESCE(active_playtime,0) AS active_playtime" +
FROM + UsersTable.TABLE_NAME + " ux" +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_ID +
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
(onServers.isEmpty() ? "" : AND + SessionsTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(onServers, "','") + "')") +
GROUP_BY + SessionsTable.USER_UUID +
") sx on sx.uuid=ux.uuid";
(onServers.isEmpty() ? "" : AND + SessionsTable.SERVER_ID + " IN (" + selectServerIds + ")") +
GROUP_BY + SessionsTable.USER_ID +
") sx on sx." + SessionsTable.USER_ID + "=ux." + UsersTable.ID;
String selectThreeWeeks = selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL + UNION_ALL + selectActivePlaytimeSQL;
return SELECT +
"5.0 - 5.0 * AVG(1.0 / (?/2.0 * (q1.active_playtime*1.0/?) +1.0)) as activity_index," +
"q1." + SessionsTable.USER_UUID +
"u." + UsersTable.ID + " as " + SessionsTable.USER_ID + ',' +
"u." + UsersTable.USER_UUID +
FROM + '(' + selectThreeWeeks + ") q1" +
GROUP_BY + "q1." + SessionsTable.USER_UUID;
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=q1." + UsersTable.ID +
GROUP_BY + "q1." + UsersTable.ID;
}
public static void setSelectActivityIndexSQLParameters(PreparedStatement statement, int index, long playtimeThreshold, long date) throws SQLException {
@ -117,7 +126,7 @@ public class NetworkActivityIndexQueries {
String selectIndexes = SELECT + "COALESCE(activity_index, 0) as activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectActivityIndex + ") q2 on q2." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectActivityIndex + ") q2 on q2." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "u." + UsersTable.REGISTERED + "<=?";
String selectCount = SELECT + "COUNT(1) as count" +
@ -146,7 +155,7 @@ public class NetworkActivityIndexQueries {
String selectIndexes = SELECT + "activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "u." + UsersTable.REGISTERED + "<=?";
return new QueryStatement<Map<String, Integer>>(selectIndexes) {
@ -169,15 +178,15 @@ public class NetworkActivityIndexQueries {
};
}
public static Query<Map<String, Integer>> fetchActivityIndexGroupingsOn(long date, long threshold, Collection<UUID> playerUUIDs, List<ServerUUID> serverUUIDs) {
public static Query<Map<String, Integer>> fetchActivityIndexGroupingsOn(long date, long threshold, Collection<Integer> userIds, List<ServerUUID> serverUUIDs) {
String selectActivityIndex = selectActivityIndexSQL(serverUUIDs);
String selectIndexes = SELECT + "activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectActivityIndex + ") s on s." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "u." + UsersTable.REGISTERED + "<=?" +
AND + "u." + UsersTable.USER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')";
AND + "u." + UsersTable.ID + " IN (" +
new TextStringBuilder().appendWithSeparators(userIds, ",").build() + ")";
return new QueryStatement<Map<String, Integer>>(selectIndexes) {
@Override
@ -204,7 +213,7 @@ public class NetworkActivityIndexQueries {
String selectActivePlayerCount = SELECT + "COUNT(1) as count" +
FROM + '(' + selectActivityIndex + ") q2" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=q2." + SessionsTable.USER_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on q2." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "u." + UsersTable.REGISTERED + ">=?" +
AND + "u." + UsersTable.REGISTERED + "<=?" +
AND + "q2.activity_index>=?" +
@ -240,7 +249,7 @@ public class NetworkActivityIndexQueries {
FROM + '(' + selectActivityIndex + ") q2" +
// Join two select activity index queries together to query Regular and Inactive players
INNER_JOIN + '(' + selectActivityIndex.replace("q1", "q3") + ") q4" +
" on q2." + SessionsTable.USER_UUID + "=q4." + SessionsTable.USER_UUID +
" on q2." + SessionsTable.USER_ID + "=q4." + SessionsTable.USER_ID +
WHERE + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
AND + "q4.activity_index>=?" +
@ -268,15 +277,15 @@ public class NetworkActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectPlaytimePerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"SUM(p." + SessionsTable.SESSION_END + "-p." + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
GROUP_BY + "p." + SessionsTable.USER_UUID;
GROUP_BY + "p." + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -301,10 +310,10 @@ public class NetworkActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectSessionLengthPerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"p." + SessionsTable.SESSION_END + "-p." + SessionsTable.SESSION_START + " as length" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "q2.activity_index>=?" +
@ -333,15 +342,15 @@ public class NetworkActivityIndexQueries {
return database -> {
// INNER JOIN limits the users to only those that are regular
String selectPlaytimePerPlayer = SELECT +
"p." + SessionsTable.USER_UUID + "," +
"p." + SessionsTable.USER_ID + "," +
"SUM(p." + SessionsTable.AFK_TIME + ") as afk" +
FROM + SessionsTable.TABLE_NAME + " p" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_UUID + "=p." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") q2 on q2." + SessionsTable.USER_ID + "=p." + SessionsTable.USER_ID +
WHERE + "p." + SessionsTable.SESSION_END + "<=?" +
AND + "p." + SessionsTable.SESSION_START + ">=?" +
AND + "q2.activity_index>=?" +
AND + "q2.activity_index<?" +
GROUP_BY + "p." + SessionsTable.USER_UUID;
GROUP_BY + "p." + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(afk) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -363,14 +372,14 @@ public class NetworkActivityIndexQueries {
}
public static Query<Collection<ActivityIndex>> activityIndexForNewPlayers(long after, long before, Long threshold) {
String selectNewUUIDs = SELECT + UsersTable.USER_UUID +
String selectNewUUIDs = SELECT + UsersTable.ID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.REGISTERED + "<=?" +
AND + UsersTable.REGISTERED + ">=?";
String sql = SELECT + "activity_index" +
FROM + '(' + selectNewUUIDs + ") n" +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID;
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + UsersTable.ID + "=a." + SessionsTable.USER_ID;
return new QueryStatement<Collection<ActivityIndex>>(sql) {
@Override
@ -392,20 +401,20 @@ public class NetworkActivityIndexQueries {
}
public static Query<ActivityIndex> averageActivityIndexForRetainedPlayers(long after, long before, Long threshold) {
String selectNewUUIDs = SELECT + UsersTable.USER_UUID +
String selectNewUUIDs = SELECT + UsersTable.ID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.REGISTERED + "<=?" +
AND + UsersTable.REGISTERED + ">=?";
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_UUID +
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_ID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?";
String sql = SELECT + "AVG(activity_index) as average" +
FROM + '(' + selectNewUUIDs + ") n" +
INNER_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_UUID + "=u." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID;
INNER_JOIN + '(' + selectUniqueUUIDs + ") u on n." + UsersTable.ID + "=u." + SessionsTable.USER_ID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + UsersTable.ID + "=a." + SessionsTable.USER_ID;
return new QueryStatement<ActivityIndex>(sql) {
@Override
@ -427,57 +436,20 @@ public class NetworkActivityIndexQueries {
};
}
public static Query<ActivityIndex> averageActivityIndexForNonRetainedPlayers(long after, long before, Long threshold) {
String selectNewUUIDs = SELECT + UsersTable.USER_UUID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.REGISTERED + "<=?" +
AND + UsersTable.REGISTERED + ">=?";
String selectUniqueUUIDs = SELECT + "DISTINCT " + SessionsTable.USER_UUID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?";
String sql = SELECT + "AVG(activity_index) as average" +
FROM + '(' + selectNewUUIDs + ") n" +
LEFT_JOIN + '(' + selectUniqueUUIDs + ") u on n." + SessionsTable.USER_UUID + "=u." + SessionsTable.USER_UUID +
INNER_JOIN + '(' + selectActivityIndexSQL() + ") a on n." + SessionsTable.USER_UUID + "=a." + SessionsTable.USER_UUID +
WHERE + "n." + SessionsTable.USER_UUID + IS_NULL;
return new QueryStatement<ActivityIndex>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, before);
statement.setLong(2, after);
// Have played in the last half of the time frame
long half = before - (before - after) / 2;
statement.setLong(3, half);
statement.setLong(4, before);
setSelectActivityIndexSQLParameters(statement, 5, threshold, before);
}
@Override
public ActivityIndex processResults(ResultSet set) throws SQLException {
return set.next() ? new ActivityIndex(set.getDouble("average"), before) : new ActivityIndex(0.0, before);
}
};
}
public static Query<Map<UUID, ActivityIndex>> activityIndexForAllPlayers(long date, long playtimeThreshold) {
public static Query<Map<Integer, ActivityIndex>> activityIndexForAllPlayers(long date, long playtimeThreshold) {
String selectActivityIndex = selectActivityIndexSQL();
return new QueryStatement<Map<UUID, ActivityIndex>>(selectActivityIndex, 1000) {
return new QueryStatement<Map<Integer, ActivityIndex>>(selectActivityIndex, 1000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
setSelectActivityIndexSQLParameters(statement, 1, playtimeThreshold, date);
}
@Override
public Map<UUID, ActivityIndex> processResults(ResultSet set) throws SQLException {
Map<UUID, ActivityIndex> indexes = new HashMap<>();
public Map<Integer, ActivityIndex> processResults(ResultSet set) throws SQLException {
Map<Integer, ActivityIndex> indexes = new HashMap<>();
while (set.next()) {
indexes.put(
UUID.fromString(set.getString(SessionsTable.USER_UUID)),
set.getInt(UsersTable.ID),
new ActivityIndex(set.getDouble("activity_index"), date)
);
}

View File

@ -20,6 +20,7 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.building.Sql;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
@ -74,11 +75,11 @@ public class PlayerCountQueries {
}
public static Query<Integer> uniquePlayerCount(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
String sql = SELECT + "COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?";
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return queryPlayerCount(sql, after, before, serverUUID);
}
@ -91,7 +92,7 @@ public class PlayerCountQueries {
* @return Unique player count (players who played within time frame)
*/
public static Query<Integer> uniquePlayerCount(long after, long before) {
String sql = SELECT + "COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
String sql = SELECT + "COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?";
@ -100,11 +101,12 @@ public class PlayerCountQueries {
}
public static Query<Map<ServerUUID, Integer>> uniquePlayerCounts(long after, long before) {
String sql = SELECT + SessionsTable.SERVER_UUID + ",COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
String sql = SELECT + ServerTable.SERVER_UUID + ",COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " se on se." + ServerTable.ID + "=" + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
GROUP_BY + UserInfoTable.SERVER_UUID;
GROUP_BY + SessionsTable.SERVER_ID;
return new QueryStatement<Map<ServerUUID, Integer>>(sql) {
@Override
@ -117,7 +119,7 @@ public class PlayerCountQueries {
public Map<ServerUUID, Integer> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Integer> byServer = new HashMap<>();
while (set.next()) {
byServer.put(ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count"));
byServer.put(ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)), set.getInt("player_count"));
}
return byServer;
}
@ -139,11 +141,11 @@ public class PlayerCountQueries {
String selectUniquePlayersPerDay = SELECT +
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
"*1000 as date," +
"COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
"COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectUniquePlayersPerDay, 100) {
@ -182,11 +184,11 @@ public class PlayerCountQueries {
String selectUniquePlayersPerDay = SELECT +
sql.dateToEpochSecond(sql.dateToHourStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
"*1000 as date," +
"COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
"COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectUniquePlayersPerDay, 100) {
@ -224,7 +226,7 @@ public class PlayerCountQueries {
String selectUniquePlayersPerDay = SELECT +
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
"*1000 as date," +
"COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
"COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
@ -264,7 +266,7 @@ public class PlayerCountQueries {
String selectUniquePlayersPerDay = SELECT +
sql.dateToEpochSecond(sql.dateToHourStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
"*1000 as date," +
"COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
"COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
@ -296,11 +298,11 @@ public class PlayerCountQueries {
String selectUniquePlayersPerDay = SELECT +
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + SessionsTable.SESSION_START + "+?)/1000"))) +
"*1000 as date," +
"COUNT(DISTINCT " + SessionsTable.USER_UUID + ") as player_count" +
"COUNT(DISTINCT " + SessionsTable.USER_ID + ") as player_count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
String selectAverage = SELECT + "AVG(player_count) as average" + FROM + '(' + selectUniquePlayersPerDay + ") q1";
@ -326,7 +328,7 @@ public class PlayerCountQueries {
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return queryPlayerCount(sql, after, before, serverUUID);
}
@ -341,11 +343,12 @@ public class PlayerCountQueries {
}
public static Query<Map<ServerUUID, Integer>> newPlayerCounts(long after, long before) {
String sql = SELECT + UserInfoTable.SERVER_UUID + ",COUNT(1) as player_count" +
String sql = SELECT + ServerTable.SERVER_UUID + ",COUNT(1) as player_count" +
FROM + UserInfoTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + '=' + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.SERVER_ID +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
GROUP_BY + UserInfoTable.SERVER_UUID;
GROUP_BY + UserInfoTable.SERVER_ID;
return new QueryStatement<Map<ServerUUID, Integer>>(sql) {
@Override
@ -358,7 +361,7 @@ public class PlayerCountQueries {
public Map<ServerUUID, Integer> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Integer> byServer = new HashMap<>();
while (set.next()) {
byServer.put(ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID)), set.getInt("player_count"));
byServer.put(ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)), set.getInt("player_count"));
}
return byServer;
}
@ -384,7 +387,7 @@ public class PlayerCountQueries {
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?" +
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectNewPlayersQuery, 100) {
@ -427,7 +430,7 @@ public class PlayerCountQueries {
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?" +
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectNewPlayersQuery, 100) {
@ -541,7 +544,7 @@ public class PlayerCountQueries {
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.SERVER_UUID + "=?" +
AND + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
String selectAverage = SELECT + "AVG(player_count) as average" + FROM + '(' + selectNewPlayersQuery + ") q1";
@ -563,46 +566,44 @@ public class PlayerCountQueries {
}
public static Query<Integer> retainedPlayerCount(long after, long before, ServerUUID serverUUID) {
String selectNewUUIDs = SELECT + UserInfoTable.USER_UUID +
FROM + UserInfoTable.TABLE_NAME +
String selectUniqueUUIDs = SELECT + DISTINCT + "s." + SessionsTable.USER_ID +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " ux" +
" on ux." + UserInfoTable.USER_ID + "=s." + SessionsTable.USER_ID +
AND + "ux." + UserInfoTable.SERVER_ID + "=s." + SessionsTable.SERVER_ID +
WHERE + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.SERVER_UUID + "=?";
String selectUniqueUUIDs = SELECT + DISTINCT + SessionsTable.USER_UUID +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SERVER_UUID + "=?";
AND + "s." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
String sql = SELECT + "COUNT(1) as player_count" +
FROM + '(' + selectNewUUIDs + ") q1" +
INNER_JOIN + '(' + selectUniqueUUIDs + ") q2 on q1." + UserInfoTable.USER_UUID + "=q2." + SessionsTable.USER_UUID;
return new QueryStatement<Integer>(sql) {
return new QueryStatement<Integer>(selectUniqueUUIDs) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, after);
statement.setLong(2, before);
statement.setString(3, serverUUID.toString());
// Have played in the last half of the time frame
long half = before - (before - after) / 2;
statement.setLong(4, half);
statement.setLong(5, before);
statement.setString(6, serverUUID.toString());
statement.setLong(3, half);
statement.setLong(4, before);
statement.setString(5, serverUUID.toString());
}
@Override
public Integer processResults(ResultSet set) throws SQLException {
return set.next() ? set.getInt("player_count") : 0;
int count = 0;
while (set.next()) {
count++;
}
return count;
}
};
}
public static Query<Integer> operators(ServerUUID serverUUID) {
String sql = SELECT + "COUNT(1) as player_count" + FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.SERVER_UUID + "=?" +
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + UserInfoTable.OP + "=?";
return new QueryStatement<Integer>(sql) {
@Override

View File

@ -19,6 +19,7 @@ package com.djrapitops.plan.storage.database.queries.analysis;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
@ -39,8 +40,8 @@ public class TopListQueries {
String sql = SELECT + UsersTable.USER_NAME + ", " +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
WHERE + SessionsTable.SERVER_UUID + "=?" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=s." + SessionsTable.USER_ID +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_START + ">?" +
AND + SessionsTable.SESSION_END + "<?" +
GROUP_BY + "name" +
@ -74,8 +75,8 @@ public class TopListQueries {
String sql = SELECT + UsersTable.USER_NAME + ", " +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
WHERE + SessionsTable.SERVER_UUID + "=?" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=s." + SessionsTable.USER_ID +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_START + ">?" +
AND + SessionsTable.SESSION_END + "<?" +
GROUP_BY + "name" +

View File

@ -1,155 +0,0 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.storage.database.queries.containers;
import com.djrapitops.plan.delivery.domain.Nickname;
import com.djrapitops.plan.delivery.domain.container.PerServerContainer;
import com.djrapitops.plan.delivery.domain.container.PlayerContainer;
import com.djrapitops.plan.delivery.domain.keys.PlayerKeys;
import com.djrapitops.plan.delivery.domain.mutators.PerServerMutator;
import com.djrapitops.plan.delivery.domain.mutators.SessionsMutator;
import com.djrapitops.plan.gathering.domain.*;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.SQLDB;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.objects.*;
import java.util.*;
/**
* Used to get PlayerContainers of all players on a server, some limitations apply to DataContainer keys.
* <p>
* Limitations:
* - PlayerContainers do not support: PlayerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
* - PlayerContainers PlayerKeys.PER_SERVER does not support: PerServerKeys WORLD_TIMES, PLAYER_KILLS, PLAYER_KILL_COUNT
* <p>
* Blocking methods are not called until DataContainer getter methods are called.
*
* @author AuroraLS3
*/
public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>> {
private final ServerUUID serverUUID;
public ServerPlayerContainersQuery(ServerUUID serverUUID) {
this.serverUUID = serverUUID;
}
@Override
public List<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>();
Collection<BaseUser> baseUsers = db.query(BaseUserQueries.fetchServerBaseUsers(serverUUID));
Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID));
Map<UUID, List<Nickname>> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID));
Map<UUID, List<Ping>> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID));
Map<UUID, List<FinishedSession>> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID));
Map<UUID, UserInfo> userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID));
Map<UUID, PerServerContainer> perServerInfo = getPerServerData(
userInformation,
sessions,
pingData
);
for (BaseUser user : baseUsers) {
PlayerContainer container = new PlayerContainer();
// BaseUser
UUID uuid = user.getUuid();
container.putRawData(PlayerKeys.UUID, uuid);
container.putRawData(PlayerKeys.NAME, user.getName());
container.putRawData(PlayerKeys.REGISTERED, user.getRegistered());
container.putRawData(PlayerKeys.KICK_COUNT, user.getTimesKicked());
// GeoInfo
container.putRawData(PlayerKeys.GEO_INFO, geoInformation.getOrDefault(uuid, Collections.emptyList()));
// Ping
container.putRawData(PlayerKeys.PING, pingData.get(uuid));
// Nickname, only used for the raw server JSON.
container.putRawData(PlayerKeys.NICKNAMES, nicknames.get(uuid));
// PerServerContainer
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
List<FinishedSession> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
container.getValue(PlayerKeys.ACTIVE_SESSION)
.map(ActiveSession::toFinishedSessionFromStillActive)
.ifPresent(playerSessions::add);
return playerSessions;
}
);
// Calculating getters
container.putCachingSupplier(PlayerKeys.WORLD_TIMES, () -> {
WorldTimes worldTimes = new PerServerMutator(container.getUnsafe(PlayerKeys.PER_SERVER)).flatMapWorldTimes();
container.getValue(PlayerKeys.ACTIVE_SESSION)
.ifPresent(session -> worldTimes.add(
session.getExtraData(WorldTimes.class).orElseGet(WorldTimes::new))
);
return worldTimes;
});
container.putSupplier(PlayerKeys.BANNED, () -> PerServerMutator.forContainer(container).isBanned());
container.putSupplier(PlayerKeys.OPERATOR, () -> PerServerMutator.forContainer(container).isOperator());
container.putSupplier(PlayerKeys.LAST_SEEN, () -> SessionsMutator.forContainer(container).toLastSeen());
container.putSupplier(PlayerKeys.PLAYER_KILLS, () -> SessionsMutator.forContainer(container).toPlayerKillList());
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size());
container.putSupplier(PlayerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
containers.add(container);
}
return containers;
}
/**
* Create PerServerContainers for each player.
*
* @param userInformation Map: Player UUID - UserInfo of this server
* @param sessions Map: Player UUID - List of Sessions of this server
* @param ping Map: Player UUID - List of Ping data of this server
* @return Map: Player UUID - PerServerContainer
*/
private Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, UserInfo> userInformation,
Map<UUID, List<FinishedSession>> sessions,
Map<UUID, List<Ping>> ping
) {
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
for (Map.Entry<UUID, UserInfo> entry : userInformation.entrySet()) {
UUID playerUUID = entry.getKey();
PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer());
perServerContainer.putUserInfo(entry.getValue()); // Information found withing UserInfo
perServerContainer.putSessions(sessions.get(playerUUID)); // Session list
perServerContainer.putPing(ping.get(playerUUID)); // Ping list
perServerContainer.putCalculatingSuppliers(); // Derivative values
perServerContainers.put(playerUUID, perServerContainer);
}
return perServerContainers;
}
}

View File

@ -42,11 +42,11 @@ public interface Filter {
* @return Set of UUIDs this filter applies to
* @throws IllegalArgumentException If the arguments are not valid.
*/
Set<UUID> getMatchingUUIDs(InputFilterDto query);
Set<Integer> getMatchingUserIds(InputFilterDto query);
default Result apply(InputFilterDto query) {
try {
return new Result(null, getKind(), getMatchingUUIDs(query));
return new Result(null, getKind(), getMatchingUserIds(query));
} catch (CompleteSetException allMatch) {
return new Result(null, getKind() + " (skip)", new HashSet<>());
}
@ -57,35 +57,35 @@ public interface Filter {
private final String filterKind;
private final int resultSize;
private final Set<UUID> currentUUIDs;
private final Set<Integer> currentUserIds;
private Result(Result previous, String filterKind, Set<UUID> currentUUIDs) {
private Result(Result previous, String filterKind, Set<Integer> currentUserIds) {
this.previous = previous;
this.filterKind = filterKind;
this.resultSize = currentUUIDs.size();
this.currentUUIDs = currentUUIDs;
this.resultSize = currentUserIds.size();
this.currentUserIds = currentUserIds;
}
public Result apply(Filter filter, InputFilterDto query) {
try {
Set<UUID> got = filter.getMatchingUUIDs(query);
currentUUIDs.retainAll(got);
return new Result(this, filter.getKind(), currentUUIDs);
Set<Integer> got = filter.getMatchingUserIds(query);
currentUserIds.retainAll(got);
return new Result(this, filter.getKind(), currentUserIds);
} catch (CompleteSetException allMatch) {
return notApplied(filter);
}
}
public Result notApplied(Filter filter) {
return new Result(this, filter.getKind() + " (skip)", currentUUIDs);
return new Result(this, filter.getKind() + " (skip)", currentUserIds);
}
public boolean isEmpty() {
return resultSize <= 0;
}
public Set<UUID> getResultUUIDs() {
return currentUUIDs;
public Set<Integer> getResultUserIds() {
return currentUserIds;
}
public List<ResultPath> getInverseResultPath() {

View File

@ -27,7 +27,10 @@ import com.djrapitops.plan.storage.database.queries.filter.CompleteSetException;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Singleton
@ -63,7 +66,7 @@ public class ActivityIndexFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
List<String> selected = getSelected(query);
String[] options = getOptionsArray();
@ -78,7 +81,7 @@ public class ActivityIndexFilter extends MultiOptionFilter {
}
long date = System.currentTimeMillis();
long playtimeThreshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
Map<UUID, ActivityIndex> indexes = dbSystem.getDatabase().query(NetworkActivityIndexQueries.activityIndexForAllPlayers(date, playtimeThreshold));
Map<Integer, ActivityIndex> indexes = dbSystem.getDatabase().query(NetworkActivityIndexQueries.activityIndexForAllPlayers(date, playtimeThreshold));
return indexes.entrySet().stream()
.filter(entry -> selected.contains(entry.getValue().getGroup(locale)))

View File

@ -24,7 +24,6 @@ import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQuerie
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Set;
import java.util.UUID;
/**
* Special filter only used in cases where no filters are specified.
@ -52,7 +51,7 @@ public class AllPlayersFilter implements Filter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllPlayerUUIDs());
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchAllUserIds());
}
}

View File

@ -57,17 +57,17 @@ public class BannedFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
List<String> selected = getSelected(query);
Set<UUID> uuids = new HashSet<>();
Set<Integer> userIds = new HashSet<>();
String[] options = getOptionsArray();
boolean includeBanned = selected.contains(options[0]);
boolean includeNotBanned = selected.contains(options[1]);
if (includeBanned && includeNotBanned) throw new CompleteSetException(); // Full set, no need for query
if (includeBanned) uuids.addAll(dbSystem.getDatabase().query(UserInfoQueries.uuidsOfBanned()));
if (includeNotBanned) uuids.addAll(dbSystem.getDatabase().query(UserInfoQueries.uuidsOfNotBanned()));
return uuids;
if (includeBanned) userIds.addAll(dbSystem.getDatabase().query(UserInfoQueries.userIdsOfBanned()));
if (includeNotBanned) userIds.addAll(dbSystem.getDatabase().query(UserInfoQueries.userIdsOfNotBanned()));
return userIds;
}
}

View File

@ -22,7 +22,10 @@ import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Singleton
public class GeolocationsFilter extends MultiOptionFilter {
@ -47,7 +50,7 @@ public class GeolocationsFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
return dbSystem.getDatabase().query(GeoInfoQueries.uuidsOfPlayersWithGeolocations(getSelected(query)));
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
return dbSystem.getDatabase().query(GeoInfoQueries.userIdsOfPlayersWithGeolocations(getSelected(query)));
}
}

View File

@ -22,7 +22,10 @@ import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Singleton
public class JoinAddressFilter extends MultiOptionFilter {
@ -47,7 +50,7 @@ public class JoinAddressFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
return dbSystem.getDatabase().query(UserInfoQueries.uuidsOfPlayersWithJoinAddresses(getSelected(query)));
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
return dbSystem.getDatabase().query(UserInfoQueries.userIdsOfPlayersWithJoinAddresses(getSelected(query)));
}
}

View File

@ -57,17 +57,17 @@ public class OperatorsFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
List<String> selected = getSelected(query);
Set<UUID> uuids = new HashSet<>();
Set<Integer> userIds = new HashSet<>();
String[] options = getOptionsArray();
boolean includeOperators = selected.contains(options[0]);
boolean includeNonOperators = selected.contains(options[1]);
if (includeOperators && includeNonOperators) throw new CompleteSetException(); // Full set, no need for query
if (includeOperators) uuids.addAll(dbSystem.getDatabase().query(UserInfoQueries.uuidsOfOperators()));
if (includeNonOperators) uuids.addAll(dbSystem.getDatabase().query(UserInfoQueries.uuidsOfNonOperators()));
return uuids;
if (includeOperators) userIds.addAll(dbSystem.getDatabase().query(UserInfoQueries.userIdsOfOperators()));
if (includeNonOperators) userIds.addAll(dbSystem.getDatabase().query(UserInfoQueries.userIdsOfNonOperators()));
return userIds;
}
}

View File

@ -25,7 +25,10 @@ import com.google.gson.Gson;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@Singleton
public class PlayedBetweenDateRangeFilter extends DateRangeFilter {
@ -44,12 +47,12 @@ public class PlayedBetweenDateRangeFilter extends DateRangeFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
long after = getAfter(query);
long before = getBefore(query);
List<String> serverNames = getServerNames(query);
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
return dbSystem.getDatabase().query(SessionQueries.uuidsOfPlayedBetween(after, before, serverUUIDs));
return dbSystem.getDatabase().query(SessionQueries.userIdsOfPlayedBetween(after, before, serverUUIDs));
}
private List<String> getServerNames(InputFilterDto query) {

View File

@ -24,7 +24,10 @@ import com.djrapitops.plan.storage.database.queries.objects.UserInfoQueries;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Singleton
public class PlayedOnServerFilter extends MultiOptionFilter {
@ -51,10 +54,10 @@ public class PlayedOnServerFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
List<String> serverNames = getSelected(query);
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
return dbSystem.getDatabase().query(UserInfoQueries.uuidsOfRegisteredBetween(0, System.currentTimeMillis(), serverUUIDs));
return dbSystem.getDatabase().query(UserInfoQueries.userIdsOfRegisteredBetween(0, System.currentTimeMillis(), serverUUIDs));
}
}

View File

@ -25,10 +25,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPlayerValueTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionPluginTable;
import com.djrapitops.plan.storage.database.sql.tables.ExtensionProviderTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.*;
import org.apache.commons.lang3.StringUtils;
import javax.inject.Inject;
@ -51,8 +48,8 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
}
private static Query<List<PluginBooleanOption>> pluginBooleanOptionsQuery() {
String selectOptions = SELECT +
"server." + ServerTable.SERVER_ID + " as server_id," +
String selectOptions = SELECT + DISTINCT +
"server." + ServerTable.ID + " as server_id," +
"server." + ServerTable.NAME + " as server_name," +
"plugin." + ExtensionPluginTable.PLUGIN_NAME + " as plugin_name," +
"provider." + ExtensionProviderTable.TEXT + " as provider_text" +
@ -83,16 +80,16 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
};
}
private static Query<Set<UUID>> playersInGroups(
private static Query<Set<Integer>> playersInGroups(
Map<PluginBooleanOption, SelectedBoolean> selected,
Map<String, ServerUUID> namesToUUIDs
) {
return db -> {
Set<UUID> playerUUIDs = new HashSet<>();
Set<Integer> userIds = new HashSet<>();
for (Map.Entry<PluginBooleanOption, SelectedBoolean> option : selected.entrySet()) {
PluginBooleanOption pluginBooleanOption = option.getKey();
SelectedBoolean selectedBoolean = option.getValue();
playerUUIDs.addAll(
userIds.addAll(
db.query(playersInGroup(
namesToUUIDs.get(pluginBooleanOption.getServerName()),
pluginBooleanOption.getPluginName(),
@ -101,23 +98,24 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
))
);
}
return playerUUIDs;
return userIds;
};
}
private static Query<Set<UUID>> playersInGroup(
private static Query<Set<Integer>> playersInGroup(
ServerUUID serverUUID, String pluginName, String providerText, SelectedBoolean selectedBoolean
) {
String selectUUIDsWithBooleanValues = SELECT + DISTINCT + "value." + ExtensionPlayerValueTable.USER_UUID + " as uuid" +
String selectUUIDsWithBooleanValues = SELECT + DISTINCT + "u." + UsersTable.ID + " as id" +
FROM + ExtensionPluginTable.TABLE_NAME + " plugin" +
INNER_JOIN + ExtensionProviderTable.TABLE_NAME + " provider on provider." + ExtensionProviderTable.PLUGIN_ID + "=plugin." + ExtensionPluginTable.ID +
INNER_JOIN + ExtensionPlayerValueTable.TABLE_NAME + " value on value." + ExtensionPlayerValueTable.PROVIDER_ID + "=provider." + ExtensionProviderTable.ID +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=value." + ExtensionPlayerValueTable.USER_UUID +
WHERE + "plugin." + ExtensionPluginTable.SERVER_UUID + "=?" +
AND + "plugin." + ExtensionPluginTable.PLUGIN_NAME + "=?" +
AND + "provider." + ExtensionProviderTable.TEXT + "=?" +
AND + "value." + ExtensionPlayerValueTable.BOOLEAN_VALUE + (selectedBoolean == SelectedBoolean.BOTH ? "IS NOT NULL" : "=?");
return new QueryStatement<Set<UUID>>(selectUUIDsWithBooleanValues) {
return new QueryStatement<Set<Integer>>(selectUUIDsWithBooleanValues) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
@ -129,12 +127,12 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString("uuid")));
userIds.add(set.getInt("id"));
}
return uuids;
return userIds;
}
};
}
@ -164,7 +162,7 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
Map<PluginBooleanOption, SelectedBoolean> selectedBooleanOptions = new HashMap<>();
for (String selected : getSelected(query)) {
String[] optionAndBoolean = StringUtils.split(selected, ":", 2);
@ -185,7 +183,7 @@ public class PluginBooleanGroupFilter extends MultiOptionFilter {
BOTH
}
private static class PluginBooleanOption implements Comparable<PluginBooleanOption> {
public static class PluginBooleanOption implements Comparable<PluginBooleanOption> {
private final String serverName;
private final String pluginName;
private final String providerText;

View File

@ -18,7 +18,7 @@ package com.djrapitops.plan.storage.database.queries.filter.filters;
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
import com.djrapitops.plan.extension.implementation.providers.ProviderIdentifier;
import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionUUIDsInGroupQuery;
import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionUserIdsInGroupQuery;
import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.identification.ServerUUID;
@ -67,9 +67,9 @@ public class PluginGroupsFilter extends MultiOptionFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
return dbSystem.getDatabase().query(
new ExtensionUUIDsInGroupQuery(identifier.getPluginName(), identifier.getProviderName(), identifier.getServerUUID(), getSelected(query))
new ExtensionUserIdsInGroupQuery(identifier.getPluginName(), identifier.getProviderName(), identifier.getServerUUID(), getSelected(query))
);
}
@ -83,7 +83,7 @@ public class PluginGroupsFilter extends MultiOptionFilter {
super(SELECT + DISTINCT +
"pl." + ExtensionPluginTable.PLUGIN_NAME + " as plugin_name," +
"s." + ServerTable.NAME + " as server_name," +
"s." + ServerTable.SERVER_ID + " as server_id," +
"s." + ServerTable.ID + " as server_id," +
"pl." + ExtensionPluginTable.SERVER_UUID + " as server_uuid," +
"pr." + ExtensionProviderTable.PROVIDER_NAME + " as provider_name," +
"gr." + ExtensionGroupsTable.GROUP_NAME + " as group_name" +

View File

@ -26,7 +26,10 @@ import com.google.gson.Gson;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
@Singleton
public class RegisteredBetweenDateRangeFilter extends DateRangeFilter {
@ -45,14 +48,14 @@ public class RegisteredBetweenDateRangeFilter extends DateRangeFilter {
}
@Override
public Set<UUID> getMatchingUUIDs(InputFilterDto query) {
public Set<Integer> getMatchingUserIds(InputFilterDto query) {
long after = getAfter(query);
long before = getBefore(query);
List<String> serverNames = getServerNames(query);
List<ServerUUID> serverUUIDs = serverNames.isEmpty() ? Collections.emptyList() : dbSystem.getDatabase().query(ServerQueries.fetchServersMatchingIdentifiers(serverNames));
return dbSystem.getDatabase().query(
serverUUIDs.isEmpty() ? BaseUserQueries.uuidsOfRegisteredBetween(after, before)
: UserInfoQueries.uuidsOfRegisteredBetween(after, before, serverUUIDs)
serverUUIDs.isEmpty() ? BaseUserQueries.userIdsOfRegisteredBetween(after, before)
: UserInfoQueries.userIdsOfRegisteredBetween(after, before, serverUUIDs)
);
}

View File

@ -18,12 +18,10 @@ package com.djrapitops.plan.storage.database.queries.objects;
import com.djrapitops.plan.gathering.domain.BaseUser;
import com.djrapitops.plan.gathering.domain.UserInfo;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.building.Select;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import java.sql.PreparedStatement;
@ -107,45 +105,12 @@ public class BaseUserQueries {
};
}
/**
* Query database for common user information for players that have played on a specific server.
* <p>
* Only one {@link BaseUser} per player exists unlike {@link UserInfo} which is available per server.
* <p>
* This will fetch BaseUsers for which UserInfo object also exists on the server.
*
* @param serverUUID UUID of the Plan server.
* @return Collection: BaseUsers
*/
public static Query<Collection<BaseUser>> fetchServerBaseUsers(ServerUUID serverUUID) {
String sql = SELECT +
UsersTable.TABLE_NAME + '.' + UsersTable.USER_UUID + ',' +
UsersTable.USER_NAME + ',' +
UsersTable.TABLE_NAME + '.' + UsersTable.REGISTERED + ',' +
UsersTable.TIMES_KICKED +
FROM + UsersTable.TABLE_NAME +
INNER_JOIN + UserInfoTable.TABLE_NAME + " on " +
UsersTable.TABLE_NAME + '.' + UsersTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_UUID +
WHERE + UserInfoTable.SERVER_UUID + "=?";
return new QueryStatement<Collection<BaseUser>>(sql, 1000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Collection<BaseUser> processResults(ResultSet set) throws SQLException {
return extractBaseUsers(set);
}
};
}
public static Query<Set<UUID>> uuidsOfRegisteredBetween(long after, long before) {
String sql = SELECT + DISTINCT + UsersTable.USER_UUID +
public static Query<Set<Integer>> userIdsOfRegisteredBetween(long after, long before) {
String sql = SELECT + DISTINCT + UsersTable.ID +
FROM + UsersTable.TABLE_NAME +
WHERE + UsersTable.REGISTERED + ">=?" +
AND + UsersTable.REGISTERED + "<=?";
return new QueryStatement<Set<UUID>>(sql) {
return new QueryStatement<Set<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, after);
@ -153,12 +118,12 @@ public class BaseUserQueries {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString(UsersTable.USER_UUID)));
userIds.add(set.getInt(UsersTable.ID));
}
return uuids;
return userIds;
}
};
}
@ -178,4 +143,21 @@ public class BaseUserQueries {
};
}
public static Query<Integer> fetchUserId(UUID playerUUID) {
String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.ID)
.where(UsersTable.USER_UUID + "=?")
.toString();
return new QueryStatement<Integer>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}
@Override
public Integer processResults(ResultSet set) throws SQLException {
return set.next() ? set.getInt(UsersTable.ID) : -1;
}
};
}
}

View File

@ -22,7 +22,9 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.utilities.java.Lists;
import org.apache.commons.text.TextStringBuilder;
@ -53,8 +55,9 @@ public class GeoInfoQueries {
String sql = SELECT +
GeoInfoTable.GEOLOCATION + ',' +
GeoInfoTable.LAST_USED + ',' +
GeoInfoTable.USER_UUID +
FROM + GeoInfoTable.TABLE_NAME;
UsersTable.USER_UUID +
FROM + GeoInfoTable.TABLE_NAME + " g" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on g.user_id=u.id";
return new QueryAllStatement<Map<UUID, List<GeoInfo>>>(sql, 50000) {
@Override
@ -67,7 +70,7 @@ public class GeoInfoQueries {
private static Map<UUID, List<GeoInfo>> extractGeoInformation(ResultSet set) throws SQLException {
Map<UUID, List<GeoInfo>> geoInformation = new HashMap<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(GeoInfoTable.USER_UUID));
UUID uuid = UUID.fromString(set.getString(UsersTable.USER_UUID));
List<GeoInfo> userGeoInfo = geoInformation.computeIfAbsent(uuid, Lists::create);
GeoInfo geoInfo = new GeoInfo(set.getString(GeoInfoTable.GEOLOCATION), set.getLong(GeoInfoTable.LAST_USED));
@ -87,7 +90,7 @@ public class GeoInfoQueries {
GeoInfoTable.GEOLOCATION +
",MAX(" + GeoInfoTable.LAST_USED + ") as " + GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME +
WHERE + GeoInfoTable.USER_UUID + "=?" +
WHERE + GeoInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + GeoInfoTable.GEOLOCATION;
return new QueryStatement<List<GeoInfo>>(sql, 100) {
@ -109,43 +112,17 @@ public class GeoInfoQueries {
};
}
public static Query<Map<UUID, List<GeoInfo>>> fetchServerGeoInformation(ServerUUID serverUUID) {
String sql = SELECT + GeoInfoTable.TABLE_NAME + '.' + GeoInfoTable.USER_UUID + ',' +
GeoInfoTable.GEOLOCATION + ',' +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME +
INNER_JOIN + UserInfoTable.TABLE_NAME + " on " +
GeoInfoTable.TABLE_NAME + '.' + GeoInfoTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_UUID +
WHERE + UserInfoTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, List<GeoInfo>>>(sql, 10000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<GeoInfo>> processResults(ResultSet set) throws SQLException {
return extractGeoInformation(set);
}
};
}
public static Query<Map<String, Integer>> networkGeolocationCounts() {
String subQuery1 = SELECT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String subQuery2 = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String sql = SELECT + GeoInfoTable.GEOLOCATION + ", COUNT(1) as c FROM " +
"(" + subQuery1 + ") AS q1" +
INNER_JOIN + "(" + subQuery2 + ") AS q2 ON q1.uuid = q2.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=m" +
GROUP_BY + GeoInfoTable.GEOLOCATION;
String sql = SELECT +
"a." + GeoInfoTable.GEOLOCATION + ", " +
"COUNT(1) as c" +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL +
GROUP_BY + "a." + GeoInfoTable.GEOLOCATION;
return new QueryAllStatement<Map<String, Integer>>(sql) {
@Override
@ -159,24 +136,20 @@ public class GeoInfoQueries {
};
}
public static Query<Map<String, Integer>> networkGeolocationCounts(Collection<UUID> playerUUIDs) {
String subQuery1 = SELECT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME +
WHERE + GeoInfoTable.USER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')";
String subQuery2 = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String sql = SELECT + GeoInfoTable.GEOLOCATION + ", COUNT(1) as c FROM " +
"(" + subQuery1 + ") AS q1" +
INNER_JOIN + "(" + subQuery2 + ") AS q2 ON q1.uuid = q2.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=m" +
GROUP_BY + GeoInfoTable.GEOLOCATION;
public static Query<Map<String, Integer>> networkGeolocationCounts(Collection<Integer> userIds) {
String sql = SELECT +
"a." + GeoInfoTable.GEOLOCATION + ", " +
"COUNT(1) as c" +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
INNER_JOIN + UsersTable.TABLE_NAME + " u on a." + GeoInfoTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL +
AND + "u." + UsersTable.ID + " IN (" +
new TextStringBuilder().appendWithSeparators(userIds, ",").build() + ")" +
GROUP_BY + "a." + GeoInfoTable.GEOLOCATION;
return new QueryAllStatement<Map<String, Integer>>(sql) {
@Override
@ -191,23 +164,19 @@ public class GeoInfoQueries {
}
public static Query<Map<String, Integer>> serverGeolocationCounts(ServerUUID serverUUID) {
String selectGeolocations = SELECT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String sql = SELECT + GeoInfoTable.GEOLOCATION + ", COUNT(1) as c FROM " +
"(" + selectGeolocations + ") AS q1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS q2 ON q1.uuid = q2.uuid" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " u on u." + UserInfoTable.USER_UUID + "=q1.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=m" +
AND + "u." + UserInfoTable.SERVER_UUID + "=?" +
GROUP_BY + GeoInfoTable.GEOLOCATION;
String sql = SELECT +
"a." + GeoInfoTable.GEOLOCATION + ", " +
"COUNT(1) as c" +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=a." + GeoInfoTable.USER_ID +
INNER_JOIN + UserInfoTable.TABLE_NAME + " ui on ui." + UserInfoTable.USER_ID + "=u." + UsersTable.ID +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL +
AND + "ui." + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "a." + GeoInfoTable.GEOLOCATION;
return new QueryStatement<Map<String, Integer>>(sql) {
@Override
@ -239,18 +208,19 @@ public class GeoInfoQueries {
};
}
public static Query<Set<UUID>> uuidsOfPlayersWithGeolocations(List<String> selected) {
String sql = SELECT + GeoInfoTable.USER_UUID +
FROM + GeoInfoTable.TABLE_NAME +
public static Query<Set<Integer>> userIdsOfPlayersWithGeolocations(List<String> selected) {
String sql = SELECT + "u." + UsersTable.ID +
FROM + GeoInfoTable.TABLE_NAME + " g" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=g." + GeoInfoTable.USER_ID +
WHERE + GeoInfoTable.GEOLOCATION +
" IN ('" +
new TextStringBuilder().appendWithSeparators(selected, "','") +
"')";
return new QueryAllStatement<Set<UUID>>(sql) {
return new QueryAllStatement<Set<Integer>>(sql) {
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> geolocations = new HashSet<>();
while (set.next()) geolocations.add(UUID.fromString(set.getString(GeoInfoTable.USER_UUID)));
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> geolocations = new HashSet<>();
while (set.next()) geolocations.add(set.getInt(UsersTable.ID));
return geolocations;
}
};

View File

@ -22,7 +22,10 @@ import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.identification.ServerUUID;
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 com.djrapitops.plan.storage.database.sql.tables.KillsTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -55,7 +58,7 @@ public class KillQueries {
KillsTable.DATE + ", " +
KillsTable.WEAPON + ", " +
"server." + ServerTable.NAME + " as server_name," +
"server." + ServerTable.SERVER_ID + " as server_id" +
"server." + ServerTable.ID + " as server_id" +
FROM + KillsTable.TABLE_NAME + " ki" +
INNER_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + "=ki." + KillsTable.VICTIM_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " k on k." + UsersTable.USER_UUID + "=ki." + KillsTable.KILLER_UUID +
@ -91,7 +94,7 @@ public class KillQueries {
KillsTable.DATE + ", " +
KillsTable.WEAPON + ", " +
"server." + ServerTable.NAME + " as server_name," +
"server." + ServerTable.SERVER_ID + " as server_id" +
"server." + ServerTable.ID + " as server_id" +
FROM + KillsTable.TABLE_NAME + " ki" +
INNER_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + "=ki." + KillsTable.VICTIM_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " k on k." + UsersTable.USER_UUID + "=ki." + KillsTable.KILLER_UUID +
@ -126,7 +129,7 @@ public class KillQueries {
KillsTable.DATE + ", " +
KillsTable.WEAPON + ", " +
"server." + ServerTable.NAME + " as server_name," +
"server." + ServerTable.SERVER_ID + " as server_id" +
"server." + ServerTable.ID + " as server_id" +
FROM + KillsTable.TABLE_NAME + " ki" +
INNER_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + "=ki." + KillsTable.VICTIM_UUID +
INNER_JOIN + UsersTable.TABLE_NAME + " k on k." + UsersTable.USER_UUID + "=ki." + KillsTable.KILLER_UUID +
@ -198,17 +201,18 @@ public class KillQueries {
AND + KillsTable.DATE + ">=?" +
AND + KillsTable.DATE + "<=?" +
GROUP_BY + KillsTable.KILLER_UUID;
String selectDeathCounts = SELECT + "COUNT(1) as deaths," + KillsTable.VICTIM_UUID +
String selectPlayerDeathCounts = SELECT + "COUNT(1) as deaths," + KillsTable.VICTIM_UUID +
FROM + KillsTable.TABLE_NAME +
WHERE + KillsTable.SERVER_UUID + "=?" +
AND + KillsTable.DATE + ">=?" +
AND + KillsTable.DATE + "<=?" +
GROUP_BY + KillsTable.VICTIM_UUID;
String sql = SELECT + "u." + UserInfoTable.USER_UUID + ",kills, deaths" +
FROM + UserInfoTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectKillCounts + ") q1 on q1." + KillsTable.KILLER_UUID + "=u." + UserInfoTable.USER_UUID +
LEFT_JOIN + '(' + selectDeathCounts + ") q2 on q2." + KillsTable.VICTIM_UUID + "=u." + UserInfoTable.USER_UUID +
WHERE + "u." + UserInfoTable.SERVER_UUID + "=?";
String sql = SELECT + "kills, deaths" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectKillCounts + ") q1 on q1." + KillsTable.KILLER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectPlayerDeathCounts + ") q2 on q2." + KillsTable.VICTIM_UUID + "=u." + UsersTable.USER_UUID +
WHERE + "kills" + IS_NOT_NULL +
AND + "deaths" + IS_NOT_NULL;
return new QueryStatement<Double>(sql) {
@Override
@ -219,7 +223,6 @@ public class KillQueries {
statement.setString(4, serverUUID.toString());
statement.setLong(5, after);
statement.setLong(6, before);
statement.setString(7, serverUUID.toString());
}
@Override
@ -240,7 +243,7 @@ public class KillQueries {
public static Query<Long> mobKillCount(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "SUM(" + SessionsTable.MOB_KILLS + ") as count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {
@ -261,7 +264,7 @@ public class KillQueries {
public static Query<Long> deathCount(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "SUM(" + SessionsTable.DEATHS + ") as count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {

View File

@ -140,42 +140,4 @@ public class NicknameQueries {
};
}
/**
* Query database for nickname information of a server.
*
* @param serverUUID UUID the the Plan server.
* @return Map: Player UUID - List of Nicknames on the server.
*/
public static Query<Map<UUID, List<Nickname>>> fetchNicknameDataOfServer(ServerUUID serverUUID) {
String sql = SELECT +
NicknamesTable.NICKNAME + ',' +
NicknamesTable.LAST_USED + ',' +
NicknamesTable.USER_UUID +
FROM + NicknamesTable.TABLE_NAME +
WHERE + NicknamesTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, List<Nickname>>>(sql, 5000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Nickname>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<Nickname>> serverMap = new HashMap<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(NicknamesTable.USER_UUID));
List<Nickname> nicknames = serverMap.computeIfAbsent(uuid, Lists::create);
nicknames.add(new Nickname(
set.getString(NicknamesTable.NICKNAME),
set.getLong(NicknamesTable.LAST_USED),
serverUUID
));
}
return serverMap;
}
};
}
}

View File

@ -23,6 +23,8 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.PingTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.utilities.java.Lists;
import java.sql.PreparedStatement;
@ -54,9 +56,11 @@ public class PingQueries {
PingTable.MAX_PING + ',' +
PingTable.MIN_PING + ',' +
PingTable.AVG_PING + ',' +
PingTable.USER_UUID + ',' +
PingTable.SERVER_UUID +
FROM + PingTable.TABLE_NAME;
"u." + UsersTable.USER_UUID + " as uuid," +
"s." + ServerTable.SERVER_UUID + " as server_uuid" +
FROM + PingTable.TABLE_NAME + " p" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u.id=p." + PingTable.USER_ID +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s.id=p." + PingTable.SERVER_ID;
return new QueryAllStatement<Map<UUID, List<Ping>>>(sql, 100000) {
@Override
public Map<UUID, List<Ping>> processResults(ResultSet set) throws SQLException {
@ -69,8 +73,8 @@ public class PingQueries {
Map<UUID, List<Ping>> userPings = new HashMap<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(PingTable.USER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString(PingTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString("uuid"));
ServerUUID serverUUID = ServerUUID.fromString(set.getString("server_uuid"));
long date = set.getLong(PingTable.DATE);
double avgPing = set.getDouble(PingTable.AVG_PING);
int minPing = set.getInt(PingTable.MIN_PING);
@ -93,8 +97,9 @@ public class PingQueries {
* @return List of Ping entries for this player.
*/
public static Query<List<Ping>> fetchPingDataOfPlayer(UUID playerUUID) {
String sql = SELECT + '*' + FROM + PingTable.TABLE_NAME +
WHERE + PingTable.USER_UUID + "=?";
String sql = SELECT + '*' + FROM + PingTable.TABLE_NAME + " p" +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + "=p." + PingTable.SERVER_ID +
WHERE + PingTable.USER_ID + "=" + UsersTable.SELECT_USER_ID;
return new QueryStatement<List<Ping>>(sql, 10000) {
@Override
@ -109,7 +114,7 @@ public class PingQueries {
while (set.next()) {
pings.add(new Ping(
set.getLong(PingTable.DATE),
ServerUUID.fromString(set.getString(PingTable.SERVER_UUID)),
ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getInt(PingTable.MIN_PING),
set.getInt(PingTable.MAX_PING),
set.getDouble(PingTable.AVG_PING)
@ -122,38 +127,14 @@ public class PingQueries {
};
}
public static Query<Map<UUID, List<Ping>>> fetchPingDataOfServer(ServerUUID serverUUID) {
String sql = SELECT +
PingTable.DATE + ',' +
PingTable.MAX_PING + ',' +
PingTable.MIN_PING + ',' +
PingTable.AVG_PING + ',' +
PingTable.USER_UUID + ',' +
PingTable.SERVER_UUID +
FROM + PingTable.TABLE_NAME +
WHERE + PingTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, List<Ping>>>(sql, 100000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Ping>> processResults(ResultSet set) throws SQLException {
return extractUserPings(set);
}
};
}
public static Query<List<Ping>> fetchPingDataOfServer(long after, long before, ServerUUID serverUUID) {
String sql = SELECT +
PingTable.DATE + ", " +
PingTable.MAX_PING + ", " +
PingTable.MIN_PING + ", " +
PingTable.AVG_PING + ", " +
PingTable.SERVER_UUID +
PingTable.AVG_PING +
FROM + PingTable.TABLE_NAME +
WHERE + PingTable.SERVER_UUID + "=?" +
WHERE + PingTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + PingTable.DATE + ">=?" +
AND + PingTable.DATE + "<=?";
return new QueryStatement<List<Ping>>(sql, 1000) {
@ -169,7 +150,6 @@ public class PingQueries {
List<Ping> pings = new ArrayList<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(PingTable.SERVER_UUID));
long date = set.getLong(PingTable.DATE);
double avgPing = set.getDouble(PingTable.AVG_PING);
int minPing = set.getInt(PingTable.MIN_PING);
@ -187,35 +167,19 @@ public class PingQueries {
}
public static Query<Map<String, Ping>> fetchPingDataOfServerByGeolocation(ServerUUID serverUUID) {
String selectPingOfServer = SELECT +
PingTable.MAX_PING + ", " +
PingTable.MIN_PING + ", " +
PingTable.AVG_PING + ", " +
PingTable.USER_UUID + ", " +
PingTable.SERVER_UUID +
FROM + PingTable.TABLE_NAME;
String selectGeolocations = SELECT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String selectPingByGeolocation = SELECT + GeoInfoTable.GEOLOCATION +
String selectPingByGeolocation = SELECT + "a." + GeoInfoTable.GEOLOCATION +
", MIN(" + PingTable.MIN_PING + ") as minPing" +
", MAX(" + PingTable.MAX_PING + ") as maxPing" +
", AVG(" + PingTable.AVG_PING + ") as avgPing" +
FROM + "(" + selectGeolocations + ") AS q1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS q2 ON q1.uuid = q2.uuid" +
INNER_JOIN + '(' + selectPingOfServer + ") sp on sp." + PingTable.USER_UUID + "=q1.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=m" +
AND + "sp." + PingTable.SERVER_UUID + "=?" +
GROUP_BY + GeoInfoTable.GEOLOCATION;
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
INNER_JOIN + PingTable.TABLE_NAME + " sp on sp." + PingTable.USER_ID + "=a." + GeoInfoTable.USER_ID +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL +
AND + "sp." + PingTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "a." + GeoInfoTable.GEOLOCATION;
return new QueryStatement<Map<String, Ping>>(selectPingByGeolocation) {
@Override
@ -243,35 +207,18 @@ public class PingQueries {
}
public static Query<Map<String, Ping>> fetchPingDataOfNetworkByGeolocation() {
String selectPingOfServer = SELECT +
PingTable.MAX_PING + ", " +
PingTable.MIN_PING + ", " +
PingTable.AVG_PING + ", " +
PingTable.USER_UUID + ", " +
PingTable.SERVER_UUID +
FROM + PingTable.TABLE_NAME;
String selectGeolocations = SELECT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String selectPingByGeolocation = SELECT + GeoInfoTable.GEOLOCATION +
String selectPingByGeolocation = SELECT + "a." + GeoInfoTable.GEOLOCATION +
", MIN(" + PingTable.MIN_PING + ") as minPing" +
", MAX(" + PingTable.MAX_PING + ") as maxPing" +
", AVG(" + PingTable.AVG_PING + ") as avgPing" +
FROM + "(" +
"(" + selectGeolocations + ") AS q1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS q2 ON q1.uuid = q2.uuid" +
INNER_JOIN + '(' + selectPingOfServer + ") sp on sp." + PingTable.USER_UUID + "=q1.uuid)" +
WHERE + GeoInfoTable.LAST_USED + "=m" +
GROUP_BY + GeoInfoTable.GEOLOCATION;
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
INNER_JOIN + PingTable.TABLE_NAME + " sp on sp." + PingTable.USER_ID + "=a." + GeoInfoTable.USER_ID +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL +
GROUP_BY + "a." + GeoInfoTable.GEOLOCATION;
return new QueryAllStatement<Map<String, Ping>>(selectPingByGeolocation) {
@Override
@ -295,7 +242,7 @@ public class PingQueries {
public static Query<Double> averagePing(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + PingTable.AVG_PING + ") as average" + FROM + PingTable.TABLE_NAME +
WHERE + PingTable.SERVER_UUID + "=?" +
WHERE + PingTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + PingTable.DATE + ">=?" +
AND + PingTable.DATE + "<=?";

View File

@ -58,7 +58,7 @@ public class ServerQueries {
Collection<Server> servers = new HashSet<>();
while (set.next()) {
servers.add(new Server(
set.getInt(ServerTable.SERVER_ID),
set.getInt(ServerTable.ID),
ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
@ -90,7 +90,7 @@ public class ServerQueries {
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
servers.put(serverUUID, new Server(
set.getInt(ServerTable.SERVER_ID),
set.getInt(ServerTable.ID),
serverUUID,
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
@ -114,8 +114,8 @@ public class ServerQueries {
String sql = SELECT + '*' + FROM + ServerTable.TABLE_NAME +
WHERE + "(LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" +
OR + "LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" +
OR + ServerTable.SERVER_ID + "=?" +
OR + ServerTable.SERVER_ID + "=?)" +
OR + ServerTable.ID + "=?" +
OR + ServerTable.ID + "=?)" +
AND + ServerTable.INSTALLED + "=?" +
LIMIT + '1';
return new QueryStatement<Optional<Server>>(sql) {
@ -133,7 +133,7 @@ public class ServerQueries {
public Optional<Server> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(new Server(
set.getInt(ServerTable.SERVER_ID),
set.getInt(ServerTable.ID),
ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
@ -161,7 +161,7 @@ public class ServerQueries {
public Optional<Server> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(new Server(
set.getInt(ServerTable.SERVER_ID),
set.getInt(ServerTable.ID),
ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
@ -175,7 +175,7 @@ public class ServerQueries {
public static Query<List<String>> fetchGameServerNames() {
String sql = Select.from(ServerTable.TABLE_NAME,
ServerTable.SERVER_ID, ServerTable.SERVER_UUID, ServerTable.NAME)
ServerTable.ID, ServerTable.SERVER_UUID, ServerTable.NAME)
.where(ServerTable.PROXY + "=0")
.toString();
@ -184,7 +184,7 @@ public class ServerQueries {
public List<String> processResults(ResultSet set) throws SQLException {
List<String> names = new ArrayList<>();
while (set.next()) {
names.add(Server.getIdentifiableName(set.getString(ServerTable.NAME), set.getInt(ServerTable.SERVER_ID)));
names.add(Server.getIdentifiableName(set.getString(ServerTable.NAME), set.getInt(ServerTable.ID)));
}
return names;
}
@ -193,7 +193,7 @@ public class ServerQueries {
public static Query<Map<ServerUUID, String>> fetchServerNames() {
String sql = Select.from(ServerTable.TABLE_NAME,
ServerTable.SERVER_ID, ServerTable.SERVER_UUID, ServerTable.NAME)
ServerTable.ID, ServerTable.SERVER_UUID, ServerTable.NAME)
.toString();
return new QueryAllStatement<Map<ServerUUID, String>>(sql) {
@ -202,7 +202,7 @@ public class ServerQueries {
Map<ServerUUID, String> names = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
names.put(serverUUID, Server.getIdentifiableName(set.getString(ServerTable.NAME), set.getInt(ServerTable.SERVER_ID)));
names.put(serverUUID, Server.getIdentifiableName(set.getString(ServerTable.NAME), set.getInt(ServerTable.ID)));
}
return names;
}
@ -215,8 +215,8 @@ public class ServerQueries {
String sql = SELECT + '*' + FROM + ServerTable.TABLE_NAME +
WHERE + "(LOWER(" + ServerTable.SERVER_UUID + ") LIKE LOWER(?)" +
OR + "LOWER(" + ServerTable.NAME + ") LIKE LOWER(?)" +
OR + ServerTable.SERVER_ID + "=?" +
OR + ServerTable.SERVER_ID + "=?)" +
OR + ServerTable.ID + "=?" +
OR + ServerTable.ID + "=?)" +
AND + ServerTable.INSTALLED + "=?" +
LIMIT + '1';
return new QueryStatement<List<Server>>(sql) {
@ -235,7 +235,7 @@ public class ServerQueries {
List<Server> matches = new ArrayList<>();
while (set.next()) {
matches.add(new Server(
set.getInt(ServerTable.SERVER_ID),
set.getInt(ServerTable.ID),
ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)),
set.getString(ServerTable.NAME),
set.getString(ServerTable.WEB_ADDRESS),
@ -264,7 +264,7 @@ public class ServerQueries {
}
public static Query<Integer> fetchBiggestServerID() {
String sql = SELECT + "MAX(" + ServerTable.SERVER_ID + ") as max_id" + FROM + ServerTable.TABLE_NAME +
String sql = SELECT + "MAX(" + ServerTable.ID + ") as max_id" + FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.INSTALLED + "=?";
return new QueryStatement<Integer>(sql) {
@Override

View File

@ -54,12 +54,12 @@ public class SessionQueries {
private static final String SELECT_SESSIONS_STATEMENT = SELECT +
"s." + SessionsTable.ID + ',' +
"s." + SessionsTable.USER_UUID + ',' +
"s." + SessionsTable.SERVER_UUID + ',' +
"u." + UsersTable.USER_NAME + " as name," +
"u." + UsersTable.USER_UUID + ',' +
"u_info." + UserInfoTable.REGISTERED + " as registered," +
"server." + ServerTable.NAME + " as server_name," +
"server." + ServerTable.SERVER_ID + " as server_id," +
"server." + ServerTable.ID + " as server_id," +
"server." + ServerTable.SERVER_UUID + " as server_uuid," +
SessionsTable.SESSION_START + ',' +
SessionsTable.SESSION_END + ',' +
SessionsTable.MOB_KILLS + ',' +
@ -77,9 +77,9 @@ public class SessionQueries {
KillsTable.DATE + ',' +
KillsTable.WEAPON +
FROM + SessionsTable.TABLE_NAME + " s" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.USER_UUID + "=s." + SessionsTable.USER_UUID +
INNER_JOIN + ServerTable.TABLE_NAME + " server on server." + ServerTable.SERVER_UUID + "=s." + SessionsTable.SERVER_UUID +
LEFT_JOIN + UserInfoTable.TABLE_NAME + " u_info on (u_info." + UserInfoTable.USER_UUID + "=s." + SessionsTable.USER_UUID + AND + "u_info." + UserInfoTable.SERVER_UUID + "=s." + SessionsTable.SERVER_UUID + ')' +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=s." + SessionsTable.USER_ID +
INNER_JOIN + ServerTable.TABLE_NAME + " server on server." + ServerTable.ID + "=s." + SessionsTable.SERVER_ID +
LEFT_JOIN + UserInfoTable.TABLE_NAME + " u_info on (u_info." + UserInfoTable.USER_ID + "=s." + SessionsTable.USER_ID + AND + "u_info." + UserInfoTable.SERVER_ID + "=s." + SessionsTable.SERVER_ID + ')' +
LEFT_JOIN + KillsTable.TABLE_NAME + " ON " + "s." + SessionsTable.ID + '=' + KillsTable.TABLE_NAME + '.' + KillsTable.SESSION_ID +
LEFT_JOIN + UsersTable.TABLE_NAME + " v on v." + UsersTable.USER_UUID + '=' + KillsTable.VICTIM_UUID +
LEFT_JOIN + UsersTable.TABLE_NAME + " k on k." + UsersTable.USER_UUID + '=' + KillsTable.KILLER_UUID +
@ -104,33 +104,6 @@ public class SessionQueries {
};
}
/**
* Query the database for Session data of a server with kill and world data.
*
* @param serverUUID UUID of the Plan server.
* @return Map: Player UUID - List of sessions on the server.
*/
public static Query<Map<UUID, List<FinishedSession>>> fetchSessionsOfServer(ServerUUID serverUUID) {
return db -> SessionsMutator.sortByPlayers(db.query(fetchSessionsOfServerFlat(serverUUID)));
}
public static QueryStatement<List<FinishedSession>> fetchSessionsOfServerFlat(ServerUUID serverUUID) {
String sql = SELECT_SESSIONS_STATEMENT +
WHERE + "s." + SessionsTable.SERVER_UUID + "=?" +
ORDER_BY_SESSION_START_DESC;
return new QueryStatement<List<FinishedSession>>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public List<FinishedSession> processResults(ResultSet set) throws SQLException {
return extractDataFromSessionSelectStatement(set);
}
};
}
/**
* Query the database for Session data of a player with kill and world data.
*
@ -139,7 +112,7 @@ public class SessionQueries {
*/
public static Query<Map<ServerUUID, List<FinishedSession>>> fetchSessionsOfPlayer(UUID playerUUID) {
String sql = SELECT_SESSIONS_STATEMENT +
WHERE + "s." + SessionsTable.USER_UUID + "=?" +
WHERE + "s." + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
ORDER_BY_SESSION_START_DESC;
return new QueryStatement<Map<ServerUUID, List<FinishedSession>>>(sql, 50000) {
@Override
@ -165,10 +138,10 @@ public class SessionQueries {
Comparator<Long> longRecentComparator = (one, two) -> Long.compare(two, one); // Descending order, most recent first.
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(SessionsTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString("server_uuid"));
Map<UUID, SortedMap<Long, FinishedSession>> serverSessions = byServer.computeIfAbsent(serverUUID, Maps::create);
UUID playerUUID = UUID.fromString(set.getString(SessionsTable.USER_UUID));
UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID));
SortedMap<Long, FinishedSession> playerSessions = serverSessions.computeIfAbsent(playerUUID, key -> new TreeMap<>(longRecentComparator));
long sessionStart = set.getLong(SessionsTable.SESSION_START);
@ -253,15 +226,16 @@ public class SessionQueries {
public static Query<List<FinishedSession>> fetchServerSessionsWithoutKillOrWorldData(long after, long before, ServerUUID serverUUID) {
String sql = SELECT +
SessionsTable.ID + ',' +
SessionsTable.USER_UUID + ',' +
SessionsTable.TABLE_NAME + '.' + SessionsTable.ID + ',' +
UsersTable.USER_UUID + ',' +
SessionsTable.SESSION_START + ',' +
SessionsTable.SESSION_END + ',' +
SessionsTable.DEATHS + ',' +
SessionsTable.MOB_KILLS + ',' +
SessionsTable.AFK_TIME +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.USER_ID +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
@ -277,7 +251,7 @@ public class SessionQueries {
public List<FinishedSession> processResults(ResultSet set) throws SQLException {
List<FinishedSession> sessions = new ArrayList<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(SessionsTable.USER_UUID));
UUID uuid = UUID.fromString(set.getString(UsersTable.USER_UUID));
long start = set.getLong(SessionsTable.SESSION_START);
long end = set.getLong(SessionsTable.SESSION_END);
@ -300,7 +274,7 @@ public class SessionQueries {
private static Query<Long> fetchLatestSessionStartLimitForServer(ServerUUID serverUUID, int limit) {
String sql = SELECT + SessionsTable.SESSION_START + FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
ORDER_BY_SESSION_START_DESC + " LIMIT ?";
return new QueryStatement<Long>(sql, limit) {
@ -344,7 +318,7 @@ public class SessionQueries {
public static Query<List<FinishedSession>> fetchLatestSessionsOfServer(ServerUUID serverUUID, int limit) {
String sql = SELECT_SESSIONS_STATEMENT +
WHERE + "s." + SessionsTable.SERVER_UUID + "=?" +
WHERE + "s." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "s." + SessionsTable.SESSION_START + ">=?" +
ORDER_BY_SESSION_START_DESC;
@ -368,7 +342,7 @@ public class SessionQueries {
public static Query<List<FinishedSession>> fetchLatestSessions(int limit) {
String sql = SELECT_SESSIONS_STATEMENT
// Fix for "First Session" icons in the Most recent sessions on network page
.replace(LEFT_JOIN + UserInfoTable.TABLE_NAME + " u_info on (u_info." + UserInfoTable.USER_UUID + "=s." + SessionsTable.USER_UUID + AND + "u_info." + UserInfoTable.SERVER_UUID + "=s." + SessionsTable.SERVER_UUID + ')', "")
.replace(LEFT_JOIN + UserInfoTable.TABLE_NAME + " u_info on (u_info." + UserInfoTable.USER_ID + "=s." + SessionsTable.USER_ID + AND + "u_info." + UserInfoTable.SERVER_ID + "=s." + SessionsTable.SERVER_ID + ')', "")
.replace("u_info", "u") +
WHERE + "s." + SessionsTable.SESSION_START + ">=?" +
ORDER_BY_SESSION_START_DESC;
@ -391,7 +365,7 @@ public class SessionQueries {
public static Query<Long> sessionCount(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "COUNT(1) as count" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {
@ -447,7 +421,7 @@ public class SessionQueries {
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectSessionsPerDay, 100) {
@ -474,7 +448,7 @@ public class SessionQueries {
public static Query<Long> playtime(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {
@ -493,12 +467,13 @@ public class SessionQueries {
}
public static Query<Map<ServerUUID, Long>> playtimeOfPlayer(long after, long before, UUID playerUUID) {
String sql = SELECT + SessionsTable.SERVER_UUID + ",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
String sql = SELECT + ServerTable.SERVER_UUID + ",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.USER_UUID + "=?" +
INNER_JOIN + ServerTable.TABLE_NAME + " se on se." + ServerTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
GROUP_BY + SessionsTable.SERVER_UUID;
GROUP_BY + SessionsTable.SERVER_ID;
return new QueryStatement<Map<ServerUUID, Long>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -511,7 +486,7 @@ public class SessionQueries {
public Map<ServerUUID, Long> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, Long> playtimeOfPlayer = new HashMap<>();
while (set.next()) {
playtimeOfPlayer.put(ServerUUID.fromString(set.getString(SessionsTable.SERVER_UUID)), set.getLong("playtime"));
playtimeOfPlayer.put(ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)), set.getLong("playtime"));
}
return playtimeOfPlayer;
}
@ -556,7 +531,7 @@ public class SessionQueries {
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
return database.query(new QueryStatement<NavigableMap<Long, Long>>(selectPlaytimePerDay, 100) {
@ -590,7 +565,7 @@ public class SessionQueries {
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "date";
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerDay + ") q1";
@ -614,13 +589,13 @@ public class SessionQueries {
public static Query<Long> averagePlaytimePerPlayer(long after, long before, ServerUUID serverUUID) {
return database -> {
String selectPlaytimePerPlayer = SELECT +
SessionsTable.USER_UUID + "," +
SessionsTable.USER_ID + "," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
GROUP_BY + SessionsTable.USER_UUID;
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -649,12 +624,12 @@ public class SessionQueries {
public static Query<Long> averagePlaytimePerPlayer(long after, long before) {
return database -> {
String selectPlaytimePerPlayer = SELECT +
SessionsTable.USER_UUID + "," +
SessionsTable.USER_ID + "," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
GROUP_BY + SessionsTable.USER_UUID;
GROUP_BY + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(playtime) as average" + FROM + '(' + selectPlaytimePerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -675,13 +650,13 @@ public class SessionQueries {
public static Query<Long> averageAfkPerPlayer(long after, long before, ServerUUID serverUUID) {
return database -> {
String selectAfkPerPlayer = SELECT +
SessionsTable.USER_UUID + "," +
SessionsTable.USER_ID + "," +
"SUM(" + SessionsTable.AFK_TIME + ") as afk" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SERVER_UUID + "=?" +
GROUP_BY + SessionsTable.USER_UUID;
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(afk) as average" + FROM + '(' + selectAfkPerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -710,12 +685,12 @@ public class SessionQueries {
public static Query<Long> averageAfkPerPlayer(long after, long before) {
return database -> {
String selectAfkPerPlayer = SELECT +
SessionsTable.USER_UUID + "," +
SessionsTable.USER_ID + "," +
"SUM(" + SessionsTable.AFK_TIME + ") as afk" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + "<=?" +
AND + SessionsTable.SESSION_START + ">=?" +
GROUP_BY + SessionsTable.USER_UUID;
GROUP_BY + SessionsTable.USER_ID;
String selectAverage = SELECT + "AVG(afk) as average" + FROM + '(' + selectAfkPerPlayer + ") q1";
return database.query(new QueryStatement<Long>(selectAverage, 100) {
@ -736,7 +711,7 @@ public class SessionQueries {
public static Query<Long> afkTime(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "SUM(" + SessionsTable.AFK_TIME + ") as afk_time" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {
@ -776,13 +751,13 @@ public class SessionQueries {
public static Query<Map<String, Long>> playtimePerServer(long after, long before) {
String sql = SELECT +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime," +
"s." + ServerTable.SERVER_ID + ',' +
"s." + ServerTable.ID + ',' +
"s." + ServerTable.NAME +
FROM + SessionsTable.TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.SERVER_UUID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_UUID +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID +
WHERE + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
GROUP_BY + "s." + ServerTable.SERVER_ID;
GROUP_BY + "s." + ServerTable.ID;
return new QueryStatement<Map<String, Long>>(sql, 100) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -796,7 +771,7 @@ public class SessionQueries {
while (set.next()) {
String name = Server.getIdentifiableName(
set.getString(ServerTable.NAME),
set.getInt(ServerTable.SERVER_ID)
set.getInt(ServerTable.ID)
);
playtimePerServer.put(name, set.getLong("playtime"));
}
@ -808,8 +783,8 @@ public class SessionQueries {
public static Query<Long> lastSeen(UUID playerUUID, ServerUUID serverUUID) {
String sql = SELECT + "MAX(" + SessionsTable.SESSION_END + ") as last_seen" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.USER_UUID + "=?" +
AND + SessionsTable.SERVER_UUID + "=?";
WHERE + SessionsTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return new QueryStatement<Long>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -828,7 +803,7 @@ public class SessionQueries {
String sql = SELECT + "SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME +
") as playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SERVER_UUID + "=?" +
WHERE + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?";
return new QueryStatement<Long>(sql) {
@ -846,13 +821,18 @@ public class SessionQueries {
};
}
public static Query<Set<UUID>> uuidsOfPlayedBetween(long after, long before, List<ServerUUID> serverUUIDs) {
String sql = SELECT + DISTINCT + SessionsTable.USER_UUID +
public static Query<Set<Integer>> userIdsOfPlayedBetween(long after, long before, List<ServerUUID> serverUUIDs) {
String selectServerIds = SELECT + ServerTable.ID +
FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')";
String sql = SELECT + DISTINCT + "u." + UsersTable.ID +
FROM + SessionsTable.TABLE_NAME +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + SessionsTable.USER_ID +
WHERE + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
(serverUUIDs.isEmpty() ? "" : AND + SessionsTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')");
return new QueryStatement<Set<UUID>>(sql) {
(serverUUIDs.isEmpty() ? "" : AND + SessionsTable.SERVER_ID + " IN (" + selectServerIds + ")");
return new QueryStatement<Set<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, after);
@ -860,17 +840,22 @@ public class SessionQueries {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString(SessionsTable.USER_UUID)));
userIds.add(set.getInt(UsersTable.ID));
}
return uuids;
return userIds;
}
};
}
public static Query<Map<String, Long>> summaryOfPlayers(Set<UUID> playerUUIDs, List<ServerUUID> serverUUIDs, long after, long before) {
public static Query<Map<String, Long>> summaryOfPlayers(Set<Integer> userIds, List<ServerUUID> serverUUIDs, long after, long before) {
String uuidsInSet = " IN (" + new TextStringBuilder().appendWithSeparators(userIds, ",") + ")";
String selectServerIds = SELECT + ServerTable.ID +
FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')";
String selectAggregates = SELECT +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime," +
@ -878,9 +863,8 @@ public class SessionQueries {
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_START + ">?" +
AND + SessionsTable.SESSION_END + "<?" +
AND + SessionsTable.USER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')" +
(serverUUIDs.isEmpty() ? "" : AND + SessionsTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')");
AND + SessionsTable.USER_ID + uuidsInSet +
(serverUUIDs.isEmpty() ? "" : AND + SessionsTable.SERVER_ID + " IN (" + selectServerIds + ")");
return new QueryStatement<Map<String, Long>>(selectAggregates) {
@Override
@ -895,7 +879,7 @@ public class SessionQueries {
long sessionCount = set.getLong("session_count");
long playtime = set.getLong("playtime");
long activePlaytime = set.getLong("active_playtime");
int playerCount = playerUUIDs.size();
int playerCount = userIds.size();
return Maps.builder(String.class, Long.class)
.put("total_playtime", playtime)
.put("average_playtime", playerCount != 0 ? playtime / playerCount : -1L)

View File

@ -58,7 +58,7 @@ public class TPSQueries {
max("t." + CHUNKS) + " as " + CHUNKS + ',' +
max("t." + FREE_DISK) + " as " + FREE_DISK +
FROM + TABLE_NAME + " t" +
WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + DATE + ">=?" +
AND + DATE + "<?" +
GROUP_BY + floor(DATE + "/?") +
@ -100,7 +100,7 @@ public class TPSQueries {
public static Query<List<TPS>> fetchTPSDataOfServer(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "*" + FROM + TABLE_NAME +
WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + DATE + ">=?" +
AND + DATE + "<=?" +
ORDER_BY + DATE;
@ -129,7 +129,7 @@ public class TPSQueries {
String sql = SELECT + min(DATE) + " as " + DATE + ',' +
max(PLAYERS_ONLINE) + " as " + PLAYERS_ONLINE +
FROM + TABLE_NAME +
WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + floor(DATE + "/?");
return new QueryStatement<List<DateObj<Integer>>>(sql) {
@ -151,7 +151,7 @@ public class TPSQueries {
public static Query<List<DateObj<Integer>>> fetchPlayersOnlineOfServer(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + ServerTable.SERVER_UUID + ',' + DATE + ',' + PLAYERS_ONLINE +
FROM + TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_ID + '=' + SERVER_ID +
INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.ID + '=' + SERVER_ID +
WHERE + ServerTable.SERVER_UUID + "=?" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -176,15 +176,15 @@ public class TPSQueries {
};
}
public static Query<Map<ServerUUID, List<TPS>>> fetchTPSDataOfAllServersBut(long after, long before, ServerUUID leaveOut) {
String sql = SELECT + '*' +
public static Query<Map<Integer, List<TPS>>> fetchTPSDataOfAllServersBut(long after, long before, ServerUUID leaveOut) {
String sql = SELECT + DATE + ',' + TPS + ',' + PLAYERS_ONLINE + ',' + SERVER_ID +
FROM + TABLE_NAME +
INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_ID + '=' + SERVER_ID +
INNER_JOIN + ServerTable.TABLE_NAME + " on " + ServerTable.TABLE_NAME + '.' + ServerTable.ID + '=' + SERVER_ID +
WHERE + ServerTable.SERVER_UUID + "!=?" +
AND + ServerTable.INSTALLED + "=?" +
AND + DATE + "<?" +
AND + DATE + ">?";
return new QueryStatement<Map<ServerUUID, List<TPS>>>(sql, 1000) {
return new QueryStatement<Map<Integer, List<TPS>>>(sql, 5000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
if (leaveOut != null) {
@ -198,12 +198,16 @@ public class TPSQueries {
}
@Override
public Map<ServerUUID, List<TPS>> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, List<TPS>> byServer = new HashMap<>();
public Map<Integer, List<TPS>> processResults(ResultSet set) throws SQLException {
Map<Integer, List<TPS>> byServer = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
List<TPS> ofServer = byServer.computeIfAbsent(serverUUID, Lists::create);
ofServer.add(extractTPS(set));
Integer serverUID = set.getInt(SERVER_ID);
List<TPS> ofServer = byServer.computeIfAbsent(serverUID, Lists::create);
ofServer.add(TPSBuilder.get()
.date(set.getLong(DATE))
.tps(set.getDouble(TPS))
.playersOnline(set.getInt(PLAYERS_ONLINE))
.toTPS());
}
return byServer;
}
@ -211,12 +215,12 @@ public class TPSQueries {
}
public static Query<Optional<DateObj<Integer>>> fetchPeakPlayerCount(ServerUUID serverUUID, long afterDate) {
String subQuery = '(' + SELECT + "MAX(" + PLAYERS_ONLINE + ')' + FROM + TABLE_NAME + WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID +
String subQuery = '(' + SELECT + "MAX(" + PLAYERS_ONLINE + ')' + FROM + TABLE_NAME + WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + DATE + ">= ?)";
String sql = SELECT +
DATE + ',' + PLAYERS_ONLINE +
FROM + TABLE_NAME +
WHERE + SERVER_ID + "=" + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + DATE + ">= ?" +
AND + PLAYERS_ONLINE + "=" + subQuery +
ORDER_BY + DATE + " DESC LIMIT 1";
@ -250,7 +254,7 @@ public class TPSQueries {
public static Query<Optional<TPS>> fetchLatestTPSEntryForServer(ServerUUID serverUUID) {
String sql = SELECT + "*" +
FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
ORDER_BY + DATE + " DESC LIMIT 1";
return new QueryStatement<Optional<TPS>>(sql) {
@ -280,7 +284,7 @@ public class TPSQueries {
public static Query<Double> averageTPS(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + TPS + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + TPS + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -301,7 +305,7 @@ public class TPSQueries {
public static Query<Double> averageCPU(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + CPU_USAGE + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + CPU_USAGE + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -322,7 +326,7 @@ public class TPSQueries {
public static Query<Long> averageRAM(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + RAM_USAGE + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + RAM_USAGE + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -343,7 +347,7 @@ public class TPSQueries {
public static Query<Long> averageChunks(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + CHUNKS + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + CHUNKS + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -364,7 +368,7 @@ public class TPSQueries {
public static Query<Long> averageEntities(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + ENTITIES + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + ENTITIES + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -385,7 +389,7 @@ public class TPSQueries {
public static Query<Long> maxFreeDisk(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "MAX(" + FREE_DISK + ") as free" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + FREE_DISK + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -406,7 +410,7 @@ public class TPSQueries {
public static Query<Long> minFreeDisk(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "MIN(" + FREE_DISK + ") as free" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + FREE_DISK + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -427,7 +431,7 @@ public class TPSQueries {
public static Query<Long> averageFreeDisk(long after, long before, ServerUUID serverUUID) {
String sql = SELECT + "AVG(" + FREE_DISK + ") as average" + FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
AND + FREE_DISK + ">=0" +
AND + DATE + "<?" +
AND + DATE + ">?";
@ -477,17 +481,17 @@ public class TPSQueries {
"-1+ROW_NUMBER() over (ORDER BY " + DATE + ") AS previous_rn, " +
DATE + " AS d1" +
FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
ORDER_BY + "d1 DESC";
String selectRowNumber = SELECT +
"ROW_NUMBER() over (ORDER BY " + DATE + ") AS rn, " +
DATE + " AS previous_date" +
FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID +
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID +
ORDER_BY + "previous_date DESC";
String selectFirstEntryDate = SELECT + "MIN(" + DATE + ") as start_time" +
FROM + TABLE_NAME +
WHERE + SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID;
WHERE + SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID;
// Finds the start time since difference between d1 and previous date is a gap,
// so d1 is always first entry after a gap in the data. MAX finds the latest.
// Union ensures if there are no gaps to use the first date recorded.

View File

@ -22,6 +22,7 @@ import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.building.Select;
import com.djrapitops.plan.storage.database.sql.tables.NicknamesTable;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
@ -75,8 +76,8 @@ public class UserIdentifierQueries {
UsersTable.TABLE_NAME + '.' + UsersTable.USER_UUID + ',' +
FROM + UsersTable.TABLE_NAME +
INNER_JOIN + UserInfoTable.TABLE_NAME + " on " +
UsersTable.TABLE_NAME + '.' + UsersTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_UUID +
WHERE + UserInfoTable.SERVER_UUID + "=?";
UsersTable.TABLE_NAME + '.' + UsersTable.ID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_ID +
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID;
return new QueryStatement<Set<UUID>>(sql, 1000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -202,4 +203,19 @@ public class UserIdentifierQueries {
}
};
}
public static Query<Set<Integer>> fetchAllUserIds() {
String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.ID).toString();
return new QueryAllStatement<Set<Integer>>(sql, 2000) {
@Override
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> playerUUIDs = new HashSet<>();
while (set.next()) {
playerUUIDs.add(set.getInt(UsersTable.ID));
}
return playerUUIDs;
}
};
}
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.utilities.java.Lists;
@ -53,21 +54,23 @@ public class UserInfoQueries {
*/
public static Query<Map<ServerUUID, List<UserInfo>>> fetchAllUserInformation() {
String sql = SELECT +
UserInfoTable.REGISTERED + ',' +
"ux." + UserInfoTable.REGISTERED + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.OP + ',' +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.SERVER_UUID + ',' +
"u." + UsersTable.USER_UUID + ',' +
"s." + ServerTable.SERVER_UUID + " as server_uuid," +
UserInfoTable.JOIN_ADDRESS +
FROM + UserInfoTable.TABLE_NAME;
FROM + UserInfoTable.TABLE_NAME + " ux" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + "ux." + UserInfoTable.USER_ID +
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + '=' + "ux." + UserInfoTable.SERVER_ID;
return new QueryAllStatement<Map<ServerUUID, List<UserInfo>>>(sql, 50000) {
@Override
public Map<ServerUUID, List<UserInfo>> processResults(ResultSet set) throws SQLException {
Map<ServerUUID, List<UserInfo>> serverMap = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(UserInfoTable.USER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString("server_uuid"));
UUID uuid = UUID.fromString(set.getString(UsersTable.USER_UUID));
List<UserInfo> userInfos = serverMap.computeIfAbsent(serverUUID, Lists::create);
@ -94,10 +97,11 @@ public class UserInfoQueries {
UserInfoTable.TABLE_NAME + '.' + UserInfoTable.REGISTERED + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.OP + ',' +
UserInfoTable.SERVER_UUID + ',' +
ServerTable.SERVER_UUID + ',' +
UserInfoTable.JOIN_ADDRESS +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_UUID + "=?";
INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.ID + '=' + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.SERVER_ID +
WHERE + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID;
return new QueryStatement<Set<UserInfo>>(sql) {
@Override
@ -112,7 +116,7 @@ public class UserInfoQueries {
long registered = set.getLong(UserInfoTable.REGISTERED);
boolean op = set.getBoolean(UserInfoTable.OP);
boolean banned = set.getBoolean(UserInfoTable.BANNED);
ServerUUID serverUUID = ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
String joinAddress = set.getString(UserInfoTable.JOIN_ADDRESS);
userInformation.add(new UserInfo(playerUUID, serverUUID, registered, op, joinAddress, banned));
@ -122,57 +126,15 @@ public class UserInfoQueries {
};
}
/**
* Query database for all User information of a specific server.
*
* @param serverUUID UUID of the Plan server.
* @return Map: Player UUID - user information
*/
public static Query<Map<UUID, UserInfo>> fetchUserInformationOfServer(ServerUUID serverUUID) {
String sql = SELECT +
UserInfoTable.REGISTERED + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.JOIN_ADDRESS + ',' +
UserInfoTable.OP + ',' +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.SERVER_UUID +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.SERVER_UUID + "=?";
return new QueryStatement<Map<UUID, UserInfo>>(sql, 1000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, UserInfo> processResults(ResultSet set) throws SQLException {
Map<UUID, UserInfo> userInformation = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(UserInfoTable.SERVER_UUID));
UUID uuid = UUID.fromString(set.getString(UserInfoTable.USER_UUID));
long registered = set.getLong(UserInfoTable.REGISTERED);
boolean banned = set.getBoolean(UserInfoTable.BANNED);
boolean op = set.getBoolean(UserInfoTable.OP);
String joinAddress = set.getString(UserInfoTable.JOIN_ADDRESS);
userInformation.put(uuid, new UserInfo(uuid, serverUUID, registered, op, joinAddress, banned));
}
return userInformation;
}
};
}
public static Query<Map<UUID, Long>> fetchRegisterDates(long after, long before, ServerUUID serverUUID) {
String sql = SELECT +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.REGISTERED +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.SERVER_UUID + "=?" +
AND + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.REGISTERED + "<=?";
UsersTable.USER_UUID + ',' +
"ux." + UserInfoTable.REGISTERED +
FROM + UserInfoTable.TABLE_NAME + " ux" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + "ux." + UserInfoTable.USER_ID +
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + "ux." + UserInfoTable.REGISTERED + ">=?" +
AND + "ux." + UserInfoTable.REGISTERED + "<=?";
return new QueryStatement<Map<UUID, Long>>(sql, 1000) {
@Override
@ -187,7 +149,7 @@ public class UserInfoQueries {
Map<UUID, Long> registerDates = new HashMap<>();
while (set.next()) {
registerDates.put(
UUID.fromString(set.getString(UserInfoTable.USER_UUID)),
UUID.fromString(set.getString(UsersTable.USER_UUID)),
set.getLong(UserInfoTable.REGISTERED)
);
}
@ -202,7 +164,7 @@ public class UserInfoQueries {
"LOWER(COALESCE(" + UserInfoTable.JOIN_ADDRESS + ", ?)) as address" +
FROM + '(' +
SELECT + DISTINCT +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.USER_ID + ',' +
UserInfoTable.JOIN_ADDRESS +
FROM + UserInfoTable.TABLE_NAME +
") q1" +
@ -231,7 +193,7 @@ public class UserInfoQueries {
"COUNT(1) as total," +
"LOWER(COALESCE(" + UserInfoTable.JOIN_ADDRESS + ", ?)) as address" +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.SERVER_UUID + "=?" +
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "address" +
ORDER_BY + "address ASC";
@ -272,58 +234,61 @@ public class UserInfoQueries {
};
}
public static Query<Set<UUID>> uuidsOfOperators() {
return getUUIDsForBooleanGroup(UserInfoTable.OP, true);
public static Query<Set<Integer>> userIdsOfOperators() {
return getUserIdsForBooleanGroup(UserInfoTable.OP, true);
}
public static Query<Set<UUID>> getUUIDsForBooleanGroup(String column, boolean value) {
String sql = SELECT + UserInfoTable.USER_UUID + FROM + UserInfoTable.TABLE_NAME +
public static Query<Set<Integer>> getUserIdsForBooleanGroup(String column, boolean value) {
String sql = SELECT + "u." + UsersTable.ID +
FROM + UserInfoTable.TABLE_NAME +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_ID +
WHERE + column + "=?";
return new QueryStatement<Set<UUID>>(sql) {
return new QueryStatement<Set<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setBoolean(1, value);
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
return extractUUIDs(set);
public Set<Integer> processResults(ResultSet set) throws SQLException {
return extractUserIds(set);
}
};
}
public static Set<UUID> extractUUIDs(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public static Set<Integer> extractUserIds(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString(UserInfoTable.USER_UUID)));
userIds.add(set.getInt(UsersTable.ID));
}
return uuids;
return userIds;
}
public static Query<Set<UUID>> uuidsOfNonOperators() {
return getUUIDsForBooleanGroup(UserInfoTable.OP, false);
public static Query<Set<Integer>> userIdsOfNonOperators() {
return getUserIdsForBooleanGroup(UserInfoTable.OP, false);
}
public static Query<Set<UUID>> uuidsOfBanned() {
return getUUIDsForBooleanGroup(UserInfoTable.BANNED, true);
public static Query<Set<Integer>> userIdsOfBanned() {
return getUserIdsForBooleanGroup(UserInfoTable.BANNED, true);
}
public static Query<Set<UUID>> uuidsOfNotBanned() {
return getUUIDsForBooleanGroup(UserInfoTable.BANNED, false);
public static Query<Set<Integer>> userIdsOfNotBanned() {
return getUserIdsForBooleanGroup(UserInfoTable.BANNED, false);
}
public static Query<Set<UUID>> uuidsOfPlayersWithJoinAddresses(List<String> joinAddresses) {
public static Query<Set<Integer>> userIdsOfPlayersWithJoinAddresses(List<String> joinAddresses) {
String selectLowercaseJoinAddresses = SELECT +
UserInfoTable.USER_UUID + ',' +
"u." + UsersTable.ID + ',' +
"LOWER(COALESCE(" + UserInfoTable.JOIN_ADDRESS + ", ?)) as address" +
FROM + UserInfoTable.TABLE_NAME;
String sql = SELECT + DISTINCT + UserInfoTable.USER_UUID +
FROM + UserInfoTable.TABLE_NAME +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_ID;
String sql = SELECT + DISTINCT + UsersTable.ID +
FROM + '(' + selectLowercaseJoinAddresses + ") q1" +
WHERE + "address IN (" +
new TextStringBuilder().appendWithSeparators(joinAddresses.stream().map(item -> '?').iterator(), ",") +
')'; // Don't append addresses directly, SQL injection hazard
return new QueryStatement<Set<UUID>>(sql) {
return new QueryStatement<Set<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, "unknown");
@ -334,19 +299,24 @@ public class UserInfoQueries {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
return extractUUIDs(set);
public Set<Integer> processResults(ResultSet set) throws SQLException {
return extractUserIds(set);
}
};
}
public static Query<Set<UUID>> uuidsOfRegisteredBetween(long after, long before, List<ServerUUID> serverUUIDs) {
String sql = SELECT + DISTINCT + UserInfoTable.USER_UUID +
FROM + UserInfoTable.TABLE_NAME +
WHERE + UserInfoTable.REGISTERED + ">=?" +
AND + UserInfoTable.REGISTERED + "<=?" +
AND + UserInfoTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')";
return new QueryStatement<Set<UUID>>(sql) {
public static Query<Set<Integer>> userIdsOfRegisteredBetween(long after, long before, List<ServerUUID> serverUUIDs) {
String selectServerIds = SELECT + ServerTable.ID +
FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')";
String sql = SELECT + DISTINCT + "u." + UsersTable.ID +
FROM + UserInfoTable.TABLE_NAME + " ux" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + "=ux." + UserInfoTable.USER_ID +
INNER_JOIN + "(" + selectServerIds + ") sel_server on sel_server." + ServerTable.ID + "=ux." + UserInfoTable.SERVER_ID +
WHERE + "ux." + UserInfoTable.REGISTERED + ">=?" +
AND + "ux." + UserInfoTable.REGISTERED + "<=?";
return new QueryStatement<Set<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, after);
@ -354,12 +324,12 @@ public class UserInfoQueries {
}
@Override
public Set<UUID> processResults(ResultSet set) throws SQLException {
Set<UUID> uuids = new HashSet<>();
public Set<Integer> processResults(ResultSet set) throws SQLException {
Set<Integer> userIds = new HashSet<>();
while (set.next()) {
uuids.add(UUID.fromString(set.getString(UsersTable.USER_UUID)));
userIds.add(set.getInt(UsersTable.ID));
}
return uuids;
return userIds;
}
};
}

View File

@ -23,9 +23,7 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
import com.djrapitops.plan.storage.database.sql.tables.WorldTimesTable;
import com.djrapitops.plan.storage.database.sql.tables.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -64,7 +62,7 @@ public class WorldTimesQueries {
public static Query<WorldTimes> fetchServerTotalWorldTimes(ServerUUID serverUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_UUID + "=?" +
WHERE + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + WORLD_COLUMN;
return new QueryStatement<WorldTimes>(sql, 1000) {
@ -99,7 +97,7 @@ public class WorldTimesQueries {
public static Query<WorldTimes> fetchPlayerTotalWorldTimes(UUID playerUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.USER_UUID + "=?" +
WHERE + WorldTimesTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + WORLD_COLUMN;
return new QueryStatement<WorldTimes>(sql) {
@ -133,10 +131,11 @@ public class WorldTimesQueries {
*/
public static Query<Map<ServerUUID, WorldTimes>> fetchPlayerWorldTimesOnServers(UUID playerUUID) {
String sql = SELECT_WORLD_TIMES_STATEMENT_START +
WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_UUID + ',' +
"s." + ServerTable.SERVER_UUID + ',' +
SELECT_WORLD_TIMES_JOIN_WORLD_NAME +
WHERE + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.USER_UUID + "=?" +
GROUP_BY + WORLD_COLUMN + ',' + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_UUID;
INNER_JOIN + ServerTable.TABLE_NAME + " s on " + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_ID + "=s." + ServerTable.ID +
WHERE + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.USER_ID + "=" + UsersTable.SELECT_USER_ID +
GROUP_BY + WORLD_COLUMN + ',' + WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SERVER_ID;
return new QueryStatement<Map<ServerUUID, WorldTimes>>(sql, 1000) {
@Override
@ -150,7 +149,7 @@ public class WorldTimesQueries {
Map<ServerUUID, WorldTimes> worldTimesMap = new HashMap<>();
while (set.next()) {
ServerUUID serverUUID = ServerUUID.fromString(set.getString(WorldTimesTable.SERVER_UUID));
ServerUUID serverUUID = ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID));
WorldTimes worldTimes = worldTimesMap.getOrDefault(serverUUID, new WorldTimes());
String worldName = set.getString(WORLD_COLUMN);
@ -180,7 +179,7 @@ public class WorldTimesQueries {
"SUM(" + WorldTimesTable.SPECTATOR + ") as SPECTATOR" +
FROM + WorldTimesTable.TABLE_NAME + " w1" +
INNER_JOIN + SessionsTable.TABLE_NAME + " s1 on s1." + SessionsTable.ID + '=' + WorldTimesTable.SESSION_ID +
WHERE + "w1." + WorldTimesTable.SERVER_UUID + "=?" +
WHERE + "w1." + WorldTimesTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SessionsTable.SESSION_START + ">=?" +
AND + SessionsTable.SESSION_END + "<=?";

View File

@ -55,31 +55,24 @@ public class NetworkTablePlayersQuery implements Query<List<TablePlayer>> {
@Override
public List<TablePlayer> executeQuery(SQLDB db) {
String selectGeolocations = SELECT + DISTINCT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as last_used_g" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String selectLatestGeolocations = SELECT +
"g1." + GeoInfoTable.GEOLOCATION + ',' +
"g1." + GeoInfoTable.USER_UUID +
FROM + "(" + selectGeolocations + ") AS g1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS g2 ON g1.uuid = g2.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=last_used_g";
"a." + GeoInfoTable.USER_ID + ',' +
"a." + GeoInfoTable.GEOLOCATION +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL;
String selectSessionData = SELECT + "s." + SessionsTable.USER_UUID + ',' +
String selectSessionData = SELECT + "s." + SessionsTable.USER_ID + ',' +
"MAX(" + SessionsTable.SESSION_END + ") as last_seen," +
"COUNT(1) as count," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
GROUP_BY + "s." + SessionsTable.USER_UUID;
GROUP_BY + "s." + SessionsTable.USER_ID;
String selectBanned = SELECT + DISTINCT + "ub." + UserInfoTable.USER_UUID +
String selectBanned = SELECT + DISTINCT + "ub." + UserInfoTable.USER_ID +
FROM + UserInfoTable.TABLE_NAME + " ub" +
WHERE + UserInfoTable.BANNED + "=?";
@ -87,17 +80,17 @@ public class NetworkTablePlayersQuery implements Query<List<TablePlayer>> {
"u." + UsersTable.USER_UUID + ',' +
"u." + UsersTable.USER_NAME + ',' +
"u." + UsersTable.REGISTERED + ',' +
"ban." + UserInfoTable.USER_UUID + " as banned," +
"ban." + UserInfoTable.USER_ID + " as banned," +
"geo." + GeoInfoTable.GEOLOCATION + ',' +
"ses.last_seen," +
"ses.count," +
"ses.active_playtime," +
"act.activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectBanned + ") ban on ban." + UserInfoTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + NetworkActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + UsersTable.USER_UUID + "=act." + UserInfoTable.USER_UUID +
LEFT_JOIN + '(' + selectBanned + ") ban on ban." + UserInfoTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + NetworkActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + UsersTable.ID + "=act." + UserInfoTable.USER_ID +
ORDER_BY + "ses.last_seen DESC LIMIT ?";
return db.query(new QueryStatement<List<TablePlayer>>(selectBaseUsers, 1000) {

View File

@ -23,10 +23,7 @@ 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.queries.analysis.NetworkActivityIndexQueries;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.sql.tables.*;
import org.apache.commons.text.TextStringBuilder;
import java.sql.PreparedStatement;
@ -46,7 +43,7 @@ import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
*/
public class QueryTablePlayersQuery implements Query<List<TablePlayer>> {
private final Collection<UUID> playerUUIDs;
private final Collection<Integer> userIds;
private final List<ServerUUID> serverUUIDs;
private final long afterDate;
private final long beforeDate;
@ -55,14 +52,14 @@ public class QueryTablePlayersQuery implements Query<List<TablePlayer>> {
/**
* Create a new query.
*
* @param playerUUIDs UUIDs of the players in the query
* @param userIds User ids of the players in the query
* @param serverUUIDs View data for these Server UUIDs
* @param afterDate View data after this epoch ms
* @param beforeDate View data before this epoch ms
* @param activeMsThreshold Playtime threshold for Activity Index calculation
*/
public QueryTablePlayersQuery(Collection<UUID> playerUUIDs, List<ServerUUID> serverUUIDs, long afterDate, long beforeDate, long activeMsThreshold) {
this.playerUUIDs = playerUUIDs;
public QueryTablePlayersQuery(Collection<Integer> userIds, List<ServerUUID> serverUUIDs, long afterDate, long beforeDate, long activeMsThreshold) {
this.userIds = userIds;
this.serverUUIDs = serverUUIDs;
this.afterDate = afterDate;
this.beforeDate = beforeDate;
@ -71,60 +68,54 @@ public class QueryTablePlayersQuery implements Query<List<TablePlayer>> {
@Override
public List<TablePlayer> executeQuery(SQLDB db) {
String uuidsInSet = " IN ('" + new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')";
String selectServerIds = SELECT + ServerTable.ID +
FROM + ServerTable.TABLE_NAME +
WHERE + ServerTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')";
String selectGeolocations = SELECT + DISTINCT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as last_used_g" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String selectLatestGeolocations = SELECT +
"g1." + GeoInfoTable.GEOLOCATION + ',' +
"g1." + GeoInfoTable.USER_UUID +
FROM + "(" + selectGeolocations + ") AS g1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS g2 ON g1.uuid = g2.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=last_used_g";
"a." + GeoInfoTable.USER_ID + ',' +
"a." + GeoInfoTable.GEOLOCATION +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL;
String selectSessionData = SELECT + "s." + SessionsTable.USER_UUID + ',' +
String userIdsInSet = " IN (" + new TextStringBuilder().appendWithSeparators(userIds, ",") + ')';
String selectSessionData = SELECT + "s." + SessionsTable.USER_ID + ',' +
"MAX(" + SessionsTable.SESSION_END + ") as last_seen," +
"COUNT(1) as count," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
(serverUUIDs.isEmpty() ? "" : INNER_JOIN + '(' + selectServerIds + ") sel_servers on sel_servers." + ServerTable.ID + "=s." + SessionsTable.SERVER_ID) +
WHERE + "s." + SessionsTable.SESSION_START + ">=?" +
AND + "s." + SessionsTable.SESSION_END + "<=?" +
AND + "s." + SessionsTable.USER_UUID +
uuidsInSet +
(serverUUIDs.isEmpty() ? "" : AND + "s." + SessionsTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')") +
GROUP_BY + "s." + SessionsTable.USER_UUID;
AND + "s." + SessionsTable.USER_ID + userIdsInSet +
GROUP_BY + "s." + SessionsTable.USER_ID;
String selectBanned = SELECT + DISTINCT + "ub." + UserInfoTable.USER_UUID +
String selectBanned = SELECT + DISTINCT + "ub." + UserInfoTable.USER_ID +
FROM + UserInfoTable.TABLE_NAME + " ub" +
WHERE + UserInfoTable.BANNED + "=?" +
AND + UserInfoTable.USER_UUID + uuidsInSet +
(serverUUIDs.isEmpty() ? "" : AND + UserInfoTable.SERVER_UUID + " IN ('" + new TextStringBuilder().appendWithSeparators(serverUUIDs, "','") + "')");
AND + "ub." + UserInfoTable.USER_ID + userIdsInSet +
(serverUUIDs.isEmpty() ? "" : AND + "ub." + UserInfoTable.SERVER_ID + " IN (" + selectServerIds + ")");
String selectBaseUsers = SELECT +
"u." + UsersTable.USER_UUID + ',' +
"u." + UsersTable.USER_NAME + ',' +
"u." + UsersTable.REGISTERED + ',' +
"ban." + UserInfoTable.USER_UUID + " as banned," +
"ban." + UserInfoTable.USER_ID + " as banned," +
"geo." + GeoInfoTable.GEOLOCATION + ',' +
"ses.last_seen," +
"ses.count," +
"ses.active_playtime," +
"act.activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
LEFT_JOIN + '(' + selectBanned + ") ban on ban." + UserInfoTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + NetworkActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + SessionsTable.USER_UUID + "=act." + UserInfoTable.USER_UUID +
WHERE + "u." + UserInfoTable.USER_UUID +
uuidsInSet +
LEFT_JOIN + '(' + selectBanned + ") ban on ban." + UserInfoTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + NetworkActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + UsersTable.ID + "=act." + UserInfoTable.USER_ID +
WHERE + "u." + UsersTable.ID + userIdsInSet +
ORDER_BY + "ses.last_seen DESC";
return db.query(new QueryStatement<List<TablePlayer>>(selectBaseUsers, 1000) {

View File

@ -23,10 +23,7 @@ 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.queries.analysis.ActivityIndexQueries;
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.sql.tables.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -66,30 +63,23 @@ public class ServerTablePlayersQuery implements Query<List<TablePlayer>> {
@Override
public List<TablePlayer> executeQuery(SQLDB db) {
String selectGeolocations = SELECT + DISTINCT +
GeoInfoTable.USER_UUID + ", " +
GeoInfoTable.GEOLOCATION + ", " +
GeoInfoTable.LAST_USED +
FROM + GeoInfoTable.TABLE_NAME;
String selectLatestGeolocationDate = SELECT +
GeoInfoTable.USER_UUID + ", " +
"MAX(" + GeoInfoTable.LAST_USED + ") as last_used_g" +
FROM + GeoInfoTable.TABLE_NAME +
GROUP_BY + GeoInfoTable.USER_UUID;
String selectLatestGeolocations = SELECT +
"g1." + GeoInfoTable.GEOLOCATION + ',' +
"g1." + GeoInfoTable.USER_UUID +
FROM + "(" + selectGeolocations + ") AS g1" +
INNER_JOIN + "(" + selectLatestGeolocationDate + ") AS g2 ON g1.uuid = g2.uuid" +
WHERE + GeoInfoTable.LAST_USED + "=last_used_g";
"a." + GeoInfoTable.USER_ID + ',' +
"a." + GeoInfoTable.GEOLOCATION +
FROM + GeoInfoTable.TABLE_NAME + " a" +
// Super smart optimization https://stackoverflow.com/a/28090544
// Join the last_used column, but only if there's a bigger one.
// That way the biggest a.last_used value will have NULL on the b.last_used column and MAX doesn't need to be used.
LEFT_JOIN + GeoInfoTable.TABLE_NAME + " b ON a." + GeoInfoTable.USER_ID + "=b." + GeoInfoTable.USER_ID + AND + "a." + GeoInfoTable.LAST_USED + "<b." + GeoInfoTable.LAST_USED +
WHERE + "b." + GeoInfoTable.LAST_USED + IS_NULL;
String selectSessionData = SELECT + "s." + SessionsTable.USER_UUID + ',' +
String selectSessionData = SELECT + "s." + SessionsTable.USER_ID + ',' +
"MAX(" + SessionsTable.SESSION_END + ") as last_seen," +
"COUNT(1) as count," +
"SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME + " s" +
WHERE + "s." + SessionsTable.SERVER_UUID + "=?" +
GROUP_BY + "s." + SessionsTable.USER_UUID;
WHERE + "s." + SessionsTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
GROUP_BY + "s." + SessionsTable.USER_ID;
String selectBaseUsers = SELECT +
"u." + UsersTable.USER_UUID + ',' +
@ -102,11 +92,11 @@ public class ServerTablePlayersQuery implements Query<List<TablePlayer>> {
"ses.active_playtime," +
"act.activity_index" +
FROM + UsersTable.TABLE_NAME + " u" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " on u." + UsersTable.USER_UUID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_UUID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_UUID + "=u." + UsersTable.USER_UUID +
LEFT_JOIN + '(' + ActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + SessionsTable.USER_UUID + "=act." + UserInfoTable.USER_UUID +
WHERE + UserInfoTable.SERVER_UUID + "=?" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " on u." + UsersTable.ID + "=" + UserInfoTable.TABLE_NAME + '.' + UserInfoTable.USER_ID +
LEFT_JOIN + '(' + selectLatestGeolocations + ") geo on geo." + GeoInfoTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + selectSessionData + ") ses on ses." + SessionsTable.USER_ID + "=u." + UsersTable.ID +
LEFT_JOIN + '(' + ActivityIndexQueries.selectActivityIndexSQL() + ") act on u." + UsersTable.ID + "=act." + UserInfoTable.USER_ID +
WHERE + UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
ORDER_BY + "ses.last_seen DESC LIMIT ?";
return db.query(new QueryStatement<List<TablePlayer>>(selectBaseUsers, 1000) {

View File

@ -38,7 +38,7 @@ public class SessionIDServerIDRelationQuery extends QueryAllStatement<Map<Intege
public SessionIDServerIDRelationQuery() {
super(SELECT + SessionsTable.ID + ',' +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid=" + SessionsTable.SERVER_UUID + ") as server_id" +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.id=" + SessionsTable.SERVER_ID + ") as server_id" +
FROM + SessionsTable.TABLE_NAME, 50000);
}

View File

@ -34,14 +34,18 @@ public class CreateTableBuilder {
private int columnCount = 0;
private int constraintCount = 0;
private CreateTableBuilder(DBType dbType, String tableName) {
private CreateTableBuilder(DBType dbType, String tableName, boolean temporaryTable) {
this.dbType = dbType;
columns = new StringBuilder("CREATE TABLE IF NOT EXISTS " + tableName + " (");
columns = new StringBuilder("CREATE " + (temporaryTable ? "TEMPORARY " : "") + "TABLE IF NOT EXISTS " + tableName + " (");
keyConstraints = new StringBuilder();
}
public static CreateTableBuilder create(String tableName, DBType type) {
return new CreateTableBuilder(type, tableName);
return new CreateTableBuilder(type, tableName, false);
}
public static CreateTableBuilder createTemporary(String tableName, DBType type) {
return new CreateTableBuilder(type, tableName, true);
}
private void finalizeColumn() {

View File

@ -28,7 +28,7 @@ import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
import static com.djrapitops.plan.storage.database.sql.building.Sql.INT;
/**
* Table information about 'plan_extension_icons'.
@ -44,12 +44,6 @@ public class ExtensionIconTable {
public static final String FAMILY = "family";
public static final String COLOR = "color";
public static final String STATEMENT_SELECT_ICON_ID = '(' + SELECT + ID +
FROM + TABLE_NAME +
WHERE + ICON_NAME + "=?" +
AND + FAMILY + "=?" +
AND + COLOR + "=? LIMIT 1)";
public static void set3IconValuesToStatement(PreparedStatement statement, Icon icon) throws SQLException {
set3IconValuesToStatement(statement, 1, icon);
}

View File

@ -41,19 +41,19 @@ public class GeoInfoTable {
public static final String TABLE_NAME = "plan_geolocations";
public static final String ID = "id";
public static final String USER_UUID = "uuid";
public static final String USER_ID = "user_id";
public static final String GEOLOCATION = "geolocation";
public static final String LAST_USED = "last_used";
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " ("
+ USER_UUID + ','
+ USER_ID + ','
+ GEOLOCATION + ','
+ LAST_USED
+ ") VALUES (?, ?, ?)";
+ ") VALUES (" + UsersTable.SELECT_USER_ID + ", ?, ?)";
public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET "
+ LAST_USED + "=?" +
WHERE + USER_UUID + "=?" +
public static final String UPDATE_STATEMENT = "UPDATE " + TABLE_NAME + " SET " +
LAST_USED + "=?" +
WHERE + USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + GEOLOCATION + "=?";
private GeoInfoTable() {
@ -63,9 +63,10 @@ public class GeoInfoTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey()
.column(USER_UUID, Sql.varchar(36)).notNull()
.column(USER_ID, Sql.INT).notNull()
.column(GEOLOCATION, Sql.varchar(50)).notNull()
.column(LAST_USED, Sql.LONG).notNull().defaultValue("0")
.foreignKey(USER_ID, UsersTable.TABLE_NAME, UsersTable.ID)
.toString();
}

View File

@ -34,21 +34,21 @@ public class PingTable {
public static final String TABLE_NAME = "plan_ping";
public static final String ID = "id";
public static final String USER_UUID = "uuid";
public static final String SERVER_UUID = "server_uuid";
public static final String USER_ID = "user_id";
public static final String SERVER_ID = "server_id";
public static final String DATE = "date";
public static final String MAX_PING = "max_ping";
public static final String AVG_PING = "avg_ping";
public static final String MIN_PING = "min_ping";
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" +
USER_UUID + ',' +
SERVER_UUID + ',' +
USER_ID + ',' +
SERVER_ID + ',' +
DATE + ',' +
MIN_PING + ',' +
MAX_PING + ',' +
AVG_PING +
") VALUES (?, ?, ?, ?, ?, ?)";
") VALUES (" + UsersTable.SELECT_USER_ID + ',' + ServerTable.SELECT_SERVER_ID + ", ?, ?, ?, ?)";
private PingTable() {
/* Static information class */
@ -57,12 +57,14 @@ public class PingTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey()
.column(USER_UUID, Sql.varchar(36)).notNull()
.column(SERVER_UUID, Sql.varchar(36)).notNull()
.column(USER_ID, Sql.INT).notNull()
.column(SERVER_ID, Sql.INT).notNull()
.column(DATE, Sql.LONG).notNull()
.column(MAX_PING, Sql.INT).notNull()
.column(MIN_PING, Sql.INT).notNull()
.column(AVG_PING, Sql.DOUBLE).notNull()
.foreignKey(USER_ID, UsersTable.TABLE_NAME, UsersTable.ID)
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.ID)
.toString();
}
}

View File

@ -39,7 +39,7 @@ public class ServerTable {
public static final String TABLE_NAME = "plan_servers";
public static final String SERVER_ID = "id";
public static final String ID = "id";
public static final String SERVER_UUID = "uuid";
public static final String NAME = "name";
public static final String WEB_ADDRESS = "web_address";
@ -61,10 +61,10 @@ public class ServerTable {
.where(SERVER_UUID + "=?")
.toString();
public static final String STATEMENT_SELECT_SERVER_ID =
'(' + SELECT + TABLE_NAME + '.' + SERVER_ID +
public static final String SELECT_SERVER_ID =
'(' + SELECT + TABLE_NAME + '.' + ID +
FROM + TABLE_NAME +
WHERE + TABLE_NAME + '.' + SERVER_UUID + "=? LIMIT 1)";
WHERE + TABLE_NAME + '.' + SERVER_UUID + "=?" + LIMIT + "1)";
private ServerTable() {
/* Static information class */
@ -72,7 +72,7 @@ public class ServerTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(SERVER_ID, Sql.INT).primaryKey()
.column(ID, Sql.INT).primaryKey()
.column(SERVER_UUID, Sql.varchar(36)).notNull().unique()
.column(NAME, Sql.varchar(100))
.column(WEB_ADDRESS, Sql.varchar(100))
@ -83,7 +83,7 @@ public class ServerTable {
}
public static String selectServerIds(Collection<ServerUUID> serverUUIDs) {
return '(' + SELECT + TABLE_NAME + '.' + SERVER_ID +
return '(' + SELECT + TABLE_NAME + '.' + ID +
FROM + TABLE_NAME +
WHERE + TABLE_NAME + '.' + SERVER_UUID + " IN ('" +
new TextStringBuilder().appendWithSeparators(serverUUIDs, "','").build() +

View File

@ -40,8 +40,8 @@ public class SessionsTable {
public static final String TABLE_NAME = "plan_sessions";
public static final String ID = "id";
public static final String USER_UUID = "uuid";
public static final String SERVER_UUID = "server_uuid";
public static final String USER_ID = "user_id";
public static final String SERVER_ID = "server_id";
public static final String SESSION_START = "session_start";
public static final String SESSION_END = "session_end";
public static final String MOB_KILLS = "mob_kills";
@ -49,18 +49,18 @@ public class SessionsTable {
public static final String AFK_TIME = "afk_time";
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " ("
+ USER_UUID + ','
+ USER_ID + ','
+ SESSION_START + ','
+ SESSION_END + ','
+ DEATHS + ','
+ MOB_KILLS + ','
+ AFK_TIME + ','
+ SERVER_UUID
+ ") VALUES (?, ?, ?, ?, ?, ?, ?)";
+ SERVER_ID
+ ") VALUES (" + UsersTable.SELECT_USER_ID + ", ?, ?, ?, ?, ?, " + ServerTable.SELECT_SERVER_ID + ")";
public static final String SELECT_SESSION_ID_STATEMENT = "(SELECT " + TABLE_NAME + '.' + ID + FROM + TABLE_NAME +
WHERE + TABLE_NAME + '.' + USER_UUID + "=?" +
AND + TABLE_NAME + '.' + SERVER_UUID + "=?" +
WHERE + TABLE_NAME + '.' + USER_ID + "=" + UsersTable.SELECT_USER_ID +
AND + TABLE_NAME + '.' + SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID +
AND + SESSION_START + "=?" +
AND + SESSION_END + "=? LIMIT 1)";
@ -71,13 +71,15 @@ public class SessionsTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey()
.column(USER_UUID, Sql.varchar(36)).notNull()
.column(SERVER_UUID, Sql.varchar(36)).notNull()
.column(USER_ID, Sql.INT).notNull()
.column(SERVER_ID, Sql.INT).notNull()
.column(SESSION_START, Sql.LONG).notNull()
.column(SESSION_END, Sql.LONG).notNull()
.column(MOB_KILLS, Sql.INT).notNull()
.column(DEATHS, Sql.INT).notNull()
.column(AFK_TIME, Sql.LONG).notNull()
.foreignKey(USER_ID, UsersTable.TABLE_NAME, UsersTable.ID)
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.ID)
.toString();
}
}

View File

@ -50,7 +50,7 @@ public class TPSTable {
+ CHUNKS + ','
+ FREE_DISK
+ ") VALUES ("
+ ServerTable.STATEMENT_SELECT_SERVER_ID + ','
+ ServerTable.SELECT_SERVER_ID + ','
+ "?, ?, ?, ?, ?, ?, ?, ?)";
private TPSTable() {
@ -68,7 +68,7 @@ public class TPSTable {
.column(ENTITIES, Sql.INT).notNull()
.column(CHUNKS, Sql.INT).notNull()
.column(FREE_DISK, Sql.LONG).notNull()
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.SERVER_ID)
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.ID)
.toString();
}
}

View File

@ -37,21 +37,21 @@ public class UserInfoTable {
public static final String TABLE_NAME = "plan_user_info";
public static final String ID = "id";
public static final String USER_UUID = "uuid";
public static final String SERVER_UUID = "server_uuid";
public static final String USER_ID = "user_id";
public static final String SERVER_ID = "server_id";
public static final String REGISTERED = "registered";
public static final String OP = "opped";
public static final String BANNED = "banned";
public static final String JOIN_ADDRESS = "join_address";
public static final String INSERT_STATEMENT = "INSERT INTO " + TABLE_NAME + " (" +
USER_UUID + ',' +
USER_ID + ',' +
REGISTERED + ',' +
SERVER_UUID + ',' +
SERVER_ID + ',' +
BANNED + ',' +
JOIN_ADDRESS + ',' +
OP +
") VALUES (?, ?, ?, ?, ?, ?)";
") VALUES (" + UsersTable.SELECT_USER_ID + ", ?, " + ServerTable.SELECT_SERVER_ID + ", ?, ?, ?)";
private UserInfoTable() {
/* Static information class */
@ -60,12 +60,14 @@ public class UserInfoTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey()
.column(USER_UUID, Sql.varchar(36)).notNull()
.column(SERVER_UUID, Sql.varchar(36)).notNull()
.column(USER_ID, Sql.INT).notNull()
.column(SERVER_ID, Sql.INT).notNull()
.column(JOIN_ADDRESS, Sql.varchar(255))
.column(REGISTERED, Sql.LONG).notNull()
.column(OP, Sql.BOOL).notNull().defaultValue(false)
.column(BANNED, Sql.BOOL).notNull().defaultValue(false)
.foreignKey(USER_ID, UsersTable.TABLE_NAME, UsersTable.ID)
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.ID)
.toString();
}
}

View File

@ -21,6 +21,8 @@ import com.djrapitops.plan.storage.database.sql.building.CreateTableBuilder;
import com.djrapitops.plan.storage.database.sql.building.Insert;
import com.djrapitops.plan.storage.database.sql.building.Sql;
import static com.djrapitops.plan.storage.database.sql.building.Sql.*;
/**
* Table information about 'plan_users'.
* <p>
@ -43,6 +45,9 @@ public class UsersTable {
public static final String TIMES_KICKED = "times_kicked";
public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, USER_UUID, USER_NAME, REGISTERED, TIMES_KICKED);
public static final String SELECT_USER_ID = '(' + SELECT + TABLE_NAME + '.' + ID +
FROM + TABLE_NAME +
WHERE + TABLE_NAME + '.' + USER_UUID + "=?" + LIMIT + "1)";
private UsersTable() {
/* Static information class */

View File

@ -50,8 +50,8 @@ public class WorldTimesTable {
public static final String TABLE_NAME = "plan_world_times";
public static final String ID = "id";
public static final String USER_UUID = "uuid";
public static final String SERVER_UUID = "server_uuid";
public static final String USER_ID = "user_id";
public static final String SERVER_ID = "server_id";
public static final String SESSION_ID = "session_id";
public static final String WORLD_ID = "world_id";
public static final String SURVIVAL = "survival_time";
@ -62,8 +62,8 @@ public class WorldTimesTable {
public static final String INSERT_STATEMENT = "INSERT INTO " + WorldTimesTable.TABLE_NAME + " (" +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID + ',' +
WorldTimesTable.USER_UUID + ',' +
WorldTimesTable.SERVER_UUID + ',' +
WorldTimesTable.USER_ID + ',' +
WorldTimesTable.SERVER_ID + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.ADVENTURE + ',' +
@ -71,7 +71,9 @@ public class WorldTimesTable {
") VALUES ( " +
SessionsTable.SELECT_SESSION_ID_STATEMENT + ',' +
WorldTable.SELECT_WORLD_ID_STATEMENT + ',' +
"?, ?, ?, ?, ?, ?)";
UsersTable.SELECT_USER_ID + ',' +
ServerTable.SELECT_SERVER_ID + ',' +
"?, ?, ?, ?)";
private WorldTimesTable() {
/* Static information class */
@ -80,9 +82,9 @@ public class WorldTimesTable {
public static String createTableSQL(DBType dbType) {
return CreateTableBuilder.create(TABLE_NAME, dbType)
.column(ID, Sql.INT).primaryKey()
.column(USER_UUID, Sql.varchar(36)).notNull()
.column(USER_ID, Sql.INT).notNull()
.column(WORLD_ID, Sql.INT).notNull()
.column(SERVER_UUID, Sql.varchar(36)).notNull()
.column(SERVER_ID, Sql.INT).notNull()
.column(SESSION_ID, Sql.INT).notNull()
.column(SURVIVAL, Sql.LONG).notNull().defaultValue("0")
.column(CREATIVE, Sql.LONG).notNull().defaultValue("0")
@ -90,6 +92,8 @@ public class WorldTimesTable {
.column(SPECTATOR, Sql.LONG).notNull().defaultValue("0")
.foreignKey(WORLD_ID, WorldTable.TABLE_NAME, WorldTable.ID)
.foreignKey(SESSION_ID, SessionsTable.TABLE_NAME, SessionsTable.ID)
.foreignKey(USER_ID, UsersTable.TABLE_NAME, UsersTable.ID)
.foreignKey(SERVER_ID, ServerTable.TABLE_NAME, ServerTable.ID)
.toString();
}

View File

@ -18,9 +18,7 @@ package com.djrapitops.plan.storage.database.transactions;
import com.djrapitops.plan.exceptions.database.DBOpException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.*;
/**
* SQL executing statement that closes appropriate elements.
@ -35,12 +33,26 @@ public abstract class ExecStatement implements Executable {
this.sql = sql;
}
public int executeReturningId(Connection connection) {
try (PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
prepare(preparedStatement);
preparedStatement.executeUpdate();
return executeReturningId(preparedStatement);
} catch (SQLException e) {
throw DBOpException.forCause(sql, e);
}
}
private int executeReturningId(PreparedStatement preparedStatement) throws SQLException {
try (ResultSet ids = preparedStatement.getGeneratedKeys()) {
return ids.next() ? ids.getInt(1) : -1;
}
}
@Override
public boolean execute(Connection connection) {
try {
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
return execute(preparedStatement);
}
try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
return execute(preparedStatement);
} catch (SQLException e) {
throw DBOpException.forCause(sql, e);
}

View File

@ -18,12 +18,14 @@ package com.djrapitops.plan.storage.database.transactions;
import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.locale.lang.PluginLang;
import com.djrapitops.plan.storage.database.DBType;
import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.SQLDB;
import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryAPIQuery;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.transactions.patches.Patch;
import com.djrapitops.plan.utilities.logging.ErrorContext;
import net.playeranalytics.plugin.scheduling.TimeAmount;
@ -79,6 +81,9 @@ public abstract class Transaction {
initializeConnection(db);
if (shouldBeExecuted()) {
initializeTransaction(db);
if (this instanceof Patch) {
db.getLogger().info(db.getLocale().getString(PluginLang.DB_APPLY_PATCH, getClass().getSimpleName()));
}
performOperations();
if (connection != null) connection.commit();
}
@ -207,6 +212,10 @@ public abstract class Transaction {
return executable.execute(connection);
}
protected int executeReturningId(ExecStatement executable) {
return executable.executeReturningId(connection);
}
protected boolean execute(String sql) {
return execute(new ExecStatement(sql) {
@Override

View File

@ -49,13 +49,13 @@ public class RemovePlayerTransaction extends ThrowawayTransaction {
protected void performOperations() {
query(PlayerFetchQueries.playerUserName(playerUUID)).ifPresent(this::deleteWebUser);
deleteFromTable(GeoInfoTable.TABLE_NAME);
deleteFromUserIdTable(GeoInfoTable.TABLE_NAME);
deleteFromTable(NicknamesTable.TABLE_NAME);
deleteFromKillsTable();
deleteFromTable(WorldTimesTable.TABLE_NAME);
deleteFromTable(SessionsTable.TABLE_NAME);
deleteFromTable(PingTable.TABLE_NAME);
deleteFromTable(UserInfoTable.TABLE_NAME);
deleteFromUserIdTable(WorldTimesTable.TABLE_NAME);
deleteFromUserIdTable(SessionsTable.TABLE_NAME);
deleteFromUserIdTable(PingTable.TABLE_NAME);
deleteFromUserIdTable(UserInfoTable.TABLE_NAME);
deleteFromTable(UsersTable.TABLE_NAME);
deleteFromTable(ExtensionPlayerTableValueTable.TABLE_NAME);
@ -76,6 +76,15 @@ public class RemovePlayerTransaction extends ThrowawayTransaction {
});
}
private void deleteFromUserIdTable(String tableName) {
execute(new ExecStatement(DELETE_FROM + tableName + WHERE + "user_id=" + UsersTable.SELECT_USER_ID) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}
});
}
private void deleteFromKillsTable() {
String sql = DELETE_FROM + KillsTable.TABLE_NAME +
WHERE + KillsTable.KILLER_UUID + "=?" +

View File

@ -18,7 +18,9 @@ package com.djrapitops.plan.storage.database.transactions.events;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.building.Update;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.Transaction;
@ -52,8 +54,8 @@ public class BanStatusTransaction extends Transaction {
private Executable updateBanStatus() {
String sql = Update.values(UserInfoTable.TABLE_NAME, UserInfoTable.BANNED)
.where(UserInfoTable.USER_UUID + "=?")
.and(UserInfoTable.SERVER_UUID + "=?")
.where(UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID)
.and(UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID)
.toString();
return new ExecStatement(sql) {

View File

@ -18,7 +18,9 @@ package com.djrapitops.plan.storage.database.transactions.events;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.sql.building.Update;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.transactions.ExecStatement;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.ThrowawayTransaction;
@ -51,8 +53,8 @@ public class OperatorStatusTransaction extends ThrowawayTransaction {
private Executable updateOperatorStatus() {
String sql = Update.values(UserInfoTable.TABLE_NAME, UserInfoTable.OP)
.where(UserInfoTable.USER_UUID + "=?")
.and(UserInfoTable.SERVER_UUID + "=?")
.where(UserInfoTable.USER_ID + "=" + UsersTable.SELECT_USER_ID)
.and(UserInfoTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID)
.toString();
return new ExecStatement(sql) {

View File

@ -34,21 +34,18 @@ public class CreateIndexTransaction extends Transaction {
createIndex(UsersTable.TABLE_NAME, "plan_users_uuid_index",
UsersTable.USER_UUID
);
createIndex(UserInfoTable.TABLE_NAME, "plan_user_info_uuid_index",
UserInfoTable.USER_UUID,
UserInfoTable.SERVER_UUID
);
createIndex(SessionsTable.TABLE_NAME, "plan_sessions_uuid_index",
SessionsTable.USER_UUID,
SessionsTable.SERVER_UUID
);
// replaced by foreign keys
dropIndex(UserInfoTable.TABLE_NAME, "plan_user_info_uuid_index");
// replaced by foreign keys
dropIndex(SessionsTable.TABLE_NAME, "plan_sessions_uuid_index");
createIndex(SessionsTable.TABLE_NAME, "plan_sessions_date_index",
SessionsTable.SESSION_START
);
createIndex(WorldTimesTable.TABLE_NAME, "plan_world_times_uuid_index",
WorldTimesTable.USER_UUID,
WorldTimesTable.SERVER_UUID
);
// Replaced by foreign keys
dropIndex(WorldTimesTable.TABLE_NAME, "plan_world_times_uuid_index");
createIndex(KillsTable.TABLE_NAME, "plan_kills_uuid_index",
KillsTable.KILLER_UUID,
KillsTable.VICTIM_UUID,
@ -57,10 +54,9 @@ public class CreateIndexTransaction extends Transaction {
createIndex(KillsTable.TABLE_NAME, "plan_kills_date_index",
KillsTable.DATE
);
createIndex(PingTable.TABLE_NAME, "plan_ping_uuid_index",
PingTable.USER_UUID,
PingTable.SERVER_UUID
);
// Replaced with foreign keys.
dropIndex(PingTable.TABLE_NAME, "plan_ping_uuid_index");
createIndex(PingTable.TABLE_NAME, "plan_ping_date_index",
PingTable.DATE
);
@ -92,4 +88,15 @@ public class CreateIndexTransaction extends Transaction {
execute(sql.toString());
}
private void dropIndex(String tableName, String indexName) {
boolean isMySQL = dbType == DBType.MYSQL;
if (isMySQL) {
boolean indexExists = query(MySQLSchemaQueries.doesIndexExist(indexName, tableName));
if (!indexExists) return;
execute("DROP INDEX " + indexName + " ON " + tableName);
} else {
execute("DROP INDEX IF EXISTS " + indexName);
}
}
}

View File

@ -44,8 +44,8 @@ public class RemoveDuplicateUserInfoTransaction extends ThrowawayTransaction {
SELECT + DISTINCT + "u2." + UserInfoTable.ID + " as id" +
FROM + UserInfoTable.TABLE_NAME + " u1" +
INNER_JOIN + UserInfoTable.TABLE_NAME + " u2 on " +
"u1." + UserInfoTable.USER_UUID + "=u2." + UserInfoTable.USER_UUID + AND +
"u1." + UserInfoTable.SERVER_UUID + "=u2." + UserInfoTable.SERVER_UUID + AND +
"u1." + UserInfoTable.USER_ID + "=u2." + UserInfoTable.USER_ID + AND +
"u1." + UserInfoTable.SERVER_ID + "=u2." + UserInfoTable.SERVER_ID + AND +
"u1." + UserInfoTable.ID + "<u2." + UserInfoTable.ID;
@Override

View File

@ -65,7 +65,7 @@ public class RemoveOldSampledDataTransaction extends ThrowawayTransaction {
String sql = DELETE_FROM + TPSTable.TABLE_NAME +
WHERE + TPSTable.DATE + "<?" +
AND + TPSTable.PLAYERS_ONLINE + "!=?" +
AND + TPSTable.SERVER_ID + '=' + ServerTable.STATEMENT_SELECT_SERVER_ID;
AND + TPSTable.SERVER_ID + '=' + ServerTable.SELECT_SERVER_ID;
return new ExecStatement(sql) {
@Override
@ -80,7 +80,7 @@ public class RemoveOldSampledDataTransaction extends ThrowawayTransaction {
private Executable cleanPingTable() {
String sql = DELETE_FROM + PingTable.TABLE_NAME +
WHERE + '(' + PingTable.DATE + "<?" +
AND + PingTable.SERVER_UUID + "=?)" +
AND + PingTable.SERVER_ID + "=" + ServerTable.SELECT_SERVER_ID + ")" +
OR + PingTable.MIN_PING + "<0";
return new ExecStatement(sql) {

View File

@ -58,11 +58,11 @@ public class DeleteIPsPatch extends Patch {
execute(GeoInfoTable.createTableSQL(dbType));
execute("INSERT INTO " + GeoInfoTable.TABLE_NAME + " (" +
GeoInfoTable.USER_UUID + ',' +
GeoInfoTable.USER_ID + ',' +
GeoInfoTable.LAST_USED + ',' +
GeoInfoTable.GEOLOCATION +
") SELECT " + DISTINCT +
GeoInfoTable.USER_UUID + ',' +
GeoInfoTable.USER_ID + ',' +
GeoInfoTable.LAST_USED + ',' +
GeoInfoTable.GEOLOCATION +
FROM + tempTableName

View File

@ -31,16 +31,16 @@ public class GeoInfoOptimizationPatch extends Patch {
private final String oldTableName;
public GeoInfoOptimizationPatch() {
oldTableName = "plan_ips";
tempTableName = "temp_ips";
oldTableName = GeoInfoTable.TABLE_NAME;
tempTableName = "temp_geoinformation";
}
@Override
public boolean hasBeenApplied() {
return !hasTable(oldTableName)
|| hasColumn(oldTableName, GeoInfoTable.ID)
&& hasColumn(oldTableName, GeoInfoTable.USER_UUID)
&& !hasColumn(oldTableName, "user_id")
&& hasColumn(oldTableName, GeoInfoTable.USER_ID)
&& !hasColumn(oldTableName, "uuid")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@ -50,11 +50,11 @@ public class GeoInfoOptimizationPatch extends Patch {
execute(GeoInfoTable.createTableSQL(dbType));
execute("INSERT INTO " + GeoInfoTable.TABLE_NAME + " (" +
GeoInfoTable.USER_UUID + ',' +
GeoInfoTable.USER_ID + ',' +
GeoInfoTable.LAST_USED + ',' +
GeoInfoTable.GEOLOCATION +
") " + SELECT + DISTINCT +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
"(SELECT plan_users.id FROM plan_users WHERE plan_users.uuid = " + tempTableName + ".uuid LIMIT 1)," +
GeoInfoTable.LAST_USED + ',' +
GeoInfoTable.GEOLOCATION +
FROM + tempTableName

View File

@ -78,7 +78,7 @@ public class NicknameLastSeenPatch extends Patch {
private Map<Integer, ServerUUID> getServerUUIDsByID() {
String sql = Select.from(ServerTable.TABLE_NAME,
ServerTable.SERVER_ID, ServerTable.SERVER_UUID)
ServerTable.ID, ServerTable.SERVER_UUID)
.toString();
return query(new QueryAllStatement<Map<Integer, ServerUUID>>(sql) {
@ -86,7 +86,7 @@ public class NicknameLastSeenPatch extends Patch {
public Map<Integer, ServerUUID> processResults(ResultSet set) throws SQLException {
Map<Integer, ServerUUID> uuids = new HashMap<>();
while (set.next()) {
int id = set.getInt(ServerTable.SERVER_ID);
int id = set.getInt(ServerTable.ID);
uuids.put(id, ServerUUID.fromString(set.getString(ServerTable.SERVER_UUID)));
}
return uuids;

View File

@ -22,7 +22,7 @@ import com.djrapitops.plan.storage.database.sql.tables.PingTable;
import static com.djrapitops.plan.storage.database.sql.building.Sql.FROM;
/**
* Replaces user_id and server_id foreign keys with respective uuid fields in ping table.
* Replaces uuid and server_uuid with foreign keys in ping table.
*
* @author AuroraLS3
*/
@ -38,10 +38,10 @@ public class PingOptimizationPatch extends Patch {
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, PingTable.USER_UUID)
&& hasColumn(tableName, PingTable.SERVER_UUID)
&& !hasColumn(tableName, "user_id")
&& !hasColumn(tableName, "server_id")
return hasColumn(tableName, PingTable.USER_ID)
&& hasColumn(tableName, PingTable.SERVER_ID)
&& !hasColumn(tableName, "uuid")
&& !hasColumn(tableName, "server_uuid")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@ -52,16 +52,16 @@ public class PingOptimizationPatch extends Patch {
execute(PingTable.createTableSQL(dbType));
execute("INSERT INTO " + tableName + " (" +
PingTable.USER_UUID + ',' +
PingTable.SERVER_UUID + ',' +
PingTable.USER_ID + ',' +
PingTable.SERVER_ID + ',' +
PingTable.ID + ',' +
PingTable.MIN_PING + ',' +
PingTable.MAX_PING + ',' +
PingTable.AVG_PING + ',' +
PingTable.DATE +
") SELECT " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
"(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " +
"(SELECT plan_users.id FROM plan_users WHERE plan_users.uuid = " + tempTableName + ".uuid LIMIT 1), " +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid = " + tempTableName + ".server_uuid LIMIT 1), " +
PingTable.ID + ',' +
PingTable.MIN_PING + ',' +
PingTable.MAX_PING + ',' +

View File

@ -51,12 +51,15 @@ public class RegisterDateMinimizationPatch extends Patch {
}
private Query<Map<UUID, Long>> fetchSmallestServerRegisterDates() {
String sql = SELECT + "u1.uuid,u1." + UsersTable.REGISTERED + ",min_registered" + FROM + '(' +
SELECT + UserInfoTable.USER_UUID + ',' +
String selectSmallestRegisterDates = SELECT +
UserInfoTable.USER_ID + ',' +
"MIN(" + UserInfoTable.REGISTERED + ") as min_registered" +
FROM + UserInfoTable.TABLE_NAME +
GROUP_BY + UserInfoTable.USER_UUID + ") u2" +
INNER_JOIN + UsersTable.TABLE_NAME + " u1 on u1.uuid=u2.uuid" +
GROUP_BY + UserInfoTable.USER_ID;
String sql = SELECT + UsersTable.USER_UUID + ",u1." + UsersTable.REGISTERED + ",min_registered" +
FROM + '(' + selectSmallestRegisterDates + ") u2" +
INNER_JOIN + UsersTable.TABLE_NAME + " u1 on u1." + UsersTable.ID + "=u2." + UserInfoTable.USER_ID +
WHERE + "u1." + UsersTable.REGISTERED + ">min_registered";
return new QueryAllStatement<Map<UUID, Long>>(sql, 500) {
@ -64,7 +67,7 @@ public class RegisterDateMinimizationPatch extends Patch {
public Map<UUID, Long> processResults(ResultSet set) throws SQLException {
Map<UUID, Long> dates = new HashMap<>();
while (set.next()) {
UUID playerUUID = UUID.fromString(set.getString(1));
UUID playerUUID = UUID.fromString(set.getString(UsersTable.USER_UUID));
long newRegisterDate = set.getLong("min_registered");
dates.put(playerUUID, newRegisterDate);
}

View File

@ -40,10 +40,10 @@ public class SessionsOptimizationPatch extends Patch {
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, SessionsTable.USER_UUID)
&& hasColumn(tableName, SessionsTable.SERVER_UUID)
&& !hasColumn(tableName, "user_id")
&& !hasColumn(tableName, "server_id")
return hasColumn(tableName, SessionsTable.USER_ID)
&& hasColumn(tableName, SessionsTable.SERVER_ID)
&& !hasColumn(tableName, "uuid")
&& !hasColumn(tableName, "server_uuid")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@ -58,8 +58,8 @@ public class SessionsOptimizationPatch extends Patch {
execute(SessionsTable.createTableSQL(dbType));
execute("INSERT INTO " + tableName + " (" +
SessionsTable.USER_UUID + ',' +
SessionsTable.SERVER_UUID + ',' +
SessionsTable.USER_ID + ',' +
SessionsTable.SERVER_ID + ',' +
SessionsTable.ID + ',' +
SessionsTable.SESSION_START + ',' +
SessionsTable.SESSION_END + ',' +
@ -67,8 +67,8 @@ public class SessionsOptimizationPatch extends Patch {
SessionsTable.DEATHS + ',' +
SessionsTable.AFK_TIME +
") SELECT " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
"(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " +
"(SELECT plan_users.id FROM plan_users WHERE plan_users.uuid = " + tempTableName + ".uuid LIMIT 1), " +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid = " + tempTableName + ".server_uuid LIMIT 1), " +
SessionsTable.ID + ',' +
SessionsTable.SESSION_START + ',' +
SessionsTable.SESSION_END + ',' +

View File

@ -32,14 +32,14 @@ import static com.djrapitops.plan.storage.database.sql.building.Sql.FROM;
*/
public class UserInfoHostnameAllowNullPatch extends Patch {
private final String tempTableName = "temp_user_info_join_address_patching";
private final String tableName = UserInfoTable.TABLE_NAME;
private static final String TEMP_TABLE_NAME = "temp_user_info_join_address_patching";
private static final String TABLE_NAME = UserInfoTable.TABLE_NAME;
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, UserInfoTable.JOIN_ADDRESS)
&& !hasColumn(tableName, "hostname")
&& !hasTable(tempTableName);
return hasColumn(TABLE_NAME, UserInfoTable.JOIN_ADDRESS)
&& !hasColumn(TABLE_NAME, "hostname")
&& !hasTable(TEMP_TABLE_NAME);
}
@Override
@ -47,23 +47,23 @@ public class UserInfoHostnameAllowNullPatch extends Patch {
tempOldTable();
execute(UserInfoTable.createTableSQL(dbType));
execute(new ExecStatement("INSERT INTO " + tableName + " (" +
execute(new ExecStatement("INSERT INTO " + TABLE_NAME + " (" +
UserInfoTable.ID + ',' +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.SERVER_UUID + ',' +
UserInfoTable.USER_ID + ',' +
UserInfoTable.SERVER_ID + ',' +
UserInfoTable.REGISTERED + ',' +
UserInfoTable.OP + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.JOIN_ADDRESS +
") SELECT " +
UserInfoTable.ID + ',' +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.SERVER_UUID + ',' +
UserInfoTable.USER_ID + ',' +
UserInfoTable.SERVER_ID + ',' +
UserInfoTable.REGISTERED + ',' +
UserInfoTable.OP + ',' +
UserInfoTable.BANNED + ',' +
"?" +
FROM + tempTableName
FROM + TEMP_TABLE_NAME
) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
@ -71,13 +71,13 @@ public class UserInfoHostnameAllowNullPatch extends Patch {
}
});
dropTable(tempTableName);
dropTable(TEMP_TABLE_NAME);
}
private void tempOldTable() {
if (!hasTable(tempTableName)) {
renameTable(tableName, tempTableName);
if (!hasTable(TEMP_TABLE_NAME)) {
renameTable(TABLE_NAME, TEMP_TABLE_NAME);
}
}
}

View File

@ -38,10 +38,10 @@ public class UserInfoOptimizationPatch extends Patch {
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, UserInfoTable.USER_UUID)
&& hasColumn(tableName, UserInfoTable.SERVER_UUID)
&& !hasColumn(tableName, "user_id")
&& !hasColumn(tableName, "server_id")
return hasColumn(tableName, UserInfoTable.USER_ID)
&& hasColumn(tableName, UserInfoTable.SERVER_ID)
&& !hasColumn(tableName, "uuid")
&& !hasColumn(tableName, "server_uuid")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@ -52,14 +52,14 @@ public class UserInfoOptimizationPatch extends Patch {
execute(UserInfoTable.createTableSQL(dbType));
execute("INSERT INTO " + tableName + " (" +
UserInfoTable.USER_UUID + ',' +
UserInfoTable.SERVER_UUID + ',' +
UserInfoTable.USER_ID + ',' +
UserInfoTable.SERVER_ID + ',' +
UserInfoTable.REGISTERED + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.OP +
") SELECT " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
"(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " +
"(SELECT plan_users.id FROM plan_users WHERE plan_users.uuid = " + tempTableName + ".uuid LIMIT 1), " +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid = " + tempTableName + ".server_uuid LIMIT 1), " +
UserInfoTable.REGISTERED + ',' +
UserInfoTable.BANNED + ',' +
UserInfoTable.OP +

View File

@ -41,10 +41,10 @@ public class WorldTimesOptimizationPatch extends Patch {
@Override
public boolean hasBeenApplied() {
return hasColumn(tableName, WorldTimesTable.ID)
&& hasColumn(tableName, WorldTimesTable.USER_UUID)
&& hasColumn(tableName, WorldTimesTable.SERVER_UUID)
&& !hasColumn(tableName, "user_id")
&& !hasColumn(tableName, "server_id")
&& hasColumn(tableName, WorldTimesTable.USER_ID)
&& hasColumn(tableName, WorldTimesTable.SERVER_ID)
&& !hasColumn(tableName, "uuid")
&& !hasColumn(tableName, "server_uuid")
&& !hasTable(tempTableName); // If this table exists the patch has failed to finish.
}
@ -54,26 +54,49 @@ public class WorldTimesOptimizationPatch extends Patch {
tempOldTable();
execute(WorldTimesTable.createTableSQL(dbType));
execute("INSERT INTO " + tableName + " (" +
WorldTimesTable.USER_UUID + ',' +
WorldTimesTable.SERVER_UUID + ',' +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
") SELECT " +
"(SELECT plan_users.uuid FROM plan_users WHERE plan_users.id = " + tempTableName + ".user_id LIMIT 1), " +
"(SELECT plan_servers.uuid FROM plan_servers WHERE plan_servers.id = " + tempTableName + ".server_id LIMIT 1), " +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
FROM + tempTableName
);
if (hasColumn(tempTableName, WorldTimesTable.ID)) {
execute("INSERT INTO " + tableName + " (" +
WorldTimesTable.USER_ID + ',' +
WorldTimesTable.SERVER_ID + ',' +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
") SELECT " +
"(SELECT plan_users.id FROM plan_users WHERE plan_users.uuid = " + tempTableName + ".uuid LIMIT 1), " +
"(SELECT plan_servers.id FROM plan_servers WHERE plan_servers.uuid = " + tempTableName + ".server_uuid LIMIT 1), " +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
FROM + tempTableName
);
} else {
execute("INSERT INTO " + tableName + " (" +
WorldTimesTable.USER_ID + ',' +
WorldTimesTable.SERVER_ID + ',' +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
") SELECT " +
WorldTimesTable.USER_ID + ',' +
WorldTimesTable.SERVER_ID + ',' +
WorldTimesTable.ADVENTURE + ',' +
WorldTimesTable.CREATIVE + ',' +
WorldTimesTable.SURVIVAL + ',' +
WorldTimesTable.SPECTATOR + ',' +
WorldTimesTable.SESSION_ID + ',' +
WorldTimesTable.WORLD_ID +
FROM + tempTableName
);
}
dropTable(tempTableName);
} catch (Exception e) {

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.storage.database.queries.LargeStoreQueries;
import com.djrapitops.plan.storage.database.queries.QueryAllStatement;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.storage.database.sql.tables.ServerTable;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.WorldTable;
import com.djrapitops.plan.storage.database.sql.tables.WorldTimesTable;
@ -73,14 +74,17 @@ public class WorldsServerIDPatch extends Patch {
String worldIDColumn = WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.WORLD_ID;
String worldSessionIDColumn = WorldTimesTable.TABLE_NAME + '.' + WorldTimesTable.SESSION_ID;
String sessionIDColumn = SessionsTable.TABLE_NAME + '.' + SessionsTable.ID;
String sessionServerUUIDColumn = SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_UUID;
String sessionServerIDColumn = SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_ID;
String serverIDColumn = ServerTable.TABLE_NAME + '.' + ServerTable.ID;
String serverUUIDColumn = ServerTable.TABLE_NAME + '.' + ServerTable.SERVER_UUID;
String sql = SELECT + DISTINCT +
WorldTable.NAME + FROM +
WorldTable.TABLE_NAME +
INNER_JOIN + WorldTimesTable.TABLE_NAME + " on " + worldIDColumn + "=" + WorldTable.TABLE_NAME + '.' + WorldTable.ID +
INNER_JOIN + SessionsTable.TABLE_NAME + " on " + worldSessionIDColumn + "=" + sessionIDColumn +
WHERE + sessionServerUUIDColumn + "=?";
INNER_JOIN + ServerTable.TABLE_NAME + " on " + serverIDColumn + "=" + sessionServerIDColumn +
WHERE + serverUUIDColumn + "=?";
return query(new QueryStatement<Set<String>>(sql, 1000) {
@Override

View File

@ -32,6 +32,7 @@ import com.djrapitops.plan.storage.database.queries.Query;
import com.djrapitops.plan.storage.database.queries.QueryStatement;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.storage.database.sql.tables.SessionsTable;
import com.djrapitops.plan.storage.database.sql.tables.UsersTable;
import com.djrapitops.plan.storage.database.transactions.commands.RemovePlayerTransaction;
import com.djrapitops.plan.storage.database.transactions.init.RemoveDuplicateUserInfoTransaction;
import com.djrapitops.plan.storage.database.transactions.init.RemoveOldExtensionsTransaction;
@ -169,11 +170,13 @@ public class DBCleanTask extends TaskSystem.Task {
}
private Query<List<UUID>> fetchInactivePlayerUUIDs(long keepActiveAfter) {
String sql = SELECT + "uuid, last_seen" + FROM +
'(' + SELECT + "MAX(" + SessionsTable.SESSION_END + ") as last_seen, " +
SessionsTable.USER_UUID +
String selectLastSeen = SELECT + "MAX(" + SessionsTable.SESSION_END + ") as last_seen, " +
SessionsTable.USER_ID +
FROM + SessionsTable.TABLE_NAME +
GROUP_BY + SessionsTable.USER_UUID + ") as q1" +
GROUP_BY + SessionsTable.USER_ID;
String sql = SELECT + "uuid, last_seen" +
FROM + '(' + selectLastSeen + ") as q1" +
INNER_JOIN + UsersTable.TABLE_NAME + " u on u." + UsersTable.ID + '=' + "q1." + SessionsTable.USER_ID +
WHERE + "last_seen < ?";
return new QueryStatement<List<UUID>>(sql, 20000) {

View File

@ -373,6 +373,7 @@ function displayResults(json) {
/* Player table */
$('.player-table').DataTable({
responsive: true,
deferRender: true,
columns: json.data.players.columns,
data: json.data.players.data,
order: [[5, "desc"]]

View File

@ -289,6 +289,7 @@
}
table = $('.player-table').DataTable({
responsive: true,
deferRender: true,
columns: playersTableJson.columns,
data: playersTableJson.data,
order: [[5, "desc"]]

View File

@ -1428,6 +1428,7 @@
}
table = $('.player-table').DataTable({
responsive: true,
deferRender: true,
columns: json.columns,
data: json.data,
order: [[5, "desc"]]

View File

@ -32,7 +32,6 @@ import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.storage.database.queries.*;
import com.djrapitops.plan.storage.database.queries.containers.ContainerFetchQueries;
import com.djrapitops.plan.storage.database.queries.containers.ServerPlayerContainersQuery;
import com.djrapitops.plan.storage.database.queries.objects.*;
import com.djrapitops.plan.storage.database.queries.objects.playertable.NetworkTablePlayersQuery;
import com.djrapitops.plan.storage.database.queries.objects.playertable.ServerTablePlayersQuery;
@ -47,13 +46,15 @@ import com.djrapitops.plan.storage.database.transactions.patches.RegisterDateMin
import com.djrapitops.plan.storage.upkeep.DBCleanTask;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import utilities.*;
import utilities.FieldFetcher;
import utilities.RandomData;
import utilities.TestConstants;
import utilities.TestPluginLogger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.djrapitops.plan.storage.database.sql.building.Sql.SELECT;
import static com.djrapitops.plan.storage.database.sql.building.Sql.WHERE;
@ -143,7 +144,7 @@ public interface DatabaseTest extends DatabaseTestPreparer {
null
).cleanOldPlayers(db());
Collection<BaseUser> found = db().query(BaseUserQueries.fetchServerBaseUsers(serverUUID()));
Collection<BaseUser> found = db().query(BaseUserQueries.fetchAllBaseUsers());
assertFalse(found.isEmpty(), "All users were deleted!! D:");
}
@ -213,23 +214,6 @@ public interface DatabaseTest extends DatabaseTestPreparer {
assertEquals(expected, result);
}
@Test
default void serverPlayerContainersQueryDoesNotReturnDuplicatePlayers() {
db().executeTransaction(TestData.storeServers());
executeTransactions(TestData.storePlayerOneData());
executeTransactions(TestData.storePlayerTwoData());
List<UUID> expected = Arrays.asList(playerUUID, player2UUID);
Collections.sort(expected);
Collection<UUID> result = db().query(new ServerPlayerContainersQuery(TestConstants.SERVER_UUID))
.stream().map(player -> player.getUnsafe(PlayerKeys.UUID))
.sorted()
.collect(Collectors.toList());
assertEquals(expected, result);
}
@Test
default void sqlDateConversionSanityCheck() {
Database db = db();
@ -239,6 +223,7 @@ public interface DatabaseTest extends DatabaseTestPreparer {
Sql sql = db.getType().getSql();
String testSQL = SELECT + sql.dateToEpochSecond(sql.epochSecondToDate(Long.toString(expected))) + " as ms";
//noinspection Convert2Diamond Causes compiler issues without Generic type definition
long result = db.query(new QueryAllStatement<Long>(testSQL) {
@Override
public Long processResults(ResultSet set) throws SQLException {
@ -259,6 +244,7 @@ public interface DatabaseTest extends DatabaseTestPreparer {
String testSQL = SELECT + sql.dateToDayStamp(sql.epochSecondToDate(Long.toString((time + offset) / 1000))) + " as date";
String expected = deliveryUtilities().getFormatters().iso8601NoClockLong().apply(time);
//noinspection Convert2Diamond Causes compiler issues without Generic type definition
String result = db.query(new QueryAllStatement<String>(testSQL) {
@Override
public String processResults(ResultSet set) throws SQLException {
@ -285,6 +271,7 @@ public interface DatabaseTest extends DatabaseTestPreparer {
String testSQL = SELECT + sql.dateToDayStamp(sql.epochSecondToDate(Long.toString((time + offset) / 1000))) + " as date";
String expected = deliveryUtilities().getFormatters().iso8601NoClockLong().apply(time);
//noinspection Convert2Diamond Causes compiler issues without Generic type definition
String result = db.query(new QueryAllStatement<String>(testSQL) {
@Override
public String processResults(ResultSet set) throws SQLException {
@ -305,7 +292,7 @@ public interface DatabaseTest extends DatabaseTestPreparer {
, new Transaction() {
@Override
protected void performOperations() {
execute("UPDATE " + UserInfoTable.TABLE_NAME + " SET " + UserInfoTable.REGISTERED + "=0" + WHERE + UserInfoTable.USER_UUID + "='" + playerUUID + "'");
execute("UPDATE " + UserInfoTable.TABLE_NAME + " SET " + UserInfoTable.REGISTERED + "=0" + WHERE + UserInfoTable.USER_ID + "=1");
}
}
);

View File

@ -22,6 +22,7 @@ import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.modules.FiltersModule;
import com.djrapitops.plan.settings.ConfigSystem;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
import com.djrapitops.plan.storage.file.PlanFiles;
import dagger.BindsInstance;
import dagger.Component;
@ -53,6 +54,8 @@ import java.nio.file.Path;
public interface DatabaseTestComponent extends DBPreparer.Dependencies {
default void enable() {
SQLDB.setDownloadDriver(false);
files().enable();
configSystem().enable();
dbSystem().enable();
@ -80,6 +83,8 @@ public interface DatabaseTestComponent extends DBPreparer.Dependencies {
ExtensionSvc extensionService();
QueryFilters queryFilters();
@Component.Builder
interface Builder {
@BindsInstance

View File

@ -22,6 +22,7 @@ import com.djrapitops.plan.extension.ExtensionSvc;
import com.djrapitops.plan.identification.ServerInfo;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
import com.djrapitops.plan.storage.database.transactions.Executable;
import com.djrapitops.plan.storage.database.transactions.Transaction;
import utilities.TestConstants;
@ -61,6 +62,8 @@ public interface DatabaseTestPreparer {
default ExtensionSvc extensionService() {return system().getExtensionService();}
QueryFilters queryFilters();
default void execute(Executable executable) {
try {
db().executeTransaction(new Transaction() {

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.storage.database.queries.ExtensionsDatabaseTest;
import com.djrapitops.plan.storage.database.queries.QueriesTestAggregate;
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
import com.djrapitops.plan.storage.database.transactions.init.CreateTablesTransaction;
@ -145,6 +146,11 @@ class MySQLTest implements DatabaseTest, QueriesTestAggregate {
return component.extensionService();
}
@Override
public QueryFilters queryFilters() {
return component.queryFilters();
}
@Override
public PlanSystem system() {
PlanSystem mockSystem = Mockito.mock(PlanSystem.class);

View File

@ -25,6 +25,7 @@ import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.storage.database.queries.ExtensionsDatabaseTest;
import com.djrapitops.plan.storage.database.queries.QueriesTestAggregate;
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
import com.djrapitops.plan.storage.database.transactions.StoreServerInformationTransaction;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
import com.djrapitops.plan.storage.database.transactions.init.CreateTablesTransaction;
@ -138,6 +139,11 @@ public class SQLiteTest implements DatabaseTest, QueriesTestAggregate {
return component.extensionService();
}
@Override
public QueryFilters queryFilters() {
return component.queryFilters();
}
@Override
public PlanSystem system() {
PlanSystem mockSystem = Mockito.mock(PlanSystem.class);

View File

@ -216,14 +216,14 @@ public interface ActivityIndexQueriesTest extends DatabaseTestPreparer {
String sql = SELECT +
"ux." + UsersTable.USER_UUID + ",COALESCE(active_playtime,0) AS active_playtime" +
FROM + UsersTable.TABLE_NAME + " ux" +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_UUID +
LEFT_JOIN + '(' + SELECT + SessionsTable.USER_ID +
",SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + '-' + SessionsTable.AFK_TIME + ") as active_playtime" +
FROM + SessionsTable.TABLE_NAME +
WHERE + SessionsTable.SESSION_END + ">=?" +
AND + SessionsTable.SESSION_START + "<=?" +
GROUP_BY + SessionsTable.USER_UUID +
") sx on sx.uuid=ux.uuid";
return new QueryStatement<Long>(sql) {
GROUP_BY + SessionsTable.USER_ID +
") sx on sx." + SessionsTable.USER_ID + "=ux." + UsersTable.ID;
return new QueryStatement<>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setLong(1, after);

View File

@ -37,6 +37,7 @@ import com.djrapitops.plan.gathering.domain.WorldTimes;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
import com.djrapitops.plan.storage.database.transactions.events.PlayerRegisterTransaction;
import com.djrapitops.plan.storage.database.transactions.events.WorldNameStoreTransaction;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -86,6 +87,8 @@ public interface ExtensionsDatabaseTest extends DatabaseTestPreparer {
@Test
default void extensionPlayerValuesAreStored() {
db().executeTransaction(new PlayerRegisterTransaction(TestConstants.PLAYER_ONE_UUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
ExtensionSvc extensionService = extensionService();
extensionService.register(new PlayerExtension());

View File

@ -0,0 +1,108 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.storage.database.queries;
import com.djrapitops.plan.delivery.domain.datatransfer.InputFilterDto;
import com.djrapitops.plan.settings.locale.lang.FilterLang;
import com.djrapitops.plan.settings.locale.lang.HtmlLang;
import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
import com.djrapitops.plan.storage.database.queries.filter.Filter;
import com.djrapitops.plan.storage.database.queries.filter.filters.PluginBooleanGroupFilter;
import com.djrapitops.plan.utilities.java.Maps;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import utilities.TestConstants;
import java.util.*;
import java.util.stream.Collectors;
import static org.junit.jupiter.api.Assertions.*;
public interface FilterQueryTest extends DatabaseTestPreparer {
@TestFactory
default Collection<DynamicTest> filterOptionsQueriesTests() {
Map<String, Filter> filters = queryFilters().getFilters();
return filters.entrySet().stream()
.map(entry -> DynamicTest.dynamicTest("Filter " + entry.getKey() + " gets options",
() -> assertNotNull(entry.getValue().getOptions())))
.collect(Collectors.toList());
}
@TestFactory
default Collection<DynamicTest> filterGetsResults() {
Map<String, Map> filtersAndOptions = Maps.builder(String.class, Map.class)
.put("playedBetween", Maps.builder(String.class, String.class)
.put("afterDate", "10/10/10")
.put("afterTime", "00:00")
.put("beforeDate", "10/10/10")
.put("beforeTime", "00:00")
.build())
.put("registeredBetween", Maps.builder(String.class, String.class)
.put("afterDate", "10/10/10")
.put("afterTime", "00:00")
.put("beforeDate", "10/10/10")
.put("beforeTime", "00:00")
.build())
.put("operators", Map.of("selected", "[" + FilterLang.OPERATORS.getDefault() + "]"))
.put("playedOnServer", Map.of("selected", "[" + TestConstants.SERVER_NAME + "]"))
.put("activityIndexNow", Map.of("selected", "[" + HtmlLang.INDEX_ACTIVE.getDefault() + "]"))
.put("banned", Map.of("selected", "[" + FilterLang.BANNED.getDefault() + "]"))
.put("geolocations", Map.of("selected", "[Finland]"))
.put("joinAddresses", Map.of("selected", "[unknown]"))
.put("pluginsBooleanGroups", Map.of("selected", "[\"" + new PluginBooleanGroupFilter.PluginBooleanOption(TestConstants.SERVER_NAME, "TestExtension", "isJailed").format() + ": false\"]"))
.build();
List<DynamicTest> tests = new ArrayList<>();
Set<String> testedKinds = new HashSet<>();
for (Map.Entry<String, Map> entry : filtersAndOptions.entrySet()) {
String kind = entry.getKey();
Map<String, String> parameters = (Map<String, String>) entry.getValue();
tests.add(DynamicTest.dynamicTest("Filter " + kind + " gets results", () -> {
Filter filter = getFilter(kind);
InputFilterDto input = new InputFilterDto(kind, parameters);
testFilter(filter, input);
}));
testedKinds.add(kind);
}
assertAll(queryFilters().getFilters().keySet().stream()
.map(kind -> () -> assertTrue(testedKinds.contains(kind), () -> "Incorrect test setup: Filter '" + kind + "' is not being tested")));
return tests;
}
private Filter getFilter(String kind) {
return queryFilters().getFilter(kind)
.orElseThrow(() -> new AssertionError("Unknown filter '" + kind + "'"));
}
private void testFilter(Filter filter, InputFilterDto input) {
Set<String> setParameters = input.getSetParameters();
assertAll(Arrays.stream(filter.getExpectedParameters())
.map(parameter -> () -> assertTrue(setParameters.contains(parameter), () -> "Incorrect test setup: Parameter '" + parameter + "' was not set for filter " + filter.getKind())));
Set<Integer> matchingUserIds = filter.getMatchingUserIds(input);
assertNotNull(matchingUserIds);
}
}

View File

@ -21,6 +21,7 @@ import com.djrapitops.plan.gathering.domain.GeoInfo;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
import com.djrapitops.plan.storage.database.queries.objects.BaseUserQueries;
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
import com.djrapitops.plan.storage.database.queries.objects.PingQueries;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
@ -177,8 +178,8 @@ public interface GeolocationQueriesTest extends DatabaseTestPreparer {
save(playerUUID, geoInfo);
}
Set<UUID> expected = Collections.singleton(playerUUID);
Set<UUID> result = db().query(GeoInfoQueries.uuidsOfPlayersWithGeolocations(
Set<Integer> expected = Set.of(db().query(BaseUserQueries.fetchUserId(playerUUID)));
Set<Integer> result = db().query(GeoInfoQueries.userIdsOfPlayersWithGeolocations(
Collections.singletonList(savedData.get(0).getGeolocation()))
);
assertEquals(expected, result);

View File

@ -22,8 +22,10 @@ import com.djrapitops.plan.storage.database.DatabaseTestPreparer;
import com.djrapitops.plan.storage.database.queries.objects.PingQueries;
import com.djrapitops.plan.storage.database.transactions.commands.RemoveEverythingTransaction;
import com.djrapitops.plan.storage.database.transactions.events.PingStoreTransaction;
import com.djrapitops.plan.storage.database.transactions.events.PlayerServerRegisterTransaction;
import org.junit.jupiter.api.Test;
import utilities.RandomData;
import utilities.TestConstants;
import java.util.Collections;
import java.util.List;
@ -35,8 +37,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public interface PingQueriesTest extends DatabaseTestPreparer {
private void prepareForPingStorage() {
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, RandomData::randomTime,
TestConstants.PLAYER_ONE_NAME, serverUUID(), TestConstants.GET_PLAYER_HOSTNAME));
}
@Test
default void singlePingIsStored() {
prepareForPingStorage();
DateObj<Integer> saved = RandomData.randomIntDateObject();
int value = saved.getValue();
db().executeTransaction(new PingStoreTransaction(playerUUID, serverUUID(),
@ -51,6 +60,8 @@ public interface PingQueriesTest extends DatabaseTestPreparer {
@Test
default void pingIsStored() {
prepareForPingStorage();
Map<UUID, List<Ping>> expected = Collections.singletonMap(playerUUID, RandomData.randomPings(serverUUID()));
execute(LargeStoreQueries.storeAllPingData(expected));
Map<UUID, List<Ping>> fetched = db().query(PingQueries.fetchAllPingData());

View File

@ -30,6 +30,7 @@ public interface QueriesTestAggregate extends
TopListQueriesTest,
TPSQueriesTest,
UserInfoQueriesTest,
WebUserQueriesTest {
WebUserQueriesTest,
FilterQueryTest {
/* Collects all query tests together so its easier to implement database tests */
}

View File

@ -209,20 +209,6 @@ public interface SessionQueriesTest extends DatabaseTestPreparer {
assertEquals(new WorldTimes(), worldTimesOfServer);
}
@Test
default void serverSessionsAreFetchedByPlayerUUID() {
prepareForSessionSave();
FinishedSession session = RandomData.randomSession(serverUUID(), worlds, playerUUID, player2UUID);
execute(DataStoreQueries.storeSession(session));
forcePersistenceCheck();
Map<UUID, List<FinishedSession>> expected = Collections.singletonMap(playerUUID, Collections.singletonList(session));
Map<UUID, List<FinishedSession>> fetched = db().query(SessionQueries.fetchSessionsOfServer(serverUUID()));
assertEquals(expected, fetched);
}
@Test
default void playerSessionsAreFetchedByServerUUID() {
prepareForSessionSave();

View File

@ -32,7 +32,6 @@ import org.junit.jupiter.api.Test;
import utilities.OptionalAssert;
import utilities.RandomData;
import utilities.TestConstants;
import utilities.TestData;
import java.util.*;
import java.util.concurrent.ExecutionException;
@ -148,21 +147,6 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
OptionalAssert.equals(random, db().query(BaseUserQueries.fetchBaseUserOfPlayer(playerUUID)).map(BaseUser::getTimesKicked));
}
@Test
default void baseUsersQueryDoesNotReturnDuplicatePlayers() {
db().executeTransaction(TestData.storeServers());
executeTransactions(TestData.storePlayerOneData());
executeTransactions(TestData.storePlayerTwoData());
Collection<BaseUser> expected = new HashSet<>(Arrays.asList(TestData.getPlayerBaseUser(), TestData.getPlayer2BaseUser()));
Collection<BaseUser> server1Result = db().query(BaseUserQueries.fetchServerBaseUsers(TestConstants.SERVER_UUID));
assertEquals(expected, server1Result);
Collection<BaseUser> server2Result = db().query(BaseUserQueries.fetchServerBaseUsers(TestConstants.SERVER_TWO_UUID));
assertEquals(expected, server2Result);
}
@Test
default void matchingByNameFindsNamesCaseInsensitive() {
String exp1 = "TestName";
@ -217,6 +201,9 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
@Test
default void cleanRemovesOnlyDuplicatedUserInfo() throws ExecutionException, InterruptedException {
db().executeTransaction(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, TestConstants.PLAYER_ONE_NAME));
db().executeTransaction(new PlayerRegisterTransaction(player2UUID, System::currentTimeMillis, TestConstants.PLAYER_TWO_NAME));
// Store one duplicate
db().executeTransaction(new Transaction() {
@Override
@ -256,8 +243,8 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
}
}).get();
Set<UUID> expected = Collections.singleton(player2UUID);
Set<UUID> result = db().query(BaseUserQueries.uuidsOfRegisteredBetween(2500L, 7500L));
Set<Integer> expected = Set.of(db().query(BaseUserQueries.fetchUserId(player2UUID)));
Set<Integer> result = db().query(BaseUserQueries.userIdsOfRegisteredBetween(2500L, 7500L));
assertEquals(expected, result);
}
@ -322,6 +309,7 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
@Test
default void joinAddressFilterOptionsAreFetchedWhenThereAreMultiple() {
joinAddressIsUpdatedUponSecondLogin();
db().executeTransaction(new StoreServerInformationTransaction(new Server(TestConstants.SERVER_TWO_UUID, TestConstants.SERVER_TWO_NAME, "", TestConstants.VERSION)));
db().executeTransaction(new PlayerServerRegisterTransaction(playerUUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, serverUUID(), () -> TestConstants.GET_PLAYER_HOSTNAME.get() + "_b"));
db().executeTransaction(new PlayerServerRegisterTransaction(player2UUID, () -> TestConstants.REGISTER_TIME, TestConstants.PLAYER_ONE_NAME, TestConstants.SERVER_TWO_UUID, () -> TestConstants.GET_PLAYER_HOSTNAME.get() + "_a"));
@ -339,8 +327,8 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
default void joinAddressFilterUUIDsAreFetched() {
joinAddressIsUpdatedUponSecondLogin();
Set<UUID> expected = Collections.singleton(playerUUID);
Set<UUID> result = db().query(UserInfoQueries.uuidsOfPlayersWithJoinAddresses(
Set<Integer> expected = Set.of(db().query(BaseUserQueries.fetchUserId(playerUUID)));
Set<Integer> result = db().query(UserInfoQueries.userIdsOfPlayersWithJoinAddresses(
Collections.singletonList(TestConstants.GET_PLAYER_HOSTNAME.get().toLowerCase()))
);
assertEquals(expected, result);
@ -350,8 +338,8 @@ public interface UserInfoQueriesTest extends DatabaseTestPreparer {
default void joinAddressFilterUUIDsAreFetchedWhenUnknown() {
joinAddressCanBeNull();
Set<UUID> expected = Collections.singleton(playerUUID);
Set<UUID> result = db().query(UserInfoQueries.uuidsOfPlayersWithJoinAddresses(
Set<Integer> expected = Set.of(db().query(BaseUserQueries.fetchUserId(playerUUID)));
Set<Integer> result = db().query(UserInfoQueries.userIdsOfPlayersWithJoinAddresses(
Collections.singletonList("unknown"))
);
assertEquals(expected, result);

View File

@ -33,7 +33,7 @@ class CreateTableBuilderTest {
void createsSameTablesAsOldParser() {
String expected = "CREATE TABLE IF NOT EXISTS plan_servers (id integer NOT NULL AUTO_INCREMENT,uuid varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL UNIQUE,name varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,web_address varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,is_installed boolean NOT NULL DEFAULT 1,max_players integer NOT NULL DEFAULT -1,PRIMARY KEY (id))";
String result = CreateTableBuilder.create(ServerTable.TABLE_NAME, DBType.MYSQL)
.column(ServerTable.SERVER_ID, Sql.INT)
.column(ServerTable.ID, Sql.INT)
.primaryKey()
.column(ServerTable.SERVER_UUID, Sql.varchar(36)).notNull().unique()
.column(ServerTable.NAME, Sql.varchar(100))