From ab556212699389a7386822d071861d8723e179ea Mon Sep 17 00:00:00 2001 From: lantzelot-swe <75668734+lantzelot-swe@users.noreply.github.com> Date: Sun, 20 Aug 2023 22:15:42 +0200 Subject: [PATCH] fix: #16 Imported games from gamebase are sorted into game views Game views are created so that each contain a maximum of 250 files. Games are sorted alphabetically and the game views are named after the first letter of the first and last game in the view (e.g. "A-E"). --- src/main/java/se/lantz/db/DbConnector.java | 131 ++++++++++++++++++ .../gui/imports/GamebaseImportWorker.java | 24 +--- .../java/se/lantz/manager/ImportManager.java | 5 + .../java/se/lantz/model/MainViewModel.java | 5 + 4 files changed, 144 insertions(+), 21 deletions(-) diff --git a/src/main/java/se/lantz/db/DbConnector.java b/src/main/java/se/lantz/db/DbConnector.java index aa3337a..6d6ec3a 100644 --- a/src/main/java/se/lantz/db/DbConnector.java +++ b/src/main/java/se/lantz/db/DbConnector.java @@ -11,6 +11,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -359,6 +361,135 @@ public class DbConnector return returnList; } + public void createAndUpdateGameViewForImportedGBGames(String mainViewTag) + { + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("SELECT rowid, disk2, disk3, disk4, disk5, disk6 FROM gameinfo WHERE Viewtag LIKE '"); + sqlBuilder.append(mainViewTag.replaceAll("'", "''")); + sqlBuilder.append("' ORDER BY title COLLATE NOCASE ASC"); + + //Map containing gameId and diskCount for each game + LinkedHashMap sortedGameMap = new LinkedHashMap<>(); + + logger.debug("Generated View SQL: {}", sqlBuilder); + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sqlBuilder.toString())) + { + // loop through the result set + while (rs.next()) + { + int additionalDiskCount = 0; + additionalDiskCount = updateDiskCount(rs.getString("disk2"), additionalDiskCount); + additionalDiskCount = updateDiskCount(rs.getString("disk3"), additionalDiskCount); + additionalDiskCount = updateDiskCount(rs.getString("disk4"), additionalDiskCount); + additionalDiskCount = updateDiskCount(rs.getString("disk5"), additionalDiskCount); + additionalDiskCount = updateDiskCount(rs.getString("disk6"), additionalDiskCount); + sortedGameMap.put(rs.getInt("rowId"), additionalDiskCount); + } + } + catch (SQLException e) + { + ExceptionHandler.handleException(e, "Could not fetch all games for updating game views during gb import"); + } + int viewNumber = 1; + int i = 0; + int additionalDiskCount = 0; + + int firstGameInView = -1; + int lastGameInView = -1; + //Loop through and update gameView for games + for (Integer gameId : sortedGameMap.keySet()) + { + if (i == 0) + { + firstGameInView = gameId; + } + additionalDiskCount = additionalDiskCount + sortedGameMap.get(gameId); + if (((i + additionalDiskCount) / 250) > (viewNumber - 1)) + { + //Rename previous game view before creating a new one + renameGameView(mainViewTag, viewNumber, firstGameInView, lastGameInView); + + viewNumber++; + //Create new game view + String name = mainViewTag + "/" + viewNumber; + ViewFilter filter = new ViewFilter(DbConstants.VIEW_TAG, ViewFilter.EQUALS_TEXT, name, true); + GameView newView = new GameView(0); + newView.setViewFilters(Arrays.asList(filter)); + newView.setName(name.replaceAll("_", " ")); + saveGameView(newView); + firstGameInView = gameId; + } + else + { + lastGameInView = gameId; + } + if (viewNumber > 1) + { + //Tag with right game tag + setViewTag(gameId.toString(), mainViewTag.replaceAll("'", "''") + "/" + viewNumber); + } + i++; + } + //Rename the last view also + if (viewNumber > 1) + { + renameGameView(mainViewTag, viewNumber, firstGameInView, lastGameInView); + } + } + + private void renameGameView(String originalViewName, int viewNumber, int firstGameId, int lastGameId) + { + String firstGameTitle = ""; + String lastGameTitle = ""; + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("SELECT title FROM gameinfo WHERE rowId IN ("); + sqlBuilder.append(firstGameId); + sqlBuilder.append(", "); + sqlBuilder.append(lastGameId); + sqlBuilder.append(") ORDER BY title COLLATE NOCASE ASC"); + + logger.debug("Generated View SQL: {}", sqlBuilder); + try (Connection conn = this.connect(); Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sqlBuilder.toString())) + { + rs.next(); + firstGameTitle = rs.getString("title"); + rs.next(); + lastGameTitle = rs.getString("title"); + } + catch (SQLException e) + { + ExceptionHandler.handleException(e, "Could not fetch title by id"); + } + + String oldViewName = viewNumber > 1 ? originalViewName + "/" + viewNumber : originalViewName; + + //Always use "0" as for first view (sorting is a bit random...) + String firstGameLetter = viewNumber == 1 ? "0" : firstGameTitle.substring(0, 1).toUpperCase(); + String newViewName = originalViewName + "/" + firstGameLetter + "-" + + lastGameTitle.substring(0, 1).toUpperCase(); + + sqlBuilder = new StringBuilder(); + sqlBuilder.append(""); + + sqlBuilder.append("UPDATE gameview SET name = '"); + sqlBuilder.append(newViewName.replaceAll("'", "''")); + sqlBuilder.append("' WHERE name = '"); + sqlBuilder.append(oldViewName.replaceAll("'", "''")); + sqlBuilder.append("';"); + logger.debug("Generated update view SQL: {}", sqlBuilder); + try (Connection conn = this.connect(); + PreparedStatement gameViewstmt = conn.prepareStatement(sqlBuilder.toString())) + { + gameViewstmt.executeUpdate(); + } + catch (SQLException e) + { + ExceptionHandler.handleException(e, "Could not update gameview name during gb import"); + } + } + private int updateDiskCount(String disk, int fileCount) { if (disk != null && !disk.isEmpty()) diff --git a/src/main/java/se/lantz/gui/imports/GamebaseImportWorker.java b/src/main/java/se/lantz/gui/imports/GamebaseImportWorker.java index 669bf57..545e45f 100644 --- a/src/main/java/se/lantz/gui/imports/GamebaseImportWorker.java +++ b/src/main/java/se/lantz/gui/imports/GamebaseImportWorker.java @@ -46,9 +46,8 @@ public class GamebaseImportWorker extends AbstractImportWorker importManager.setViewName(viewName); String additonalInfo = ", genre: " + genre.getGenreName() + " (" + counter + " of " + numberOfGenres + ")"; int processedForGenre = executeImport(additonalInfo); - - createAdditionalGameViews(processedForGenre, viewName); - + //Read the games from the DB, create game views and edit the viewTag so that a max of 250 games ends up in each game view + importManager.createAndUpdateGameViewForImportedGBGames(viewName); totalProcessed = totalProcessed + processedForGenre; } publish("Processed " + totalProcessed + " games."); @@ -71,27 +70,10 @@ public class GamebaseImportWorker extends AbstractImportWorker } } - private void createAdditionalGameViews(int processedGames, String viewName) - { - //Lets use 250 as limit for each view - int numOfViews = processedGames / 250; - if (processedGames % 250 > 0) - { - numOfViews++; - } - for (int i = 2; i < (numOfViews + 1); i++) - { - //Create additional views that can be filled later by editing view tags - String name = viewName + "/" + i; - importManager.setViewName(name); - importManager.setViewTag(name); - importManager.createGameViewForViewTag(this); - } - } - private String getViewName(GenreInfo info) { String newName = info.getGenreName(); + newName = newName.replaceAll("/", " "); newName = newName.replaceAll(" - ", "/"); newName = newName.replace("[", ""); newName = newName.replace("]", ""); diff --git a/src/main/java/se/lantz/manager/ImportManager.java b/src/main/java/se/lantz/manager/ImportManager.java index 1a6df2f..969f2be 100644 --- a/src/main/java/se/lantz/manager/ImportManager.java +++ b/src/main/java/se/lantz/manager/ImportManager.java @@ -258,6 +258,11 @@ public class ImportManager uiModel.saveGameView(newView); } } + + public void createAndUpdateGameViewForImportedGBGames(String mainViewName) + { + uiModel.createAndUpdateGameViewForImportedGBGames(mainViewName); + } public void readGameInfoFiles(PublishWorker worker) { diff --git a/src/main/java/se/lantz/model/MainViewModel.java b/src/main/java/se/lantz/model/MainViewModel.java index c68b7ab..9c9eeee 100644 --- a/src/main/java/se/lantz/model/MainViewModel.java +++ b/src/main/java/se/lantz/model/MainViewModel.java @@ -534,6 +534,11 @@ public class MainViewModel extends AbstractModel { dbConnector.saveGameView(gameView); } + + public void createAndUpdateGameViewForImportedGBGames(String mainGameView) + { + dbConnector.createAndUpdateGameViewForImportedGBGames(mainGameView); + } public void addSaveChangeListener(PropertyChangeListener saveChangeListener) {