diff --git a/h2_playermanager/build.gradle b/h2_playermanager/build.gradle index 876f47b..acdbf0c 100644 --- a/h2_playermanager/build.gradle +++ b/h2_playermanager/build.gradle @@ -1,12 +1,17 @@ version '1.0-SNAPSHOT' +ext { + spring_data_version = '2.1.0.RELEASE' +} + dependencies { /* Core */ compile_excludeCopy project(':core') /* Spring */ - compile (group: 'org.springframework', name: 'spring-jdbc', version: spring_version) + compile (group: 'org.springframework.data', name: 'spring-data-jpa', version: spring_data_version) /* Database */ + compile (group: 'org.hibernate', name: 'hibernate-entitymanager', version: '5.3.6.Final') compile (group: 'com.h2database', name: 'h2', version: '1.4.197') } \ No newline at end of file diff --git a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java deleted file mode 100644 index 7004ba8..0000000 --- a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerDAO.java +++ /dev/null @@ -1,259 +0,0 @@ -package mc.core.h2db; - -import lombok.extern.slf4j.Slf4j; -import mc.core.EntityLocation; -import mc.core.world.World; -import org.apache.commons.io.IOUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.support.GeneratedKeyHolder; -import org.springframework.jdbc.support.KeyHolder; -import org.springframework.stereotype.Component; - -import javax.annotation.PostConstruct; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.UUID; - -@Slf4j -@Component -public class H2PlayerDAO { - private static String INSERT_SQL, INSERT2_SQL, - SELECT_BYNAME_SQL, SELECT_BYID_SQL, - UPDATE_SQL, UPDATE_LOCATION_SQL, - DELETE_SQL; - - @Autowired - private JdbcTemplate jdbcTemplate; - @Autowired - private World world; - - @PostConstruct - public void init() throws IOException { - jdbcTemplate.execute(IOUtils.resourceToString("/sqls/create_tables.sql", StandardCharsets.UTF_8)); - } - - 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 -> { - PreparedStatement stmt = psc.prepareStatement(INSERT_SQL, Statement.RETURN_GENERATED_KEYS); - - 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()); - - return stmt; - }, keyHolder); - - if (affectedRows == 0) { - throw new SQLException("Serialize player failed: no rows affected."); - } - - 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); - } - } - - private void locationDeserialize(H2Player playerBuffer, ResultSet resultSet) throws SQLException { - if (!world.getName().equals(resultSet.getString("location_world"))) { - log.warn("Unknown world \"{}\"", resultSet.getString("location_world")); - log.warn("Using default (spawn) location for user \"{}\"", playerBuffer.getName()); - playerBuffer.setLocation(world.getSpawn().clone()); - } else { - playerBuffer.setLocation(new EntityLocation( - resultSet.getDouble("location_x"), - resultSet.getDouble("location_y"), - resultSet.getDouble("location_z"), - resultSet.getFloat("location_yaw"), - resultSet.getFloat("location_pitch") - )); - playerBuffer.setWorld(world); - } - } - - public boolean getByName(H2Player playerBuffer) throws SQLException { - if (playerBuffer.getName() == null || playerBuffer.getName().isEmpty()) { - throw new SQLException("Field 'name' is " + (playerBuffer.getName() == null ? "null" : "empty")); - } - - final boolean[] result = new boolean[]{false}; - jdbcTemplate.query(SELECT_BYNAME_SQL, - ps -> ps.setString(1, playerBuffer.getName()), - rs -> { - playerBuffer.setId(rs.getInt("id")); - playerBuffer.setUuid(UUID.fromString(rs.getString("uuid"))); - locationDeserialize(playerBuffer, rs); - result[0] = true; - }); - - return result[0]; - } - - public boolean getById(H2Player playerBuffer) throws SQLException { - if (playerBuffer.getId() == 0) { - throw new SQLException("Field 'id' is zero"); - } - - final boolean[] result = new boolean[]{false}; - jdbcTemplate.query(SELECT_BYID_SQL, - ps -> ps.setInt(1, playerBuffer.getId()), - rs -> { - playerBuffer.setUuid(UUID.fromString(rs.getString("uuid"))); - playerBuffer.setName(rs.getString("name")); - locationDeserialize(playerBuffer, rs); - result[0] = true; - }); - - return result[0]; - } - - public void update(H2Player player) throws SQLException { - if (player.getId() == 0) { - 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()); - pss.setString(2, player.getName()); - pss.setDouble(3, player.getLocation().getX()); - pss.setDouble(4, player.getLocation().getY()); - pss.setDouble(5, player.getLocation().getZ()); - pss.setFloat(6, player.getLocation().getYaw()); - pss.setFloat(7, player.getLocation().getPitch()); - pss.setString(8, player.getWorld().getName()); - }); - - if (affectedRows == 0) { - throw new SQLException("Update player failed, no rows affected."); - } - } - - public void updateLocation(H2Player player) throws SQLException { - if (player.getId() == 0) { - 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 -> { - PreparedStatement stmt = connection.prepareStatement(UPDATE_LOCATION_SQL); - - stmt.setInt(7, player.getId()); - stmt.setDouble(1, player.getLocation().getX()); - stmt.setDouble(2, player.getLocation().getY()); - stmt.setDouble(3, player.getLocation().getZ()); - stmt.setFloat(4, player.getLocation().getYaw()); - stmt.setFloat(5, player.getLocation().getPitch()); - stmt.setString(6, player.getWorld().getName()); - - return stmt; - }); - - if (affectedRows == 0) { - throw new SQLException("Update player failed, no rows affected."); - } - } - - public void remove(H2Player player) throws SQLException { - if (player.getId() == 0) { - throw new SQLException("Field 'id' is zero"); - } - - int affectedRows = jdbcTemplate.update(DELETE_SQL, pss -> pss.setInt(1, player.getId())); - - if (affectedRows == 0) { - throw new SQLException("Remove player failed, no rows affected."); - } - - player.setId(0); - } - - 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_BYNAME_SQL = IOUtils.resourceToString("/sqls/select_player_byName.sql", StandardCharsets.UTF_8); - SELECT_BYID_SQL = IOUtils.resourceToString("/sqls/select_player_byId.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); - DELETE_SQL = IOUtils.resourceToString("/sqls/delete_player.sql", StandardCharsets.UTF_8); - } catch (IOException e) { - log.error("Load sql templates", e); - } - } -} diff --git a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java index 2f4780d..9741d30 100644 --- a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java +++ b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableList; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import mc.core.EntityLocation; +import mc.core.h2db.service.H2PlayerService; import mc.core.network.BroadcastNetChannel; import mc.core.network.NetChannel; import mc.core.player.Player; @@ -13,28 +14,23 @@ import mc.core.world.World; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import javax.annotation.PostConstruct; -import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.UUID; -import static org.slf4j.helpers.MessageFormatter.format; - @Slf4j @Component public class H2PlayerManager implements PlayerManager { @Setter @Autowired - private H2PlayerDAO h2playerDao; + private H2PlayerService h2PlayerService; private List playerList = Collections.synchronizedList(new ArrayList<>()); @Autowired - private World world; + private World world; //FIXME @Override public Player createPlayer(String name, EntityLocation location, World world) { - //TODO в дальнейшем следует в этом методе только имплементацию Player H2Player h2Player = new H2Player(); h2Player.setName(name); h2Player.setUuid(UUID.randomUUID()); @@ -43,14 +39,7 @@ public class H2PlayerManager implements PlayerManager { h2Player.setWorld(world); h2Player.setSettings(new PlayerSettings()); - try { - h2playerDao.insert(h2Player); - } catch (SQLException e) { - log.error(format("Insert player '{}'", h2Player.getName()).getMessage(), e); - return null; - } - - return h2Player; + return h2PlayerService.save(h2Player); } @Override @@ -64,15 +53,9 @@ public class H2PlayerManager implements PlayerManager { @Override public void leftServer(Player player) { H2Player h2Player = (H2Player) player; - try { - h2playerDao.update(h2Player); - } catch (SQLException e) { - log.error(format("Update player '{}'", h2Player.getName()).getMessage(), e); - playerList.remove(h2Player); - } finally { - h2Player.setOnline(false); - h2Player.getLoadedChunks().clear(); - } + h2PlayerService.save(h2Player); + h2Player.setOnline(false); + h2Player.getLoadedChunks().clear(); } @Override @@ -108,26 +91,17 @@ public class H2PlayerManager implements PlayerManager { @Override public Player getOfflinePlayer(String name) { + //TODO похоже в попытке где-то оптимизировать/сэконопить я сам себя ******[обманул] + //необходимо этот участок кода переписать + //потому как похоже на экономию на спичках H2Player h2Player = playerList.stream() .filter(player -> player.getName().equals(name)) .filter(player -> !player.isOnline()) .findFirst().orElse(null); if (h2Player == null) { - h2Player = playerList.stream() - .filter(player -> !player.isOnline()) - .findAny().orElse(new H2Player()); - h2Player.setName(name); - - boolean result; - try { - result = h2playerDao.getByName(h2Player); - } catch (SQLException e) { - log.error(format("getByName player '{}'", h2Player.getName()).getMessage(), e); - return null; - } - - if (result) { + h2Player = h2PlayerService.getByName(name); + if (h2Player != null) { h2Player.setWorld(world); return h2Player; } else { diff --git a/h2_playermanager/src/main/java/mc/core/h2db/entity/H2PlayerEntity.java b/h2_playermanager/src/main/java/mc/core/h2db/entity/H2PlayerEntity.java new file mode 100644 index 0000000..1edc5f4 --- /dev/null +++ b/h2_playermanager/src/main/java/mc/core/h2db/entity/H2PlayerEntity.java @@ -0,0 +1,104 @@ +package mc.core.h2db.entity; + +import lombok.Data; +import lombok.NoArgsConstructor; +import mc.core.EntityLocation; +import mc.core.h2db.H2Player; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.UUID; + +@Entity +@Table(name = "players", + indexes = {@Index(name = "idx_players_uuid", columnList = "uuid", unique = true), + @Index(name = "idx_players_name", columnList = "name")}) +@NoArgsConstructor +@Data +public class H2PlayerEntity { + @Id + @GeneratedValue(generator = "increment") + @GenericGenerator(name= "increment", strategy= "increment") + @Column(nullable = false) + private Long id; + + @Column(length = 36, nullable = false) + private String uuid; + + @Column(length = 16, nullable = false) + private String name; + + @Column(name = "location_x", nullable = false) + private Double locationX; + + @Column(name = "location_y", nullable = false) + private Double locationY; + + @Column(name = "location_z", nullable = false) + private Double locationZ; + + @Column(name = "location_yaw", nullable = false) + private Float locationYaw; + + @Column(name = "location_pitch", nullable = false) + private Float locationPitch; + + @Column(name = "location_world", length = 64, nullable = false) + private String locationWorld; + + public H2PlayerEntity(H2Player player) { + this.id = (long) player.getId(); + setUuid(player.getUuid().toString()); + setName(this.name = player.getName()); + this.locationX = player.getLocation().getX(); + this.locationY = player.getLocation().getY(); + this.locationZ = player.getLocation().getZ(); + this.locationYaw = player.getLocation().getYaw(); + this.locationPitch = player.getLocation().getPitch(); + if (player.getWorld() != null) { //FIXME + this.locationWorld = player.getWorld().getName(); + } else { + this.locationWorld = "null_world"; + } + } + + public void setUuid(String uuid) { + if (uuid == null || uuid.trim().isEmpty()) { + this.uuid = null; + } else { + this.uuid = uuid; + } + } + + public void setName(String name) { + if (name == null || name.trim().isEmpty()) { + this.name = null; + } else { + this.name = name; + } + } + + public H2Player toPlayer() { + H2Player player = new H2Player(); + return toPlayer(player); + } + + public H2Player toPlayer(H2Player player) { + player.setId(this.id.intValue()); + player.setUuid(UUID.fromString(this.uuid)); + player.setName(this.name); + if (player.getLocation() == null) { + player.setLocation(new EntityLocation( + this.locationX, this.locationY, this.locationZ, + this.locationYaw, this.locationPitch + )); + } else { + player.getLocation().setXYZ(this.locationX, this.locationY, this.locationZ); + player.getLocation().setYawPitch(this.locationYaw, this.locationPitch); + } + + player.setWorld(null); //FIXME + + return player; + } +} diff --git a/h2_playermanager/src/main/java/mc/core/h2db/repository/H2PlayerEntityRepository.java b/h2_playermanager/src/main/java/mc/core/h2db/repository/H2PlayerEntityRepository.java new file mode 100644 index 0000000..47b4f45 --- /dev/null +++ b/h2_playermanager/src/main/java/mc/core/h2db/repository/H2PlayerEntityRepository.java @@ -0,0 +1,12 @@ +package mc.core.h2db.repository; + +import mc.core.h2db.entity.H2PlayerEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface H2PlayerEntityRepository extends JpaRepository { + Optional findByName(String name); +} diff --git a/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerService.java b/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerService.java new file mode 100644 index 0000000..a20fb7b --- /dev/null +++ b/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerService.java @@ -0,0 +1,11 @@ +package mc.core.h2db.service; + +import mc.core.h2db.H2Player; + +public interface H2PlayerService { + H2Player save(H2Player player); + void remove(H2Player player); + + H2Player getByName(String name); + H2Player getById(int id); +} diff --git a/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerServiceImpl.java b/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerServiceImpl.java new file mode 100644 index 0000000..d716444 --- /dev/null +++ b/h2_playermanager/src/main/java/mc/core/h2db/service/H2PlayerServiceImpl.java @@ -0,0 +1,41 @@ +package mc.core.h2db.service; + +import mc.core.h2db.H2Player; +import mc.core.h2db.entity.H2PlayerEntity; +import mc.core.h2db.repository.H2PlayerEntityRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class H2PlayerServiceImpl implements H2PlayerService { + @Autowired + private H2PlayerEntityRepository h2PlayerEntityRepository; + + @Override + public H2Player save(H2Player player) { + H2PlayerEntity entity = new H2PlayerEntity(player); + //TODO возможно имеет смысл здесь оптимизация + //вместо toPlayer() сделать toPlayer(H2Player) который в существующий + //будет дописывать/обновлять данные + return h2PlayerEntityRepository.saveAndFlush(entity).toPlayer(player); + } + + @Override + public void remove(H2Player player) { + h2PlayerEntityRepository.deleteById((long) player.getId()); + } + + @Override + public H2Player getByName(String name) { + Optional optEntity = h2PlayerEntityRepository.findByName(name); + return optEntity.map(H2PlayerEntity::toPlayer).orElse(null); + } + + @Override + public H2Player getById(int id) { + Optional optEntity = h2PlayerEntityRepository.findById((long) id); + return optEntity.map(H2PlayerEntity::toPlayer).orElse(null); + } +} diff --git a/h2_playermanager/src/main/resources/sqls/create_tables.sql b/h2_playermanager/src/main/resources/sqls/create_tables.sql deleted file mode 100644 index c436f80..0000000 --- a/h2_playermanager/src/main/resources/sqls/create_tables.sql +++ /dev/null @@ -1,14 +0,0 @@ -CREATE TABLE IF NOT EXISTS players ( - id INT AUTO_INCREMENT PRIMARY KEY NOT NULL, - uuid VARCHAR(36) NOT NULL UNIQUE, - name VARCHAR(16) NOT NULL, - location_x DOUBLE NOT NULL, - location_y DOUBLE NOT NULL, - location_z DOUBLE NOT NULL, - location_yaw FLOAT NOT NULL, - location_pitch FLOAT NOT NULL, - location_world VARCHAR(64) NOT NULL -); - -CREATE INDEX IF NOT EXISTS idx_players_uuid ON players(uuid); -CREATE INDEX IF NOT EXISTS idx_players_name ON players(name); \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/delete_player.sql b/h2_playermanager/src/main/resources/sqls/delete_player.sql deleted file mode 100644 index d16f13d..0000000 --- a/h2_playermanager/src/main/resources/sqls/delete_player.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM players WHERE id = ?; \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/insert_player.sql b/h2_playermanager/src/main/resources/sqls/insert_player.sql deleted file mode 100644 index ab9bdff..0000000 --- a/h2_playermanager/src/main/resources/sqls/insert_player.sql +++ /dev/null @@ -1,2 +0,0 @@ -INSERT INTO players (uuid, name, location_x, location_y, location_z, location_yaw, location_pitch, location_world) - VALUES (?, ?, ?, ?, ?, ?, ?, ?); \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql b/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql deleted file mode 100644 index c0119bc..0000000 --- a/h2_playermanager/src/main/resources/sqls/insert_player_withId.sql +++ /dev/null @@ -1,2 +0,0 @@ -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/main/resources/sqls/select_player_byId.sql b/h2_playermanager/src/main/resources/sqls/select_player_byId.sql deleted file mode 100644 index 0267ce6..0000000 --- a/h2_playermanager/src/main/resources/sqls/select_player_byId.sql +++ /dev/null @@ -1,3 +0,0 @@ -SELECT uuid, name, location_x, location_y, location_z, location_yaw, location_pitch, location_world -FROM players WHERE id = ? -LIMIT 1; \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/select_player_byName.sql b/h2_playermanager/src/main/resources/sqls/select_player_byName.sql deleted file mode 100644 index 36a9b3d..0000000 --- a/h2_playermanager/src/main/resources/sqls/select_player_byName.sql +++ /dev/null @@ -1,3 +0,0 @@ -SELECT id, uuid, location_x, location_y, location_z, location_yaw, location_pitch, location_world -FROM players WHERE name LIKE ? -LIMIT 1; \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/update_player.sql b/h2_playermanager/src/main/resources/sqls/update_player.sql deleted file mode 100644 index 0e7bb2d..0000000 --- a/h2_playermanager/src/main/resources/sqls/update_player.sql +++ /dev/null @@ -1,10 +0,0 @@ -UPDATE players -SET uuid = ?, - name = ?, - location_x = ?, - location_y = ?, - location_z = ?, - location_yaw = ?, - location_pitch = ?, - location_world = ? -WHERE id = ?; \ No newline at end of file diff --git a/h2_playermanager/src/main/resources/sqls/update_player_location.sql b/h2_playermanager/src/main/resources/sqls/update_player_location.sql deleted file mode 100644 index 30b2d29..0000000 --- a/h2_playermanager/src/main/resources/sqls/update_player_location.sql +++ /dev/null @@ -1,8 +0,0 @@ -UPDATE players -SET location_x = ?, - location_y = ?, - location_z = ?, - location_yaw = ?, - location_pitch = ?, - location_world = ? -WHERE id = ?; \ No newline at end of file diff --git a/h2_playermanager/src/test/java/mc/core/h2db/SpringConfig.java b/h2_playermanager/src/test/java/mc/core/h2db/SpringConfig.java deleted file mode 100644 index 58eb283..0000000 --- a/h2_playermanager/src/test/java/mc/core/h2db/SpringConfig.java +++ /dev/null @@ -1,49 +0,0 @@ -package mc.core.h2db; - -import mc.core.world.World; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Scope; -import org.springframework.jdbc.core.JdbcTemplate; -import org.springframework.jdbc.datasource.DriverManagerDataSource; - -import javax.sql.DataSource; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -@Configuration -@ComponentScan("mc.core.h2db") -public class SpringConfig { - @Bean - public World mockWorld() { - World mockWorld = mock(World.class); - when(mockWorld.getName()).thenReturn("mock_world"); - return mockWorld; - } - - @Bean - public DataSource dataSource() { - DriverManagerDataSource dmds = new DriverManagerDataSource(); - dmds.setDriverClassName("org.h2.Driver"); - dmds.setUrl("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"); - dmds.setUsername("sa"); - return dmds; - } - - @Bean - public JdbcTemplate jdbcTemplate(DataSource dataSource) { - JdbcTemplate jdbcTemplate = new JdbcTemplate(); - jdbcTemplate.setDataSource(dataSource); - return jdbcTemplate; - } - - @Bean - @Scope(value = "prototype") - public H2PlayerManager h2PlayerManager(H2PlayerDAO h2PlayerDAO) { - H2PlayerManager playerManager = new H2PlayerManager(); - playerManager.setH2playerDao(h2PlayerDAO); - return playerManager; - } -} diff --git a/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java b/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java deleted file mode 100644 index 9abc262..0000000 --- a/h2_playermanager/src/test/java/mc/core/h2db/TestDAO.java +++ /dev/null @@ -1,274 +0,0 @@ -package mc.core.h2db; - -import mc.core.EntityLocation; -import mc.core.world.World; -import org.apache.commons.io.IOUtils; -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; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; -import java.util.UUID; -import java.util.concurrent.ThreadLocalRandom; - -import static org.junit.Assert.*; - -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {SpringConfig.class}) -public class TestDAO { - @Autowired - private JdbcTemplate jdbcTemplate; - @Autowired - private World mockWorld; - @Autowired - private H2PlayerDAO playerDAO; - private H2Player player; - - private void createPlayer() { - final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - final double minD = 0.0d, maxD = 10.0d; - final float minF = 0.0f, maxF = 359.9f; - final int minI = 1000, maxI = 9999; - - player = new H2Player(); - player.setUuid(UUID.randomUUID()); - player.setName("player" + rnd.nextInt(minI, maxI)); - player.setLocation(new EntityLocation( - rnd.nextDouble(minD, maxD), - rnd.nextDouble(minD, maxD), - rnd.nextDouble(minD, maxD), - rnd.nextFloat() * (maxF - minF) + minF, - rnd.nextFloat() * (maxF - minF) + minF - )); - player.setWorld(mockWorld); - } - - private void assertPlayer(H2Player actualPlayer) { - final String sql = "SELECT * FROM players WHERE id = ?"; - jdbcTemplate.query(sql, - ps -> ps.setInt(1, player.getId()), - rs -> { - assertEquals(actualPlayer.getId(), rs.getInt("id")); - assertEquals(actualPlayer.getName(), rs.getString("name")); - assertEquals(actualPlayer.getLocation().getX(), rs.getDouble("location_x"), 0.01d); - assertEquals(actualPlayer.getLocation().getY(), rs.getDouble("location_y"), 0.01d); - assertEquals(actualPlayer.getLocation().getZ(), rs.getDouble("location_z"), 0.01d); - assertEquals(actualPlayer.getLocation().getYaw(), rs.getFloat("location_yaw"), 0.01f); - assertEquals(actualPlayer.getLocation().getPitch(), rs.getFloat("location_pitch"), 0.01f); - assertEquals(actualPlayer.getWorld().getName(), rs.getString("location_world")); - }); - } - - @Before - public void before() throws IOException { - jdbcTemplate.execute(IOUtils.resourceToString("/sqls/drop_table_players.sql", StandardCharsets.UTF_8)); - jdbcTemplate.execute(IOUtils.resourceToString("/sqls/create_tables.sql", StandardCharsets.UTF_8)); - createPlayer(); - assertEquals(0, player.getId()); - } - - @Test - public void testInsert() throws SQLException { - playerDAO.insert(player); - assertNotEquals(0, player.getId()); - - assertPlayer(player); - } - - @Test(expected = DuplicateKeyException.class) - public void testInsertDuplicateKey() throws SQLException { - playerDAO.insert(player); - 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); - - H2Player queryPlayer = new H2Player(); - queryPlayer.setName(player.getName()); - - boolean result = playerDAO.getByName(queryPlayer); - - assertTrue(result); - assertEquals(player, queryPlayer); - } - - @Test - public void testGetByNonExistsName() throws SQLException { - playerDAO.insert(this.player); - - H2Player player = new H2Player(); - player.setName("NON_EXISTS_NAME"); - - boolean result = playerDAO.getByName(player); - assertFalse(result); - } - - @Test - public void testGetById() throws SQLException { - playerDAO.insert(this.player); - - H2Player queryPlayer = new H2Player(); - queryPlayer.setId(player.getId()); - - boolean result = playerDAO.getById(queryPlayer); - - assertTrue(result); - assertEquals(player, queryPlayer); - } - - @Test - public void testGetByNonExistsId() throws SQLException { - playerDAO.insert(player); - assertEquals(1, player.getId()); - - H2Player queryPlayer = new H2Player(); - queryPlayer.setId(999); - - boolean result = playerDAO.getById(queryPlayer); - assertFalse(result); - } - - @Test - public void testUpdate() throws SQLException { - playerDAO.insert(player); - - player.setName("UNKNOWN_PLAYER"); - playerDAO.update(player); - - assertPlayer(player); - } - - @Test(expected = SQLException.class) - public void testUpdateEmptyName() throws SQLException { - playerDAO.insert(player); - - player.setName(""); - playerDAO.update(player); - } - - @Test(expected = SQLException.class) - public void testUpdateNullName() throws SQLException { - playerDAO.insert(player); - - player.setName(null); - playerDAO.update(player); - } - - @Test(expected = SQLException.class) - public void testUpdateNullUuid() throws SQLException { - playerDAO.insert(player); - - player.setUuid(null); - playerDAO.update(player); - } - - @Test(expected = SQLException.class) - public void testUpdateNullLocation() throws SQLException { - playerDAO.insert(player); - - player.setLocation(null); - playerDAO.update(player); - } - - @Test(expected = SQLException.class) - public void testUpdateNullWorld() throws SQLException { - playerDAO.insert(player); - - player.setWorld(null); - playerDAO.update(player); - } - - @Test - public void testUpdateLocation() throws SQLException { - playerDAO.insert(player); - - final String origName = player.getName(); - player.setName("UNKNOWN_PLAYER"); - player.getLocation().setX(33.1d); - player.getLocation().setZ(28.99d); - playerDAO.updateLocation(player); - - final String sql = "SELECT * FROM players WHERE id = ?"; - jdbcTemplate.query(sql, - ps -> ps.setInt(1, player.getId()), - rs -> { - assertEquals(player.getId(), rs.getInt("id")); - assertEquals(origName, rs.getString("name")); - assertEquals(player.getLocation().getX(), rs.getDouble("location_x"), 0.01d); - assertEquals(player.getLocation().getY(), rs.getDouble("location_y"), 0.01d); - assertEquals(player.getLocation().getZ(), rs.getDouble("location_z"), 0.01d); - assertEquals(player.getLocation().getYaw(), rs.getFloat("location_yaw"), 0.01f); - assertEquals(player.getLocation().getPitch(), rs.getFloat("location_pitch"), 0.01f); - assertEquals(player.getWorld().getName(), rs.getString("location_world")); - }); - } - - @Test(expected = SQLException.class) - public void testUpdateLocationNull() throws SQLException { - playerDAO.insert(player); - - player.setLocation(null); - playerDAO.updateLocation(player); - } - - @Test - public void testRemove() throws SQLException { - playerDAO.insert(player); - - final int origId = player.getId(); - playerDAO.remove(player); - assertEquals(0, player.getId()); - - final String sql = "SELECT COUNT(*) FROM players WHERE id = ?"; - jdbcTemplate.query(sql, - ps -> ps.setInt(1, origId), - rs -> {assertEquals(0, rs.getInt(1));}); - } - - @Test(expected = SQLException.class) - public void testRemoveNonExistsId() throws SQLException { - playerDAO.insert(player); - - player.setId(999); - playerDAO.remove(player); - } -} diff --git a/h2_playermanager/src/test/java/mc/core/h2db/TestH2PlayerManager.java b/h2_playermanager/src/test/java/mc/core/h2db/TestH2PlayerManager.java index f2780a4..7a83b65 100644 --- a/h2_playermanager/src/test/java/mc/core/h2db/TestH2PlayerManager.java +++ b/h2_playermanager/src/test/java/mc/core/h2db/TestH2PlayerManager.java @@ -1,48 +1,33 @@ package mc.core.h2db; import mc.core.EntityLocation; +import mc.core.h2db.service.H2PlayerService; import mc.core.player.Player; import mc.core.world.World; -import org.apache.commons.io.IOUtils; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationContext; -import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.sql.SQLException; import java.util.List; import static org.junit.Assert.*; @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = {SpringConfig.class}) +@ContextConfiguration(classes = {TestSpringConfig.class}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) public class TestH2PlayerManager { @Autowired - private ApplicationContext context; - @Autowired - private JdbcTemplate jdbcTemplate; - @Autowired - private H2PlayerDAO h2PlayerDAO; + private H2PlayerService h2PlayerService; @Autowired private World mockWorld; + @Autowired private H2PlayerManager playerManager; - @Before - public void before() throws IOException { - playerManager = context.getBean(H2PlayerManager.class); - - jdbcTemplate.execute(IOUtils.resourceToString("/sqls/drop_table_players.sql", StandardCharsets.UTF_8)); - jdbcTemplate.execute(IOUtils.resourceToString("/sqls/create_tables.sql", StandardCharsets.UTF_8)); - } - @Test - public void testCreatePlayer() throws SQLException { + public void testCreatePlayer() { final String playerName = "NEW_PLAYER"; final Player newPlayer = playerManager.createPlayer(playerName, EntityLocation.ZERO(), mockWorld); @@ -50,9 +35,7 @@ public class TestH2PlayerManager { assertEquals(H2Player.class, newPlayer.getClass()); assertTrue(newPlayer.getId() > 0); - final H2Player queryPlayer = new H2Player(); - queryPlayer.setName(playerName); - h2PlayerDAO.getByName(queryPlayer); + final H2Player queryPlayer = h2PlayerService.getByName(playerName); assertTrue(queryPlayer.getId() > 0); assertEquals(newPlayer, queryPlayer); @@ -74,7 +57,7 @@ public class TestH2PlayerManager { } @Test - public void testLeftServer() throws SQLException { + public void testLeftServer() { assertEquals(0, playerManager.getCountPlayers()); final String playerName = "NEW_PLAYER"; @@ -96,11 +79,9 @@ public class TestH2PlayerManager { assertFalse(player.isOnline()); assertTrue(player.getLoadedChunks().isEmpty()); - H2Player queryPlayer = new H2Player(); - queryPlayer.setId(playerId); - boolean result = h2PlayerDAO.getById(queryPlayer); + final H2Player queryPlayer = h2PlayerService.getById(playerId); - assertTrue(result); + assertNotNull(queryPlayer); ((H2Player)player).setId(playerId); assertEquals(player, queryPlayer); } diff --git a/h2_playermanager/src/test/java/mc/core/h2db/TestSpringConfig.java b/h2_playermanager/src/test/java/mc/core/h2db/TestSpringConfig.java new file mode 100644 index 0000000..5ff647b --- /dev/null +++ b/h2_playermanager/src/test/java/mc/core/h2db/TestSpringConfig.java @@ -0,0 +1,90 @@ +package mc.core.h2db; + +import mc.core.h2db.service.H2PlayerService; +import mc.core.world.World; +import org.hibernate.jpa.HibernatePersistenceProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.orm.jpa.JpaTransactionManager; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.persistence.EntityManagerFactory; +import javax.sql.DataSource; +import java.util.Properties; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@Configuration +@EnableJpaRepositories +@EnableTransactionManagement +@ComponentScan("mc.core.h2db") +public class TestSpringConfig { + private static final String DATABASE_DRIVER = "org.h2.Driver"; + private static final String DATABASE_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"; + private static final String DATABASE_USERNAME = "sa"; + private static final String DATABASE_PASSWORD = "s3cReT"; + + static { + System.setProperty("org.jboss.logging.provider", "slf4j"); + } + + private Properties hibernateProp() { + Properties properties = new Properties(); + properties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + properties.put("hibernate.show_sql", "true"); + properties.put("hibernate.format_sql", "true"); + properties.put("hibernate.use_sql_comments", "true"); + properties.put("hibernate.hbm2ddl.auto", "create"); + + return properties; + } + + @Bean + public World mockWorld() { + World mockWorld = mock(World.class); + when(mockWorld.getName()).thenReturn("mock_world"); + return mockWorld; + } + + @Bean + public DataSource dataSource() { + DriverManagerDataSource dmds = new DriverManagerDataSource(); + dmds.setDriverClassName(DATABASE_DRIVER); + dmds.setUrl(DATABASE_URL); + dmds.setUsername(DATABASE_USERNAME); + dmds.setPassword(DATABASE_PASSWORD); + + return dmds; + } + + @Bean + public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) { + LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); + entityManagerFactoryBean.setDataSource(dataSource); + entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistenceProvider.class); + entityManagerFactoryBean.setPackagesToScan("mc.core.h2db.entity"); + entityManagerFactoryBean.setJpaProperties(hibernateProp()); + + return entityManagerFactoryBean; + } + + @Bean + public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { + JpaTransactionManager transactionManager = new JpaTransactionManager(); + transactionManager.setEntityManagerFactory(entityManagerFactory); + + return transactionManager; + } + + @Bean + public H2PlayerManager h2PlayerManager(H2PlayerService h2PlayerService) { + H2PlayerManager playerManager = new H2PlayerManager(); + playerManager.setH2PlayerService(h2PlayerService); + return playerManager; + } +} diff --git a/h2_playermanager/src/test/java/mc/core/h2db/service/H2PlayerServiceTest.java b/h2_playermanager/src/test/java/mc/core/h2db/service/H2PlayerServiceTest.java new file mode 100644 index 0000000..6b2ff03 --- /dev/null +++ b/h2_playermanager/src/test/java/mc/core/h2db/service/H2PlayerServiceTest.java @@ -0,0 +1,133 @@ +package mc.core.h2db.service; + +import mc.core.EntityLocation; +import mc.core.h2db.H2Player; +import mc.core.h2db.TestSpringConfig; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {TestSpringConfig.class}) +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class H2PlayerServiceTest { + @Autowired + private H2PlayerService h2PlayerService; + + private H2Player buildPlayer() { + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final double minD = 0.0d, maxD = 10.0d; + final float minF = 0.0f, maxF = 359.9f; + final int minI = 1000, maxI = 9999; + + final H2Player player = new H2Player(); + player.setUuid(UUID.randomUUID()); + player.setName("player" + rnd.nextInt(minI, maxI)); + player.setLocation(new EntityLocation( + rnd.nextDouble(minD, maxD), + rnd.nextDouble(minD, maxD), + rnd.nextDouble(minD, maxD), + rnd.nextFloat() * (maxF - minF) + minF, + rnd.nextFloat() * (maxF - minF) + minF + )); + player.setWorld(null); //FIXME + + return player; + } + + @Test + public void save() { + H2Player player = buildPlayer(); + H2Player savedPlayer = h2PlayerService.save(player); + + player.setId(savedPlayer.getId()); //FIXME костыль, однако + Assert.assertEquals(player, savedPlayer); + } + + @Test(expected = Exception.class) + public void save_NameEmpty() { + H2Player player = buildPlayer(); + player.setName(""); + h2PlayerService.save(player); + } + + @Test(expected = Exception.class) + public void save_NameNull() { + H2Player player = buildPlayer(); + player.setName(null); + h2PlayerService.save(player); + } + + @Test(expected = Exception.class) + public void save_UuidNull() { + H2Player player = buildPlayer(); + player.setUuid(null); + h2PlayerService.save(player); + } + + @Test(expected = Exception.class) + public void save_LocationNull() { + H2Player player = buildPlayer(); + player.setLocation(null); + h2PlayerService.save(player); + } + + @Test + public void remove() { + H2Player player = h2PlayerService.save(buildPlayer()); + h2PlayerService.remove(player); + + H2Player player2 = h2PlayerService.getById(player.getId()); + Assert.assertNull(player2); + } + + @Test(expected = Exception.class) + public void remove_NotExists() { + H2Player player = h2PlayerService.save(buildPlayer()); + h2PlayerService.remove(player); + h2PlayerService.remove(player); + } + + @Test + public void getByName() { + H2Player player = h2PlayerService.save(buildPlayer()); + + H2Player player2 = h2PlayerService.getByName(player.getName()); + Assert.assertEquals(player, player2); + } + + @Test + public void getByName_NotExists() { + Assert.assertNull(h2PlayerService.getByName("UNKNOW_PLAYER")); + } + + @Test + public void getByName_Empty() { + Assert.assertNull(h2PlayerService.getByName("")); + } + + @Test + public void getByName_Null() { + Assert.assertNull(h2PlayerService.getByName(null)); + } + + @Test + public void getById() { + H2Player player = h2PlayerService.save(buildPlayer()); + + H2Player player2 = h2PlayerService.getById(player.getId()); + Assert.assertEquals(player, player2); + } + + @Test + public void getById_NotExists() { + Assert.assertNull(h2PlayerService.getById(9999)); + } +} diff --git a/h2_playermanager/src/test/resources/sqls/drop_table_players.sql b/h2_playermanager/src/test/resources/sqls/drop_table_players.sql deleted file mode 100644 index dd4ab91..0000000 --- a/h2_playermanager/src/test/resources/sqls/drop_table_players.sql +++ /dev/null @@ -1,3 +0,0 @@ -DROP INDEX IF EXISTS idx_players_uuid; -DROP INDEX IF EXISTS idx_players_name; -DROP TABLE IF EXISTS players; \ No newline at end of file