Refactored many session fetch methods to queries:

- Sessions of a Server
- Sessions of a Player
- Flat sessions with kills and world data

Removed:
- KillsTable#addKillsToSessions(UUID uuid, Map<Integer, Session>)
- KillsTable#addDeathsToSessions(UUID uuid, Map<Integer, Session>)
- WorldTimesTable#addWorldTimesToSessions(UUID uuid, Map<Integer, Session> sessions)
- SessionsTable#getSessionInformation, #getSessions, #getSessionInfoOfServer
This commit is contained in:
Rsl1122 2019-02-13 20:32:17 +02:00
parent 70417f5359
commit adb2b865e1
11 changed files with 236 additions and 292 deletions

View File

@ -16,7 +16,7 @@
*/ */
package com.djrapitops.plan.data.container; package com.djrapitops.plan.data.container;
import com.djrapitops.plan.data.store.containers.SupplierDataContainer; import com.djrapitops.plan.data.store.containers.DynamicDataContainer;
import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.objects.DateHolder; import com.djrapitops.plan.data.store.objects.DateHolder;
import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.data.time.WorldTimes;
@ -29,7 +29,7 @@ import java.util.*;
* @author Rsl1122 * @author Rsl1122
* @see SessionKeys for Key objects. * @see SessionKeys for Key objects.
*/ */
public class Session extends SupplierDataContainer implements DateHolder { public class Session extends DynamicDataContainer implements DateHolder {
private long sessionStart; private long sessionStart;
private WorldTimes worldTimes; private WorldTimes worldTimes;
@ -228,4 +228,17 @@ public class Session extends SupplierDataContainer implements DateHolder {
private long getAfkTime() { private long getAfkTime() {
return afkTime; return afkTime;
} }
@Override
public String toString() {
return "Session{" +
"sessionStart=" + getUnsafe(SessionKeys.START) +
", sessionEnd=" + getUnsafe(SessionKeys.END) +
", worldTimes=" + worldTimes +
", playerKills=" + playerKills +
", mobKills=" + mobKills +
", deaths=" + deaths +
", afkTime=" + afkTime +
'}';
}
} }

View File

@ -46,6 +46,7 @@ public class SessionKeys {
public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; public static final Key<Integer> PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT;
public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; public static final Key<Integer> MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT;
public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT; public static final Key<Integer> DEATH_COUNT = CommonKeys.DEATH_COUNT;
@Deprecated
public static final Key<List<PlayerDeath>> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; public static final Key<List<PlayerDeath>> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS;
@Deprecated @Deprecated

View File

@ -204,6 +204,28 @@ public class SessionsMutator {
}; };
} }
public static Map<UUID, List<Session>> sortByPlayers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID playerUUID = session.getUnsafe(SessionKeys.UUID);
List<Session> playerSessions = sorted.getOrDefault(playerUUID, new ArrayList<>());
playerSessions.add(session);
sorted.put(playerUUID, playerSessions);
}
return sorted;
}
public static Map<UUID, List<Session>> sortByServers(List<Session> sessions) {
Map<UUID, List<Session>> sorted = new HashMap<>();
for (Session session : sessions) {
UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID);
List<Session> serverSessions = sorted.getOrDefault(serverUUID, new ArrayList<>());
serverSessions.add(session);
sorted.put(serverUUID, serverSessions);
}
return sorted;
}
public int toPlayerDeathCount() { public int toPlayerDeathCount() {
return toPlayerDeathList().size(); return toPlayerDeathList().size();
} }

View File

@ -182,4 +182,7 @@ public class WorldTimes {
} }
} }
public boolean contains(String worldName) {
return times.containsKey(worldName);
}
} }

View File

@ -27,6 +27,7 @@ import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.Query; import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.access.queries.PerServerAggregateQueries; import com.djrapitops.plan.db.access.queries.PerServerAggregateQueries;
import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries; import com.djrapitops.plan.db.access.queries.objects.UserInfoQueries;
import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries; import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries;
@ -66,7 +67,7 @@ public class PerServerContainerQuery implements Query<PerServerContainer> {
); );
} }
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessions(playerUUID); Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID));
for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) { for (Map.Entry<UUID, List<Session>> entry : sessions.entrySet()) {
UUID serverUUID = entry.getKey(); UUID serverUUID = entry.getKey();
List<Session> serverSessions = entry.getValue(); List<Session> serverSessions = entry.getValue();

View File

@ -50,36 +50,6 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
this.serverUUID = serverUUID; this.serverUUID = serverUUID;
} }
/**
* 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 static Map<UUID, PerServerContainer> getPerServerData(
Map<UUID, UserInfo> userInformation,
Map<UUID, List<Session>> 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;
}
@Override @Override
public List<PlayerContainer> executeQuery(SQLDB db) { public List<PlayerContainer> executeQuery(SQLDB db) {
List<PlayerContainer> containers = new ArrayList<>(); List<PlayerContainer> containers = new ArrayList<>();
@ -89,14 +59,7 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID)); Map<UUID, List<GeoInfo>> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID));
Map<UUID, List<Nickname>> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID)); Map<UUID, List<Nickname>> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID));
Map<UUID, List<Ping>> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID)); Map<UUID, List<Ping>> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID));
Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID));
// v ------------- Needs work
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessionInfoOfServer(serverUUID);
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
map.put(serverUUID, sessions);
db.getKillsTable().addKillsToSessions(map); // TODO Optimize
db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize
// ^ ------------- Needs work
Map<UUID, UserInfo> userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID)); Map<UUID, UserInfo> userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID));
@ -128,7 +91,6 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
// PerServerContainer // PerServerContainer
container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid));
// v ------------- Needs work
container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { container.putCachingSupplier(PlayerKeys.SESSIONS, () -> {
List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); List<Session> playerSessions = sessions.getOrDefault(uuid, new ArrayList<>());
container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add);
@ -154,10 +116,39 @@ public class ServerPlayerContainersQuery implements Query<List<PlayerContainer>>
container.putSupplier(PlayerKeys.PLAYER_KILL_COUNT, () -> container.getUnsafe(PlayerKeys.PLAYER_KILLS).size()); 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.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount()); container.putSupplier(PlayerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
// ^ ------------- Needs work
containers.add(container); containers.add(container);
} }
return containers; 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<Session>> sessions,
Map<UUID, List<Ping>> ping
) {
Map<UUID, PerServerContainer> perServerContainers = new HashMap<>();
for (Map.Entry<UUID, UserInfo> entry : userInformation.entrySet()) {
UUID playerUUID = entry.getKey();
PerServerContainer perServerContainer = perServerContainers.getOrDefault(playerUUID, new PerServerContainer());
perServerContainer.putUserInfo(entry.getValue()); // Information found withing UserInfo
perServerContainer.putSessions(sessions.get(playerUUID)); // Session list
perServerContainer.putPing(ping.get(playerUUID)); // Ping list
perServerContainer.putCalculatingSuppliers(); // Derivative values
perServerContainers.put(playerUUID, perServerContainer);
}
return perServerContainers;
}
} }

View File

@ -18,12 +18,17 @@ package com.djrapitops.plan.db.access.queries.objects;
import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
import com.djrapitops.plan.data.time.GMTimes;
import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.db.access.Query; import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.access.QueryAllStatement; import com.djrapitops.plan.db.access.QueryAllStatement;
import com.djrapitops.plan.db.sql.tables.KillsTable; import com.djrapitops.plan.db.access.QueryStatement;
import com.djrapitops.plan.db.sql.tables.SessionsTable; import com.djrapitops.plan.db.sql.tables.*;
import com.djrapitops.plan.db.sql.tables.UsersTable; import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.*;
@ -40,6 +45,30 @@ public class SessionQueries {
/* Static method class */ /* Static method class */
} }
private static final String SELECT_SESSIONS_STATEMENT = "SELECT " +
SessionsTable.TABLE_NAME + "." + SessionsTable.ID + ", " +
SessionsTable.TABLE_NAME + "." + SessionsTable.USER_UUID + ", " +
SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID + ", " +
SessionsTable.SESSION_START + ", " +
SessionsTable.SESSION_END + ", " +
SessionsTable.MOB_KILLS + ", " +
SessionsTable.DEATHS + ", " +
SessionsTable.AFK_TIME + ", " +
WorldTimesTable.SURVIVAL + ", " +
WorldTimesTable.CREATIVE + ", " +
WorldTimesTable.ADVENTURE + ", " +
WorldTimesTable.SPECTATOR + ", " +
WorldTable.NAME + ", " +
KillsTable.VICTIM_UUID + ", " +
UsersTable.USER_NAME + " as victim_name, " +
KillsTable.DATE + ", " +
KillsTable.WEAPON +
" FROM " + SessionsTable.TABLE_NAME +
" LEFT JOIN " + KillsTable.TABLE_NAME + " ON " + SessionsTable.TABLE_NAME + "." + SessionsTable.ID + "=" + KillsTable.TABLE_NAME + "." + KillsTable.SESSION_ID +
" LEFT JOIN " + UsersTable.TABLE_NAME + " on " + UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID + "=" + KillsTable.VICTIM_UUID +
" INNER JOIN " + WorldTimesTable.TABLE_NAME + " ON " + SessionsTable.TABLE_NAME + "." + SessionsTable.ID + "=" + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.SESSION_ID +
" INNER JOIN " + WorldTable.TABLE_NAME + " ON " + WorldTimesTable.TABLE_NAME + "." + WorldTimesTable.WORLD_ID + "=" + WorldTable.TABLE_NAME + "." + WorldTable.ID;
/** /**
* Query database for all Kill data. * Query database for all Kill data.
* *
@ -146,10 +175,121 @@ public class SessionQueries {
* @return List of sessions * @return List of sessions
*/ */
public static Query<List<Session>> fetchAllSessionsFlatWithKillAndWorldData() { public static Query<List<Session>> fetchAllSessionsFlatWithKillAndWorldData() {
return db -> db.query(fetchAllSessionsWithKillAndWorldData()) String sql = SELECT_SESSIONS_STATEMENT + " ORDER BY " + SessionsTable.SESSION_START + " DESC";
.values().stream() return new QueryAllStatement<List<Session>>(sql, 50000) {
@Override
public List<Session> processResults(ResultSet set) throws SQLException {
return extractDataFromSessionSelectStatement(set);
}
};
}
/**
* 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<Session>>> fetchSessionsOfServer(UUID serverUUID) {
String sql = SELECT_SESSIONS_STATEMENT + " WHERE " + SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID + "=?" +
" ORDER BY " + SessionsTable.SESSION_START + " DESC";
return new QueryStatement<Map<UUID, List<Session>>>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Session>> processResults(ResultSet set) throws SQLException {
List<Session> sessions = extractDataFromSessionSelectStatement(set);
return SessionsMutator.sortByPlayers(sessions);
}
};
}
/**
* Query the database for Session data of a player with kill and world data.
*
* @param playerUUID UUID of the Player.
* @return Map: Server UUID - List of sessions on the server.
*/
public static Query<Map<UUID, List<Session>>> fetchSessionsOfPlayer(UUID playerUUID) {
String sql = SELECT_SESSIONS_STATEMENT + " WHERE " + SessionsTable.TABLE_NAME + "." + SessionsTable.USER_UUID + "=?" +
" ORDER BY " + SessionsTable.SESSION_START + " DESC";
return new QueryStatement<Map<UUID, List<Session>>>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}
@Override
public Map<UUID, List<Session>> processResults(ResultSet set) throws SQLException {
List<Session> sessions = extractDataFromSessionSelectStatement(set);
return SessionsMutator.sortByServers(sessions);
}
};
}
private static List<Session> extractDataFromSessionSelectStatement(ResultSet set) throws SQLException {
// Server UUID - Player UUID - Session Start - Session
Map<UUID, Map<UUID, Map<Long, Session>>> tempSessionMap = new HashMap<>();
// Utilities
String[] gms = GMTimes.getGMKeyArray();
DateHolderRecentComparator dateColderRecentComparator = new DateHolderRecentComparator();
while (set.next()) {
UUID serverUUID = UUID.fromString(set.getString(SessionsTable.SERVER_UUID));
Map<UUID, Map<Long, Session>> serverSessions = tempSessionMap.getOrDefault(serverUUID, new HashMap<>());
UUID playerUUID = UUID.fromString(set.getString(SessionsTable.USER_UUID));
Map<Long, Session> playerSessions = serverSessions.getOrDefault(playerUUID, new HashMap<>());
long sessionStart = set.getLong(SessionsTable.SESSION_START);
// id, uuid, serverUUID, sessionStart, sessionEnd, mobKills, deaths, afkTime
Session session = playerSessions.getOrDefault(sessionStart, new Session(
set.getInt(SessionsTable.ID),
playerUUID,
serverUUID,
sessionStart,
set.getLong(SessionsTable.SESSION_END),
set.getInt(SessionsTable.MOB_KILLS),
set.getInt(SessionsTable.DEATHS),
set.getLong(SessionsTable.AFK_TIME)
));
WorldTimes worldTimes = session.getUnsafe(SessionKeys.WORLD_TIMES);
String worldName = set.getString(WorldTable.NAME);
if (!worldTimes.contains(worldName)) {
Map<String, Long> gmMap = new HashMap<>();
gmMap.put(gms[0], set.getLong(WorldTimesTable.SURVIVAL));
gmMap.put(gms[1], set.getLong(WorldTimesTable.CREATIVE));
gmMap.put(gms[2], set.getLong(WorldTimesTable.ADVENTURE));
gmMap.put(gms[3], set.getLong(WorldTimesTable.SPECTATOR));
GMTimes gmTimes = new GMTimes(gmMap);
worldTimes.setGMTimesForWorld(worldName, gmTimes);
}
String victimName = set.getString("victim_name");
if (victimName != null) {
UUID victim = UUID.fromString(set.getString(KillsTable.VICTIM_UUID));
long date = set.getLong(KillsTable.DATE);
String weapon = set.getString(KillsTable.WEAPON);
List<PlayerKill> playerKills = session.getPlayerKills();
playerKills.add(new PlayerKill(victim, weapon, date, victimName));
playerKills.sort(dateColderRecentComparator);
}
playerSessions.put(sessionStart, session);
serverSessions.put(playerUUID, playerSessions);
tempSessionMap.put(serverUUID, serverSessions);
}
return tempSessionMap.values().stream()
.map(Map::values) .map(Map::values)
.flatMap(Collection::stream) .flatMap(Collection::stream)
.map(Map::values)
.flatMap(Collection::stream) .flatMap(Collection::stream)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }

View File

@ -16,13 +16,11 @@
*/ */
package com.djrapitops.plan.db.sql.tables; package com.djrapitops.plan.db.sql.tables;
import com.djrapitops.plan.data.container.PlayerDeath;
import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.db.DBType; import com.djrapitops.plan.db.DBType;
import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.QueryStatement;
import com.djrapitops.plan.db.access.queries.objects.SessionQueries; import com.djrapitops.plan.db.access.queries.objects.SessionQueries;
import com.djrapitops.plan.db.patches.KillsOptimizationPatch; import com.djrapitops.plan.db.patches.KillsOptimizationPatch;
import com.djrapitops.plan.db.patches.KillsServerIDPatch; import com.djrapitops.plan.db.patches.KillsServerIDPatch;
@ -31,7 +29,6 @@ import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
import com.djrapitops.plan.db.sql.parsing.Sql; import com.djrapitops.plan.db.sql.parsing.Sql;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -108,82 +105,6 @@ public class KillsTable extends Table {
} }
} }
public void addKillsToSessions(UUID uuid, Map<Integer, Session> sessions) {
String usersUUIDColumn = UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID;
String usersNameColumn = UsersTable.TABLE_NAME + "." + UsersTable.USER_NAME + " as victim_name";
String sql = "SELECT " +
SESSION_ID + ", " +
DATE + ", " +
WEAPON + ", " +
VICTIM_UUID + ", " +
usersNameColumn +
" FROM " + TABLE_NAME +
" INNER JOIN " + UsersTable.TABLE_NAME + " on " + usersUUIDColumn + "=" + VICTIM_UUID +
" WHERE " + KILLER_UUID + "=?";
query(new QueryStatement<Object>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, uuid.toString());
}
@Override
public Object processResults(ResultSet set) throws SQLException {
while (set.next()) {
int sessionID = set.getInt(SESSION_ID);
Session session = sessions.get(sessionID);
if (session == null) {
continue;
}
UUID victim = UUID.fromString(set.getString(VICTIM_UUID));
String victimName = set.getString("victim_name");
long date = set.getLong(DATE);
String weapon = set.getString(WEAPON);
session.getPlayerKills().add(new PlayerKill(victim, weapon, date, victimName));
}
return null;
}
});
}
public void addDeathsToSessions(UUID uuid, Map<Integer, Session> sessions) {
String usersUUIDColumn = UsersTable.TABLE_NAME + "." + UsersTable.USER_UUID;
String usersNameColumn = UsersTable.TABLE_NAME + "." + UsersTable.USER_NAME + " as killer_name";
String sql = "SELECT " +
SESSION_ID + ", " +
DATE + ", " +
WEAPON + ", " +
KILLER_UUID + ", " +
usersNameColumn +
" FROM " + TABLE_NAME +
" INNER JOIN " + UsersTable.TABLE_NAME + " on " + usersUUIDColumn + "=" + KILLER_UUID +
" WHERE " + VICTIM_UUID + "=?";
query(new QueryStatement<Object>(sql, 50000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, uuid.toString());
}
@Override
public Object processResults(ResultSet set) throws SQLException {
while (set.next()) {
int sessionID = set.getInt(SESSION_ID);
Session session = sessions.get(sessionID);
if (session == null) {
continue;
}
UUID killer = UUID.fromString(set.getString(KILLER_UUID));
String name = set.getString("killer_name");
long date = set.getLong(DATE);
String weapon = set.getString(WEAPON);
session.getUnsafe(SessionKeys.PLAYER_DEATHS).add(new PlayerDeath(killer, name, weapon, date));
}
return null;
}
});
}
public void addKillsToSessions(Map<UUID, Map<UUID, List<Session>>> map) { public void addKillsToSessions(Map<UUID, Map<UUID, List<Session>>> map) {
Map<Integer, List<PlayerKill>> playerKillsBySessionID = db.query(SessionQueries.fetchAllPlayerKillDataBySessionID()); Map<Integer, List<PlayerKill>> playerKillsBySessionID = db.query(SessionQueries.fetchAllPlayerKillDataBySessionID());
for (UUID serverUUID : map.keySet()) { for (UUID serverUUID : map.keySet()) {

View File

@ -16,8 +16,6 @@
*/ */
package com.djrapitops.plan.db.sql.tables; package com.djrapitops.plan.db.sql.tables;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.data.store.keys.SessionKeys;
import com.djrapitops.plan.db.DBType; import com.djrapitops.plan.db.DBType;
import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.QueryAllStatement; import com.djrapitops.plan.db.access.QueryAllStatement;
@ -26,15 +24,14 @@ import com.djrapitops.plan.db.patches.SessionAFKTimePatch;
import com.djrapitops.plan.db.patches.SessionsOptimizationPatch; import com.djrapitops.plan.db.patches.SessionsOptimizationPatch;
import com.djrapitops.plan.db.patches.Version10Patch; import com.djrapitops.plan.db.patches.Version10Patch;
import com.djrapitops.plan.db.sql.parsing.CreateTableParser; import com.djrapitops.plan.db.sql.parsing.CreateTableParser;
import com.djrapitops.plan.db.sql.parsing.Select;
import com.djrapitops.plan.db.sql.parsing.Sql; import com.djrapitops.plan.db.sql.parsing.Sql;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.*; import java.util.HashMap;
import java.util.function.Function; import java.util.Map;
import java.util.stream.Collectors; import java.util.UUID;
/** /**
* Table that represents plan_sessions. * Table that represents plan_sessions.
@ -92,48 +89,6 @@ public class SessionsTable extends Table {
.toString(); .toString();
} }
/**
* Returns a Map containing Lists of sessions, key as ServerName.
* <p>
* Does not include Kills or WorldTimes.
* Use {@code getSessions} to get full Sessions.
*
* @param uuid UUID of the player
* @return Map with Sessions that don't contain Kills or WorldTimes.
*/
private Map<UUID, List<Session>> getSessionInformation(UUID uuid) {
String sql = Select.from(tableName, "*")
.where(USER_UUID + "=?")
.toString();
return query(new QueryStatement<Map<UUID, List<Session>>>(sql, 10000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, uuid.toString());
}
@Override
public Map<UUID, List<Session>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<Session>> sessionsByServer = new HashMap<>();
while (set.next()) {
int id = set.getInt(ID);
long start = set.getLong(SESSION_START);
long end = set.getLong(SESSION_END);
UUID serverUUID = UUID.fromString(set.getString(SERVER_UUID));
long timeAFK = set.getLong(AFK_TIME);
int deaths = set.getInt(DEATHS);
int mobKills = set.getInt(MOB_KILLS);
List<Session> sessions = sessionsByServer.getOrDefault(serverUUID, new ArrayList<>());
sessions.add(new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK));
sessionsByServer.put(serverUUID, sessions);
}
return sessionsByServer;
}
});
}
/** /**
* Used to get Playtime after Epoch ms on a server. * Used to get Playtime after Epoch ms on a server.
* *
@ -168,18 +123,6 @@ public class SessionsTable extends Table {
}); });
} }
public Map<UUID, List<Session>> getSessions(UUID uuid) {
Map<UUID, List<Session>> sessions = getSessionInformation(uuid);
Map<Integer, Session> allSessions = sessions.values().stream()
.flatMap(Collection::stream)
.collect(Collectors.toMap(s -> s.getUnsafe(SessionKeys.DB_ID), Function.identity()));
db.getKillsTable().addKillsToSessions(uuid, allSessions);
db.getKillsTable().addDeathsToSessions(uuid, allSessions);
db.getWorldTimesTable().addWorldTimesToSessions(uuid, allSessions);
return sessions;
}
/** /**
* Used to get Playtime after a date of a Server. * Used to get Playtime after a date of a Server.
* *
@ -245,47 +188,6 @@ public class SessionsTable extends Table {
}); });
} }
public Map<UUID, List<Session>> getSessionInfoOfServer(UUID serverUUID) {
String sql = "SELECT " +
tableName + "." + ID + ", " +
USER_UUID + ", " +
SESSION_START + ", " +
SESSION_END + ", " +
DEATHS + ", " +
MOB_KILLS + ", " +
AFK_TIME +
" FROM " + tableName +
" WHERE " + SERVER_UUID + "=?";
return query(new QueryStatement<Map<UUID, List<Session>>>(sql, 5000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Map<UUID, List<Session>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<Session>> sessionsByUser = new HashMap<>();
while (set.next()) {
int id = set.getInt(ID);
UUID uuid = UUID.fromString(set.getString(USER_UUID));
long start = set.getLong(SESSION_START);
long end = set.getLong(SESSION_END);
int deaths = set.getInt(DEATHS);
int mobKills = set.getInt(MOB_KILLS);
long timeAFK = set.getLong(AFK_TIME);
List<Session> sessions = sessionsByUser.getOrDefault(uuid, new ArrayList<>());
sessions.add(new Session(id, uuid, serverUUID, start, end, mobKills, deaths, timeAFK));
sessionsByUser.put(uuid, sessions);
}
return sessionsByUser;
}
});
}
public Map<UUID, Long> getLastSeenForAllPlayers() { public Map<UUID, Long> getLastSeenForAllPlayers() {
String sql = "SELECT" + String sql = "SELECT" +
" MAX(" + SESSION_END + ") as last_seen, " + " MAX(" + SESSION_END + ") as last_seen, " +

View File

@ -23,7 +23,6 @@ import com.djrapitops.plan.data.time.WorldTimes;
import com.djrapitops.plan.db.DBType; import com.djrapitops.plan.db.DBType;
import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.QueryAllStatement; import com.djrapitops.plan.db.access.QueryAllStatement;
import com.djrapitops.plan.db.access.QueryStatement;
import com.djrapitops.plan.db.patches.Version10Patch; import com.djrapitops.plan.db.patches.Version10Patch;
import com.djrapitops.plan.db.patches.WorldTimesOptimizationPatch; import com.djrapitops.plan.db.patches.WorldTimesOptimizationPatch;
import com.djrapitops.plan.db.patches.WorldTimesSeverIDPatch; import com.djrapitops.plan.db.patches.WorldTimesSeverIDPatch;
@ -125,54 +124,6 @@ public class WorldTimesTable extends Table {
} }
} }
public void addWorldTimesToSessions(UUID uuid, Map<Integer, Session> sessions) {
String worldIDColumn = WorldTable.TABLE_NAME + "." + WorldTable.ID;
String worldNameColumn = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as world_name";
String sql = "SELECT " +
SESSION_ID + ", " +
SURVIVAL + ", " +
CREATIVE + ", " +
ADVENTURE + ", " +
SPECTATOR + ", " +
worldNameColumn +
" FROM " + TABLE_NAME +
" INNER JOIN " + WorldTable.TABLE_NAME + " on " + worldIDColumn + "=" + WORLD_ID +
" WHERE " + USER_UUID + "=?";
query(new QueryStatement<Object>(sql, 2000) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, uuid.toString());
}
@Override
public Object processResults(ResultSet set) throws SQLException {
String[] gms = GMTimes.getGMKeyArray();
while (set.next()) {
int sessionID = set.getInt(SESSION_ID);
Session session = sessions.get(sessionID);
if (session == null) {
continue;
}
String worldName = set.getString("world_name");
Map<String, Long> gmMap = new HashMap<>();
gmMap.put(gms[0], set.getLong(SURVIVAL));
gmMap.put(gms[1], set.getLong(CREATIVE));
gmMap.put(gms[2], set.getLong(ADVENTURE));
gmMap.put(gms[3], set.getLong(SPECTATOR));
GMTimes gmTimes = new GMTimes(gmMap);
session.getUnsafe(SessionKeys.WORLD_TIMES).setGMTimesForWorld(worldName, gmTimes);
}
return null;
}
});
}
public Map<Integer, WorldTimes> getAllWorldTimesBySessionID() { public Map<Integer, WorldTimes> getAllWorldTimesBySessionID() {
String worldIDColumn = WorldTable.TABLE_NAME + "." + WorldTable.ID; String worldIDColumn = WorldTable.TABLE_NAME + "." + WorldTable.ID;
String worldNameColumn = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as world_name"; String worldNameColumn = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as world_name";

View File

@ -45,6 +45,7 @@ import com.djrapitops.plan.system.settings.config.Config;
import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.config.PlanConfig;
import com.djrapitops.plan.system.settings.paths.WebserverSettings; import com.djrapitops.plan.system.settings.paths.WebserverSettings;
import com.djrapitops.plan.utilities.SHA256Hash; import com.djrapitops.plan.utilities.SHA256Hash;
import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator;
import org.junit.*; import org.junit.*;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.junit.rules.Timeout; import org.junit.rules.Timeout;
@ -333,6 +334,7 @@ public abstract class CommonDBTest {
List<PlayerKill> kills = new ArrayList<>(); List<PlayerKill> kills = new ArrayList<>();
kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Iron Sword", 4321L)); kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Iron Sword", 4321L));
kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Gold Sword", 5321L)); kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Gold Sword", 5321L));
kills.sort(new DateHolderRecentComparator());
return kills; return kills;
} }
@ -381,7 +383,7 @@ public abstract class CommonDBTest {
commitTest(); commitTest();
Map<UUID, List<Session>> sessions = sessionsTable.getSessions(playerUUID); Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID));
List<Session> savedSessions = sessions.get(serverUUID); List<Session> savedSessions = sessions.get(serverUUID);
assertNotNull(savedSessions); assertNotNull(savedSessions);
@ -488,7 +490,7 @@ public abstract class CommonDBTest {
assertFalse(db.query(PlayerFetchQueries.isPlayerRegisteredOnServer(playerUUID, serverUUID))); assertFalse(db.query(PlayerFetchQueries.isPlayerRegisteredOnServer(playerUUID, serverUUID)));
assertTrue(db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).isEmpty()); assertTrue(db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).isEmpty());
assertTrue(db.query(GeoInfoQueries.fetchPlayerGeoInformation(playerUUID)).isEmpty()); assertTrue(db.query(GeoInfoQueries.fetchPlayerGeoInformation(playerUUID)).isEmpty());
assertTrue(sessionsTable.getSessions(playerUUID).isEmpty()); assertQueryIsEmpty(db, SessionQueries.fetchSessionsOfPlayer(playerUUID));
} }
@Test @Test
@ -587,15 +589,11 @@ public abstract class CommonDBTest {
session.setWorldTimes(createWorldTimes()); session.setWorldTimes(createWorldTimes());
session.setPlayerKills(createKills()); session.setPlayerKills(createKills());
SessionsTable sessionsTable = db.getSessionsTable();
execute(DataStoreQueries.storeSession(session)); execute(DataStoreQueries.storeSession(session));
commitTest(); commitTest();
Map<UUID, List<Session>> sessions = sessionsTable.getSessionInfoOfServer(serverUUID); Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID));
session.setPlayerKills(new ArrayList<>());
session.setWorldTimes(new WorldTimes(new HashMap<>()));
List<Session> sSessions = sessions.get(playerUUID); List<Session> sSessions = sessions.get(playerUUID);
assertFalse(sessions.isEmpty()); assertFalse(sessions.isEmpty());
@ -616,7 +614,7 @@ public abstract class CommonDBTest {
commitTest(); commitTest();
Map<UUID, List<Session>> sessions = db.getSessionsTable().getSessions(playerUUID); Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID));
List<Session> savedSessions = sessions.get(serverUUID); List<Session> savedSessions = sessions.get(serverUUID);
assertNotNull(savedSessions); assertNotNull(savedSessions);
assertFalse(savedSessions.isEmpty()); assertFalse(savedSessions.isEmpty());
@ -669,20 +667,21 @@ public abstract class CommonDBTest {
} }
@Test @Test
public void testSaveWorldTimes() { public void sessionWorldTimesAreFetchedCorrectly() {
saveUserOne(); saveUserOne();
WorldTimes worldTimes = createWorldTimes(); WorldTimes worldTimes = createWorldTimes();
WorldTimesTable worldTimesTable = db.getWorldTimesTable();
Session session = new Session(1, playerUUID, serverUUID, 12345L, 23456L, 0, 0, 0); Session session = new Session(1, playerUUID, serverUUID, 12345L, 23456L, 0, 0, 0);
session.setWorldTimes(worldTimes); session.setWorldTimes(worldTimes);
execute(DataStoreQueries.storeSession(session)); execute(DataStoreQueries.storeSession(session));
Map<Integer, Session> sessions = new HashMap<>(); // Fetch the session
sessions.put(1, session); Map<UUID, List<Session>> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID));
worldTimesTable.addWorldTimesToSessions(playerUUID, sessions); List<Session> serverSessions = sessions.get(serverUUID);
assertNotNull(serverSessions);
assertFalse(serverSessions.isEmpty());
assertEquals(worldTimes, session.getUnsafe(SessionKeys.WORLD_TIMES)); Session savedSession = serverSessions.get(0);
assertEquals(worldTimes, savedSession.getUnsafe(SessionKeys.WORLD_TIMES));
} }
@Test @Test