diff --git a/.gitignore b/.gitignore index c2065bc..329367c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,150 @@ -HELP.md -.gradle -build/ -!gradle/wrapper/gradle-wrapper.jar -!**/src/main/**/build/ -!**/src/test/**/build/ +### macOS +# General +.DS_Store +.AppleDouble +.LSOverride -### STS ### -.apt_generated -.classpath -.factorypath -.project -.settings -.springBeans -.sts4-cache -bin/ -!**/src/main/**/bin/ -!**/src/test/**/bin/ +# Thumbnails +._* -### IntelliJ IDEA ### +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# Metadata left by Dolphin file manager, which comes with KDE Plasma +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +# Log files created by default by the nohup command +nohup.out + +### Windows + +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +### JetBrains IDE +# Covers JetBrains IDEs: IntelliJ, GoLand, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff .idea -*.iws + +# Gradle and Maven with auto-import *.iml *.ipr + +# File-based project format +*.iws + +# IntelliJ out/ -!**/src/main/**/out/ -!**/src/test/**/out/ -### NetBeans ### -/nbproject/private/ -/nbbuild/ -/dist/ -/nbdist/ -/.nb-gradle/ +# JIRA plugin +atlassian-ide-plugin.xml -### VS Code ### -.vscode/ +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based HTTP Client +http-client.private.env.json + +### Server +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar +*.jar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* + +# Config +config/*.yml +config/*.yaml +config/*.properties + +# Tests +test/ + +### Gradle +.gradle +**/build/ +!**/src/**/build/ + +!gradle/ +!gradle/wrapper +!gradle/wrapper/gradle-wrapper.jar +!gradle/wrapper/gradle-wrapper.properties +gradle-app.setting +.gradletasknamecache + +# Eclipse Gradle plugin generated files +# Eclipse Core +.project +# JDT-specific (Eclipse Java Development Tools) +.classpath diff --git a/build.gradle.kts b/build.gradle.kts index 17ddcac..90f0258 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -48,13 +48,14 @@ dependencies { implementation(libs.spring.boot.starter.jpa) implementation(libs.mybatis.starter.core) implementation(libs.flyway.core) - implementation(libs.flyway.postgresql) + implementation(libs.flyway.mysql) implementation(libs.jackson.jsr310) testImplementation(libs.spring.boot.starter.test) testImplementation(libs.reactor.test) testImplementation(libs.spring.security.test) testImplementation(libs.mybatis.starter.test) - runtimeOnly(libs.postgres.driver) + // runtimeOnly(libs.postgres.driver) + runtimeOnly(libs.mysql.driver) testRuntimeOnly(libs.h2.database) testRuntimeOnly(libs.junit.launcher) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index db80386..b0429e9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,10 +41,12 @@ mybatis-starter-core = { group = "org.mybatis.spring.boot", name = "mybatis-spri spring-boot-starter-jpa = { group = "org.springframework.boot", name = "spring-boot-starter-data-jpa" } hypersistence-core = { group = "io.hypersistence", name = "hypersistence-utils-hibernate-63", version.ref = "hypersistenceVersion" } postgres-driver = { group = "org.postgresql", name = "postgresql", version.ref = "postgresDriverVersion" } +mysql-driver = { group = "com.mysql", name = "mysql-connector-j" } h2-database = { group = "com.h2database", name = "h2", version.ref = "h2Version" } spring-boot-starter-redis = { group = "org.springframework.boot", name = "spring-boot-starter-data-redis", version.ref = "springBootVersion" } flyway-core = { group = "org.flywaydb", name = "flyway-core" } flyway-postgresql = { group = "org.flywaydb", name = "flyway-database-postgresql" } +flyway-mysql = { group = "org.flywaydb", name = "flyway-mysql" } # Spring Boot Core & Web spring-boot-starter-web = { group = "org.springframework.boot", name = "spring-boot-starter-web" } diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java new file mode 100644 index 0000000..478cc66 --- /dev/null +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Firearm.java @@ -0,0 +1,96 @@ +package com.onixbyte.deltaforceguide.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "firearm") +public class Firearm { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, length = 64) + private String name; + + @Column(name = "type", nullable = false) + private Integer type; + + @Column(name = "level", nullable = false) + private Integer level; + + @Column(name = "review", columnDefinition = "TEXT") + private String review; + + @OneToMany(mappedBy = "firearm", cascade = CascadeType.ALL, orphanRemoval = true) + private List modifications = new ArrayList<>(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + + public Integer getLevel() { + return level; + } + + public void setLevel(Integer level) { + this.level = level; + } + + public String getReview() { + return review; + } + + public void setReview(String review) { + this.review = review; + } + + public List getModifications() { + return modifications; + } + + public void setModifications(List modifications) { + this.modifications = modifications; + } + + public void addModification(Modification modification) { + this.modifications.add(modification); + modification.setFirearm(this); + } + + public void removeModification(Modification modification) { + this.modifications.remove(modification); + modification.setFirearm(null); + } +} + diff --git a/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java new file mode 100644 index 0000000..6f29bd5 --- /dev/null +++ b/src/main/java/com/onixbyte/deltaforceguide/domain/entity/Modification.java @@ -0,0 +1,120 @@ +package com.onixbyte.deltaforceguide.domain.entity; + +import io.hypersistence.utils.hibernate.type.json.JsonType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.ForeignKey; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Index; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import org.hibernate.annotations.Type; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table( + name = "modification", + indexes = { + @Index(name = "idx_modification_firearm_id", columnList = "firearm_id") + } +) +public class Modification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "firearm_id", nullable = false, foreignKey = @ForeignKey(name = "fk_modification_firearm")) + private Firearm firearm; + + @Column(name = "name", nullable = false, length = 64) + private String name; + + @Column(name = "code", nullable = false, length = 64) + private String code; + + @Type(JsonType.class) + @Column(name = "tags", columnDefinition = "json") + private List tags = new ArrayList<>(); + + @Column(name = "note", columnDefinition = "TEXT") + private String note; + + @Column(name = "author", length = 64) + private String author; + + @Column(name = "video_url", length = 512) + private String videoUrl; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Firearm getFirearm() { + return firearm; + } + + public void setFirearm(Firearm firearm) { + this.firearm = firearm; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getNote() { + return note; + } + + public void setNote(String note) { + this.note = note; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getVideoUrl() { + return videoUrl; + } + + public void setVideoUrl(String videoUrl) { + this.videoUrl = videoUrl; + } +} + diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 4ca676b..65b087c 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,3 +1,46 @@ spring: application: - name: delta-force-guide-server + name: delta-force-guide + cache: + type: redis + redis: + time-to-live: PT2H + data: + redis: + repositories: + # Disable redis repositories + enabled: false + jta: + # Disable JTA support + enabled: false + jpa: + properties: + hibernate: + transaction: + jta: + # No need to use distributed transaction manager for 1 datasource. + platform: org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform + hibernate: + ddl-auto: none + open-in-view: false + datasource: + hikari: + minimum-idle: 1 + maximum-pool-size: 10 + flyway: + enabled: true + baseline-on-migrate: true + +mybatis: + configuration: + log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl + map-underscore-to-camel-case: true + type-aliases-package: com.onixbyte.deltaforceguide.domain.entity + type-handlers-package: com.onixbyte.deltaforceguide.mapper.handler + mapper-locations: classpath:/mapper/*.xml + +logging: + level: + org.hibernate: + orm.connections.pooling: off + diff --git a/src/main/resources/db/migration/V2__init.sql b/src/main/resources/db/migration/V2__init.sql new file mode 100644 index 0000000..332f98e --- /dev/null +++ b/src/main/resources/db/migration/V2__init.sql @@ -0,0 +1,34 @@ +DROP TABLE IF EXISTS firearm CASCADE; +DROP TABLE IF EXISTS modification CASCADE; + + +CREATE TABLE IF NOT EXISTS firearm +( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(64) NOT NULL, + type INT NOT NULL, + level INT NOT NULL, + review TEXT NULL +); + + +CREATE TABLE IF NOT EXISTS modification +( + id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, + firearm_id BIGINT NOT NULL, + name VARCHAR(64) NOT NULL, + code VARCHAR(64) NOT NULL, + tags JSON NULL, + note TEXT NULL, + author VARCHAR(64) NULL, + video_url VARCHAR(512) NULL, + CONSTRAINT fk_modification_firearm + FOREIGN KEY (firearm_id) + REFERENCES firearm (id) + ON DELETE CASCADE + ON UPDATE RESTRICT +); + +CREATE INDEX idx_modification_firearm_id ON modification (firearm_id); + +