mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-11 01:41:55 +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);
|
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;
|
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.Plan;
|
||||||
import main.java.com.djrapitops.plan.api.exceptions.DBCreateTableException;
|
import main.java.com.djrapitops.plan.api.exceptions.DBCreateTableException;
|
||||||
import main.java.com.djrapitops.plan.data.Session;
|
import main.java.com.djrapitops.plan.data.Session;
|
||||||
@ -28,6 +29,7 @@ public class SessionsTable extends UserIDTable {
|
|||||||
private final String columnDeaths = "deaths";
|
private final String columnDeaths = "deaths";
|
||||||
|
|
||||||
private final ServerTable serverTable;
|
private final ServerTable serverTable;
|
||||||
|
private String insertStatement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param db
|
* @param db
|
||||||
@ -36,6 +38,17 @@ public class SessionsTable extends UserIDTable {
|
|||||||
public SessionsTable(SQLDB db, boolean usingMySQL) {
|
public SessionsTable(SQLDB db, boolean usingMySQL) {
|
||||||
super("plan_sessions", db, usingMySQL);
|
super("plan_sessions", db, usingMySQL);
|
||||||
serverTable = db.getServerTable();
|
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 {
|
private void saveSessionInformation(UUID uuid, Session session) throws SQLException {
|
||||||
PreparedStatement statement = null;
|
PreparedStatement statement = null;
|
||||||
try {
|
try {
|
||||||
statement = prepareStatement("INSERT INTO " + tableName + " ("
|
statement = prepareStatement(insertStatement);
|
||||||
+ columnUserID + ", "
|
|
||||||
+ columnSessionStart + ", "
|
|
||||||
+ columnSessionEnd + ", "
|
|
||||||
+ columnDeaths + ", "
|
|
||||||
+ columnMobKills + ", "
|
|
||||||
+ columnServerID
|
|
||||||
+ ") VALUES ("
|
|
||||||
+ usersTable.statementSelectID + ", "
|
|
||||||
+ "?, ?, ?, ?, "
|
|
||||||
+ serverTable.statementSelectServerID + ")");
|
|
||||||
statement.setString(1, uuid.toString());
|
statement.setString(1, uuid.toString());
|
||||||
|
|
||||||
statement.setLong(2, session.getSessionStart());
|
statement.setLong(2, session.getSessionStart());
|
||||||
@ -543,4 +546,145 @@ public class SessionsTable extends UserIDTable {
|
|||||||
close(set, statement);
|
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.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table class representing database table plan_world_times.
|
* Table class representing database table plan_world_times.
|
||||||
@ -35,6 +33,7 @@ public class WorldTimesTable extends UserIDTable {
|
|||||||
|
|
||||||
private final WorldTable worldTable;
|
private final WorldTable worldTable;
|
||||||
private final SessionsTable sessionsTable;
|
private final SessionsTable sessionsTable;
|
||||||
|
private String insertStatement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -46,6 +45,18 @@ public class WorldTimesTable extends UserIDTable {
|
|||||||
super("plan_world_times", db, usingMySQL);
|
super("plan_world_times", db, usingMySQL);
|
||||||
worldTable = db.getWorldTable();
|
worldTable = db.getWorldTable();
|
||||||
sessionsTable = db.getSessionsTable();
|
sessionsTable = db.getSessionsTable();
|
||||||
|
insertStatement = "INSERT INTO " + tableName + " (" +
|
||||||
|
columnUserID + ", " +
|
||||||
|
columnWorldId + ", " +
|
||||||
|
columnSessionID + ", " +
|
||||||
|
columnSurvival + ", " +
|
||||||
|
columnCreative + ", " +
|
||||||
|
columnAdventure + ", " +
|
||||||
|
columnSpectator +
|
||||||
|
") VALUES (" +
|
||||||
|
usersTable.statementSelectID + ", " +
|
||||||
|
worldTable.statementSelectID + ", " +
|
||||||
|
"?, ?, ?, ?, ?)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,18 +87,7 @@ public class WorldTimesTable extends UserIDTable {
|
|||||||
|
|
||||||
PreparedStatement statement = null;
|
PreparedStatement statement = null;
|
||||||
try {
|
try {
|
||||||
statement = prepareStatement("INSERT INTO " + tableName + " (" +
|
statement = prepareStatement(insertStatement);
|
||||||
columnUserID + ", " +
|
|
||||||
columnWorldId + ", " +
|
|
||||||
columnSessionID + ", " +
|
|
||||||
columnSurvival + ", " +
|
|
||||||
columnCreative + ", " +
|
|
||||||
columnAdventure + ", " +
|
|
||||||
columnSpectator +
|
|
||||||
") VALUES (" +
|
|
||||||
usersTable.statementSelectID + ", " +
|
|
||||||
worldTable.statementSelectID + ", " +
|
|
||||||
"?, ?, ?, ?, ?)");
|
|
||||||
|
|
||||||
for (Map.Entry<String, GMTimes> entry : worldTimesMap.entrySet()) {
|
for (Map.Entry<String, GMTimes> entry : worldTimesMap.entrySet()) {
|
||||||
String worldName = entry.getKey();
|
String worldName = entry.getKey();
|
||||||
@ -244,4 +244,113 @@ public class WorldTimesTable extends UserIDTable {
|
|||||||
close(set, statement);
|
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