Add DropProvider and dao for monster drops
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package database;
|
||||
|
||||
import database.drop.MonsterDropRowMapper;
|
||||
import database.maker.MakerIngredientRowMapper;
|
||||
import database.maker.MakerReagentRowMapper;
|
||||
import database.maker.MakerRecipeRowMapper;
|
||||
@@ -16,6 +17,7 @@ public final class JdbiConfig {
|
||||
.registerRowMapper(new NoteRowMapper())
|
||||
.registerRowMapper(new MakerReagentRowMapper())
|
||||
.registerRowMapper(new MakerRecipeRowMapper())
|
||||
.registerRowMapper(new MakerIngredientRowMapper());
|
||||
.registerRowMapper(new MakerIngredientRowMapper())
|
||||
.registerRowMapper(new MonsterDropRowMapper());
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/java/database/drop/DropDao.java
Normal file
29
src/main/java/database/drop/DropDao.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package database.drop;
|
||||
|
||||
import database.DaoException;
|
||||
import database.PgDatabaseConnection;
|
||||
import org.jdbi.v3.core.Handle;
|
||||
import org.jdbi.v3.core.JdbiException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DropDao {
|
||||
private final PgDatabaseConnection connection;
|
||||
|
||||
public DropDao(PgDatabaseConnection connection) {
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public List<MonsterDrop> getMonsterDrops(int monsterId) {
|
||||
try (Handle handle = connection.getHandle()) {
|
||||
return handle.createQuery("""
|
||||
SELECT *
|
||||
FROM monster_drop
|
||||
WHERE monster_id = ?;""")
|
||||
.mapTo(MonsterDrop.class)
|
||||
.list();
|
||||
} catch (JdbiException e) {
|
||||
throw new DaoException("Failed to get monster drops for id %d".formatted(monsterId), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/main/java/database/drop/DropProvider.java
Normal file
32
src/main/java/database/drop/DropProvider.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package database.drop;
|
||||
|
||||
import com.github.benmanes.caffeine.cache.Cache;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import server.life.MonsterDropEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DropProvider {
|
||||
private final DropDao dropDao;
|
||||
private final Cache<Integer, List<MonsterDrop>> monsterDropCache = Caffeine.newBuilder().build();
|
||||
|
||||
public DropProvider(DropDao dropDao) {
|
||||
if (dropDao == null) {
|
||||
throw new IllegalArgumentException("DropDao must not be null");
|
||||
}
|
||||
this.dropDao = dropDao;
|
||||
}
|
||||
|
||||
public List<MonsterDropEntry> getMonsterDropEntries(int monsterId) {
|
||||
return monsterDropCache.get(monsterId, dropDao::getMonsterDrops).stream()
|
||||
.map(this::mapToDropEntry)
|
||||
.toList();
|
||||
}
|
||||
|
||||
// TODO: Temporary. MonsterDropEntry should be removed.
|
||||
private MonsterDropEntry mapToDropEntry(MonsterDrop monsterDrop) {
|
||||
short questId = monsterDrop.questId() == null ? 0 : monsterDrop.questId().shortValue();
|
||||
return new MonsterDropEntry(monsterDrop.itemId(), monsterDrop.chance(), monsterDrop.minQuantity(),
|
||||
monsterDrop.maxQuantity(), questId);
|
||||
}
|
||||
}
|
||||
4
src/main/java/database/drop/MonsterDrop.java
Normal file
4
src/main/java/database/drop/MonsterDrop.java
Normal file
@@ -0,0 +1,4 @@
|
||||
package database.drop;
|
||||
|
||||
public record MonsterDrop(int monsterId, int itemId, int minQuantity, int maxQuantity, Integer questId, int chance) {
|
||||
}
|
||||
21
src/main/java/database/drop/MonsterDropRowMapper.java
Normal file
21
src/main/java/database/drop/MonsterDropRowMapper.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package database.drop;
|
||||
|
||||
import org.jdbi.v3.core.mapper.RowMapper;
|
||||
import org.jdbi.v3.core.statement.StatementContext;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class MonsterDropRowMapper implements RowMapper<MonsterDrop> {
|
||||
|
||||
@Override
|
||||
public MonsterDrop map(ResultSet rs, StatementContext ctx) throws SQLException {
|
||||
final int monsterId = rs.getInt("monster_id");
|
||||
final int itemId = rs.getInt("item_id");
|
||||
final int minQuantity = rs.getInt("min_quantity");
|
||||
final int maxQuantity = rs.getInt("max_quantity");
|
||||
final Integer questId = rs.getObject("quest_id", Integer.class);
|
||||
final int chance = rs.getInt("chance");
|
||||
return new MonsterDrop(monsterId, itemId, minQuantity, maxQuantity, questId, chance);
|
||||
}
|
||||
}
|
||||
79
src/test/java/database/drop/DropProviderTest.java
Normal file
79
src/test/java/database/drop/DropProviderTest.java
Normal file
@@ -0,0 +1,79 @@
|
||||
package database.drop;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import server.life.MonsterDropEntry;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
class DropProviderTest {
|
||||
|
||||
@Mock
|
||||
private DropDao dropDao;
|
||||
|
||||
private DropProvider dropProvider;
|
||||
|
||||
@BeforeEach
|
||||
void reset() {
|
||||
MockitoAnnotations.openMocks(this);
|
||||
this.dropProvider = new DropProvider(dropDao);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMonsterDropEntries_noDrops() {
|
||||
when(dropDao.getMonsterDrops(anyInt())).thenReturn(Collections.emptyList());
|
||||
|
||||
List<MonsterDropEntry> dropEntries = dropProvider.getMonsterDropEntries(489340);
|
||||
|
||||
assertTrue(dropEntries.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMonsterDropEntries() {
|
||||
MonsterDrop snailShellDrop = snailShellDrop();
|
||||
when(dropDao.getMonsterDrops(anyInt())).thenReturn(List.of(snailShellDrop));
|
||||
|
||||
List<MonsterDropEntry> dropEntries = dropProvider.getMonsterDropEntries(100100);
|
||||
|
||||
assertEquals(1, dropEntries.size());
|
||||
MonsterDropEntry dropEntry = dropEntries.get(0);
|
||||
assertEquals(snailShellDrop.itemId(), dropEntry.itemId);
|
||||
assertEquals(snailShellDrop.minQuantity(), dropEntry.Minimum);
|
||||
assertEquals(snailShellDrop.maxQuantity(), dropEntry.Maximum);
|
||||
assertEquals(snailShellDrop.chance(), dropEntry.chance);
|
||||
assertEquals(0, dropEntry.questid);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getCachedMonsterDropEntries() {
|
||||
when(dropDao.getMonsterDrops(anyInt())).thenReturn(List.of(snailShellDrop()));
|
||||
int monsterId = 100100;
|
||||
|
||||
List<MonsterDropEntry> dropEntries1 = dropProvider.getMonsterDropEntries(monsterId);
|
||||
List<MonsterDropEntry> dropEntries2 = dropProvider.getMonsterDropEntries(monsterId);
|
||||
|
||||
assertEquals(1, dropEntries1.size());
|
||||
assertEquals(1, dropEntries2.size());
|
||||
MonsterDropEntry dropEntry1 = dropEntries1.get(0);
|
||||
MonsterDropEntry dropEntry2 = dropEntries2.get(0);
|
||||
assertEquals(dropEntry1.itemId, dropEntry2.itemId);
|
||||
assertEquals(dropEntry1.Minimum, dropEntry2.Minimum);
|
||||
assertEquals(dropEntry1.Maximum, dropEntry2.Maximum);
|
||||
assertEquals(dropEntry1.questid, dropEntry2.questid);
|
||||
assertEquals(dropEntry1.chance, dropEntry2.chance);
|
||||
verify(dropDao, times(1)).getMonsterDrops(anyInt());
|
||||
}
|
||||
|
||||
private MonsterDrop snailShellDrop() {
|
||||
return new MonsterDrop(100100, 4000019, 1, 2, null, 600_000);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user