Skip to content

Commit

Permalink
Register plan_user row if missing when required
Browse files Browse the repository at this point in the history
- PingStoreTransaction
- GeoInfoStoreTransaction
- SessionEndTransaction

Affects issues:
- Fixed #2361
- Fixed #2343
  • Loading branch information
AuroraLS3 committed May 7, 2022
1 parent 8cae81f commit 6fa552c
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
public class DBOpException extends IllegalStateException implements ExceptionWithContext {

public static final String CONSTRAINT_VIOLATION = "Constraint Violation";
private final ErrorContext context;

public DBOpException(String message) {
Expand Down Expand Up @@ -101,7 +102,7 @@ public static DBOpException forCause(String sql, SQLException e) {
case 1364:
case 1451:
case 1557:
context.related("Constraint Violation")
context.related(CONSTRAINT_VIOLATION)
.whatToDo("Report this, there is an SQL Constraint Violation.");
break;
// Custom rules based on reported errors
Expand Down Expand Up @@ -146,4 +147,10 @@ public static DBOpException forCause(String sql, SQLException e) {
public Optional<ErrorContext> getContext() {
return Optional.ofNullable(context);
}

public boolean isUserIdConstraintViolation() {
return context != null
&& context.getRelated().contains(DBOpException.CONSTRAINT_VIOLATION)
&& getMessage().contains("user_id");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.queries.objects.ServerQueries;
import com.djrapitops.plan.storage.database.queries.objects.UserIdentifierQueries;
import com.djrapitops.plan.utilities.logging.ErrorLogger;

import javax.inject.Inject;
import javax.inject.Singleton;
Expand All @@ -38,11 +39,13 @@ public class Identifiers {

protected final DBSystem dbSystem;
private final UUIDUtility uuidUtility;
private final ErrorLogger errorLogger;

@Inject
public Identifiers(DBSystem dbSystem, UUIDUtility uuidUtility) {
public Identifiers(DBSystem dbSystem, UUIDUtility uuidUtility, ErrorLogger errorLogger) {
this.dbSystem = dbSystem;
this.uuidUtility = uuidUtility;
this.errorLogger = errorLogger;
}

/**
Expand Down Expand Up @@ -105,6 +108,10 @@ public UUID getPlayerUUID(String name) {
return uuidUtility.getUUIDOf(name);
}

public Optional<Integer> getPlayerUserId(UUID playerUUID) {
return dbSystem.getDatabase().query(UserIdentifierQueries.fetchUserId(playerUUID));
}

public static Optional<Long> getTimestamp(Request request) {
try {
long currentTime = System.currentTimeMillis();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ public void prepare(PreparedStatement statement) throws SQLException {
* @param playerName Name of the player.
* @return Executable, use inside a {@link com.djrapitops.plan.storage.database.transactions.Transaction}
*/
public static Executable registerBaseUser(UUID playerUUID, long registered, String playerName) {
public static ExecStatement registerBaseUser(UUID playerUUID, long registered, String playerName) {
return new ExecStatement(UsersTable.INSERT_STATEMENT) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,23 @@ public Set<Integer> processResults(ResultSet set) throws SQLException {
}
};
}

public static Query<Optional<Integer>> fetchUserId(UUID playerUUID) {
String sql = Select.from(UsersTable.TABLE_NAME, UsersTable.ID).where(UsersTable.USER_UUID + "=?").toString();

return new QueryStatement<Optional<Integer>>(sql) {
@Override
public void prepare(PreparedStatement statement) throws SQLException {
statement.setString(1, playerUUID.toString());
}

@Override
public Optional<Integer> processResults(ResultSet set) throws SQLException {
if (set.next()) {
return Optional.of(set.getInt(UsersTable.ID));
}
return Optional.empty();
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.storage.database.transactions.events;

import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.gathering.domain.GeoInfo;
import com.djrapitops.plan.storage.database.queries.DataStoreQueries;
import com.djrapitops.plan.storage.database.transactions.Transaction;
Expand Down Expand Up @@ -72,6 +73,19 @@ private GeoInfo createGeoInfo() {
protected void performOperations() {
if (geoInfo == null) geoInfo = createGeoInfo();
if (geoInfo.getGeolocation() == null) return; // Don't save null geolocation.
try {
execute(DataStoreQueries.storeGeoInfo(playerUUID, geoInfo));
} catch (DBOpException failed) {
if (failed.isUserIdConstraintViolation()) {
retry();
} else {
throw failed;
}
}
}

private void retry() {
executeOther(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, playerUUID.toString()));
execute(DataStoreQueries.storeGeoInfo(playerUUID, geoInfo));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.djrapitops.plan.storage.database.transactions.events;

import com.djrapitops.plan.delivery.domain.DateObj;
import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.storage.database.queries.DataStoreQueries;
Expand Down Expand Up @@ -48,6 +49,19 @@ public PingStoreTransaction(UUID playerUUID, ServerUUID serverUUID, List<DateObj
@Override
protected void performOperations() {
Ping ping = calculateAggregatePing();
try {
execute(DataStoreQueries.storePing(playerUUID, serverUUID, ping));
} catch (DBOpException failed) {
if (failed.isUserIdConstraintViolation()) {
retry(ping);
} else {
throw failed;
}
}
}

private void retry(Ping ping) {
executeOther(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, playerUUID.toString()));
execute(DataStoreQueries.storePing(playerUUID, serverUUID, ping));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.djrapitops.plan.storage.database.queries.PlayerFetchQueries;
import com.djrapitops.plan.storage.database.transactions.Transaction;

import java.util.Optional;
import java.util.UUID;
import java.util.function.LongSupplier;

Expand All @@ -36,6 +37,8 @@ public class PlayerRegisterTransaction extends Transaction {
protected final LongSupplier registered;
private final String playerName;

private Integer userId;

public PlayerRegisterTransaction(UUID playerUUID, LongSupplier registered, String playerName) {
this.playerUUID = playerUUID;
this.registered = registered;
Expand All @@ -54,17 +57,23 @@ protected void performOperations() {
insertUser(registerDate);
SessionCache.getCachedSession(playerUUID).ifPresent(session -> session.setAsFirstSessionIfMatches(registerDate));
}
execute(DataStoreQueries.updatePlayerName(playerUUID, playerName));
if (!playerUUID.toString().equals(playerName)) {
execute(DataStoreQueries.updatePlayerName(playerUUID, playerName));
}
}

private void insertUser(long registerDate) {
try {
execute(DataStoreQueries.registerBaseUser(playerUUID, registerDate, playerName));
userId = executeReturningId(DataStoreQueries.registerBaseUser(playerUUID, registerDate, playerName));
} catch (DBOpException failed) {
boolean alreadySaved = failed.getMessage().contains("Duplicate entry");
if (!alreadySaved) {
throw failed;
}
}
}

public Optional<Integer> getUserId() {
return Optional.ofNullable(userId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.djrapitops.plan.storage.database.transactions.events;

import com.djrapitops.plan.exceptions.database.DBOpException;
import com.djrapitops.plan.gathering.domain.FinishedSession;
import com.djrapitops.plan.storage.database.queries.DataStoreQueries;
import com.djrapitops.plan.storage.database.transactions.Transaction;
Expand All @@ -41,6 +42,20 @@ public SessionEndTransaction(FinishedSession session) {

@Override
protected void performOperations() {
try {
execute(DataStoreQueries.storeSession(session));
} catch (DBOpException failed) {
if (failed.isUserIdConstraintViolation()) {
retry();
} else {
throw failed;
}
}
}

private void retry() {
UUID playerUUID = session.getPlayerUUID();
executeOther(new PlayerRegisterTransaction(playerUUID, System::currentTimeMillis, playerUUID.toString()));
execute(DataStoreQueries.storeSession(session));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*/
public class ErrorContext implements Serializable {

private final List<Object> related;
private final transient List<Object> related;
private String whatToDo;

private ErrorContext() {
Expand Down Expand Up @@ -55,6 +55,10 @@ public void merge(ErrorContext context) {
if (this.whatToDo == null && context.whatToDo != null) this.whatToDo = context.whatToDo;
}

public List<Object> getRelated() {
return related;
}

public static class Builder {
private final ErrorContext context;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,6 @@ private void actOnJoinEvent(ServerPlayerEntity player) {
Database database = dbSystem.getDatabase();
database.executeTransaction(new WorldNameStoreTransaction(serverUUID, world));

InetSocketAddress socketAddress = (InetSocketAddress) player.networkHandler.connection.getAddress();
InetAddress address = InetAddresses.forString(socketAddress.getAddress().toString().replace("/", ""));
Supplier<String> getHostName = () -> getHostname(player);

String playerName = player.getEntityName();
Expand All @@ -195,9 +193,7 @@ private void actOnJoinEvent(ServerPlayerEntity player) {
.thenRunAsync(() -> {
boolean gatheringGeolocations = config.isTrue(DataGatheringSettings.GEOLOCATIONS);
if (gatheringGeolocations) {
database.executeTransaction(
new GeoInfoStoreTransaction(playerUUID, address, time, geolocationCache::getCountry)
);
gatherGeolocation(player, playerUUID, time, database);
}

database.executeTransaction(new OperatorStatusTransaction(playerUUID, serverUUID, server.getPlayerManager().getOpList().isOp(player.getGameProfile())));
Expand All @@ -220,6 +216,15 @@ playerUUID, new Nickname(displayName, time, serverUUID),
});
}

private void gatherGeolocation(ServerPlayerEntity player, UUID playerUUID, long time, Database database) {
InetSocketAddress socketAddress = (InetSocketAddress) player.networkHandler.connection.getAddress();
if (socketAddress == null) return;
InetAddress address = InetAddresses.forString(socketAddress.getAddress().toString().replace("/", ""));
database.executeTransaction(
new GeoInfoStoreTransaction(playerUUID, address, time, geolocationCache::getCountry)
);
}

private String getHostname(ServerPlayerEntity player) {
return joinAddresses.get(player.getUuid());
}
Expand Down

0 comments on commit 6fa552c

Please sign in to comment.