From d5daa8458b8deea30f33725b7e860450ae59f7f4 Mon Sep 17 00:00:00 2001 From: Teriuihi Date: Thu, 10 Apr 2025 01:22:19 +0200 Subject: [PATCH] Refactor database structure and improve player handling. Reorganized database-related code into a dedicated module, added mappings for UUID handling, and updated SQL queries for clarity. Enhanced team members API to use player data directly, ensuring consistency and better handling of UUIDs. Introduced new database table for connection settings and adjusted Gradle configurations for modularization. --- .gitignore | 2 + backend/build.gradle.kts | 53 +++++++++++++++++-- .../controllers/TeamApiController.java | 23 +++++++- .../database/luckperms/PlayerGroup.java | 3 -- .../database/luckperms/TeamMemberMapper.java | 14 ----- database/build.gradle.kts | 23 ++++++++ .../main/java/com/alttd/altitudeweb/Main.java | 6 +++ .../altitudeweb/database/Connection.java | 4 +- .../alttd/altitudeweb/database/Databases.java | 0 .../database/luckperms/Player.java | 7 +++ .../database/luckperms/TeamMemberMapper.java | 21 ++++++++ .../database/web_db/DatabaseSettings.java | 0 .../database/web_db/SettingsMapper.java | 2 +- .../type_handler/UUIDTypeHandler.java | 38 +++++++++++++ .../resources/create-db-settings-table.sql | 10 ++++ open_api/src/main/resources/api.yml | 20 +++---- settings.gradle.kts | 2 +- 17 files changed, 191 insertions(+), 37 deletions(-) delete mode 100644 backend/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerGroup.java delete mode 100644 backend/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java create mode 100644 database/build.gradle.kts create mode 100644 database/src/main/java/com/alttd/altitudeweb/Main.java rename {backend => database}/src/main/java/com/alttd/altitudeweb/database/Connection.java (97%) rename {backend => database}/src/main/java/com/alttd/altitudeweb/database/Databases.java (100%) create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/luckperms/Player.java create mode 100644 database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java rename {backend => database}/src/main/java/com/alttd/altitudeweb/database/web_db/DatabaseSettings.java (100%) rename {backend => database}/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java (61%) create mode 100644 database/src/main/java/com/alttd/altitudeweb/type_handler/UUIDTypeHandler.java create mode 100644 database/src/main/resources/create-db-settings-table.sql diff --git a/.gitignore b/.gitignore index 143f0c2..4698adc 100644 --- a/.gitignore +++ b/.gitignore @@ -88,3 +88,5 @@ package-lock.json ### MINE ### frontend/src/api generated + +liquibase*.properties diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 5052774..8a10646 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -2,6 +2,7 @@ plugins { java id("org.springframework.boot") version "3.4.4" id("io.spring.dependency-management") version "1.1.7" +// id("com.github.johnrengelman.shadow") version "8.1.1" } group = "com.alttd.altitudeweb" @@ -25,16 +26,62 @@ repositories { dependencies { implementation(project(":open_api")) + implementation(project(":database")) implementation("org.springframework.boot:spring-boot-starter-web") - compileOnly("org.projectlombok:lombok") - runtimeOnly("org.mariadb.jdbc:mariadb-java-client") annotationProcessor("org.projectlombok:lombok") testImplementation("org.springframework.boot:spring-boot-starter-test") - testRuntimeOnly("org.junit.platform:junit-platform-launcher") + implementation("com.mysql:mysql-connector-j:8.0.32") implementation("org.mybatis:mybatis:3.5.13") + testRuntimeOnly("org.junit.platform:junit-platform-launcher") implementation("org.springframework.boot:spring-boot-configuration-processor") } tasks.withType { useJUnitPlatform() } + +tasks.bootJar { + mainClass.set("com.alttd.altitudeweb.AltitudeWebApplication") + archiveBaseName.set("altitudeweb") + archiveClassifier.set("") +} + + +//tasks.withType { +// mergeServiceFiles() +// dependencies { +// include(dependency("com.mysql:mysql-connector-j")) +// } +//} + +//tasks.withType { +// manifest { +// attributes["Main-Class"] = "com.alttd.altitudeweb.AltitudeWebApplication" +// } +// archiveBaseName.set("altitudeweb") +// archiveClassifier.set("") +// mergeServiceFiles() +// +// // Include everything +// from(sourceSets.main.get().output) +// +// // Include all project dependencies +// configurations = listOf(project.configurations.runtimeClasspath.get()) +// +// // Ensure MySQL is included (even though it should be part of runtimeClasspath already) +// dependencies { +// include(dependency("com.mysql:mysql-connector-j")) +// } +// +// // Enable zip64 mode for large JARs +// isZip64 = true +//} +// +//// Make the shadowJar task the default jar task +//tasks.named("jar") { +// enabled = false +//} +// +//tasks.named("assemble") { +// dependsOn("shadowJar") +//} diff --git a/backend/src/main/java/com/alttd/altitudeweb/controllers/TeamApiController.java b/backend/src/main/java/com/alttd/altitudeweb/controllers/TeamApiController.java index 718ddfe..c7cb218 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/controllers/TeamApiController.java +++ b/backend/src/main/java/com/alttd/altitudeweb/controllers/TeamApiController.java @@ -1,18 +1,39 @@ package com.alttd.altitudeweb.controllers; import com.alttd.altitudeweb.api.TeamApi; +import com.alttd.altitudeweb.database.Connection; +import com.alttd.altitudeweb.database.Databases; +import com.alttd.altitudeweb.database.luckperms.Player; +import com.alttd.altitudeweb.database.luckperms.TeamMemberMapper; +import com.alttd.altitudeweb.model.PlayerDto; import com.alttd.altitudeweb.model.TeamMemberDto; import com.alttd.altitudeweb.model.TeamMembersDto; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Slf4j @RestController public class TeamApiController implements TeamApi { @Override public ResponseEntity getTeamMembers(String group) { TeamMembersDto teamMemberDtos = new TeamMembersDto(); - teamMemberDtos.add(new TeamMemberDto("test", "good")); + CompletableFuture> playerGroupFuture = new CompletableFuture<>(); + Connection.getConnection(Databases.LUCK_PERMS, configuration -> configuration.addMapper(TeamMemberMapper.class)) + .thenApply(connection -> { + connection.runQuery(sqlSession -> { + log.info("Loading team members for group {}", group); + List players = sqlSession.getMapper(TeamMemberMapper.class).getTeamMembers("group." + group); + playerGroupFuture.complete(players); + }); + return connection; + }); + List join = playerGroupFuture.join(); + join.forEach(player -> teamMemberDtos.add(new PlayerDto(player.username(), player.uuid().toString()))); return ResponseEntity.ok().body(teamMemberDtos); } } diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerGroup.java b/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerGroup.java deleted file mode 100644 index ae9d30e..0000000 --- a/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/PlayerGroup.java +++ /dev/null @@ -1,3 +0,0 @@ -package com.alttd.altitudeweb.database.luckperms; - -public record PlayerGroup(String username, String groupName) {} diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java b/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java deleted file mode 100644 index 67adaaa..0000000 --- a/backend/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.alttd.altitudeweb.database.luckperms; - -import org.apache.ibatis.annotations.Select; - -import java.util.List; - -public interface TeamMemberMapper { - @Select(""" - SELECT players.username, #{groupName} AS group_name - FROM luckperms_user_permissions AS permissions - INNER JOIN luckperms_players AS players ON players.uuid = permissions.uuid - WHERE permission = 'group.'#{groupName}""") - List getTeamMembers(String groupName); -} diff --git a/database/build.gradle.kts b/database/build.gradle.kts new file mode 100644 index 0000000..34cf887 --- /dev/null +++ b/database/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("java") +} + +group = "com.alttd.altitudeweb" +version = "0.0.1-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + implementation(project(":open_api")) + compileOnly("org.projectlombok:lombok:1.18.38") + annotationProcessor("org.projectlombok:lombok:1.18.38") + implementation("org.mybatis:mybatis:3.5.13") + compileOnly("org.slf4j:slf4j-api:2.0.17") + compileOnly("org.slf4j:slf4j-simple:2.0.17") +} + +tasks.test { + useJUnitPlatform() +} diff --git a/database/src/main/java/com/alttd/altitudeweb/Main.java b/database/src/main/java/com/alttd/altitudeweb/Main.java new file mode 100644 index 0000000..cf6f067 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/Main.java @@ -0,0 +1,6 @@ +package com.alttd.altitudeweb; + +public class Main { + public static void main(String[] args) { + } +} diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/Connection.java b/database/src/main/java/com/alttd/altitudeweb/database/Connection.java similarity index 97% rename from backend/src/main/java/com/alttd/altitudeweb/database/Connection.java rename to database/src/main/java/com/alttd/altitudeweb/database/Connection.java index 9551545..08dc74a 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/database/Connection.java +++ b/database/src/main/java/com/alttd/altitudeweb/database/Connection.java @@ -41,7 +41,7 @@ public class Connection { return loadDefaultDatabase(addMappers); } CompletableFuture settingsFuture = new CompletableFuture<>(); - getConnection(Databases.DEFAULT, (mapper -> mapper.addMapper(DatabaseSettings.class))).thenApply(connection -> { + getConnection(Databases.DEFAULT, (mapper -> mapper.addMapper(SettingsMapper.class))).thenApply(connection -> { connection.runQuery(session -> { DatabaseSettings loadedSettings = session.getMapper(SettingsMapper.class).getSettings(database.getInternalName()); settingsFuture.complete(loadedSettings); @@ -76,7 +76,7 @@ public class Connection { try (SqlSession session = sqlSessionFactory.openSession()) { consumer.accept(session); } catch (Exception e) { - log.error("Failed to run discord query", e); + log.error("Failed to run query", e); } }).start(); } diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/Databases.java b/database/src/main/java/com/alttd/altitudeweb/database/Databases.java similarity index 100% rename from backend/src/main/java/com/alttd/altitudeweb/database/Databases.java rename to database/src/main/java/com/alttd/altitudeweb/database/Databases.java diff --git a/database/src/main/java/com/alttd/altitudeweb/database/luckperms/Player.java b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/Player.java new file mode 100644 index 0000000..0476ad4 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/Player.java @@ -0,0 +1,7 @@ +package com.alttd.altitudeweb.database.luckperms; + +import java.util.UUID; + +public record Player(String username, UUID uuid) { + +} diff --git a/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java new file mode 100644 index 0000000..242a970 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/database/luckperms/TeamMemberMapper.java @@ -0,0 +1,21 @@ +package com.alttd.altitudeweb.database.luckperms; + +import com.alttd.altitudeweb.type_handler.UUIDTypeHandler; +import org.apache.ibatis.annotations.*; + +import java.util.List; +import java.util.UUID; + +public interface TeamMemberMapper { + @ConstructorArgs({ + @Arg(column = "username", javaType = String.class), + @Arg(column = "uuid", javaType = UUID.class, typeHandler = UUIDTypeHandler.class) + }) + @Select(""" + SELECT players.username, players.uuid + FROM luckperms_user_permissions AS permissions + INNER JOIN luckperms_players AS players ON players.uuid = permissions.uuid + WHERE permission = #{groupPermission} + """) + List getTeamMembers(@Param("groupPermission") String groupPermission); +} diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/web_db/DatabaseSettings.java b/database/src/main/java/com/alttd/altitudeweb/database/web_db/DatabaseSettings.java similarity index 100% rename from backend/src/main/java/com/alttd/altitudeweb/database/web_db/DatabaseSettings.java rename to database/src/main/java/com/alttd/altitudeweb/database/web_db/DatabaseSettings.java diff --git a/backend/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java b/database/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java similarity index 61% rename from backend/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java rename to database/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java index 0aef6f1..454e0de 100644 --- a/backend/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java +++ b/database/src/main/java/com/alttd/altitudeweb/database/web_db/SettingsMapper.java @@ -3,6 +3,6 @@ package com.alttd.altitudeweb.database.web_db; import org.apache.ibatis.annotations.Select; public interface SettingsMapper { - @Select("SELECT * FROM database_settings WHERE name = #{database}") + @Select("SELECT host, port, name, username, password FROM db_connection_settings WHERE name = #{database}") DatabaseSettings getSettings(String database); } diff --git a/database/src/main/java/com/alttd/altitudeweb/type_handler/UUIDTypeHandler.java b/database/src/main/java/com/alttd/altitudeweb/type_handler/UUIDTypeHandler.java new file mode 100644 index 0000000..3a423d5 --- /dev/null +++ b/database/src/main/java/com/alttd/altitudeweb/type_handler/UUIDTypeHandler.java @@ -0,0 +1,38 @@ +package com.alttd.altitudeweb.type_handler; + +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.MappedTypes; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; + +@MappedTypes(UUID.class) +public class UUIDTypeHandler extends BaseTypeHandler { + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, parameter.toString()); + } + + @Override + public UUID getNullableResult(ResultSet rs, String columnName) throws SQLException { + String uuid = rs.getString(columnName); + return uuid == null ? null : UUID.fromString(uuid); + } + + @Override + public UUID getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + String uuid = rs.getString(columnIndex); + return uuid == null ? null : UUID.fromString(uuid); + } + + @Override + public UUID getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + String uuid = cs.getString(columnIndex); + return uuid == null ? null : UUID.fromString(uuid); + } +} diff --git a/database/src/main/resources/create-db-settings-table.sql b/database/src/main/resources/create-db-settings-table.sql new file mode 100644 index 0000000..8195a75 --- /dev/null +++ b/database/src/main/resources/create-db-settings-table.sql @@ -0,0 +1,10 @@ +CREATE TABLE db_connection_settings +( + internal_name VARCHAR(255) NOT NULL, + name VARCHAR(255) NOT NULL, + username VARCHAR(255) NOT NULL, + password VARCHAR(255) NOT NULL, + host VARCHAR(255) NOT NULL, + port INT NOT NULL, + CONSTRAINT pk_internal_name PRIMARY KEY (internal_name) +); diff --git a/open_api/src/main/resources/api.yml b/open_api/src/main/resources/api.yml index 5a74d18..e9ea756 100644 --- a/open_api/src/main/resources/api.yml +++ b/open_api/src/main/resources/api.yml @@ -65,12 +65,6 @@ paths: $ref: "#/components/schemas/Error" components: schemas: - Player: - type: object - properties: - uuid: - type: string - example: 0c35e520-927e-4c6a-87ad-ff0739c22e9d PlayerHistory: type: object properties: @@ -89,19 +83,21 @@ components: TeamMembers: type: array items: - $ref: '#/components/schemas/TeamMember' - TeamMember: + $ref: '#/components/schemas/Player' + Player: type: object properties: name: type: string - description: The name of the team member - group: + description: The name of the player + example: a_name + uuid: type: string - description: The group to which the team member belongs + example: 0c35e520-927e-4c6a-87ad-ff0739c22e9d + description: The uuid of the team player required: - name - - group + - uuid Error: type: object properties: diff --git a/settings.gradle.kts b/settings.gradle.kts index 482e96b..b924f34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1,2 @@ rootProject.name = "AltitudeWeb" -include("open_api", "backend", "frontend") +include("open_api", "backend", "frontend", "database")