diff --git a/pom.xml b/pom.xml index 6bd5f9946ef2b3a7ffee8f8f073582471b9caa25..3f573e8109b05f701496142c58517070b5138874 100644 --- a/pom.xml +++ b/pom.xml @@ -1,6 +1,4 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>vsb-cs-java1</groupId> <artifactId>lab08</artifactId> @@ -12,6 +10,11 @@ <maven.compiler.target>17</maven.compiler.target> </properties> <dependencies> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derby</artifactId> + <version>10.16.1.1</version> + </dependency> <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx-controls</artifactId> diff --git a/src/main/java/lab/GameController.java b/src/main/java/lab/GameController.java index 2fee0eb6d7873da8ef23d3fcca6b423acb18222e..d06114d4823ae60560686001858380948472facc 100644 --- a/src/main/java/lab/GameController.java +++ b/src/main/java/lab/GameController.java @@ -1,10 +1,6 @@ package lab; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; -import java.io.PrintWriter; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; @@ -51,10 +47,13 @@ public class GameController { private AnimationTimer animationTimer; + private ScoreDAO scoreDAO; + public GameController() { } public void startGame() { + scoreDAO = new ScoreDAO(); initScoreList(); this.world = new World(canvas.getWidth(), canvas.getHeight()); @@ -110,24 +109,15 @@ public class GameController { @FXML private void savePressed() throws IOException { - try(PrintWriter pw = new PrintWriter(new FileWriter("high_score.csv"))){ - for(Score score: highScores) { - pw.printf("%s;%d\n", score.getName(), score.getScore()); - } - } + scoreDAO.save(highScores); } @FXML private void loadPressed() throws IOException{ highScores.clear(); - try(BufferedReader br = new BufferedReader(new FileReader("high_score.csv"))){ - String line; - while(null != (line = br.readLine())) { - String [] tokens = line.split(";"); - highScores.add(new Score(Integer.parseInt(tokens[1]), tokens[0])); - } - } + highScores.addAll(scoreDAO.load()); + sortScores(); initScoreList(); } diff --git a/src/main/java/lab/Score.java b/src/main/java/lab/Score.java index e7f8bc7683790e1a4d8fef80971c33024c0dd778..a64c2b37c9e055af0109e2d3cb3eff10a13bd79d 100644 --- a/src/main/java/lab/Score.java +++ b/src/main/java/lab/Score.java @@ -5,11 +5,18 @@ import java.io.Serializable; public class Score implements Serializable{ private static final long serialVersionUID = 712213568495641939L; - + private Integer id; private final int score; private final String name; + + public Score(int score, String name) { - super(); + this(null, score, name); + } + + + public Score(Integer id, int score, String name) { + this.id = id; this.score = score; this.name = name; } @@ -22,6 +29,14 @@ public class Score implements Serializable{ public int getScore() { return score; } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } @Override public String toString() { diff --git a/src/main/java/lab/ScoreDAO.java b/src/main/java/lab/ScoreDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..8bfdc72c611269a7906633bcefbddc84143ee9d2 --- /dev/null +++ b/src/main/java/lab/ScoreDAO.java @@ -0,0 +1,128 @@ +package lab; + +import static java.util.stream.Collectors.toSet; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class ScoreDAO { + + public ScoreDAO() { + + try (Connection conn = getConnection()) { + createTable(conn); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + public List<Score> load( ){ + List<Score> result = new LinkedList<>(); + try(Connection con = getConnection(); Statement stmt = con.createStatement()) { + try(ResultSet rs = stmt.executeQuery("SELECT id, value, name FROM score")) { + while (rs.next()) { + result.add(new Score(rs.getInt(1), rs.getInt(2), rs.getString(3))); + } + } + } catch (SQLException e) { + e.printStackTrace(); + } + return result ; + } + + public void save(List<Score> scores) { + + /*Set<Integer> m = new HashSet<>(); + for (Score score: scores) { + if (score.getId() == null) { + continue; + } + m.add(score.getId()); + }*/ + Set<Integer> m = scores.stream() + .filter(s -> s.getId() != null) + .map(Score::getId) + .collect(toSet()); + Set<Integer> d = load().stream().map(Score::getId).collect(Collectors.toSet()); + d.removeAll(m); + Set<Integer> idsOnlyInDB = d; + removeByIDS(idsOnlyInDB); + List<Score> scoreSaved = new LinkedList<>(); + try (Connection con = getConnection(); + PreparedStatement pstmt = con.prepareStatement("INSERT INTO score (value, name) VALUES (?, ?)" + , Statement.RETURN_GENERATED_KEYS)) { + for (Score score: scores) { + if (score.getId() != null) { + continue; + } + pstmt.setInt(1, score.getScore()); + pstmt.setString(2, score.getName()); + pstmt.addBatch(); + scoreSaved.add(score); + } + if (!scoreSaved.isEmpty()) { + pstmt.executeBatch(); + ResultSet rs = pstmt.getGeneratedKeys(); + Iterator<Score> iter = scoreSaved.iterator(); + while (rs.next()) { + Score score = iter.next(); + score.setId(rs.getInt(1)); + } + } + + } catch (SQLException e) { + e.printStackTrace(); + } + } + + private void removeByIDS(Set<Integer> idsOnlyInDB) { + try(Connection con = getConnection(); + PreparedStatement pstmt = con.prepareStatement("DELETE FROM score WHERE id = ?")) { + + for (Integer id: idsOnlyInDB) { + pstmt.setInt(1, id); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } catch (SQLException e) { + e.printStackTrace(); + } + + } + + private void createTable(Connection conn) { + try (Statement stmt = conn.createStatement()){ + stmt.execute("CREATE TABLE score (" + + "id INT NOT NULL GENERATED ALWAYS AS IDENTITY, " + + "value INT NOT NULL, " + + "name VARCHAR(255) NOT NULL, " + + "PRIMARY KEY (id)" + + ")"); + } catch (SQLException e) { + if (e.getSQLState().equals("X0Y32")) { + //ignore this because table exists + return; + } + e.printStackTrace(); + } + + } + + private Connection getConnection() { + try { + return DriverManager.getConnection("jdbc:derby:scoreDB;create=true"); + } catch (SQLException e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 7006c78362486c4b03983ff6ea1321d95ca1ed40..94ff2e3c1f5017f07edc93063d29acfbfad56630 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,6 +1,7 @@ module lab01 { requires transitive javafx.controls; requires javafx.fxml; + requires java.sql; opens lab to javafx.fxml; exports lab; } \ No newline at end of file