CharacterSaver integration test with Testcontainers
This commit is contained in:
@@ -165,8 +165,7 @@ server:
|
|||||||
DB_PASS: ""
|
DB_PASS: ""
|
||||||
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
INIT_CONNECTION_POOL_TIMEOUT: 90 # Seconds
|
||||||
|
|
||||||
PG_DB_NAME: "cosmic"
|
PG_DB_URL: "jdbc:postgresql://localhost:5432/cosmic"
|
||||||
PG_DB_HOST: "localhost"
|
|
||||||
PG_DB_SCHEMA: "cosmic"
|
PG_DB_SCHEMA: "cosmic"
|
||||||
PG_DB_ADMIN_USERNAME: "cosmic_admin"
|
PG_DB_ADMIN_USERNAME: "cosmic_admin"
|
||||||
PG_DB_ADMIN_PASSWORD: "redsnailshell"
|
PG_DB_ADMIN_PASSWORD: "redsnailshell"
|
||||||
|
|||||||
20
pom.xml
20
pom.xml
@@ -69,6 +69,7 @@
|
|||||||
<jdbi-version>3.45.1</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
<jdbi-version>3.45.1</jdbi-version> <!-- Convenience wrapper around JDBC -->
|
||||||
<junit.version>5.10.2</junit.version> <!-- Unit test -->
|
<junit.version>5.10.2</junit.version> <!-- Unit test -->
|
||||||
<mockito.version>5.11.0</mockito.version> <!-- Unit test -->
|
<mockito.version>5.11.0</mockito.version> <!-- Unit test -->
|
||||||
|
<testcontainers.version>1.20.1</testcontainers.version> <!-- Docker test with real temporary database -->
|
||||||
<postgresql.version>42.5.4</postgresql.version> <!-- PostgreSQL JDBC driver -->
|
<postgresql.version>42.5.4</postgresql.version> <!-- PostgreSQL JDBC driver -->
|
||||||
<flyway.version>9.15.1</flyway.version> <!-- Database migration -->
|
<flyway.version>9.15.1</flyway.version> <!-- Database migration -->
|
||||||
<caffeine.version>3.1.4</caffeine.version> <!-- Caching -->
|
<caffeine.version>3.1.4</caffeine.version> <!-- Caching -->
|
||||||
@@ -213,6 +214,25 @@
|
|||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>mysql</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.testcontainers</groupId>
|
||||||
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
<version>${testcontainers.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import lombok.Builder;
|
|||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public record CharacterStats(
|
public record CharacterStats(
|
||||||
|
int account,
|
||||||
|
int world,
|
||||||
|
String name,
|
||||||
int id,
|
int id,
|
||||||
int level,
|
int level,
|
||||||
int fame,
|
int fame,
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ public class ServerConfig {
|
|||||||
public int INIT_CONNECTION_POOL_TIMEOUT;
|
public int INIT_CONNECTION_POOL_TIMEOUT;
|
||||||
|
|
||||||
// PostgreSQL database configuration
|
// PostgreSQL database configuration
|
||||||
public String PG_DB_NAME;
|
public String PG_DB_URL;
|
||||||
public String PG_DB_HOST;
|
|
||||||
public String PG_DB_SCHEMA;
|
public String PG_DB_SCHEMA;
|
||||||
public String PG_DB_ADMIN_USERNAME;
|
public String PG_DB_ADMIN_USERNAME;
|
||||||
public String PG_DB_ADMIN_PASSWORD;
|
public String PG_DB_ADMIN_PASSWORD;
|
||||||
|
|||||||
@@ -6,15 +6,15 @@ import java.time.Duration;
|
|||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
public record PgDatabaseConfig(
|
public record PgDatabaseConfig(
|
||||||
String databaseName, String host, String schema,
|
String url,
|
||||||
|
String schema,
|
||||||
String adminUsername, String adminPassword,
|
String adminUsername, String adminPassword,
|
||||||
String username, String password,
|
String username, String password,
|
||||||
Duration poolInitTimeout,
|
Duration poolInitTimeout,
|
||||||
boolean clean
|
boolean clean
|
||||||
) {
|
) {
|
||||||
public PgDatabaseConfig {
|
public PgDatabaseConfig {
|
||||||
verifyNotBlank(databaseName);
|
verifyNotBlank(url);
|
||||||
verifyNotBlank(host);
|
|
||||||
verifyNotBlank(schema);
|
verifyNotBlank(schema);
|
||||||
verifyNotBlank(adminUsername);
|
verifyNotBlank(adminUsername);
|
||||||
verifyNotBlank(adminPassword);
|
verifyNotBlank(adminPassword);
|
||||||
@@ -27,8 +27,4 @@ public record PgDatabaseConfig(
|
|||||||
throw new IllegalArgumentException("Missing or blank value in PG database config");
|
throw new IllegalArgumentException("Missing or blank value in PG database config");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getJdbcUrl() {
|
|
||||||
return "jdbc:postgresql://%s:5432/%s".formatted(host, databaseName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,54 @@ import java.sql.Timestamp;
|
|||||||
|
|
||||||
public class CharacterRepository {
|
public class CharacterRepository {
|
||||||
|
|
||||||
|
public int insert(Handle handle, CharacterStats stats) {
|
||||||
|
String sql = """
|
||||||
|
INSERT INTO chr (account, world, name, level, exp, str, dex, "int", luk, hp, mp, max_hp, max_mp, ap, sp,
|
||||||
|
job, fame, gender, skin, hair, face, meso, map_id, spawn_portal, gacha_exp, used_hp_mp_ap, gm_level,
|
||||||
|
party_id, buddy_capacity, equip_slots, use_slots, setup_slots, etc_slots)
|
||||||
|
VALUES (:account, :world, :name, :level, :exp, :str, :dex, :int, :luk, :hp, :mp, :max_hp, :max_mp, :ap,
|
||||||
|
:sp, :job, :fame, :gender, :skin, :hair, :face, :meso, :map_id, :spawn_portal, :gacha_exp,
|
||||||
|
:used_hp_mp_ap, :gm_level, :party_id, :buddy_capacity, :equip_slots, :use_slots, :setup_slots,
|
||||||
|
:etc_slots)""";
|
||||||
|
return handle.createUpdate(sql)
|
||||||
|
.bind("account", stats.account())
|
||||||
|
.bind("world", stats.world())
|
||||||
|
.bind("name", stats.name())
|
||||||
|
.bind("level", stats.level())
|
||||||
|
.bind("exp", stats.exp())
|
||||||
|
.bind("str", stats.str())
|
||||||
|
.bind("dex", stats.dex())
|
||||||
|
.bind("int", stats.int_())
|
||||||
|
.bind("luk", stats.luk())
|
||||||
|
.bind("hp", stats.hp())
|
||||||
|
.bind("mp", stats.mp())
|
||||||
|
.bind("max_hp", stats.maxHp())
|
||||||
|
.bind("max_mp", stats.maxMp())
|
||||||
|
.bind("ap", stats.ap())
|
||||||
|
.bind("sp", parseSp(stats.sp()))
|
||||||
|
.bind("job", stats.job())
|
||||||
|
.bind("fame", stats.fame())
|
||||||
|
.bind("gender", stats.gender())
|
||||||
|
.bind("skin", stats.skin())
|
||||||
|
.bind("hair", stats.hair())
|
||||||
|
.bind("face", stats.face())
|
||||||
|
.bind("meso", stats.meso())
|
||||||
|
.bind("map_id", stats.mapId())
|
||||||
|
.bind("spawn_portal", stats.spawnPortal())
|
||||||
|
.bind("gacha_exp", stats.gachaExp())
|
||||||
|
.bind("used_hp_mp_ap", stats.hpMpApUsed())
|
||||||
|
.bind("gm_level", stats.gmLevel())
|
||||||
|
.bind("party_id", stats.party())
|
||||||
|
.bind("buddy_capacity", stats.buddyCapacity())
|
||||||
|
.bind("equip_slots", stats.equipSlots())
|
||||||
|
.bind("use_slots", stats.useSlots())
|
||||||
|
.bind("setup_slots", stats.setupSlots())
|
||||||
|
.bind("etc_slots", stats.etcSlots())
|
||||||
|
.executeAndReturnGeneratedKeys("id")
|
||||||
|
.mapTo(Integer.class)
|
||||||
|
.one();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean update(Handle handle, CharacterStats stats) {
|
public boolean update(Handle handle, CharacterStats stats) {
|
||||||
String sql = """
|
String sql = """
|
||||||
UPDATE chr
|
UPDATE chr
|
||||||
@@ -40,7 +88,7 @@ public class CharacterRepository {
|
|||||||
.bind("max_hp", stats.maxHp())
|
.bind("max_hp", stats.maxHp())
|
||||||
.bind("max_mp", stats.maxMp())
|
.bind("max_mp", stats.maxMp())
|
||||||
.bind("ap", stats.ap())
|
.bind("ap", stats.ap())
|
||||||
.bind("sp", parseMultiSkillbookSp(stats.sp()))
|
.bind("sp", parseSp(stats.sp()))
|
||||||
.bind("job", stats.job())
|
.bind("job", stats.job())
|
||||||
.bind("fame", stats.fame())
|
.bind("fame", stats.fame())
|
||||||
.bind("gender", stats.gender())
|
.bind("gender", stats.gender())
|
||||||
@@ -89,11 +137,16 @@ public class CharacterRepository {
|
|||||||
return updatedRows > 0;
|
return updatedRows > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int parseMultiSkillbookSp(String sp) {
|
private int parseSp(String sp) {
|
||||||
if (sp == null) {
|
if (sp == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sp.contains(",")) {
|
||||||
|
return Integer.parseInt(sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Old multi skillbook sp to support Evan skills. To be changed - sp will be simple integer in new db.
|
||||||
return Integer.parseInt(sp.split(",")[0]);
|
return Integer.parseInt(sp.split(",")[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class FlywayRunner {
|
|||||||
|
|
||||||
public void migrate() throws FlywayException {
|
public void migrate() throws FlywayException {
|
||||||
Flyway flyway = Flyway.configure()
|
Flyway flyway = Flyway.configure()
|
||||||
.dataSource(dbConfig.getJdbcUrl(), dbConfig.adminUsername(), dbConfig.adminPassword())
|
.dataSource(dbConfig.url(), dbConfig.adminUsername(), dbConfig.adminPassword())
|
||||||
.schemas(dbConfig.schema())
|
.schemas(dbConfig.schema())
|
||||||
.createSchemas(true)
|
.createSchemas(true)
|
||||||
.connectRetries(10)
|
.connectRetries(10)
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
@@ -969,13 +970,9 @@ public class Server {
|
|||||||
|
|
||||||
private PgDatabaseConfig readPgDbConfig() {
|
private PgDatabaseConfig readPgDbConfig() {
|
||||||
final ServerConfig serverConfig = YamlConfig.config.server;
|
final ServerConfig serverConfig = YamlConfig.config.server;
|
||||||
String pgDbHost = System.getenv("PG_DB_HOST");
|
String url = Objects.requireNonNullElse(System.getenv("PG_DB_URL"), serverConfig.PG_DB_URL);
|
||||||
if (pgDbHost == null) {
|
|
||||||
pgDbHost = serverConfig.PG_DB_HOST;
|
|
||||||
}
|
|
||||||
return PgDatabaseConfig.builder()
|
return PgDatabaseConfig.builder()
|
||||||
.databaseName(serverConfig.PG_DB_NAME)
|
.url(url)
|
||||||
.host(pgDbHost)
|
|
||||||
.schema(serverConfig.PG_DB_SCHEMA)
|
.schema(serverConfig.PG_DB_SCHEMA)
|
||||||
.adminUsername(serverConfig.PG_DB_ADMIN_USERNAME)
|
.adminUsername(serverConfig.PG_DB_ADMIN_USERNAME)
|
||||||
.adminPassword(serverConfig.PG_DB_ADMIN_PASSWORD)
|
.adminPassword(serverConfig.PG_DB_ADMIN_PASSWORD)
|
||||||
@@ -999,8 +996,7 @@ public class Server {
|
|||||||
|
|
||||||
private HikariConfig createHikariConfig(PgDatabaseConfig config) {
|
private HikariConfig createHikariConfig(PgDatabaseConfig config) {
|
||||||
final HikariConfig hikariConfig = new HikariConfig();
|
final HikariConfig hikariConfig = new HikariConfig();
|
||||||
hikariConfig.setJdbcUrl(config.getJdbcUrl());
|
hikariConfig.setJdbcUrl(config.url());
|
||||||
hikariConfig.setSchema(config.schema());
|
|
||||||
hikariConfig.setUsername(config.username());
|
hikariConfig.setUsername(config.username());
|
||||||
hikariConfig.setPassword(config.password());
|
hikariConfig.setPassword(config.password());
|
||||||
hikariConfig.setInitializationFailTimeout(config.poolInitTimeout().toMillis());
|
hikariConfig.setInitializationFailTimeout(config.poolInitTimeout().toMillis());
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ CREATE TABLE chr
|
|||||||
used_hp_mp_ap integer NOT NULL,
|
used_hp_mp_ap integer NOT NULL,
|
||||||
gm_level smallint NOT NULL,
|
gm_level smallint NOT NULL,
|
||||||
party_id integer,
|
party_id integer,
|
||||||
buddy_capacity smallint,
|
buddy_capacity smallint NOT NULL,
|
||||||
"rank" integer,
|
"rank" integer,
|
||||||
rank_move integer,
|
rank_move integer,
|
||||||
job_rank integer,
|
job_rank integer,
|
||||||
|
|||||||
129
src/test/java/database/character/CharacterSaverTest.java
Normal file
129
src/test/java/database/character/CharacterSaverTest.java
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
package database.character;
|
||||||
|
|
||||||
|
import client.Character;
|
||||||
|
import client.CharacterStats;
|
||||||
|
import client.MonsterBook;
|
||||||
|
import config.ServerConfig;
|
||||||
|
import config.YamlConfig;
|
||||||
|
import database.PgDatabaseConfig;
|
||||||
|
import database.PgDatabaseConnection;
|
||||||
|
import database.migration.FlywayRunner;
|
||||||
|
import database.monsterbook.MonsterCardRepository;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.postgresql.ds.PGSimpleDataSource;
|
||||||
|
import org.testcontainers.containers.MySQLContainer;
|
||||||
|
import org.testcontainers.containers.PostgreSQLContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import testutil.GeneratedIds;
|
||||||
|
import testutil.TestData;
|
||||||
|
import tools.DatabaseConnection;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@Testcontainers
|
||||||
|
class CharacterSaverTest {
|
||||||
|
private static final String MYSQL_VERSION = "8.4";
|
||||||
|
private static final String POSTGRES_VERSION = "16.4";
|
||||||
|
private static final String SCHEMA_NAME = "cosmic";
|
||||||
|
|
||||||
|
@Container
|
||||||
|
static MySQLContainer<?> mySql = new MySQLContainer<>("mysql:%s".formatted(MYSQL_VERSION));
|
||||||
|
|
||||||
|
@Container
|
||||||
|
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:%s".formatted(POSTGRES_VERSION));
|
||||||
|
|
||||||
|
private PgDatabaseConnection pgConnection;
|
||||||
|
private CharacterSaver characterSaver;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
prepareMysqlConnection();
|
||||||
|
runDbMigrations();
|
||||||
|
PgDatabaseConnection pgDatabaseConnection = createPgConnection();
|
||||||
|
this.pgConnection = pgDatabaseConnection;
|
||||||
|
this.characterSaver = new CharacterSaver(pgDatabaseConnection, new CharacterRepository(),
|
||||||
|
new MonsterCardRepository(pgDatabaseConnection));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not using this, but due to the nature of how the db connections are set up, the application requires
|
||||||
|
// a real database to connect to.
|
||||||
|
private void prepareMysqlConnection() {
|
||||||
|
ServerConfig serverConfig = new ServerConfig();
|
||||||
|
serverConfig.DB_URL_FORMAT = "%s";
|
||||||
|
serverConfig.DB_HOST = mySql.getJdbcUrl();
|
||||||
|
serverConfig.DB_USER = mySql.getUsername();
|
||||||
|
serverConfig.DB_PASS = mySql.getPassword();
|
||||||
|
serverConfig.INIT_CONNECTION_POOL_TIMEOUT = 60;
|
||||||
|
YamlConfig.config.server = serverConfig;
|
||||||
|
DatabaseConnection.initializeConnectionPool();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runDbMigrations() {
|
||||||
|
PgDatabaseConfig config = PgDatabaseConfig.builder()
|
||||||
|
.url(postgres.getJdbcUrl())
|
||||||
|
.schema(SCHEMA_NAME)
|
||||||
|
.adminUsername(postgres.getUsername())
|
||||||
|
.adminPassword(postgres.getPassword())
|
||||||
|
.username(postgres.getUsername())
|
||||||
|
.password(postgres.getPassword())
|
||||||
|
.poolInitTimeout(Duration.ofSeconds(60))
|
||||||
|
.clean(false)
|
||||||
|
.build();
|
||||||
|
new FlywayRunner(config).migrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
private PgDatabaseConnection createPgConnection() {
|
||||||
|
return new PgDatabaseConnection(createDataSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PGSimpleDataSource createDataSource() {
|
||||||
|
PGSimpleDataSource dataSource = new PGSimpleDataSource();
|
||||||
|
dataSource.setUrl(postgres.getJdbcUrl());
|
||||||
|
dataSource.setCurrentSchema(SCHEMA_NAME);
|
||||||
|
dataSource.setUser(postgres.getUsername());
|
||||||
|
dataSource.setPassword(postgres.getPassword());
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void saveCharacter_shouldUpdateChrTable() {
|
||||||
|
GeneratedIds ids = TestData.create(pgConnection);
|
||||||
|
Character mockChr = Mockito.mock(Character.class);
|
||||||
|
when(mockChr.isLoggedin()).thenReturn(true);
|
||||||
|
addEmptyMonsterBook(mockChr);
|
||||||
|
when(mockChr.getCharacterStats()).thenReturn(CharacterStats.builder()
|
||||||
|
.id(ids.chrId())
|
||||||
|
.level(200)
|
||||||
|
.build());
|
||||||
|
assertEquals(0, getChrLevel(ids.chrId()));
|
||||||
|
|
||||||
|
characterSaver.save(mockChr);
|
||||||
|
|
||||||
|
assertEquals(200, getChrLevel(ids.chrId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addEmptyMonsterBook(Character mockChr) {
|
||||||
|
MonsterBook mockMonsterBook = Mockito.mock(MonsterBook.class);
|
||||||
|
when(mockMonsterBook.getCards()).thenReturn(Collections.emptyList());
|
||||||
|
when(mockChr.getMonsterBook()).thenReturn(mockMonsterBook);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getChrLevel(int chrId) {
|
||||||
|
String sql = """
|
||||||
|
SELECT level
|
||||||
|
FROM chr
|
||||||
|
WHERE id = :id""";
|
||||||
|
return pgConnection.getHandle().createQuery(sql)
|
||||||
|
.bind("id", chrId)
|
||||||
|
.mapTo(Integer.class)
|
||||||
|
.one();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
4
src/test/java/testutil/GeneratedIds.java
Normal file
4
src/test/java/testutil/GeneratedIds.java
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
package testutil;
|
||||||
|
|
||||||
|
public record GeneratedIds(int accountId, int chrId) {
|
||||||
|
}
|
||||||
41
src/test/java/testutil/TestData.java
Normal file
41
src/test/java/testutil/TestData.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package testutil;
|
||||||
|
|
||||||
|
import client.CharacterStats;
|
||||||
|
import database.PgDatabaseConnection;
|
||||||
|
import database.character.CharacterRepository;
|
||||||
|
import org.jdbi.v3.core.Handle;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class TestData {
|
||||||
|
|
||||||
|
public static GeneratedIds create(PgDatabaseConnection connection) {
|
||||||
|
try (Handle handle = connection.getHandle()) {
|
||||||
|
int accountId = insertAccount(handle);
|
||||||
|
int chrId = insertChr(handle, accountId);
|
||||||
|
return new GeneratedIds(accountId, chrId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int insertAccount(Handle handle) {
|
||||||
|
String sql = """
|
||||||
|
INSERT INTO account (name, password, birthday)
|
||||||
|
VALUES (:name, :password, :birthday)""";
|
||||||
|
return handle.createUpdate(sql)
|
||||||
|
.bind("name", "accountname")
|
||||||
|
.bind("password", "accountpassword")
|
||||||
|
.bind("birthday", LocalDate.of(2005, 5, 11))
|
||||||
|
.executeAndReturnGeneratedKeys()
|
||||||
|
.mapTo(Integer.class)
|
||||||
|
.one();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int insertChr(Handle handle, int accountId) {
|
||||||
|
CharacterRepository chrRepository = new CharacterRepository();
|
||||||
|
CharacterStats stats = CharacterStats.builder()
|
||||||
|
.account(accountId)
|
||||||
|
.name("chrname")
|
||||||
|
.build();
|
||||||
|
return chrRepository.insert(handle, stats);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user