Reworked database setup and added pagination

The database tables are now automatically created
The history lookup now uses a view for names (for simplicity and readability)
The all history lookup now uses a view combining all punishment history for efficiency
This commit is contained in:
2025-04-11 18:22:07 +02:00
parent 3c6141f7ad
commit 4b891dd672
13 changed files with 448 additions and 181 deletions
@@ -1,5 +1,8 @@
package com.alttd.altitudeweb;
import com.alttd.altitudeweb.setup.Connection;
import com.alttd.altitudeweb.setup.InitializeLiteBans;
import com.alttd.altitudeweb.setup.InitializeWebDb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -8,6 +11,7 @@ public class AltitudeWebApplication {
public static void main(String[] args) {
SpringApplication.run(AltitudeWebApplication.class, args);
Connection.initDatabases();
}
}
@@ -1,7 +1,7 @@
package com.alttd.altitudeweb.controllers.history;
import com.alttd.altitudeweb.api.HistoryApi;
import com.alttd.altitudeweb.database.Connection;
import com.alttd.altitudeweb.setup.Connection;
import com.alttd.altitudeweb.database.Databases;
import com.alttd.altitudeweb.database.litebans.*;
import com.alttd.altitudeweb.model.PunishmentHistoryDto;
@@ -19,71 +19,52 @@ import java.util.concurrent.CompletableFuture;
public class HistoryApiController implements HistoryApi {
@Override
public ResponseEntity<PunishmentHistoryDto> getHistoryForUsers(String userType, String type, String user) throws Exception {
UserType userTypeEnum = UserType.getUserType(userType);
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto();
CompletableFuture<List<HistoryRecord>> historyRecords = new CompletableFuture<>();
Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(NameHistoryMapper.class))
.thenApply(connection -> {
connection.runQuery(sqlSession -> {
log.debug("Loading user names for type {}", type);
List<HistoryRecord> temp = sqlSession.getMapper(NameHistoryMapper.class)
.getRecent(historyTypeEnum, userTypeEnum, user);
historyRecords.complete(temp);
});
return connection;
});
historyRecords.join().forEach(historyRecord -> {
PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto()
.uuid(historyRecord.getUuid())
.username(historyRecord.getPunishedName())
.reason(historyRecord.getReason())
.punishmentUserUuid(historyRecord.getBannedByUuid())
.punishmentUser(historyRecord.getBannedByName())
.removedBy(historyRecord.getRemovedByName())
.punishmentTime(historyRecord.getTime())
.expiryTime(historyRecord.getUntil())
.removedReason(historyRecord.getRemovedByReason())
.type(historyRecord.getType());
punishmentHistory.add(innerDto);
});
return ResponseEntity.ok().body(punishmentHistory);
public ResponseEntity<PunishmentHistoryDto> getHistoryForAll(String userType, String type, Integer page) {
return getHistoryForUsers(userType, type, "", page);
}
@Override
public ResponseEntity<PunishmentHistoryDto> getHistoryForUuid(String userType, String type, String uuid) throws Exception {
public ResponseEntity<PunishmentHistoryDto> getHistoryForUsers(String userType, String type, String user, Integer page) {
UserType userTypeEnum = UserType.getUserType(userType);
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto();
CompletableFuture<List<HistoryRecord>> historyRecords = new CompletableFuture<>();
Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(UUIDHistoryMapper.class))
.thenApply(connection -> {
connection.runQuery(sqlSession -> {
log.debug("Loading user names for type {}", type);
List<HistoryRecord> temp = sqlSession.getMapper(UUIDHistoryMapper.class)
.getRecent(historyTypeEnum, userTypeEnum, UUID.fromString(uuid));
historyRecords.complete(temp);
});
return connection;
});
historyRecords.join().forEach(historyRecord -> {
PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto()
.uuid(historyRecord.getUuid())
.username(historyRecord.getPunishedName())
.reason(historyRecord.getReason())
.punishmentUserUuid(historyRecord.getBannedByUuid())
.punishmentUser(historyRecord.getBannedByName())
.removedBy(historyRecord.getRemovedByName())
.punishmentTime(historyRecord.getTime())
.expiryTime(historyRecord.getUntil())
.removedReason(historyRecord.getRemovedByReason())
.type(historyRecord.getType());
punishmentHistory.add(innerDto);
});
return ResponseEntity.ok().body(punishmentHistory);
Connection.getConnection(Databases.LITE_BANS)
.runQuery(sqlSession -> {
log.debug("Loading history through name for type {}", type);
try {
List<HistoryRecord> temp = sqlSession.getMapper(NameHistoryMapper.class)
.getRecent(historyTypeEnum, userTypeEnum, user, page);
historyRecords.complete(temp);
} catch (Exception e) {
log.error("Failed to load history through name for type {}", type, e);
historyRecords.completeExceptionally(e);
}
});
return mapPunishmentHistory(punishmentHistory, historyRecords);
}
@Override
public ResponseEntity<PunishmentHistoryDto> getHistoryForUuid(String userType, String type, String uuid, Integer page) {
UserType userTypeEnum = UserType.getUserType(userType);
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
PunishmentHistoryDto punishmentHistory = new PunishmentHistoryDto();
CompletableFuture<List<HistoryRecord>> historyRecords = new CompletableFuture<>();
Connection.getConnection(Databases.LITE_BANS)
.runQuery(sqlSession -> {
log.debug("Loading history through uuid for type {}", type);
try {
List<HistoryRecord> temp = sqlSession.getMapper(UUIDHistoryMapper.class)
.getRecent(historyTypeEnum, userTypeEnum, UUID.fromString(uuid), page);
historyRecords.complete(temp);
} catch (Exception e) {
log.error("Failed to load history through uuid for type {}", type, e);
historyRecords.completeExceptionally(e);
}
});
return mapPunishmentHistory(punishmentHistory, historyRecords);
}
@Override
@@ -91,16 +72,37 @@ public class HistoryApiController implements HistoryApi {
UserType userTypeEnum = UserType.getUserType(userType);
HistoryType historyTypeEnum = HistoryType.getHistoryType(type);
CompletableFuture<List<String>> playerGroupFuture = new CompletableFuture<>();
Connection.getConnection(Databases.LITE_BANS, configuration -> configuration.addMapper(RecentNamesMapper.class))
.thenApply(connection -> {
connection.runQuery(sqlSession -> {
log.debug("Loading user names for type {}", type);
Connection.getConnection(Databases.LITE_BANS)
.runQuery(sqlSession -> {
log.debug("Loading user names for type {}", type);
try {
List<String> temp = sqlSession.getMapper(RecentNamesMapper.class)
.getRecent(historyTypeEnum, userTypeEnum);
playerGroupFuture.complete(temp);
});
return connection;
} catch (Exception e) {
log.error("Failed to load user names for type {}", type, e);
playerGroupFuture.completeExceptionally(e);
}
});
return ResponseEntity.ok().body(playerGroupFuture.join());
}
private ResponseEntity<PunishmentHistoryDto> mapPunishmentHistory(PunishmentHistoryDto punishmentHistory, CompletableFuture<List<HistoryRecord>> historyRecords) {
historyRecords.join().forEach(historyRecord -> {
PunishmentHistoryInnerDto innerDto = new PunishmentHistoryInnerDto()
.uuid(historyRecord.getUuid())
.username(historyRecord.getPunishedName())
.reason(historyRecord.getReason())
.punishmentUserUuid(historyRecord.getBannedByUuid())
.punishmentUser(historyRecord.getBannedByName())
.removedBy(historyRecord.getRemovedByName())
.punishmentTime(historyRecord.getTime())
.expiryTime(historyRecord.getUntil())
.removedReason(historyRecord.getRemovedByReason())
.type(historyRecord.getType());
punishmentHistory.add(innerDto);
});
return ResponseEntity.ok().body(punishmentHistory);
}
}
@@ -1,7 +1,7 @@
package com.alttd.altitudeweb.controllers.team;
import com.alttd.altitudeweb.api.TeamApi;
import com.alttd.altitudeweb.database.Connection;
import com.alttd.altitudeweb.setup.Connection;
import com.alttd.altitudeweb.database.Databases;
import com.alttd.altitudeweb.database.luckperms.Player;
import com.alttd.altitudeweb.database.luckperms.TeamMemberMapper;
@@ -22,14 +22,16 @@ public class TeamApiController implements TeamApi {
public ResponseEntity<TeamMembersDto> getTeamMembers(String group) {
TeamMembersDto teamMemberDtos = new TeamMembersDto();
CompletableFuture<List<Player>> playerGroupFuture = new CompletableFuture<>();
Connection.getConnection(Databases.LUCK_PERMS, configuration -> configuration.addMapper(TeamMemberMapper.class))
.thenApply(connection -> {
connection.runQuery(sqlSession -> {
log.debug("Loading team members for group {}", group);
Connection.getConnection(Databases.LUCK_PERMS)
.runQuery(sqlSession -> {
log.debug("Loading team members for group {}", group);
try {
List<Player> players = sqlSession.getMapper(TeamMemberMapper.class).getTeamMembers("group." + group);
playerGroupFuture.complete(players);
});
return connection;
} catch (Exception e) {
log.error("Failed to load team members for group {}", group, e);
playerGroupFuture.completeExceptionally(e);
}
});
List<Player> join = playerGroupFuture.join();
join.forEach(player -> teamMemberDtos.add(new PlayerDto(player.username(), player.uuid().toString())));