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").
This commit is contained in:
lantzelot-swe 2023-08-20 22:15:42 +02:00
parent f316ba2867
commit ab55621269
4 changed files with 144 additions and 21 deletions

View File

@ -11,6 +11,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -359,6 +361,135 @@ public class DbConnector
return returnList; 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<Integer, Integer> 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) private int updateDiskCount(String disk, int fileCount)
{ {
if (disk != null && !disk.isEmpty()) if (disk != null && !disk.isEmpty())

View File

@ -46,9 +46,8 @@ public class GamebaseImportWorker extends AbstractImportWorker
importManager.setViewName(viewName); importManager.setViewName(viewName);
String additonalInfo = ", genre: " + genre.getGenreName() + " (" + counter + " of " + numberOfGenres + ")"; String additonalInfo = ", genre: " + genre.getGenreName() + " (" + counter + " of " + numberOfGenres + ")";
int processedForGenre = executeImport(additonalInfo); int processedForGenre = executeImport(additonalInfo);
//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
createAdditionalGameViews(processedForGenre, viewName); importManager.createAndUpdateGameViewForImportedGBGames(viewName);
totalProcessed = totalProcessed + processedForGenre; totalProcessed = totalProcessed + processedForGenre;
} }
publish("Processed " + totalProcessed + " games."); 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) private String getViewName(GenreInfo info)
{ {
String newName = info.getGenreName(); String newName = info.getGenreName();
newName = newName.replaceAll("/", " ");
newName = newName.replaceAll(" - ", "/"); newName = newName.replaceAll(" - ", "/");
newName = newName.replace("[", ""); newName = newName.replace("[", "");
newName = newName.replace("]", ""); newName = newName.replace("]", "");

View File

@ -258,6 +258,11 @@ public class ImportManager
uiModel.saveGameView(newView); uiModel.saveGameView(newView);
} }
} }
public void createAndUpdateGameViewForImportedGBGames(String mainViewName)
{
uiModel.createAndUpdateGameViewForImportedGBGames(mainViewName);
}
public void readGameInfoFiles(PublishWorker worker) public void readGameInfoFiles(PublishWorker worker)
{ {

View File

@ -534,6 +534,11 @@ public class MainViewModel extends AbstractModel
{ {
dbConnector.saveGameView(gameView); dbConnector.saveGameView(gameView);
} }
public void createAndUpdateGameViewForImportedGBGames(String mainGameView)
{
dbConnector.createAndUpdateGameViewForImportedGBGames(mainGameView);
}
public void addSaveChangeListener(PropertyChangeListener saveChangeListener) public void addSaveChangeListener(PropertyChangeListener saveChangeListener)
{ {