Refactored UsersTable#insertUsers to an executable:

- New object to represent plan_users data, BaseUser
- Deprecated UserInfo#getName
This commit is contained in:
Rsl1122 2019-01-25 12:04:57 +02:00
parent 08c0c8f170
commit 35c9caf59a
10 changed files with 141 additions and 60 deletions

View File

@ -0,0 +1,79 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.data.container;
import com.djrapitops.plugin.utilities.Verify;
import java.util.Objects;
import java.util.UUID;
/**
* Represents user information stored in plan_users.
* <p>
* Only one per player exists unlike {@link UserInfo} which is available per server.
*
* @author Rsl1122
*/
public class BaseUser {
private final UUID uuid;
private final String name;
private final long registered;
private final int timesKicked;
public BaseUser(UUID uuid, String name, long registered, int timesKicked) {
Verify.nullCheck(uuid, () -> new IllegalArgumentException("'uuid' can not be null"));
Verify.nullCheck(name, () -> new IllegalArgumentException("'name' can not be null"));
this.uuid = uuid;
this.name = name;
this.registered = registered;
this.timesKicked = timesKicked;
}
public UUID getUuid() {
return uuid;
}
public String getName() {
return name;
}
public long getRegistered() {
return registered;
}
public int getTimesKicked() {
return timesKicked;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof BaseUser)) return false;
BaseUser baseUser = (BaseUser) o;
return registered == baseUser.registered &&
timesKicked == baseUser.timesKicked &&
uuid.equals(baseUser.uuid) &&
name.equals(baseUser.name);
}
@Override
public int hashCode() {
return Objects.hash(uuid, name, registered, timesKicked);
}
}

View File

@ -27,6 +27,7 @@ import java.util.UUID;
public class UserInfo {
private final UUID uuid;
@Deprecated
private String name;
private long registered;
private boolean banned;
@ -44,6 +45,7 @@ public class UserInfo {
return uuid;
}
@Deprecated
public String getName() {
return name;
}

View File

@ -17,12 +17,10 @@
package com.djrapitops.plan.db.access.transactions;
import com.djrapitops.plan.db.Database;
import com.djrapitops.plan.db.SQLDB;
import com.djrapitops.plan.db.access.Executable;
import com.djrapitops.plan.db.access.Query;
import com.djrapitops.plan.db.sql.queries.LargeFetchQueries;
import com.djrapitops.plan.db.sql.queries.LargeStoreQueries;
import com.djrapitops.plan.db.sql.tables.UsersTable;
import java.util.function.Function;
@ -103,11 +101,7 @@ public class BackupCopyTransaction extends RemoveEverythingTransaction {
}
private void copyUsers() {
UsersTable fromTable = ((SQLDB) sourceDB).getUsersTable();
UsersTable toTable = db.getUsersTable();
toTable.insertUsers(sourceDB.query(LargeFetchQueries.fetchAllCommonUserInformation()));
toTable.updateKicked(fromTable.getAllTimesKicked());
copy(LargeStoreQueries::storeAllCommonUserInformation, LargeFetchQueries.fetchAllCommonUserInformation());
}
private void copySessions() {

View File

@ -473,21 +473,22 @@ public class LargeFetchQueries {
* <p>
* This is the base for any user information.
*
* @return Map: Player UUID - UserInfo
* @return Map: Player UUID - BaseUser
*/
public static Query<Map<UUID, UserInfo>> fetchAllCommonUserInformation() {
public static Query<Collection<BaseUser>> fetchAllCommonUserInformation() {
String sql = Select.all(UsersTable.TABLE_NAME).toString();
return new QueryAllStatement<Map<UUID, UserInfo>>(sql, 20000) {
return new QueryAllStatement<Collection<BaseUser>>(sql, 20000) {
@Override
public Map<UUID, UserInfo> processResults(ResultSet set) throws SQLException {
Map<UUID, UserInfo> users = new HashMap<>();
public Collection<BaseUser> processResults(ResultSet set) throws SQLException {
Collection<BaseUser> users = new HashSet<>();
while (set.next()) {
UUID uuid = UUID.fromString(set.getString(UsersTable.USER_UUID));
String name = set.getString(UsersTable.USER_NAME);
long registered = set.getLong(UsersTable.REGISTERED);
int kicked = set.getInt(UsersTable.TIMES_KICKED);
users.put(uuid, new UserInfo(uuid, name, registered, false, false));
users.add(new BaseUser(uuid, name, registered, kicked));
}
return users;
}

View File

@ -17,6 +17,7 @@
package com.djrapitops.plan.db.sql.queries;
import com.djrapitops.plan.data.WebUser;
import com.djrapitops.plan.data.container.BaseUser;
import com.djrapitops.plan.data.container.GeoInfo;
import com.djrapitops.plan.data.container.TPS;
import com.djrapitops.plan.data.container.UserInfo;
@ -275,6 +276,12 @@ public class LargeStoreQueries {
};
}
/**
* Execute a big batch of world name insert statements.
*
* @param ofServers Map: Server UUID - Collection of world names
* @return Executable, use inside a {@link com.djrapitops.plan.db.access.transactions.Transaction}
*/
public static Executable storeAllWorldNames(Map<UUID, Collection<String>> ofServers) {
if (Verify.isEmpty(ofServers)) {
return Executable.empty();
@ -294,4 +301,23 @@ public class LargeStoreQueries {
}
};
}
public static Executable storeAllCommonUserInformation(Collection<BaseUser> ofUsers) {
if (Verify.isEmpty(ofUsers)) {
return Executable.empty();
}
return new ExecBatchStatement(UsersTable.INSERT_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (BaseUser user : ofUsers) {
statement.setString(1, user.getUuid().toString());
statement.setString(2, user.getName());
statement.setLong(3, user.getRegistered());
statement.setInt(4, user.getTimesKicked());
statement.addBatch();
}
}
};
}
}

View File

@ -16,7 +16,6 @@
*/
package com.djrapitops.plan.db.sql.tables;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.data.store.Key;
import com.djrapitops.plan.data.store.containers.DataContainer;
import com.djrapitops.plan.data.store.keys.PlayerKeys;
@ -50,6 +49,8 @@ public class UsersTable extends Table {
public static final String USER_NAME = "name";
public static final String TIMES_KICKED = "times_kicked";
public static final String INSERT_STATEMENT = Insert.values(TABLE_NAME, USER_UUID, USER_NAME, REGISTERED, TIMES_KICKED);
public UsersTable(SQLDB db) {
super(TABLE_NAME, db);
statementSelectID = "(" + Select.from(tableName, tableName + "." + ID).where(USER_UUID + "=?").toString() + " LIMIT 1)";
@ -276,37 +277,6 @@ public class UsersTable extends Table {
});
}
/**
* Inserts UUIDs, Register dates and Names to the table.
* <p>
* This method is for batch operations, and should not be used to add information of users.
* Use UserInfoTable instead.
*
* @param users Users to insert
*/
public void insertUsers(Map<UUID, UserInfo> users) {
if (Verify.isEmpty(users)) {
return;
}
executeBatch(new ExecStatement(insertStatement) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
for (Map.Entry<UUID, UserInfo> entry : users.entrySet()) {
UUID uuid = entry.getKey();
UserInfo info = entry.getValue();
long registered = info.getRegistered();
String name = info.getName();
statement.setString(1, uuid.toString());
statement.setLong(2, registered);
statement.setString(3, name);
statement.addBatch();
}
}
});
}
public void updateKicked(Map<UUID, Integer> timesKicked) {
if (Verify.isEmpty(timesKicked)) {
return;

View File

@ -192,8 +192,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
public List<PlayerContainer> getAllPlayerContainers() {
List<PlayerContainer> containers = new ArrayList<>();
Map<UUID, UserInfo> users = db.query(LargeFetchQueries.fetchAllCommonUserInformation());
Map<UUID, Integer> timesKicked = usersTable.getAllTimesKicked();
Collection<BaseUser> users = db.query(LargeFetchQueries.fetchAllCommonUserInformation());
Map<UUID, List<GeoInfo>> geoInfo = db.query(LargeFetchQueries.fetchAllGeoInfoData());
Map<UUID, List<Ping>> allPings = db.query(LargeFetchQueries.fetchAllPingData());
Map<UUID, List<Nickname>> allNicknames = db.query(LargeFetchQueries.fetchAllNicknameDataByPlayerUUIDs());
@ -202,14 +201,14 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
Map<UUID, List<UserInfo>> allUserInfo = db.query(LargeFetchQueries.fetchPerServerUserInformation());
Map<UUID, PerServerContainer> perServerInfo = getPerServerData(sessions, allUserInfo, allPings);
for (UserInfo userInfo : users.values()) {
for (BaseUser baseUser : users) {
PlayerContainer container = new PlayerContainer();
UUID uuid = userInfo.getUuid();
UUID uuid = baseUser.getUuid();
container.putRawData(PlayerKeys.UUID, uuid);
container.putRawData(PlayerKeys.REGISTERED, userInfo.getRegistered());
container.putRawData(PlayerKeys.NAME, userInfo.getName());
container.putRawData(PlayerKeys.KICK_COUNT, timesKicked.get(uuid));
container.putRawData(PlayerKeys.REGISTERED, baseUser.getRegistered());
container.putRawData(PlayerKeys.NAME, baseUser.getName());
container.putRawData(PlayerKeys.KICK_COUNT, baseUser.getTimesKicked());
container.putRawData(PlayerKeys.GEO_INFO, geoInfo.get(uuid));
container.putRawData(PlayerKeys.PING, allPings.get(uuid));
container.putRawData(PlayerKeys.NICKNAMES, allNicknames.get(uuid));
@ -424,7 +423,7 @@ public class SQLFetchOps extends SQLOps implements FetchOperations {
@Override
public Map<UUID, UserInfo> getUsers() {
return db.query(LargeFetchQueries.fetchAllCommonUserInformation());
return new HashMap<>();
}
@Override

View File

@ -26,9 +26,11 @@ import com.djrapitops.plan.system.database.databases.operation.SaveOperations;
import com.djrapitops.plan.system.info.server.Server;
import com.djrapitops.plan.system.settings.config.Config;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* SaveOperations implementation for SQL databases.
@ -62,8 +64,16 @@ public class SQLSaveOps extends SQLOps implements SaveOperations {
}
@Override
public void insertUsers(Map<UUID, UserInfo> ofServers) {
usersTable.insertUsers(ofServers);
public void insertUsers(Map<UUID, UserInfo> ofUsers) {
db.executeTransaction(new Transaction() {
@Override
protected void performOperations() {
Collection<BaseUser> users = ofUsers.values().stream()
.map(user -> new BaseUser(user.getUuid(), user.getName(), user.getRegistered(), 0))
.collect(Collectors.toSet());
execute(LargeStoreQueries.storeAllCommonUserInformation(users));
}
});
}
@Override

View File

@ -19,7 +19,7 @@ package com.djrapitops.plan.system.export;
import com.djrapitops.plan.PlanPlugin;
import com.djrapitops.plan.api.exceptions.ParseException;
import com.djrapitops.plan.api.exceptions.database.DBOpException;
import com.djrapitops.plan.data.container.UserInfo;
import com.djrapitops.plan.data.container.BaseUser;
import com.djrapitops.plan.db.sql.queries.LargeFetchQueries;
import com.djrapitops.plan.system.database.DBSystem;
import com.djrapitops.plan.system.file.PlanFiles;
@ -138,9 +138,9 @@ public class HtmlExport extends SpecificExport {
public void exportAvailablePlayers() {
try {
Map<UUID, UserInfo> users = dbSystem.getDatabase().query(LargeFetchQueries.fetchAllCommonUserInformation());
for (Map.Entry<UUID, UserInfo> entry : users.entrySet()) {
exportAvailablePlayerPage(entry.getKey(), entry.getValue().getName());
Collection<BaseUser> users = dbSystem.getDatabase().query(LargeFetchQueries.fetchAllCommonUserInformation());
for (BaseUser user : users) {
exportAvailablePlayerPage(user.getUuid(), user.getName());
}
} catch (IOException | DBOpException e) {
errorHandler.log(L.WARN, this.getClass(), e);

View File

@ -557,7 +557,7 @@ public abstract class CommonDBTest {
db.executeTransaction(new RemoveEverythingTransaction());
assertQueryIsEmpty(db, LargeFetchQueries.fetchAllCommonUserInformation());
assertTrue(db.query(LargeFetchQueries.fetchAllCommonUserInformation()).isEmpty());
assertQueryIsEmpty(db, LargeFetchQueries.fetchPerServerUserInformation());
assertQueryIsEmpty(db, LargeFetchQueries.fetchAllNicknameData());
assertQueryIsEmpty(db, LargeFetchQueries.fetchAllGeoInfoData());