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:
parent
0e3339be6e
commit
b74e338721
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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 +
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 + ',' +
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" +
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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() {
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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" +
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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 + "<=?";
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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 + "<=?";
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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() +
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 + "=?" +
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 + ',' +
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 + ',' +
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 +
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
||||
|
|
|
@ -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"]]
|
||||
|
|
|
@ -289,6 +289,7 @@
|
|||
}
|
||||
table = $('.player-table').DataTable({
|
||||
responsive: true,
|
||||
deferRender: true,
|
||||
columns: playersTableJson.columns,
|
||||
data: playersTableJson.data,
|
||||
order: [[5, "desc"]]
|
||||
|
|
|
@ -1428,6 +1428,7 @@
|
|||
}
|
||||
table = $('.player-table').DataTable({
|
||||
responsive: true,
|
||||
deferRender: true,
|
||||
columns: json.columns,
|
||||
data: json.data,
|
||||
order: [[5, "desc"]]
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue