Start SessionTable (not finished)

This commit is contained in:
Rsl1122 2017-08-22 17:32:19 +03:00
parent 44c9ee3925
commit 8895aca0ff
6 changed files with 169 additions and 330 deletions

View File

@ -25,10 +25,11 @@ import java.util.List;
*/
public class Session {
private final WorldTimes worldTimes;
private Long sessionID;
private WorldTimes worldTimes;
private final long sessionStart;
private long sessionEnd;
private final List<KillData> playerKills;
private List<KillData> playerKills;
private int mobKills;
private int deaths;
@ -52,7 +53,8 @@ public class Session {
* @param sessionStart Epoch millisecond the session was started.
* @param sessionEnd Epoch millisecond the session ended.
*/
public Session(long sessionStart, long sessionEnd, WorldTimes worldTimes, List<KillData> playerKills, int mobKills, int deaths) {
public Session(long id, long sessionStart, long sessionEnd, int mobKills, int deaths) {
this.sessionID = id;
this.sessionStart = sessionStart;
this.sessionEnd = sessionEnd;
this.worldTimes = worldTimes;
@ -173,4 +175,26 @@ public class Session {
public static Session start(long time, String world, String gm) {
return new Session(time, world, gm);
}
public boolean isFetchedFromDB() {
return sessionID != null;
}
public void setWorldTimes(WorldTimes worldTimes) {
this.worldTimes = worldTimes;
}
public void setPlayerKills(List<KillData> playerKills) {
this.playerKills = playerKills;
}
/**
* Used to get the ID of the session in the Database.
*
* @return ID if present.
* @throws NullPointerException if Session was not fetched from DB. Check using {@code isFetchedFromDB}
*/
public long getSessionID() {
return sessionID;
}
}

View File

@ -1,26 +1,28 @@
package main.java.com.djrapitops.plan.database.tables;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.database.databases.SQLDB;
import main.java.com.djrapitops.plan.database.sql.Select;
import main.java.com.djrapitops.plan.database.sql.Sql;
import main.java.com.djrapitops.plan.database.sql.TableSqlParser;
import main.java.com.djrapitops.plan.utilities.Benchmark;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* @author Rsl1122
*/
public class IPsTable extends UserIDTable {
// TODO Write tests
private final String columnIP = "ip";
private final String columnGeolocation = "geolocation"; // TODO
private final String columnGeolocation = "geolocation";
/**
* @param db The database
@ -40,6 +42,7 @@ public class IPsTable extends UserIDTable {
execute(TableSqlParser.createTable(tableName)
.column(columnUserID, Sql.INT).notNull()
.column(columnIP, Sql.varchar(20)).notNull()
.column(columnGeolocation, Sql.varchar(50)).notNull()
.foreignKey(columnUserID, usersTable.getTableName(), usersTable.getColumnID())
.toString()
);
@ -59,176 +62,81 @@ public class IPsTable extends UserIDTable {
}
/**
* @param userId The User ID from which the IPs should be retrieved from
* @return The retrieved IPs
* @param uuid UUID of the user.
* @return Users's Login Geolocations.
* @throws SQLException when an error at retrieval happens
*/
public List<InetAddress> getIPAddresses(int userId) throws SQLException {
public List<String> getGeolocations(UUID uuid) throws SQLException {
return getStringList(uuid, columnGeolocation);
}
public List<String> getIps(UUID uuid) throws SQLException {
return getStringList(uuid, columnIP);
}
private List<String> getStringList(UUID uuid, String column) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
List<InetAddress> ips = new ArrayList<>();
List<String> stringList = new ArrayList<>();
statement = prepareStatement("SELECT * FROM " + tableName + " WHERE UPPER(" + columnUserID + ") LIKE UPPER(?)");
statement.setInt(1, userId);
statement = prepareStatement(Select.from(tableName, column)
.where(columnUserID + "=" + usersTable.statementSelectID)
.toString());
statement.setString(1, uuid.toString());
set = statement.executeQuery();
while (set.next()) {
String ipAddressName = set.getString(columnIP);
try {
ips.add(InetAddress.getByName(ipAddressName));
} catch (UnknownHostException e) {
Log.error("Host not found at getIPAddresses: " + ipAddressName); //Shouldn't ever happen
}
stringList.add(set.getString(column));
}
return ips;
return stringList;
} finally {
close(set, statement);
}
}
/**
* @param userId The User ID for which the IPs should be saved for
* @param ips The IPs
* @throws SQLException when an error at saving happens
*/
public void saveIPList(int userId, Set<InetAddress> ips) throws SQLException {
if (ips == null) {
return;
}
ips.removeAll(getIPAddresses(userId));
if (ips.isEmpty()) {
public void updateIP(UUID uuid, String ip, String geolocation) throws SQLException {
List<String> ips = getIps(uuid);
if (ips.contains(ip)) {
return;
}
insertIp(uuid, ip, geolocation);
}
private void insertIp(UUID uuid, String ip, String geolocation) throws SQLException {
PreparedStatement statement = null;
try {
statement = prepareStatement("INSERT INTO " + tableName + " ("
+ columnUserID + ", "
+ columnIP
+ ") VALUES (?, ?)");
boolean commitRequired = false;
for (InetAddress ip : ips) {
if (ip == null) {
continue;
}
statement.setInt(1, userId);
statement.setString(2, ip.getHostAddress());
statement.addBatch();
commitRequired = true;
}
if (commitRequired) {
statement.executeBatch();
}
+ columnIP + ", "
+ columnGeolocation
+ ") VALUES ("
+ usersTable.statementSelectID + ", "
+ "?, ?)");
statement.setString(1, uuid.toString());
statement.setString(2, ip);
statement.setString(3, geolocation);
statement.execute();
} finally {
close(statement);
}
}
/**
* @param ids The User IDs for which the IPs should be retrieved for
* @return The User IDs corresponding with their used IPs
* @throws SQLException when an error at retrieval happens
*/
public Map<Integer, Set<InetAddress>> getIPList(Collection<Integer> ids) throws SQLException {
if (Verify.isEmpty(ids)) {
return new HashMap<>();
}
Benchmark.start("Get Ips Multiple");
public Optional<String> getGeolocation(String ip) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement("SELECT * FROM " + tableName);
statement = prepareStatement(Select.from(tableName, columnGeolocation)
.where(columnIP + "=?")
.toString());
statement.setString(1, ip);
set = statement.executeQuery();
Map<Integer, Set<InetAddress>> ips = new HashMap<>();
for (Integer id : ids) {
ips.put(id, new HashSet<>());
if (set.next()) {
return Optional.of(set.getString(columnGeolocation));
}
while (set.next()) {
Integer id = set.getInt(columnUserID);
if (!ids.contains(id)) {
continue;
}
String ipAddressName = set.getString(columnIP);
try {
ips.get(id).add(InetAddress.getByName(ipAddressName));
} catch (UnknownHostException e) {
Log.error("Host not found at getIPAddresses: " + ipAddressName); //Shouldn't ever happen
}
}
return ips;
return Optional.empty();
} finally {
close(set, statement);
Benchmark.stop("Database", "Get Ips Multiple");
}
}
/**
* @param ips The User IDs corresponding to their IPs used
* @throws SQLException when an error at saving happens
*/
public void saveIPList(Map<Integer, Set<InetAddress>> ips) throws SQLException {
if (Verify.isEmpty(ips)) {
return;
}
Benchmark.start("Save Ips Multiple");
Map<Integer, Set<InetAddress>> saved = getIPList(ips.keySet());
PreparedStatement statement = null;
try {
statement = prepareStatement("INSERT INTO " + tableName + " ("
+ columnUserID + ", "
+ columnIP
+ ") VALUES (?, ?)");
boolean commitRequired = false;
for (Map.Entry<Integer, Set<InetAddress>> entrySet : ips.entrySet()) {
Integer id = entrySet.getKey();
Set<InetAddress> ipAddresses = entrySet.getValue();
Set<InetAddress> s = saved.get(id);
if (s != null) {
ipAddresses.removeAll(s);
}
if (ipAddresses.isEmpty()) {
continue;
}
for (InetAddress ip : ipAddresses) {
if (ip == null) {
continue;
}
statement.setInt(1, id);
statement.setString(2, ip.getHostAddress());
statement.addBatch();
commitRequired = true;
}
}
if (commitRequired) {
statement.executeBatch();
}
} finally {
close(statement);
Benchmark.stop("Database", "Save Ips Multiple");
}
}
}

View File

@ -18,14 +18,12 @@ import java.util.*;
*/
public class KillsTable extends Table {
private final String columnKillerUserID;
private final String columnVictimUserID;
private final String columnWeapon;
private final String columnDate;
private final String columnServerID; //TODO
private final String columnSessionID; //TODO
// TODO Automatic UserID Retrieval from UsersTable.
private final String columnKillerUserID = "killer_id";
private final String columnVictimUserID = "victim_id";
private final String columnWeapon = "weapon";
private final String columnDate = "date";
private final String columnServerID = "server_id"; //TODO
private final String columnSessionID = "session_id"; //TODO
/**
* @param db
@ -33,12 +31,6 @@ public class KillsTable extends Table {
*/
public KillsTable(SQLDB db, boolean usingMySQL) {
super("plan_kills", db, usingMySQL);
columnWeapon = "weapon";
columnDate = "date";
columnKillerUserID = "killer_id";
columnVictimUserID = "victim_id";
columnServerID = "server_id";
columnSessionID = "session_id";
}
/**
@ -236,4 +228,8 @@ public class KillsTable extends Table {
Benchmark.stop("Database", "Save Kills multiple");
}
}
public void savePlayerKills(UUID uuid, List<KillData> playerKills) {
// TODO savePlayerKills
}
}

View File

@ -13,10 +13,7 @@ import main.java.com.djrapitops.plan.database.sql.*;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.*;
/**
* Table for managing multiple server's data in the database.
@ -42,10 +39,12 @@ public class ServerTable extends Table {
private final String columnInstalled = "is_installed";
public final String statementSelectServerID;
public final String statementSelectServerNameID;
public ServerTable(SQLDB db, boolean usingMySQL) {
super("plan_servers", db, usingMySQL);
statementSelectServerID = "(" + Select.from(tableName, tableName + "." + columnServerID).where(columnServerUUID + "=?").toString() + ")";
statementSelectServerNameID = "(" + Select.from(tableName, tableName + "." + columnServerName).where(columnServerID + "=?").toString() + ")";
}
@Override
@ -181,6 +180,25 @@ public class ServerTable extends Table {
}
}
public Map<Integer, String> getServerNames() throws SQLException {
Map<Integer, String> names = new HashMap<>();
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement(Select.from(tableName,
columnServerName)
.toString());
set = statement.executeQuery();
while (set.next()) {
int id = set.getInt(columnServerID);
names.put(id, set.getString(columnServerName));
}
return names;
} finally {
close(set, statement);
}
}
/**
* Used to get BungeeCord WebServer info if present.
*

View File

@ -1,12 +1,12 @@
package main.java.com.djrapitops.plan.database.tables;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.Session;
import main.java.com.djrapitops.plan.database.Container;
import main.java.com.djrapitops.plan.database.databases.SQLDB;
import main.java.com.djrapitops.plan.database.sql.Select;
import main.java.com.djrapitops.plan.database.sql.Sql;
import main.java.com.djrapitops.plan.database.sql.TableSqlParser;
import main.java.com.djrapitops.plan.utilities.Benchmark;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@ -18,12 +18,14 @@ import java.util.*;
*/
public class SessionsTable extends UserIDTable {
private final String columnSessionID = "id"; //TODO
private final String columnSessionID = "id";
private final String columnSessionStart = "session_start";
private final String columnSessionEnd = "session_end";
private final String columnServerID = "server_id"; //TODO
private final String columnMobKills = "mob_kills"; //TODO
private final String columnDeaths = "deaths"; //TODO
private final String columnServerID = "server_id";
private final String columnMobKills = "mob_kills";
private final String columnDeaths = "deaths";
private final ServerTable serverTable;
/**
* @param db
@ -31,6 +33,7 @@ public class SessionsTable extends UserIDTable {
*/
public SessionsTable(SQLDB db, boolean usingMySQL) {
super("plan_sessions", db, usingMySQL);
serverTable = db.getServerTable();
}
/**
@ -39,12 +42,17 @@ public class SessionsTable extends UserIDTable {
@Override
public boolean createTable() {
try {
UsersTable usersTable = db.getUsersTable();
execute(TableSqlParser.createTable(tableName)
.primaryKeyIDColumn(usingMySQL, columnServerID, Sql.LONG)
.column(columnUserID, Sql.INT).notNull()
.column(columnServerID, Sql.INT).notNull()
.column(columnSessionStart, Sql.LONG).notNull()
.column(columnSessionEnd, Sql.LONG).notNull()
.column(columnMobKills, Sql.INT).notNull()
.column(columnDeaths, Sql.INT).notNull()
.foreignKey(columnUserID, usersTable.getTableName(), usersTable.getColumnID())
.foreignKey(columnServerID, serverTable.getTableName(), serverTable.getColumnID())
.primaryKey(usingMySQL, columnSessionID)
.toString()
);
return true;
@ -55,31 +63,10 @@ public class SessionsTable extends UserIDTable {
}
/**
* @param userId
* @return
* @throws SQLException
*/
public List<Session> getSessionData(int userId) throws SQLException {
PreparedStatement statement = null;
ResultSet set = null;
try {
statement = prepareStatement("SELECT * FROM " + tableName + " WHERE (" + columnUserID + "=?)");
statement.setInt(1, userId);
set = statement.executeQuery();
List<Session> sessions = new ArrayList<>();
while (set.next()) {
// sessions.add(new Session(set.getLong(columnSessionStart), set.getLong(columnSessionEnd)));
}
set.close();
statement.close();
return sessions;
} finally {
close(set);
close(statement);
}
}
/**
* Removes User's Sessions from the Database.
* <p>
* // TODO KILLS SHOULD BE REMOVED FIRST.
*
* @param userId
* @return
*/
@ -87,161 +74,62 @@ public class SessionsTable extends UserIDTable {
return super.removeDataOf(userId);
}
/**
* @param userId
* @param sessions
* @throws SQLException
*/
public void saveSessionData(int userId, List<Session> sessions) throws SQLException {
if (sessions == null) {
return;
}
sessions.removeAll(getSessionData(userId));
if (sessions.isEmpty()) {
return;
}
public void saveSessionInformation(UUID uuid, Session session) throws SQLException {
PreparedStatement statement = null;
try {
statement = prepareStatement("INSERT INTO " + tableName + " ("
+ columnUserID + ", "
+ columnSessionStart + ", "
+ columnSessionEnd
+ ") VALUES (?, ?, ?)");
for (Session session : sessions) {
long end = session.getSessionEnd();
long start = session.getSessionStart();
if (end < start) {
continue;
}
+ columnSessionEnd + ", "
+ columnDeaths + ", "
+ columnMobKills + ", "
+ columnServerID
+ ") VALUES ("
+ columnUserID + "=" + usersTable.statementSelectID + ", "
+ "?, ?, ?, ?, "
+ serverTable.statementSelectServerID + ")");
statement.setString(1, uuid.toString());
statement.setInt(1, userId);
statement.setLong(2, start);
statement.setLong(3, end);
statement.addBatch();
}
statement.setLong(2, session.getSessionStart());
statement.setLong(3, session.getSessionEnd());
statement.setInt(4, session.getDeaths());
statement.setInt(5, session.getMobKills());
statement.executeBatch();
statement.setString(6, Plan.getServerUUID().toString());
statement.execute();
} finally {
close(statement);
}
db.getWorldTimesTable().saveWorldTimes(session.getWorldTimes());
db.getKillsTable().savePlayerKills(uuid, session.getPlayerKills());
}
/**
* @param ids
* @return
* @throws SQLException
*/
public Map<Integer, List<Session>> getSessionData(Collection<Integer> ids) throws SQLException {
if (ids == null || ids.isEmpty()) {
return new HashMap<>();
}
Benchmark.start("Get Sessions multiple");
public Map<String, List<Session>> getSessions(UUID uuid) throws SQLException {
Map<Integer, String> serverNames = serverTable.getServerNames();
Map<String, List<Session>> sessionsByServer = new HashMap<>();
PreparedStatement statement = null;
ResultSet set = null;
try {
Map<Integer, List<Session>> sessions = new HashMap<>();
statement = prepareStatement("SELECT * FROM " + tableName);
statement = prepareStatement(Select.from(tableName, "*")
.where(columnUserID + "=" + usersTable.statementSelectID)
.toString());
statement.setString(1, uuid.toString());
set = statement.executeQuery();
for (Integer id : ids) {
sessions.put(id, new ArrayList<>());
}
while (set.next()) {
Integer id = set.getInt(columnUserID);
if (!ids.contains(id)) {
continue;
}
long id = set.getLong(columnSessionID);
long start = set.getLong(columnSessionStart);
long end = set.getLong(columnSessionEnd);
String serverName = serverNames.get(set.getInt(columnServerID));
long sessionStart = set.getLong(columnSessionStart);
long sessionEnd = set.getLong(columnSessionEnd);
// sessions.get(id).add(new Session(sessionStart, sessionEnd));
int deaths = set.getInt(columnDeaths);
int mobKills = set.getInt(columnMobKills);
List<Session> sessions = sessionsByServer.getOrDefault(serverName, new ArrayList<>());
sessions.add(new Session(id, start, end, deaths, mobKills));
}
return sessions;
return sessionsByServer;
} finally {
close(set);
close(statement);
Benchmark.stop("Database", "Get Sessions multiple");
close(set, statement);
}
}
/**
* @param sessions
* @throws SQLException
*/
public void saveSessionData(Map<Integer, List<Session>> sessions) throws SQLException {
if (sessions == null || sessions.isEmpty()) {
return;
}
Benchmark.start("Save Sessions multiple");
Map<Integer, List<Session>> saved = getSessionData(sessions.keySet());
for (Map.Entry<Integer, List<Session>> entrySet : sessions.entrySet()) {
Integer id = entrySet.getKey();
List<Session> sessionList = entrySet.getValue();
List<Session> s = saved.get(id);
if (s != null) {
sessionList.removeAll(s);
}
if (sessionList.isEmpty()) {
continue;
}
saved.put(id, sessionList);
}
List<List<Container<Session>>> batches = splitIntoBatches(sessions);
batches.forEach(batch -> {
try {
saveSessionBatch(batch);
} catch (SQLException e) {
Log.toLog("SessionsTable.saveSessionData", e);
}
});
Benchmark.stop("Database", "Save Sessions multiple");
}
private void saveSessionBatch(List<Container<Session>> batch) throws SQLException {
if (batch.isEmpty()) {
return;
}
PreparedStatement statement = null;
try {
statement = prepareStatement("INSERT INTO " + tableName + " ("
+ columnUserID + ", "
+ columnSessionStart + ", "
+ columnSessionEnd
+ ") VALUES (?, ?, ?)");
for (Container<Session> data : batch) {
Session session = data.getObject();
int id = data.getId();
statement.setInt(1, id);
statement.setLong(2, session.getSessionStart());
statement.setLong(3, session.getSessionEnd());
statement.addBatch();
}
statement.executeBatch();
} finally {
close(statement);
}
}
public void clean() {
// TODO Clean sessions before Configurable time span
}
}

View File

@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.database.tables;
import com.djrapitops.plugin.utilities.Verify;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.data.time.WorldTimes;
import main.java.com.djrapitops.plan.database.databases.SQLDB;
import main.java.com.djrapitops.plan.database.sql.Sql;
import main.java.com.djrapitops.plan.database.sql.TableSqlParser;
@ -312,4 +313,8 @@ public class WorldTimesTable extends UserIDTable {
close(statement);
}
}
public void saveWorldTimes(WorldTimes worldTimes) {
// TODO saveWorldTimes (INSERT)
}
}