Added server_id to plan_worlds, plan_world_times, plan_kills

This commit is contained in:
Rsl1122 2018-04-07 11:19:39 +03:00
parent 6b73286c8f
commit b357fd4948
11 changed files with 437 additions and 79 deletions

View File

@ -133,7 +133,7 @@ public abstract class SQLDB extends Database {
if (newDatabase) { if (newDatabase) {
Log.info("New Database created."); Log.info("New Database created.");
versionTable.setVersion(15); versionTable.setVersion(16);
} }
int version = versionTable.getVersion(); int version = versionTable.getVersion();
@ -172,6 +172,11 @@ public abstract class SQLDB extends Database {
sessionsTable.alterTableV15(); sessionsTable.alterTableV15();
versionTable.setVersion(15); versionTable.setVersion(15);
} }
if (version < 16) {
killsTable.alterTableV16();
worldTimesTable.alterTableV16();
versionTable.setVersion(16);
}
} catch (SQLException e) { } catch (SQLException e) {
throw new DBInitException("Failed to set-up Database", e); throw new DBInitException("Failed to set-up Database", e);
} }

View File

@ -10,6 +10,7 @@ import com.djrapitops.plan.system.database.databases.sql.processing.QueryStateme
import com.djrapitops.plan.system.database.databases.sql.statements.Column; import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.utilities.Verify; import com.djrapitops.plugin.utilities.Verify;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -28,18 +29,23 @@ import java.util.*;
*/ */
public class KillsTable extends UserIDTable { public class KillsTable extends UserIDTable {
private final ServerTable serverTable;
public KillsTable(SQLDB db) { public KillsTable(SQLDB db) {
super("plan_kills", db); super("plan_kills", db);
sessionsTable = db.getSessionsTable(); sessionsTable = db.getSessionsTable();
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " (" insertStatement = "INSERT INTO " + tableName + " ("
+ Col.KILLER_ID + ", " + Col.KILLER_ID + ", "
+ Col.VICTIM_ID + ", " + Col.VICTIM_ID + ", "
+ Col.SERVER_ID + ", "
+ Col.SESSION_ID + ", " + Col.SESSION_ID + ", "
+ Col.DATE + ", " + Col.DATE + ", "
+ Col.WEAPON + Col.WEAPON
+ ") VALUES (" + ") VALUES ("
+ usersTable.statementSelectID + ", " + usersTable.statementSelectID + ", "
+ usersTable.statementSelectID + ", " + usersTable.statementSelectID + ", "
+ serverTable.statementSelectServerID + ", "
+ "?, ?, ?)"; + "?, ?, ?)";
} }
@ -51,12 +57,14 @@ public class KillsTable extends UserIDTable {
createTable(TableSqlParser.createTable(tableName) createTable(TableSqlParser.createTable(tableName)
.column(Col.KILLER_ID, Sql.INT).notNull() .column(Col.KILLER_ID, Sql.INT).notNull()
.column(Col.VICTIM_ID, Sql.INT).notNull() .column(Col.VICTIM_ID, Sql.INT).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.column(Col.WEAPON, Sql.varchar(30)).notNull() .column(Col.WEAPON, Sql.varchar(30)).notNull()
.column(Col.DATE, Sql.LONG).notNull() .column(Col.DATE, Sql.LONG).notNull()
.column(Col.SESSION_ID, Sql.INT).notNull() .column(Col.SESSION_ID, Sql.INT).notNull()
.foreignKey(Col.KILLER_ID, usersTable.getTableName(), UsersTable.Col.ID) .foreignKey(Col.KILLER_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.VICTIM_ID, usersTable.getTableName(), UsersTable.Col.ID) .foreignKey(Col.VICTIM_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID) .foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.toString() .toString()
); );
} }
@ -131,9 +139,10 @@ public class KillsTable extends UserIDTable {
statement.setString(1, uuid.toString()); statement.setString(1, uuid.toString());
statement.setString(2, victim.toString()); statement.setString(2, victim.toString());
statement.setInt(3, sessionID); statement.setString(3, ServerInfo.getServerUUID().toString());
statement.setLong(4, date); statement.setInt(4, sessionID);
statement.setString(5, weapon); statement.setLong(5, date);
statement.setString(6, weapon);
statement.addBatch(); statement.addBatch();
} }
} }
@ -243,9 +252,10 @@ public class KillsTable extends UserIDTable {
String weapon = kill.getWeapon(); String weapon = kill.getWeapon();
statement.setString(1, killer.toString()); statement.setString(1, killer.toString());
statement.setString(2, victim.toString()); statement.setString(2, victim.toString());
statement.setInt(3, sessionID); statement.setString(3, serverUUID.toString());
statement.setLong(4, date); statement.setInt(4, sessionID);
statement.setString(5, weapon); statement.setLong(5, date);
statement.setString(6, weapon);
statement.addBatch(); statement.addBatch();
} }
} }
@ -255,9 +265,33 @@ public class KillsTable extends UserIDTable {
}); });
} }
public void alterTableV16() throws SQLException {
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
Map<Integer, Integer> sessionIDServerIDRelation = sessionsTable.getIDServerIDRelation();
String sql = "UPDATE " + tableName + " SET " +
Col.SERVER_ID + "=?" +
" WHERE " + Col.SESSION_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<Integer, Integer> entry : sessionIDServerIDRelation.entrySet()) {
Integer sessionID = entry.getKey();
Integer serverID = entry.getValue();
statement.setInt(1, serverID);
statement.setInt(2, sessionID);
statement.addBatch();
}
}
});
}
public enum Col implements Column { public enum Col implements Column {
KILLER_ID("killer_id"), KILLER_ID("killer_id"),
VICTIM_ID("victim_id"), VICTIM_ID("victim_id"),
SERVER_ID("server_id"),
SESSION_ID("session_id"), SESSION_ID("session_id"),
WEAPON("weapon"), WEAPON("weapon"),
DATE("date"); DATE("date");

View File

@ -30,8 +30,10 @@ import java.util.*;
*/ */
public class ServerTable extends Table { public class ServerTable extends Table {
public static final String TABLE_NAME = "plan_servers";
public ServerTable(SQLDB db) { public ServerTable(SQLDB db) {
super("plan_servers", db); super(TABLE_NAME, db);
statementSelectServerID = "(" + Select.from(tableName, tableName + "." + Col.SERVER_ID).where(tableName + "." + Col.SERVER_UUID + "=?").toString() + " LIMIT 1)"; statementSelectServerID = "(" + Select.from(tableName, tableName + "." + Col.SERVER_ID).where(tableName + "." + Col.SERVER_UUID + "=?").toString() + " LIMIT 1)";
statementSelectServerNameID = "(" + Select.from(tableName, tableName + "." + Col.NAME).where(tableName + "." + Col.SERVER_ID + "=?").toString() + " LIMIT 1)"; statementSelectServerNameID = "(" + Select.from(tableName, tableName + "." + Col.NAME).where(tableName + "." + Col.SERVER_ID + "=?").toString() + " LIMIT 1)";
insertStatement = Insert.values(tableName, insertStatement = Insert.values(tableName,

View File

@ -737,6 +737,24 @@ public class SessionsTable extends UserIDTable {
addColumns(Col.AFK_TIME + " bigint NOT NULL DEFAULT 0"); addColumns(Col.AFK_TIME + " bigint NOT NULL DEFAULT 0");
} }
public Map<Integer, Integer> getIDServerIDRelation() throws SQLException {
String sql = "SELECT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, Integer>>(sql, 10000) {
@Override
public Map<Integer, Integer> processResults(ResultSet set) throws SQLException {
HashMap<Integer, Integer> idServerIdMap = new HashMap<>();
while (set.next()) {
idServerIdMap.put(set.getInt(Col.ID.get()), set.getInt(Col.SERVER_ID.get()));
}
return idServerIdMap;
}
});
}
public enum Col implements Column { public enum Col implements Column {
USER_ID(UserIDTable.Col.USER_ID.get()), USER_ID(UserIDTable.Col.USER_ID.get()),
ID("id"), ID("id"),

View File

@ -43,6 +43,13 @@ public abstract class Table {
} }
} }
protected void renameTable(String to) throws SQLException {
String sql = usingMySQL ?
"RENAME TABLE " + tableName + " TO " + to :
"ALTER TABLE " + tableName + " RENAME TO " + to;
execute(sql);
}
/** /**
* Used to get a new Connection to the Database. * Used to get a new Connection to the Database.
* *

View File

@ -10,11 +10,14 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.utilities.Verify; import com.djrapitops.plugin.utilities.Verify;
import com.google.common.base.Objects;
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.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* Table class representing database table plan_worlds. * Table class representing database table plan_worlds.
@ -26,19 +29,26 @@ import java.util.*;
*/ */
public class WorldTable extends Table { public class WorldTable extends Table {
public final String statementSelectID;
private final ServerTable serverTable;
public WorldTable(SQLDB db) { public WorldTable(SQLDB db) {
super("plan_worlds", db); super("plan_worlds", db);
statementSelectID = "(SELECT " + Col.ID + " FROM " + tableName + " WHERE (" + Col.NAME + "=?) LIMIT 1)"; serverTable = db.getServerTable();
statementSelectID = "(SELECT " + Col.ID + " FROM " + tableName +
" WHERE (" + Col.NAME + "=?)" +
" AND (" + Col.SERVER_ID + "=" + serverTable.statementSelectServerID + ")" +
" LIMIT 1)";
} }
public final String statementSelectID;
@Override @Override
public void createTable() throws DBInitException { public void createTable() throws DBInitException {
createTable(TableSqlParser.createTable(tableName) createTable(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, Col.ID) .primaryKeyIDColumn(usingMySQL, Col.ID)
.column(Col.NAME, Sql.varchar(100)).notNull() .column(Col.NAME, Sql.varchar(100)).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.primaryKey(usingMySQL, Col.ID) .primaryKey(usingMySQL, Col.ID)
.foreignKey(Col.SERVER_ID, ServerTable.TABLE_NAME, ServerTable.Col.SERVER_ID)
.toString() .toString()
); );
} }
@ -49,7 +59,7 @@ public class WorldTable extends Table {
* @return List of all world names in the database. * @return List of all world names in the database.
* @throws SQLException Database error occurs. * @throws SQLException Database error occurs.
*/ */
public List<String> getWorlds() throws SQLException { public List<String> getAllWorlds() throws SQLException {
String sql = "SELECT * FROM " + tableName; String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<List<String>>(sql) { return query(new QueryAllStatement<List<String>>(sql) {
@ -65,6 +75,78 @@ public class WorldTable extends Table {
}); });
} }
public Map<UUID, List<String>> getWorldsPerServer() throws SQLException {
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<Map<UUID, List<String>>>(sql, 1000) {
@Override
public Map<UUID, List<String>> processResults(ResultSet set) throws SQLException {
Map<UUID, List<String>> worldsPerServer = new HashMap<>();
while (set.next()) {
UUID serverUUID = serverUUIDsByID.get(set.getInt(Col.SERVER_ID.get()));
String worldName = set.getString(Col.NAME.get());
List<String> worlds = worldsPerServer.getOrDefault(serverUUID, new ArrayList<>());
worlds.add(worldName);
worldsPerServer.put(serverUUID, worlds);
}
return worldsPerServer;
}
});
}
public Map<Integer, UUID> getServerUUIDByWorldID() throws SQLException {
Map<Integer, UUID> serverUUIDsByID = serverTable.getServerUUIDsByID();
String sql = "SELECT DISTINCT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, UUID>>(sql, 100) {
@Override
public Map<Integer, UUID> processResults(ResultSet set) throws SQLException {
Map<Integer, UUID> idMap = new HashMap<>();
while (set.next()) {
int worldId = set.getInt(Col.ID.get());
int serverId = set.getInt(Col.SERVER_ID.get());
UUID serverUUID = serverUUIDsByID.getOrDefault(serverId, ServerInfo.getServerUUID());
idMap.put(worldId, serverUUID);
}
return idMap;
}
});
}
public List<String> getWorlds() throws SQLException {
return getWorlds(ServerInfo.getServerUUID());
}
public List<String> getWorlds(UUID serverUUID) throws SQLException {
String sql = "SELECT * FROM " + tableName +
" WHERE " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
return query(new QueryStatement<List<String>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public List<String> processResults(ResultSet set) throws SQLException {
List<String> worldNames = new ArrayList<>();
while (set.next()) {
String worldName = set.getString(Col.NAME.get());
worldNames.add(worldName);
}
return worldNames;
}
});
}
public void saveWorlds(Collection<String> worlds) throws SQLException {
saveWorlds(worlds, ServerInfo.getServerUUID());
}
/** /**
* Used to save a list of world names. * Used to save a list of world names.
* <p> * <p>
@ -73,25 +155,27 @@ public class WorldTable extends Table {
* @param worlds List of world names. * @param worlds List of world names.
* @throws SQLException Database error occurs. * @throws SQLException Database error occurs.
*/ */
public void saveWorlds(Collection<String> worlds) throws SQLException { public void saveWorlds(Collection<String> worlds, UUID serverUUID) throws SQLException {
Verify.nullCheck(worlds); Verify.nullCheck(worlds);
Set<String> worldsToSave = new HashSet<>(worlds); Set<String> worldsToSave = new HashSet<>(worlds);
List<String> saved = getWorlds(); List<String> saved = getWorlds(serverUUID);
worldsToSave.removeAll(saved); worldsToSave.removeAll(saved);
if (Verify.isEmpty(worlds)) { if (Verify.isEmpty(worlds)) {
return; return;
} }
String sql = "INSERT INTO " + tableName + " (" String sql = "INSERT INTO " + tableName + " ("
+ Col.NAME + Col.NAME + ", "
+ ") VALUES (?)"; + Col.SERVER_ID
+ ") VALUES (?, " + serverTable.statementSelectServerID + ")";
executeBatch(new ExecStatement(sql) { executeBatch(new ExecStatement(sql) {
@Override @Override
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
for (String world : worldsToSave) { for (String world : worldsToSave) {
statement.setString(1, world); statement.setString(1, world);
statement.setString(2, ServerInfo.getServerUUID().toString());
statement.addBatch(); statement.addBatch();
} }
} }
@ -99,9 +183,37 @@ public class WorldTable extends Table {
} }
public Set<String> getWorldNames(UUID serverUUID) throws SQLException { public Set<String> getWorldNames(UUID serverUUID) throws SQLException {
String sql = "SELECT DISTINCT " + Col.NAME + " FROM " + tableName +
" WHERE " + Col.SERVER_ID + "=" + serverTable.statementSelectServerID;
return query(new QueryStatement<Set<String>>(sql, 100) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, serverUUID.toString());
}
@Override
public Set<String> processResults(ResultSet set) throws SQLException {
Set<String> worldNames = new HashSet<>();
while (set.next()) {
worldNames.add(set.getString(Col.NAME.get()));
}
return worldNames;
}
});
}
/**
* Used to get world names for this server.
*
* @param serverUUID UUID of the Server
* @return World names known for that server
* @throws SQLException If DB Error occurs
* @deprecated Use getWorldNames instead, this method is slower.
*/
@Deprecated
public Set<String> getWorldNamesOld(UUID serverUUID) throws SQLException {
WorldTimesTable worldTimesTable = db.getWorldTimesTable(); WorldTimesTable worldTimesTable = db.getWorldTimesTable();
SessionsTable sessionsTable = db.getSessionsTable(); SessionsTable sessionsTable = db.getSessionsTable();
ServerTable serverTable = db.getServerTable();
String statementSelectServerID = serverTable.statementSelectServerID; String statementSelectServerID = serverTable.statementSelectServerID;
@ -134,32 +246,120 @@ public class WorldTable extends Table {
}); });
} }
public Set<String> getWorldNames() throws SQLException { private Map<Integer, Integer> getWorldIDServerIDRelation() throws SQLException {
return getWorldNames(ServerInfo.getServerUUID()); String sql = "SELECT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, Integer>>(sql, 100) {
@Override
public Map<Integer, Integer> processResults(ResultSet set) throws SQLException {
HashMap<Integer, Integer> idServerIdMap = new HashMap<>();
while (set.next()) {
idServerIdMap.put(set.getInt(Col.ID.get()), set.getInt(Col.SERVER_ID.get()));
}
return idServerIdMap;
}
});
} }
public Map<String, Integer> getWorldIds() throws SQLException { public void alterTableV16() throws SQLException {
String sql = "SELECT DISTINCT " + addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
Col.NAME + ", " +
Col.ID + " FROM " +
tableName;
return query(new QueryAllStatement<Map<String, Integer>>(sql, 200) { List<UUID> serverUUIDs = serverTable.getServerUUIDs();
Map<UUID, Set<String>> worldsPerServer = new HashMap<>();
for (UUID serverUUID : serverUUIDs) {
worldsPerServer.put(serverUUID, getWorldNamesOld(serverUUID));
}
for (Map.Entry<UUID, Set<String>> entry : worldsPerServer.entrySet()) {
UUID serverUUID = entry.getKey();
Set<String> worlds = entry.getValue();
saveWorlds(worlds, serverUUID);
}
updateWorldTimesTableWorldIDs();
execute("DELETE FROM " + tableName + " WHERE " + Col.SERVER_ID + "=0");
}
private void updateWorldTimesTableWorldIDs() throws SQLException {
List<WorldObj> worldObjects = getWorldObjects();
Map<WorldObj, List<WorldObj>> oldToNewMap =
worldObjects.stream()
.filter(worldObj -> worldObj.serverId == 0)
.collect(Collectors.toMap(
Function.identity(),
oldWorld -> worldObjects.stream()
.filter(worldObj -> worldObj.equals(oldWorld))
.collect(Collectors.toList()
)));
WorldTimesTable worldTimesTable = db.getWorldTimesTable();
String sql = "UPDATE " + worldTimesTable + " SET " +
WorldTimesTable.Col.WORLD_ID + "=?" +
" WHERE " + WorldTimesTable.Col.WORLD_ID + "=?" +
" AND " + WorldTimesTable.Col.SERVER_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override @Override
public Map<String, Integer> processResults(ResultSet set) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
Map<String, Integer> worldIds = new HashMap<>(); for (Map.Entry<WorldObj, List<WorldObj>> entry : oldToNewMap.entrySet()) {
while (set.next()) { WorldObj old = entry.getKey();
String worldName = set.getString(Col.NAME.get()); for (WorldObj newWorld : entry.getValue()) {
int worldId = set.getInt(Col.ID.get()); statement.setInt(1, newWorld.id);
worldIds.put(worldName, worldId); statement.setInt(2, old.id);
statement.setInt(3, newWorld.serverId);
statement.addBatch();
}
} }
return worldIds; }
});
}
public Map<Integer, List<Integer>> getWorldIDsByServerIDs() throws SQLException {
String sql = "SELECT " +
Col.ID + ", " +
Col.SERVER_ID +
" FROM " + tableName;
return query(new QueryAllStatement<Map<Integer, List<Integer>>>(sql, 100) {
@Override
public Map<Integer, List<Integer>> processResults(ResultSet set) throws SQLException {
HashMap<Integer, List<Integer>> map = new HashMap<>();
while (set.next()) {
int serverID = set.getInt(Col.SERVER_ID.get());
int worldID = set.getInt(Col.ID.get());
List<Integer> worldIDs = map.getOrDefault(serverID, new ArrayList<>());
worldIDs.add(worldID);
map.put(serverID, worldIDs);
}
return map;
}
});
}
public List<WorldObj> getWorldObjects() throws SQLException {
String sql = "SELECT * FROM " + tableName;
return query(new QueryAllStatement<List<WorldObj>>(sql, 100) {
@Override
public List<WorldObj> processResults(ResultSet set) throws SQLException {
List<WorldObj> objects = new ArrayList<>();
while (set.next()) {
int worldID = set.getInt(Col.ID.get());
int serverID = set.getInt(Col.SERVER_ID.get());
String worldName = set.getString(Col.NAME.get());
objects.add(new WorldObj(worldID, serverID, worldName));
}
return objects;
} }
}); });
} }
public enum Col implements Column { public enum Col implements Column {
ID("id"), ID("id"),
SERVER_ID("server_id"),
NAME("world_name"); NAME("world_name");
private final String column; private final String column;
@ -179,3 +379,28 @@ public class WorldTable extends Table {
} }
} }
} }
class WorldObj {
final int id;
final int serverId;
final String name;
public WorldObj(int id, int serverId, String name) {
this.id = id;
this.serverId = serverId;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
WorldObj worldObj = (WorldObj) o;
return Objects.equal(name, worldObj.name);
}
@Override
public int hashCode() {
return Objects.hashCode(name);
}
}

View File

@ -12,6 +12,10 @@ import com.djrapitops.plan.system.database.databases.sql.statements.Column;
import com.djrapitops.plan.system.database.databases.sql.statements.Sql; import com.djrapitops.plan.system.database.databases.sql.statements.Sql;
import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser; import com.djrapitops.plan.system.database.databases.sql.statements.TableSqlParser;
import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plugin.api.TimeAmount;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.task.AbsRunnable;
import com.djrapitops.plugin.task.RunnableFactory;
import com.djrapitops.plugin.utilities.Verify; import com.djrapitops.plugin.utilities.Verify;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
@ -31,13 +35,20 @@ import java.util.stream.Collectors;
*/ */
public class WorldTimesTable extends UserIDTable { public class WorldTimesTable extends UserIDTable {
private final ServerTable serverTable;
private final WorldTable worldTable;
private final SessionsTable sessionsTable;
private String insertStatement;
public WorldTimesTable(SQLDB db) { public WorldTimesTable(SQLDB db) {
super("plan_world_times", db); super("plan_world_times", db);
worldTable = db.getWorldTable(); worldTable = db.getWorldTable();
sessionsTable = db.getSessionsTable(); sessionsTable = db.getSessionsTable();
serverTable = db.getServerTable();
insertStatement = "INSERT INTO " + tableName + " (" + insertStatement = "INSERT INTO " + tableName + " (" +
Col.USER_ID + ", " + Col.USER_ID + ", " +
Col.WORLD_ID + ", " + Col.WORLD_ID + ", " +
Col.SERVER_ID + ", " +
Col.SESSION_ID + ", " + Col.SESSION_ID + ", " +
Col.SURVIVAL + ", " + Col.SURVIVAL + ", " +
Col.CREATIVE + ", " + Col.CREATIVE + ", " +
@ -46,18 +57,16 @@ public class WorldTimesTable extends UserIDTable {
") VALUES (" + ") VALUES (" +
usersTable.statementSelectID + ", " + usersTable.statementSelectID + ", " +
worldTable.statementSelectID + ", " + worldTable.statementSelectID + ", " +
serverTable.statementSelectServerID + ", " +
"?, ?, ?, ?, ?)"; "?, ?, ?, ?, ?)";
} }
private final WorldTable worldTable;
private final SessionsTable sessionsTable;
private String insertStatement;
@Override @Override
public void createTable() throws DBInitException { public void createTable() throws DBInitException {
createTable(TableSqlParser.createTable(tableName) createTable(TableSqlParser.createTable(tableName)
.column(Col.USER_ID, Sql.INT).notNull() .column(Col.USER_ID, Sql.INT).notNull()
.column(Col.WORLD_ID, Sql.INT).notNull() .column(Col.WORLD_ID, Sql.INT).notNull()
.column(Col.SERVER_ID, Sql.INT).notNull()
.column(Col.SESSION_ID, Sql.INT).notNull() .column(Col.SESSION_ID, Sql.INT).notNull()
.column(Col.SURVIVAL, Sql.LONG).notNull().defaultValue("0") .column(Col.SURVIVAL, Sql.LONG).notNull().defaultValue("0")
.column(Col.CREATIVE, Sql.LONG).notNull().defaultValue("0") .column(Col.CREATIVE, Sql.LONG).notNull().defaultValue("0")
@ -65,6 +74,7 @@ public class WorldTimesTable extends UserIDTable {
.column(Col.SPECTATOR, Sql.LONG).notNull().defaultValue("0") .column(Col.SPECTATOR, Sql.LONG).notNull().defaultValue("0")
.foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID) .foreignKey(Col.USER_ID, usersTable.getTableName(), UsersTable.Col.ID)
.foreignKey(Col.WORLD_ID, worldTable.getTableName(), WorldTable.Col.ID) .foreignKey(Col.WORLD_ID, worldTable.getTableName(), WorldTable.Col.ID)
.foreignKey(Col.SERVER_ID, serverTable.getTableName(), ServerTable.Col.SERVER_ID)
.foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID) .foreignKey(Col.SESSION_ID, sessionsTable.getTableName(), SessionsTable.Col.ID)
.toString() .toString()
); );
@ -135,13 +145,16 @@ public class WorldTimesTable extends UserIDTable {
GMTimes gmTimes = entry.getValue(); GMTimes gmTimes = entry.getValue();
statement.setString(1, uuid.toString()); statement.setString(1, uuid.toString());
statement.setString(2, worldName); statement.setString(2, worldName);
statement.setInt(3, sessionID); String serverUUID = ServerInfo.getServerUUID().toString();
statement.setString(3, serverUUID);
statement.setString(4, serverUUID);
statement.setInt(5, sessionID);
String[] gms = GMTimes.getGMKeyArray(); String[] gms = GMTimes.getGMKeyArray();
statement.setLong(4, gmTimes.getTime(gms[0])); statement.setLong(6, gmTimes.getTime(gms[0]));
statement.setLong(5, gmTimes.getTime(gms[1])); statement.setLong(7, gmTimes.getTime(gms[1]));
statement.setLong(6, gmTimes.getTime(gms[2])); statement.setLong(8, gmTimes.getTime(gms[2]));
statement.setLong(7, gmTimes.getTime(gms[3])); statement.setLong(9, gmTimes.getTime(gms[3]));
statement.addBatch(); statement.addBatch();
} }
} }
@ -151,8 +164,6 @@ public class WorldTimesTable extends UserIDTable {
public WorldTimes getWorldTimesOfServer(UUID serverUUID) throws SQLException { public WorldTimes getWorldTimesOfServer(UUID serverUUID) throws SQLException {
String worldIDColumn = worldTable + "." + WorldTable.Col.ID; String worldIDColumn = worldTable + "." + WorldTable.Col.ID;
String worldNameColumn = worldTable + "." + WorldTable.Col.NAME + " as world_name"; String worldNameColumn = worldTable + "." + WorldTable.Col.NAME + " as world_name";
String sessionIDColumn = sessionsTable + "." + SessionsTable.Col.ID;
String sessionServerIDColumn = sessionsTable + ".server_id";
String sql = "SELECT " + String sql = "SELECT " +
"SUM(" + Col.SURVIVAL + ") as survival, " + "SUM(" + Col.SURVIVAL + ") as survival, " +
"SUM(" + Col.CREATIVE + ") as creative, " + "SUM(" + Col.CREATIVE + ") as creative, " +
@ -161,8 +172,7 @@ public class WorldTimesTable extends UserIDTable {
worldNameColumn + worldNameColumn +
" FROM " + tableName + " FROM " + tableName +
" INNER JOIN " + worldTable + " on " + worldIDColumn + "=" + Col.WORLD_ID + " INNER JOIN " + worldTable + " on " + worldIDColumn + "=" + Col.WORLD_ID +
" INNER JOIN " + sessionsTable + " on " + sessionIDColumn + "=" + Col.SESSION_ID + " WHERE " + tableName + "." + Col.SERVER_ID + "=" + db.getServerTable().statementSelectServerID +
" WHERE " + sessionServerIDColumn + "=" + db.getServerTable().statementSelectServerID +
" GROUP BY " + Col.WORLD_ID; " GROUP BY " + Col.WORLD_ID;
return query(new QueryStatement<WorldTimes>(sql, 1000) { return query(new QueryStatement<WorldTimes>(sql, 1000) {
@ -315,9 +325,10 @@ public class WorldTimesTable extends UserIDTable {
public void prepare(PreparedStatement statement) throws SQLException { public void prepare(PreparedStatement statement) throws SQLException {
String[] gms = GMTimes.getGMKeyArray(); String[] gms = GMTimes.getGMKeyArray();
// Every Server // Every Server
for (Map<UUID, List<Session>> serverSessions : allSessions.values()) { for (Map.Entry<UUID, Map<UUID, List<Session>>> serverSessions : allSessions.entrySet()) {
UUID serverUUID = serverSessions.getKey();
// Every User // Every User
for (Map.Entry<UUID, List<Session>> entry : serverSessions.entrySet()) { for (Map.Entry<UUID, List<Session>> entry : serverSessions.getValue().entrySet()) {
UUID uuid = entry.getKey(); UUID uuid = entry.getKey();
List<Session> sessions = entry.getValue(); List<Session> sessions = entry.getValue();
// Every Session // Every Session
@ -329,11 +340,13 @@ public class WorldTimesTable extends UserIDTable {
GMTimes gmTimes = worldTimesEntry.getValue(); GMTimes gmTimes = worldTimesEntry.getValue();
statement.setString(1, uuid.toString()); statement.setString(1, uuid.toString());
statement.setString(2, worldName); statement.setString(2, worldName);
statement.setInt(3, sessionID); statement.setString(3, serverUUID.toString());
statement.setLong(4, gmTimes.getTime(gms[0])); statement.setString(4, serverUUID.toString());
statement.setLong(5, gmTimes.getTime(gms[1])); statement.setInt(5, sessionID);
statement.setLong(6, gmTimes.getTime(gms[2])); statement.setLong(6, gmTimes.getTime(gms[0]));
statement.setLong(7, gmTimes.getTime(gms[3])); statement.setLong(7, gmTimes.getTime(gms[1]));
statement.setLong(8, gmTimes.getTime(gms[2]));
statement.setLong(9, gmTimes.getTime(gms[3]));
statement.addBatch(); statement.addBatch();
} }
} }
@ -343,8 +356,45 @@ public class WorldTimesTable extends UserIDTable {
}); });
} }
public void alterTableV16() {
addColumns(Col.SERVER_ID + " integer NOT NULL DEFAULT 0");
RunnableFactory.createNew("DB version -> 16", new AbsRunnable() {
@Override
public void run() {
try {
Map<Integer, Integer> sessionIDServerIDRelation = sessionsTable.getIDServerIDRelation();
String sql = "UPDATE " + tableName + " SET " +
Col.SERVER_ID + "=?" +
" WHERE " + Col.SESSION_ID + "=?";
executeBatch(new ExecStatement(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<Integer, Integer> entry : sessionIDServerIDRelation.entrySet()) {
Integer sessionID = entry.getKey();
Integer serverID = entry.getValue();
statement.setInt(1, serverID);
statement.setInt(2, sessionID);
statement.addBatch();
}
}
});
worldTable.alterTableV16();
} catch (SQLException e) {
Log.toLog(this.getClass().getName(), e);
} finally {
cancel();
}
}
}).runTaskLaterAsynchronously(TimeAmount.SECOND.ticks() * 2);
}
public enum Col implements Column { public enum Col implements Column {
USER_ID(UserIDTable.Col.USER_ID.get()), USER_ID(UserIDTable.Col.USER_ID.get()),
SERVER_ID("server_id"),
SESSION_ID("session_id"), SESSION_ID("session_id"),
WORLD_ID("world_id"), WORLD_ID("world_id"),
SURVIVAL("survival_time"), SURVIVAL("survival_time"),

View File

@ -169,7 +169,7 @@ public class BatchOperationTable extends Table {
return; return;
} }
Log.debug("Batch Copy Worlds"); Log.debug("Batch Copy Worlds");
toDB.getDb().getWorldTable().saveWorlds(db.getWorldTable().getWorlds()); toDB.getDb().getWorldTable().saveWorlds(db.getWorldTable().getAllWorlds());
} }
public void copyUsers(BatchOperationTable toDB) throws SQLException { public void copyUsers(BatchOperationTable toDB) throws SQLException {

View File

@ -38,14 +38,16 @@ public class Version8TransferTable extends Table {
throw new IllegalStateException("Method not supposed to be used on this table."); throw new IllegalStateException("Method not supposed to be used on this table.");
} }
private String tableRenameSql(String from, String to) { private void renameTable(String from, String to) throws SQLException {
return usingMySQL ? String sql = usingMySQL ?
"RENAME TABLE " + from + " TO " + to : "RENAME TABLE " + from + " TO " + to :
"ALTER TABLE " + from + " RENAME TO " + to; "ALTER TABLE " + from + " RENAME TO " + to;
execute(sql);
} }
private String dropTableSql(String name) { private void dropTable(String name) throws SQLException {
return "DROP TABLE " + name; String sql = "DROP TABLE " + name;
execute(sql);
} }
public void alterTablesToV10() throws SQLException, DBInitException { public void alterTablesToV10() throws SQLException, DBInitException {
@ -54,23 +56,23 @@ public class Version8TransferTable extends Table {
copyTPS(); copyTPS();
execute(dropTableSql("plan_user_info")); dropTable("plan_user_info");
copyUsers(); copyUsers();
execute(dropTableSql("plan_ips")); dropTable("plan_ips");
db.getGeoInfoTable().createTable(); db.getGeoInfoTable().createTable();
execute(dropTableSql("plan_world_times")); dropTable("plan_world_times");
execute(dropTableSql("plan_worlds")); dropTable("plan_worlds");
db.getWorldTable().createTable(); db.getWorldTable().createTable();
db.getWorldTimesTable().createTable(); db.getWorldTimesTable().createTable();
execute(dropTableSql("plan_actions")); dropTable("plan_actions");
db.getActionsTable().createTable(); db.getActionsTable().createTable();
execute(dropTableSql("plan_gamemodetimes")); dropTable("plan_gamemodetimes");
execute(dropTableSql("temp_nicks")); dropTable("temp_nicks");
execute(dropTableSql("temp_kills")); dropTable("temp_kills");
execute(dropTableSql("temp_users")); dropTable("temp_users");
db.setVersion(10); db.setVersion(10);
Benchmark.stop("Schema copy from 8 to 10"); Benchmark.stop("Schema copy from 8 to 10");
@ -79,19 +81,19 @@ public class Version8TransferTable extends Table {
private void copyUsers() throws SQLException, DBInitException { private void copyUsers() throws SQLException, DBInitException {
String tempTableName = "temp_users"; String tempTableName = "temp_users";
UsersTable usersTable = db.getUsersTable(); UsersTable usersTable = db.getUsersTable();
execute(tableRenameSql("plan_users", tempTableName)); renameTable("plan_users", tempTableName);
String tempNickTableName = "temp_nicks"; String tempNickTableName = "temp_nicks";
NicknamesTable nicknamesTable = db.getNicknamesTable(); NicknamesTable nicknamesTable = db.getNicknamesTable();
execute(tableRenameSql(nicknamesTable.toString(), tempNickTableName)); renameTable(nicknamesTable.toString(), tempNickTableName);
String tempKillsTableName = "temp_kills"; String tempKillsTableName = "temp_kills";
KillsTable killsTable = db.getKillsTable(); KillsTable killsTable = db.getKillsTable();
execute(tableRenameSql(killsTable.toString(), tempKillsTableName)); renameTable(killsTable.toString(), tempKillsTableName);
usersTable.createTable(); usersTable.createTable();
nicknamesTable.createTable(); nicknamesTable.createTable();
execute(dropTableSql("plan_sessions")); dropTable("plan_sessions");
db.getSessionsTable().createTable(); db.getSessionsTable().createTable();
killsTable.createTable(); killsTable.createTable();
@ -141,7 +143,7 @@ public class Version8TransferTable extends Table {
String tempTableName = "temp_cmdusg"; String tempTableName = "temp_cmdusg";
CommandUseTable commandUseTable = db.getCommandUseTable(); CommandUseTable commandUseTable = db.getCommandUseTable();
execute(tableRenameSql("plan_commandusages", tempTableName)); renameTable("plan_commandusages", tempTableName);
commandUseTable.createTable(); commandUseTable.createTable();
@ -153,14 +155,14 @@ public class Version8TransferTable extends Table {
" FROM " + tempTableName; " FROM " + tempTableName;
execute(statement); execute(statement);
execute(dropTableSql(tempTableName)); dropTable(tempTableName);
} }
private void copyTPS() throws SQLException, DBInitException { private void copyTPS() throws SQLException, DBInitException {
String tempTableName = "temp_tps"; String tempTableName = "temp_tps";
TPSTable tpsTable = db.getTpsTable(); TPSTable tpsTable = db.getTpsTable();
execute(tableRenameSql(tpsTable.toString(), tempTableName)); renameTable(tpsTable.toString(), tempTableName);
tpsTable.createTable(); tpsTable.createTable();
@ -172,6 +174,6 @@ public class Version8TransferTable extends Table {
" FROM " + tempTableName; " FROM " + tempTableName;
execute(statement); execute(statement);
execute(dropTableSql(tempTableName)); dropTable(tempTableName);
} }
} }

View File

@ -16,6 +16,7 @@ import com.djrapitops.plan.system.info.server.ServerInfo;
import com.djrapitops.plan.system.webserver.pages.parsing.AnalysisPage; import com.djrapitops.plan.system.webserver.pages.parsing.AnalysisPage;
import com.djrapitops.plan.system.webserver.response.DefaultResponses; import com.djrapitops.plan.system.webserver.response.DefaultResponses;
import com.djrapitops.plan.system.webserver.response.Response; import com.djrapitops.plan.system.webserver.response.Response;
import com.djrapitops.plan.system.webserver.response.errors.InternalErrorResponse;
import com.djrapitops.plan.utilities.analysis.Analysis; import com.djrapitops.plan.utilities.analysis.Analysis;
import com.djrapitops.plugin.api.utility.log.Log; import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Verify; import com.djrapitops.plugin.utilities.Verify;
@ -93,7 +94,7 @@ public class GenerateAnalysisPageRequest extends InfoRequestWithVariables implem
throw new InternalErrorException("Analysis failed due to exception", e); throw new InternalErrorException("Analysis failed due to exception", e);
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {
/* Plugin is shutting down, exceptions ignored */ /* Plugin is shutting down, exceptions ignored */
return "<p>Plugin is shutting down..</p>"; return new InternalErrorResponse("Plugin may be shutting down", e).getContent();
} catch (Exception e) { } catch (Exception e) {
Log.toLog(this.getClass(), e); Log.toLog(this.getClass(), e);
throw new InternalErrorException("Analysis failed due to exception", e); throw new InternalErrorException("Analysis failed due to exception", e);

View File

@ -323,7 +323,7 @@ public class SQLiteTest {
commitTest(); commitTest();
List<String> saved = worldTable.getWorlds(); List<String> saved = worldTable.getAllWorlds();
assertEquals(new HashSet<>(worlds), new HashSet<>(saved)); assertEquals(new HashSet<>(worlds), new HashSet<>(saved));
} }
@ -602,7 +602,7 @@ public class SQLiteTest {
assertTrue(sessionsTable.getSessions(playerUUID).isEmpty()); assertTrue(sessionsTable.getSessions(playerUUID).isEmpty());
assertTrue(actionsTable.getActions(playerUUID).isEmpty()); assertTrue(actionsTable.getActions(playerUUID).isEmpty());
assertTrue(db.getCommandUseTable().getCommandUse().isEmpty()); assertTrue(db.getCommandUseTable().getCommandUse().isEmpty());
assertTrue(db.getWorldTable().getWorlds().isEmpty()); assertTrue(db.getWorldTable().getAllWorlds().isEmpty());
assertTrue(tpsTable.getTPSData().isEmpty()); assertTrue(tpsTable.getTPSData().isEmpty());
assertTrue(db.getServerTable().getBukkitServers().isEmpty()); assertTrue(db.getServerTable().getBukkitServers().isEmpty());
assertTrue(securityTable.getUsers().isEmpty()); assertTrue(securityTable.getUsers().isEmpty());
@ -784,7 +784,7 @@ public class SQLiteTest {
assertFalse(sessionsTable.getSessions(playerUUID).isEmpty()); assertFalse(sessionsTable.getSessions(playerUUID).isEmpty());
assertFalse(actionsTable.getActions(playerUUID).isEmpty()); assertFalse(actionsTable.getActions(playerUUID).isEmpty());
assertFalse(backup.getCommandUseTable().getCommandUse().isEmpty()); assertFalse(backup.getCommandUseTable().getCommandUse().isEmpty());
assertFalse(backup.getWorldTable().getWorlds().isEmpty()); assertFalse(backup.getWorldTable().getAllWorlds().isEmpty());
assertFalse(tpsTable.getTPSData().isEmpty()); assertFalse(tpsTable.getTPSData().isEmpty());
assertFalse(backup.getServerTable().getBukkitServers().isEmpty()); assertFalse(backup.getServerTable().getBukkitServers().isEmpty());
assertFalse(securityTable.getUsers().isEmpty()); assertFalse(securityTable.getUsers().isEmpty());
@ -852,6 +852,20 @@ public class SQLiteTest {
assertEquals(worldTimes, allSessions.get(serverUUID).get(playerUUID).get(0).getWorldTimes()); assertEquals(worldTimes, allSessions.get(serverUUID).get(playerUUID).get(0).getWorldTimes());
} }
@Test
public void testGetUserWorldTimes() throws SQLException {
testSaveSessionsWorldTimes();
WorldTimes worldTimesOfUser = db.getWorldTimesTable().getWorldTimesOfUser(playerUUID);
assertEquals(createWorldTimes(), worldTimesOfUser);
}
@Test
public void testGetServerWorldTimes() throws SQLException {
testSaveSessionsWorldTimes();
WorldTimes worldTimesOfServer = db.getWorldTimesTable().getWorldTimesOfServer(TestConstants.SERVER_UUID);
assertEquals(createWorldTimes(), worldTimesOfServer);
}
@Test @Test
public void testRegisterProcessorRegisterException() throws SQLException { public void testRegisterProcessorRegisterException() throws SQLException {
assertFalse(db.getUsersTable().isRegistered(playerUUID)); assertFalse(db.getUsersTable().isRegistered(playerUUID));
@ -881,7 +895,7 @@ public class SQLiteTest {
@Test @Test
public void testWorldTableGetWorldNamesNoException() throws SQLException { public void testWorldTableGetWorldNamesNoException() throws SQLException {
Set<String> worldNames = db.getWorldTable().getWorldNames(); Set<String> worldNames = db.getWorldTable().getWorldNames(TestConstants.SERVER_UUID);
} }
@Test @Test