diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java index da909cace..f85729cab 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/container/Session.java @@ -16,7 +16,7 @@ */ 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.objects.DateHolder; import com.djrapitops.plan.data.time.WorldTimes; @@ -29,7 +29,7 @@ import java.util.*; * @author Rsl1122 * @see SessionKeys for Key objects. */ -public class Session extends SupplierDataContainer implements DateHolder { +public class Session extends DynamicDataContainer implements DateHolder { private long sessionStart; private WorldTimes worldTimes; @@ -228,4 +228,17 @@ public class Session extends SupplierDataContainer implements DateHolder { private long getAfkTime() { 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 + + '}'; + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java index 2ed189e2e..9315770dd 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/keys/SessionKeys.java @@ -46,6 +46,7 @@ public class SessionKeys { public static final Key PLAYER_KILL_COUNT = CommonKeys.PLAYER_KILL_COUNT; public static final Key MOB_KILL_COUNT = CommonKeys.MOB_KILL_COUNT; public static final Key DEATH_COUNT = CommonKeys.DEATH_COUNT; + @Deprecated public static final Key> PLAYER_DEATHS = CommonKeys.PLAYER_DEATHS; @Deprecated diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java index 2014eb31f..d4a04c050 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java @@ -204,6 +204,28 @@ public class SessionsMutator { }; } + public static Map> sortByPlayers(List sessions) { + Map> sorted = new HashMap<>(); + for (Session session : sessions) { + UUID playerUUID = session.getUnsafe(SessionKeys.UUID); + List playerSessions = sorted.getOrDefault(playerUUID, new ArrayList<>()); + playerSessions.add(session); + sorted.put(playerUUID, playerSessions); + } + return sorted; + } + + public static Map> sortByServers(List sessions) { + Map> sorted = new HashMap<>(); + for (Session session : sessions) { + UUID serverUUID = session.getUnsafe(SessionKeys.SERVER_UUID); + List serverSessions = sorted.getOrDefault(serverUUID, new ArrayList<>()); + serverSessions.add(session); + sorted.put(serverUUID, serverSessions); + } + return sorted; + } + public int toPlayerDeathCount() { return toPlayerDeathList().size(); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java b/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java index 0424be87e..81f7d2087 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/data/time/WorldTimes.java @@ -182,4 +182,7 @@ public class WorldTimes { } } + public boolean contains(String worldName) { + return times.containsKey(worldName); + } } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java index b73cfb83d..3ac493e16 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/PerServerContainerQuery.java @@ -27,6 +27,7 @@ import com.djrapitops.plan.data.store.mutators.SessionsMutator; import com.djrapitops.plan.db.SQLDB; import com.djrapitops.plan.db.access.Query; 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.WorldTimesQueries; @@ -66,7 +67,7 @@ public class PerServerContainerQuery implements Query { ); } - Map> sessions = db.getSessionsTable().getSessions(playerUUID); + Map> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID)); for (Map.Entry> entry : sessions.entrySet()) { UUID serverUUID = entry.getKey(); List serverSessions = entry.getValue(); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java index 5cbc209ec..1a27d83bc 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/containers/ServerPlayerContainersQuery.java @@ -50,36 +50,6 @@ public class ServerPlayerContainersQuery implements Query> 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 getPerServerData( - Map userInformation, - Map> sessions, - Map> ping - ) { - Map perServerContainers = new HashMap<>(); - - for (Map.Entry 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 public List executeQuery(SQLDB db) { List containers = new ArrayList<>(); @@ -89,14 +59,7 @@ public class ServerPlayerContainersQuery implements Query> Map> geoInformation = db.query(GeoInfoQueries.fetchServerGeoInformation(serverUUID)); Map> nicknames = db.query(NicknameQueries.fetchNicknameDataOfServer(serverUUID)); Map> pingData = db.query(PingQueries.fetchPingDataOfServer(serverUUID)); - - // v ------------- Needs work - Map> sessions = db.getSessionsTable().getSessionInfoOfServer(serverUUID); - Map>> map = new HashMap<>(); - map.put(serverUUID, sessions); - db.getKillsTable().addKillsToSessions(map); // TODO Optimize - db.getWorldTimesTable().addWorldTimesToSessions(map); // TODO Optimize - // ^ ------------- Needs work + Map> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID)); Map userInformation = db.query(UserInfoQueries.fetchUserInformationOfServer(serverUUID)); @@ -128,7 +91,6 @@ public class ServerPlayerContainersQuery implements Query> // PerServerContainer container.putRawData(PlayerKeys.PER_SERVER, perServerInfo.get(uuid)); - // v ------------- Needs work container.putCachingSupplier(PlayerKeys.SESSIONS, () -> { List playerSessions = sessions.getOrDefault(uuid, new ArrayList<>()); container.getValue(PlayerKeys.ACTIVE_SESSION).ifPresent(playerSessions::add); @@ -154,10 +116,39 @@ public class ServerPlayerContainersQuery implements Query> 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()); - // ^ ------------- Needs work 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 getPerServerData( + Map userInformation, + Map> sessions, + Map> ping + ) { + Map perServerContainers = new HashMap<>(); + + for (Map.Entry 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; + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java index fc0122f4b..1e3aa9e75 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java @@ -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.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.QueryAllStatement; -import com.djrapitops.plan.db.sql.tables.KillsTable; -import com.djrapitops.plan.db.sql.tables.SessionsTable; -import com.djrapitops.plan.db.sql.tables.UsersTable; +import com.djrapitops.plan.db.access.QueryStatement; +import com.djrapitops.plan.db.sql.tables.*; +import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; +import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.*; @@ -40,6 +45,30 @@ public class SessionQueries { /* 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. * @@ -146,10 +175,121 @@ public class SessionQueries { * @return List of sessions */ public static Query> fetchAllSessionsFlatWithKillAndWorldData() { - return db -> db.query(fetchAllSessionsWithKillAndWorldData()) - .values().stream() + String sql = SELECT_SESSIONS_STATEMENT + " ORDER BY " + SessionsTable.SESSION_START + " DESC"; + return new QueryAllStatement>(sql, 50000) { + @Override + public List 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>> fetchSessionsOfServer(UUID serverUUID) { + String sql = SELECT_SESSIONS_STATEMENT + " WHERE " + SessionsTable.TABLE_NAME + "." + SessionsTable.SERVER_UUID + "=?" + + " ORDER BY " + SessionsTable.SESSION_START + " DESC"; + return new QueryStatement>>(sql, 50000) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setString(1, serverUUID.toString()); + } + + @Override + public Map> processResults(ResultSet set) throws SQLException { + List 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>> fetchSessionsOfPlayer(UUID playerUUID) { + String sql = SELECT_SESSIONS_STATEMENT + " WHERE " + SessionsTable.TABLE_NAME + "." + SessionsTable.USER_UUID + "=?" + + " ORDER BY " + SessionsTable.SESSION_START + " DESC"; + return new QueryStatement>>(sql, 50000) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setString(1, playerUUID.toString()); + } + + @Override + public Map> processResults(ResultSet set) throws SQLException { + List sessions = extractDataFromSessionSelectStatement(set); + return SessionsMutator.sortByServers(sessions); + } + }; + } + + private static List extractDataFromSessionSelectStatement(ResultSet set) throws SQLException { + // Server UUID - Player UUID - Session Start - Session + Map>> 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> serverSessions = tempSessionMap.getOrDefault(serverUUID, new HashMap<>()); + + UUID playerUUID = UUID.fromString(set.getString(SessionsTable.USER_UUID)); + Map 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 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 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) .flatMap(Collection::stream) + .map(Map::values) .flatMap(Collection::stream) .collect(Collectors.toList()); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java index 1e57ac997..4e2b39519 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/KillsTable.java @@ -16,13 +16,11 @@ */ 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.Session; import com.djrapitops.plan.data.store.keys.SessionKeys; import com.djrapitops.plan.db.DBType; 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.patches.KillsOptimizationPatch; 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 java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; @@ -108,82 +105,6 @@ public class KillsTable extends Table { } } - public void addKillsToSessions(UUID uuid, Map 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(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 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(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>> map) { Map> playerKillsBySessionID = db.query(SessionQueries.fetchAllPlayerKillDataBySessionID()); for (UUID serverUUID : map.keySet()) { diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java index 17f7760fc..912ad77ae 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/SessionsTable.java @@ -16,8 +16,6 @@ */ 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.SQLDB; 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.Version10Patch; 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 java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; -import java.util.function.Function; -import java.util.stream.Collectors; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** * Table that represents plan_sessions. @@ -92,48 +89,6 @@ public class SessionsTable extends Table { .toString(); } - /** - * Returns a Map containing Lists of sessions, key as ServerName. - *

- * 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> getSessionInformation(UUID uuid) { - String sql = Select.from(tableName, "*") - .where(USER_UUID + "=?") - .toString(); - - return query(new QueryStatement>>(sql, 10000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, uuid.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> 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 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. * @@ -168,18 +123,6 @@ public class SessionsTable extends Table { }); } - public Map> getSessions(UUID uuid) { - Map> sessions = getSessionInformation(uuid); - Map 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. * @@ -245,47 +188,6 @@ public class SessionsTable extends Table { }); } - public Map> 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>>(sql, 5000) { - @Override - public void prepare(PreparedStatement statement) throws SQLException { - statement.setString(1, serverUUID.toString()); - } - - @Override - public Map> processResults(ResultSet set) throws SQLException { - Map> 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 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 getLastSeenForAllPlayers() { String sql = "SELECT" + " MAX(" + SESSION_END + ") as last_seen, " + diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java index f0b9e3212..6f4f0abe0 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/sql/tables/WorldTimesTable.java @@ -23,7 +23,6 @@ import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.db.DBType; import com.djrapitops.plan.db.SQLDB; 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.WorldTimesOptimizationPatch; import com.djrapitops.plan.db.patches.WorldTimesSeverIDPatch; @@ -125,54 +124,6 @@ public class WorldTimesTable extends Table { } } - public void addWorldTimesToSessions(UUID uuid, Map 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(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 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 getAllWorldTimesBySessionID() { String worldIDColumn = WorldTable.TABLE_NAME + "." + WorldTable.ID; String worldNameColumn = WorldTable.TABLE_NAME + "." + WorldTable.NAME + " as world_name"; diff --git a/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java b/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java index c8862a664..762189d2d 100644 --- a/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java +++ b/Plan/common/src/test/java/com/djrapitops/plan/db/CommonDBTest.java @@ -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.paths.WebserverSettings; import com.djrapitops.plan.utilities.SHA256Hash; +import com.djrapitops.plan.utilities.comparators.DateHolderRecentComparator; import org.junit.*; import org.junit.rules.TemporaryFolder; import org.junit.rules.Timeout; @@ -333,6 +334,7 @@ public abstract class CommonDBTest { List kills = new ArrayList<>(); kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Iron Sword", 4321L)); kills.add(new PlayerKill(TestConstants.PLAYER_TWO_UUID, "Gold Sword", 5321L)); + kills.sort(new DateHolderRecentComparator()); return kills; } @@ -381,7 +383,7 @@ public abstract class CommonDBTest { commitTest(); - Map> sessions = sessionsTable.getSessions(playerUUID); + Map> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID)); List savedSessions = sessions.get(serverUUID); assertNotNull(savedSessions); @@ -488,7 +490,7 @@ public abstract class CommonDBTest { assertFalse(db.query(PlayerFetchQueries.isPlayerRegisteredOnServer(playerUUID, serverUUID))); assertTrue(db.query(NicknameQueries.fetchNicknameDataOfPlayer(playerUUID)).isEmpty()); assertTrue(db.query(GeoInfoQueries.fetchPlayerGeoInformation(playerUUID)).isEmpty()); - assertTrue(sessionsTable.getSessions(playerUUID).isEmpty()); + assertQueryIsEmpty(db, SessionQueries.fetchSessionsOfPlayer(playerUUID)); } @Test @@ -587,15 +589,11 @@ public abstract class CommonDBTest { session.setWorldTimes(createWorldTimes()); session.setPlayerKills(createKills()); - SessionsTable sessionsTable = db.getSessionsTable(); execute(DataStoreQueries.storeSession(session)); commitTest(); - Map> sessions = sessionsTable.getSessionInfoOfServer(serverUUID); - - session.setPlayerKills(new ArrayList<>()); - session.setWorldTimes(new WorldTimes(new HashMap<>())); + Map> sessions = db.query(SessionQueries.fetchSessionsOfServer(serverUUID)); List sSessions = sessions.get(playerUUID); assertFalse(sessions.isEmpty()); @@ -616,7 +614,7 @@ public abstract class CommonDBTest { commitTest(); - Map> sessions = db.getSessionsTable().getSessions(playerUUID); + Map> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID)); List savedSessions = sessions.get(serverUUID); assertNotNull(savedSessions); assertFalse(savedSessions.isEmpty()); @@ -669,20 +667,21 @@ public abstract class CommonDBTest { } @Test - public void testSaveWorldTimes() { + public void sessionWorldTimesAreFetchedCorrectly() { saveUserOne(); WorldTimes worldTimes = createWorldTimes(); - WorldTimesTable worldTimesTable = db.getWorldTimesTable(); - Session session = new Session(1, playerUUID, serverUUID, 12345L, 23456L, 0, 0, 0); session.setWorldTimes(worldTimes); execute(DataStoreQueries.storeSession(session)); - Map sessions = new HashMap<>(); - sessions.put(1, session); - worldTimesTable.addWorldTimesToSessions(playerUUID, sessions); + // Fetch the session + Map> sessions = db.query(SessionQueries.fetchSessionsOfPlayer(playerUUID)); + List 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