diff --git a/h2_playermanager/src/main/java/mc/core/h2db/H2Player.java b/h2_playermanager/src/main/java/mc/core/h2db/H2Player.java index a33b94a..8880503 100644 --- a/h2_playermanager/src/main/java/mc/core/h2db/H2Player.java +++ b/h2_playermanager/src/main/java/mc/core/h2db/H2Player.java @@ -40,7 +40,11 @@ public class H2Player implements Player { @Override public void setWorld(World world) { - this.$refWorld = new WeakReference<>(world); + if (world == null) { + this.$refWorld = null; + } else { + this.$refWorld = new WeakReference<>(world); + } } @Override diff --git a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java index 8bd94b0..aa9135b 100644 --- a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java +++ b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java @@ -20,14 +20,32 @@ import java.util.UUID; @Slf4j @Component public class H2PlayerDAO { - private static String INSERT_SQL, SELECT_SQL, UPDATE_SQL, UPDATE_LOCATION_SQL, DELETE_SQL; + private static String INSERT_SQL, INSERT2_SQL, SELECT_SQL, UPDATE_SQL, UPDATE_LOCATION_SQL, DELETE_SQL; @Autowired private JdbcTemplate jdbcTemplate; @Autowired private World world; - public void insert(H2Player player) throws SQLException { + private void checkPlayer(H2Player player) throws SQLException { + if (player.getName() == null || player.getName().isEmpty()) { + throw new SQLException("Field 'name' is " + (player.getName() == null ? "null" : "empty")); + } + + if (player.getUuid() == null) { + throw new SQLException("Field 'uuid' is null"); + } + + if (player.getLocation() == null) { + throw new SQLException("Fields 'location_*' is null"); + } + + if (player.getWorld() == null) { + throw new SQLException("Field 'location_world' is null"); + } + } + + private void insertWithoutId(H2Player player) throws SQLException { KeyHolder keyHolder = new GeneratedKeyHolder(); int affectedRows = jdbcTemplate.update(psc -> { @@ -52,9 +70,41 @@ public class H2PlayerDAO { player.setId(keyHolder.getKey().intValue()); } + private void insertWithId(H2Player player) throws SQLException { + int affectedRows = jdbcTemplate.update(psc -> { + PreparedStatement stmt = psc.prepareStatement(INSERT2_SQL); + + stmt.setString(1, player.getUuid().toString()); + stmt.setString(2, player.getName()); + stmt.setDouble(3, player.getLocation().getX()); + stmt.setDouble(4, player.getLocation().getY()); + stmt.setDouble(5, player.getLocation().getZ()); + stmt.setFloat(6, player.getLocation().getYaw()); + stmt.setFloat(7, player.getLocation().getPitch()); + stmt.setString(8, player.getWorld().getName()); + stmt.setInt(9, player.getId()); + + return stmt; + }); + + if (affectedRows == 0) { + throw new SQLException("Serialize player failed: no rows affected."); + } + } + + public void insert(H2Player player) throws SQLException { + checkPlayer(player); + + if (player.getId() > 0) { + insertWithId(player); + } else { + insertWithoutId(player); + } + } + public void getByName(H2Player playerBuffer) throws SQLException { if (playerBuffer.getName() == null || playerBuffer.getName().isEmpty()) { - throw new SQLException("Argument 'name' is " + (playerBuffer.getName() == null ? "null" : "empty")); + throw new SQLException("Field 'name' is " + (playerBuffer.getName() == null ? "null" : "empty")); } jdbcTemplate.query(SELECT_SQL, @@ -81,9 +131,11 @@ public class H2PlayerDAO { public void update(H2Player player) throws SQLException { if (player.getId() == 0) { - throw new SQLException("Argument 'id' is zero"); + throw new SQLException("Field 'id' is zero"); } + checkPlayer(player); + int affectedRows = jdbcTemplate.update(UPDATE_SQL, pss -> { pss.setInt(9, player.getId()); pss.setString(1, player.getUuid().toString()); @@ -103,7 +155,23 @@ public class H2PlayerDAO { public void updateLocation(H2Player player) throws SQLException { if (player.getId() == 0) { - throw new SQLException("Argument 'id' is zero"); + throw new SQLException("Field 'id' is zero"); + } + + if (player.getLocation() == null) { + throw new SQLException("Fields 'location_*' is null"); + } + + if (player.getWorld() == null) { + throw new SQLException("Field 'location_world' is null"); + } + + if (player.getLocation() == null) { + throw new SQLException("Fields 'location_*' is null"); + } + + if (player.getWorld() == null) { + throw new SQLException("Field 'location_world' is null"); } int affectedRows = jdbcTemplate.update(connection -> { @@ -127,7 +195,7 @@ public class H2PlayerDAO { public void remove(H2Player player) throws SQLException { if (player.getId() == 0) { - throw new SQLException("Argument 'id' is zero"); + throw new SQLException("Field 'id' is zero"); } int affectedRows = jdbcTemplate.update(DELETE_SQL, pss -> pss.setInt(1, player.getId())); @@ -142,6 +210,7 @@ public class H2PlayerDAO { static { try { INSERT_SQL = IOUtils.resourceToString("/sqls/insert_player.sql", StandardCharsets.UTF_8); + INSERT2_SQL = IOUtils.resourceToString("/sqls/insert_player_withId.sql", StandardCharsets.UTF_8); SELECT_SQL = IOUtils.resourceToString("/sqls/select_player_byName.sql", StandardCharsets.UTF_8); UPDATE_SQL = IOUtils.resourceToString("/sqls/update_player.sql", StandardCharsets.UTF_8); UPDATE_LOCATION_SQL = IOUtils.resourceToString("/sqls/update_player_location.sql", StandardCharsets.UTF_8); diff --git a/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql b/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql new file mode 100644 index 0000000..c0119bc --- /dev/null +++ b/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql @@ -0,0 +1,2 @@ +INSERT INTO players (uuid, name, location_x, location_y, location_z, location_yaw, location_pitch, location_world, id) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); \ No newline at end of file diff --git a/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java b/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java index 709ed52..a51e105 100644 --- a/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java +++ b/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java @@ -7,6 +7,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.DuplicateKeyException; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -81,6 +82,44 @@ public class TestDAO { assertPlayer(player); } + @Test(expected = DuplicateKeyException.class) + public void testInsertDuplicateKey() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + playerDAO.insert(player); + } + + @Test(expected = SQLException.class) + public void testInsertEmptyName() throws SQLException { + player.setName(""); + playerDAO.insert(player); + } + + @Test(expected = SQLException.class) + public void testInsertNullName() throws SQLException { + player.setName(null); + playerDAO.insert(player); + } + + @Test(expected = SQLException.class) + public void testInsertNullUuid() throws SQLException { + player.setUuid(null); + playerDAO.insert(player); + } + + @Test(expected = SQLException.class) + public void testInsertNullLocation() throws SQLException { + player.setLocation(null); + playerDAO.insert(player); + } + + @Test(expected = SQLException.class) + public void testInsertNullWorld() throws SQLException { + player.setWorld(null); + playerDAO.insert(player); + } + @Test public void testGetByName() throws SQLException { playerDAO.insert(this.player); @@ -98,6 +137,21 @@ public class TestDAO { assertEquals(player, this.player); } + @Test + public void testGetByNonExistsName() throws SQLException { + playerDAO.insert(this.player); + assertNotEquals(0, player.getId()); + + H2Player player = new H2Player(); + player.setName("NON_EXISTS_NAME"); + + assertNotNull(player.getName()); + assertFalse(player.getName().isEmpty()); + + playerDAO.getByName(player); + assertEquals(0, player.getId()); + } + @Test public void testUpdate() throws SQLException { playerDAO.insert(player); @@ -109,6 +163,51 @@ public class TestDAO { assertPlayer(player); } + @Test(expected = SQLException.class) + public void testUpdateEmptyName() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setName(""); + playerDAO.update(player); + } + + @Test(expected = SQLException.class) + public void testUpdateNullName() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setName(null); + playerDAO.update(player); + } + + @Test(expected = SQLException.class) + public void testUpdateNullUuid() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setUuid(null); + playerDAO.update(player); + } + + @Test(expected = SQLException.class) + public void testUpdateNullLocation() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setLocation(null); + playerDAO.update(player); + } + + @Test(expected = SQLException.class) + public void testUpdateNullWorld() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setWorld(null); + playerDAO.update(player); + } + @Test public void testUpdateLocation() throws SQLException { playerDAO.insert(player); @@ -135,6 +234,15 @@ public class TestDAO { }); } + @Test(expected = SQLException.class) + public void testUpdateLocationNull() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setLocation(null); + playerDAO.updateLocation(player); + } + @Test public void testRemove() throws SQLException { playerDAO.insert(player); @@ -149,4 +257,13 @@ public class TestDAO { ps -> ps.setInt(1, origId), rs -> {assertEquals(0, rs.getInt(1));}); } + + @Test(expected = SQLException.class) + public void testRemoveNonExistsId() throws SQLException { + playerDAO.insert(player); + assertNotEquals(0, player.getId()); + + player.setId(999); + playerDAO.remove(player); + } }