mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-05 15:02:26 +01:00
Batch Operations for Session and WorldTimesTables
This commit is contained in:
parent
92ae2995da
commit
604bf7e29c
@ -182,4 +182,12 @@ public class KillsTable extends UserIDTable {
|
||||
close(set, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public void addKillsToSessions(Map<UUID, Map<UUID, List<Session>>> map) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
public void savePlayerKills(Map<UUID, Map<UUID, List<Session>>> allSessions) {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package main.java.com.djrapitops.plan.database.tables;
|
||||
|
||||
import com.djrapitops.plugin.utilities.Verify;
|
||||
import main.java.com.djrapitops.plan.Plan;
|
||||
import main.java.com.djrapitops.plan.api.exceptions.DBCreateTableException;
|
||||
import main.java.com.djrapitops.plan.data.Session;
|
||||
@ -28,6 +29,7 @@ public class SessionsTable extends UserIDTable {
|
||||
private final String columnDeaths = "deaths";
|
||||
|
||||
private final ServerTable serverTable;
|
||||
private String insertStatement;
|
||||
|
||||
/**
|
||||
* @param db
|
||||
@ -36,6 +38,17 @@ public class SessionsTable extends UserIDTable {
|
||||
public SessionsTable(SQLDB db, boolean usingMySQL) {
|
||||
super("plan_sessions", db, usingMySQL);
|
||||
serverTable = db.getServerTable();
|
||||
insertStatement = "INSERT INTO " + tableName + " ("
|
||||
+ columnUserID + ", "
|
||||
+ columnSessionStart + ", "
|
||||
+ columnSessionEnd + ", "
|
||||
+ columnDeaths + ", "
|
||||
+ columnMobKills + ", "
|
||||
+ columnServerID
|
||||
+ ") VALUES ("
|
||||
+ usersTable.statementSelectID + ", "
|
||||
+ "?, ?, ?, ?, "
|
||||
+ serverTable.statementSelectServerID + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,17 +103,7 @@ public class SessionsTable extends UserIDTable {
|
||||
private void saveSessionInformation(UUID uuid, Session session) throws SQLException {
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
statement = prepareStatement("INSERT INTO " + tableName + " ("
|
||||
+ columnUserID + ", "
|
||||
+ columnSessionStart + ", "
|
||||
+ columnSessionEnd + ", "
|
||||
+ columnDeaths + ", "
|
||||
+ columnMobKills + ", "
|
||||
+ columnServerID
|
||||
+ ") VALUES ("
|
||||
+ usersTable.statementSelectID + ", "
|
||||
+ "?, ?, ?, ?, "
|
||||
+ serverTable.statementSelectServerID + ")");
|
||||
statement = prepareStatement(insertStatement);
|
||||
statement.setString(1, uuid.toString());
|
||||
|
||||
statement.setLong(2, session.getSessionStart());
|
||||
@ -543,4 +546,145 @@ public class SessionsTable extends UserIDTable {
|
||||
close(set, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<UUID, Map<UUID, List<Session>>> getAllSessions(boolean includeExtraData) throws SQLException {
|
||||
PreparedStatement statement = null;
|
||||
ResultSet set = null;
|
||||
try {
|
||||
String usersIDColumn = usersTable + "." + usersTable.getColumnID();
|
||||
String usersUUIDColumn = usersTable + "." + usersTable.getColumnUUID() + " as uuid";
|
||||
String serverIDColumn = serverTable + "." + serverTable.getColumnID();
|
||||
String serverUUIDColumn = serverTable + "." + serverTable.getColumnUUID() + " as s_uuid";
|
||||
|
||||
statement = prepareStatement("SELECT " +
|
||||
columnID + ", " +
|
||||
columnSessionStart + ", " +
|
||||
columnSessionEnd + ", " +
|
||||
columnDeaths + ", " +
|
||||
columnMobKills + ", " +
|
||||
usersUUIDColumn + ", " +
|
||||
serverUUIDColumn +
|
||||
" FROM " + tableName +
|
||||
" JOIN " + usersTable + " on " + usersIDColumn + "=" + columnUserID +
|
||||
" JOIN " + serverTable + " on " + serverIDColumn + "=" + columnServerID
|
||||
);
|
||||
statement.setFetchSize(20000);
|
||||
set = statement.executeQuery();
|
||||
|
||||
Map<UUID, Map<UUID, List<Session>>> map = new HashMap<>();
|
||||
while (set.next()) {
|
||||
UUID serverUUID = UUID.fromString(set.getString("s_uuid"));
|
||||
UUID uuid = UUID.fromString(set.getString("uuid"));
|
||||
|
||||
Map<UUID, List<Session>> sessionsByUser = map.getOrDefault(serverUUID, new HashMap<>());
|
||||
List<Session> sessions = sessionsByUser.getOrDefault(uuid, new ArrayList<>());
|
||||
|
||||
long start = set.getLong(columnSessionStart);
|
||||
long end = set.getLong(columnSessionEnd);
|
||||
|
||||
int deaths = set.getInt(columnDeaths);
|
||||
int mobKills = set.getInt(columnMobKills);
|
||||
int id = set.getInt(columnID);
|
||||
|
||||
Session session = new Session(id, start, end, mobKills, deaths);
|
||||
sessions.add(session);
|
||||
|
||||
sessionsByUser.put(uuid, sessions);
|
||||
map.put(serverUUID, sessionsByUser);
|
||||
}
|
||||
if (includeExtraData) {
|
||||
db.getKillsTable().addKillsToSessions(map);
|
||||
db.getWorldTimesTable().addWorldTimesToSessions(map);
|
||||
}
|
||||
return map;
|
||||
} finally {
|
||||
endTransaction(statement);
|
||||
close(set, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public void insertSessions(Map<UUID, Map<UUID, List<Session>>> allSessions, boolean containsExtraData) throws SQLException {
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return;
|
||||
}
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
statement = prepareStatement(insertStatement);
|
||||
for (UUID serverUUID : allSessions.keySet()) {
|
||||
for (Map.Entry<UUID, List<Session>> entry : allSessions.get(serverUUID).entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
List<Session> sessions = entry.getValue();
|
||||
|
||||
for (Session session : sessions) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setLong(2, session.getSessionStart());
|
||||
statement.setLong(3, session.getSessionEnd());
|
||||
statement.setInt(4, session.getDeaths());
|
||||
statement.setInt(5, session.getMobKills());
|
||||
statement.setString(6, serverUUID.toString());
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
statement.executeBatch();
|
||||
commit(statement.getConnection());
|
||||
} finally {
|
||||
close(statement);
|
||||
}
|
||||
if (containsExtraData) {
|
||||
Map<UUID, Map<UUID, List<Session>>> savedSessions = getAllSessions(false);
|
||||
matchSessionIDs(allSessions, savedSessions);
|
||||
db.getKillsTable().savePlayerKills(allSessions);
|
||||
db.getWorldTimesTable().saveWorldTimes(allSessions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sessions should be saved before calling this method.
|
||||
*
|
||||
* @param allSessions Sessions to match IDs to (contain extra data)
|
||||
* @param allSavedSessions Sessions in the Database.
|
||||
*/
|
||||
private void matchSessionIDs(Map<UUID, Map<UUID, List<Session>>> allSessions, Map<UUID, Map<UUID, List<Session>>> allSavedSessions) {
|
||||
for (UUID serverUUID : allSessions.keySet()) {
|
||||
Map<UUID, List<Session>> serverSessions = allSessions.get(serverUUID);
|
||||
Map<UUID, List<Session>> savedServerSessions = allSavedSessions.get(serverUUID);
|
||||
|
||||
for (Map.Entry<UUID, List<Session>> entry : serverSessions.entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
List<Session> sessions = entry.getValue();
|
||||
|
||||
List<Session> savedSessions = savedServerSessions.get(uuid);
|
||||
if (savedSessions == null) {
|
||||
throw new IllegalStateException("Some of the sessions being matched were not saved.");
|
||||
}
|
||||
|
||||
matchSessions(sessions, savedSessions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used by matchSessionIDs method.
|
||||
* <p>
|
||||
* Matches IDs of Sessions with by sessionStart.
|
||||
* Assumes that both lists are from the same user and server.
|
||||
*
|
||||
* @param sessions Sessions of Player in a Server.
|
||||
* @param savedSessions Sessions of Player in a Server in the db.
|
||||
*/
|
||||
private void matchSessions(List<Session> sessions, List<Session> savedSessions) {
|
||||
Map<Long, Session> sessionsByStart = sessions.stream().collect(Collectors.toMap(Session::getSessionStart, Function.identity()));
|
||||
Map<Long, Session> savedSessionsByStart = savedSessions.stream().collect(Collectors.toMap(Session::getSessionStart, Function.identity()));
|
||||
for (Map.Entry<Long, Session> sessionEntry : sessionsByStart.entrySet()) {
|
||||
long start = sessionEntry.getKey();
|
||||
Session savedSession = savedSessionsByStart.get(start);
|
||||
if (savedSession == null) {
|
||||
throw new IllegalStateException("Some of the sessions being matched were not saved.");
|
||||
}
|
||||
Session session = sessionEntry.getValue();
|
||||
session.setSessionID(savedSession.getSessionID());
|
||||
}
|
||||
}
|
||||
}
|
@ -13,10 +13,8 @@ import main.java.com.djrapitops.plan.database.sql.TableSqlParser;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Table class representing database table plan_world_times.
|
||||
@ -35,6 +33,7 @@ public class WorldTimesTable extends UserIDTable {
|
||||
|
||||
private final WorldTable worldTable;
|
||||
private final SessionsTable sessionsTable;
|
||||
private String insertStatement;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -46,6 +45,18 @@ public class WorldTimesTable extends UserIDTable {
|
||||
super("plan_world_times", db, usingMySQL);
|
||||
worldTable = db.getWorldTable();
|
||||
sessionsTable = db.getSessionsTable();
|
||||
insertStatement = "INSERT INTO " + tableName + " (" +
|
||||
columnUserID + ", " +
|
||||
columnWorldId + ", " +
|
||||
columnSessionID + ", " +
|
||||
columnSurvival + ", " +
|
||||
columnCreative + ", " +
|
||||
columnAdventure + ", " +
|
||||
columnSpectator +
|
||||
") VALUES (" +
|
||||
usersTable.statementSelectID + ", " +
|
||||
worldTable.statementSelectID + ", " +
|
||||
"?, ?, ?, ?, ?)";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -76,18 +87,7 @@ public class WorldTimesTable extends UserIDTable {
|
||||
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
statement = prepareStatement("INSERT INTO " + tableName + " (" +
|
||||
columnUserID + ", " +
|
||||
columnWorldId + ", " +
|
||||
columnSessionID + ", " +
|
||||
columnSurvival + ", " +
|
||||
columnCreative + ", " +
|
||||
columnAdventure + ", " +
|
||||
columnSpectator +
|
||||
") VALUES (" +
|
||||
usersTable.statementSelectID + ", " +
|
||||
worldTable.statementSelectID + ", " +
|
||||
"?, ?, ?, ?, ?)");
|
||||
statement = prepareStatement(insertStatement);
|
||||
|
||||
for (Map.Entry<String, GMTimes> entry : worldTimesMap.entrySet()) {
|
||||
String worldName = entry.getKey();
|
||||
@ -244,4 +244,113 @@ public class WorldTimesTable extends UserIDTable {
|
||||
close(set, statement);
|
||||
}
|
||||
}
|
||||
|
||||
public void addWorldTimesToSessions(Map<UUID, Map<UUID, List<Session>>> map) throws SQLException {
|
||||
Map<Integer, WorldTimes> worldTimesBySessionID = getAllWorldTimesBySessionID();
|
||||
|
||||
for (UUID serverUUID : map.keySet()) {
|
||||
for (List<Session> sessions : map.get(serverUUID).values()) {
|
||||
for (Session session : sessions) {
|
||||
WorldTimes worldTimes = worldTimesBySessionID.get(session.getSessionID());
|
||||
if (worldTimes != null) {
|
||||
session.setWorldTimes(worldTimes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void saveWorldTimes(Map<UUID, Map<UUID, List<Session>>> allSessions) throws SQLException {
|
||||
if (Verify.isEmpty(allSessions)) {
|
||||
return;
|
||||
}
|
||||
List<String> worldNames = allSessions.values().stream()
|
||||
.map(Map::values)
|
||||
.flatMap(Collection::stream)
|
||||
.flatMap(Collection::stream)
|
||||
.map(Session::getWorldTimes)
|
||||
.map(WorldTimes::getWorldTimes)
|
||||
.map(Map::keySet)
|
||||
.flatMap(Collection::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
db.getWorldTable().saveWorlds(worldNames);
|
||||
|
||||
PreparedStatement statement = null;
|
||||
try {
|
||||
statement = prepareStatement(insertStatement);
|
||||
String[] gms = GMTimes.getGMKeyArray();
|
||||
for (UUID serverUUID : allSessions.keySet()) {
|
||||
for (Map.Entry<UUID, List<Session>> entry : allSessions.get(serverUUID).entrySet()) {
|
||||
UUID uuid = entry.getKey();
|
||||
List<Session> sessions = entry.getValue();
|
||||
|
||||
for (Session session : sessions) {
|
||||
int sessionID = session.getSessionID();
|
||||
for (Map.Entry<String, GMTimes> worldTimesEntry : session.getWorldTimes().getWorldTimes().entrySet()) {
|
||||
String worldName = worldTimesEntry.getKey();
|
||||
GMTimes gmTimes = worldTimesEntry.getValue();
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, worldName);
|
||||
statement.setInt(3, sessionID);
|
||||
|
||||
statement.setLong(4, gmTimes.getTime(gms[0]));
|
||||
statement.setLong(5, gmTimes.getTime(gms[1]));
|
||||
statement.setLong(6, gmTimes.getTime(gms[2]));
|
||||
statement.setLong(7, gmTimes.getTime(gms[3]));
|
||||
statement.addBatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
statement.executeBatch();
|
||||
commit(statement.getConnection());
|
||||
} finally {
|
||||
close(statement);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, WorldTimes> getAllWorldTimesBySessionID() throws SQLException {
|
||||
PreparedStatement statement = null;
|
||||
ResultSet set = null;
|
||||
try {
|
||||
String worldIDColumn = worldTable + "." + worldTable.getColumnID();
|
||||
String worldNameColumn = worldTable + "." + worldTable.getColumnWorldName() + " as world_name";
|
||||
statement = prepareStatement("SELECT " +
|
||||
columnSessionID + ", " +
|
||||
columnSurvival + ", " +
|
||||
columnCreative + ", " +
|
||||
columnAdventure + ", " +
|
||||
columnSpectator + ", " +
|
||||
worldNameColumn +
|
||||
" FROM " + tableName +
|
||||
" JOIN " + worldTable + " on " + worldIDColumn + "=" + columnWorldId
|
||||
);
|
||||
statement.setFetchSize(10000);
|
||||
set = statement.executeQuery();
|
||||
String[] gms = GMTimes.getGMKeyArray();
|
||||
|
||||
Map<Integer, WorldTimes> worldTimes = new HashMap<>();
|
||||
while (set.next()) {
|
||||
int sessionID = set.getInt(columnSessionID);
|
||||
|
||||
String worldName = set.getString("world_name");
|
||||
|
||||
Map<String, Long> gmMap = new HashMap<>();
|
||||
gmMap.put(gms[0], set.getLong(columnSurvival));
|
||||
gmMap.put(gms[1], set.getLong(columnCreative));
|
||||
gmMap.put(gms[2], set.getLong(columnAdventure));
|
||||
gmMap.put(gms[3], set.getLong(columnSpectator));
|
||||
GMTimes gmTimes = new GMTimes(gmMap);
|
||||
|
||||
WorldTimes worldTOfSession = worldTimes.getOrDefault(sessionID, new WorldTimes(new HashMap<>()));
|
||||
worldTOfSession.setGMTimesForWorld(worldName, gmTimes);
|
||||
worldTimes.put(sessionID, worldTOfSession);
|
||||
}
|
||||
return worldTimes;
|
||||
} finally {
|
||||
endTransaction(statement);
|
||||
close(set, statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user