feat: gbimporter: add games in batches of 50

This commit is contained in:
lantzelot-swe 2021-03-06 23:49:19 +01:00
parent 0b3e77bbc1
commit 4a98e9ab3f
7 changed files with 123 additions and 61 deletions

View File

@ -10,7 +10,9 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -65,6 +67,11 @@ public class DbConnector
// @J+
private static final Logger logger = LoggerFactory.getLogger(DbConnector.class);
private List<String> columnList = new ArrayList<>();
/**
* Map keeping track of duplicate indexes when importing several games at once.
*/
Map<String, Integer> duplicateMap = new HashMap<>();
List<String> addedRowsList = new ArrayList<>();
public DbConnector()
{
@ -456,14 +463,23 @@ public class DbConnector
//Check which are already available and sort them out of rowValues
for (String rowValue : rowValues)
{
String[] splittedRowValue = rowValue.split(COMMA);
String[] splittedRowValue = rowValue.split(COMMA);
String title = splittedRowValue[0];
if (addedRowsList.contains(rowValue.substring(0, rowValue.indexOf(","))))
{
//Add game, another one has been added with the same title, no one was available in the db at that point.
infoBuilder.append("Not available, adding to db\n");
logger.debug("Game: {} is not available, adding to db", title);
newRowValues.add(rowValue);
continue;
}
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT COUNT(*) FROM gameinfo WHERE title = ");
sqlBuilder.append(splittedRowValue[0]);
sqlBuilder.append(title);
sqlBuilder.append("\" COLLATE NOCASE;");
String sql = sqlBuilder.toString();
infoBuilder.append("Checking game ");
infoBuilder.append(splittedRowValue[0].substring(1));
infoBuilder.append(title.substring(1));
infoBuilder.append(": ");
logger.debug("Checking game: {}", sql);
@ -474,13 +490,13 @@ public class DbConnector
if (rs.getInt(1) == 0)
{
infoBuilder.append("Not available, adding to db\n");
logger.debug("Game: {} is not available, adding to db", splittedRowValue[0]);
logger.debug("Game: {} is not available, adding to db", title);
newRowValues.add(rowValue);
}
else
{
infoBuilder.append("Already available, skipping\n");
logger.debug("Game: {} is already available, skipping.", splittedRowValue[0]);
logger.debug("Game: {} is already available, skipping.", title);
}
}
catch (SQLException e)
@ -554,6 +570,8 @@ public class DbConnector
{
int value = pstmt.executeUpdate();
logger.debug("Executed successfully, value = {}", value);
//Add game title to keep track of added games
rowValues.stream().forEach(row -> addedRowsList.add(row.substring(0, row.indexOf(','))));
}
catch (SQLException e)
{
@ -615,7 +633,16 @@ public class DbConnector
}
sqlBuilder.append(" WHERE title = ");
sqlBuilder.append(title);
sqlBuilder.append("\" AND Duplicate = 0 COLLATE NOCASE;");
sqlBuilder.append("\" AND Duplicate = ");
//Keep track of multiple duplicate numbers, increase for each
int duplicateNumber = 0;
if (duplicateMap.containsKey(title))
{
duplicateNumber = duplicateMap.get(title);
}
duplicateMap.put(title, duplicateNumber + 1);
sqlBuilder.append(duplicateNumber);
sqlBuilder.append(" COLLATE NOCASE;");
String sql = sqlBuilder.toString();
logger.debug("Generated UPDATE String:\n{}", sql);
try (Connection conn = this.connect(); PreparedStatement pstmt = conn.prepareStatement(sql))
@ -967,4 +994,10 @@ public class DbConnector
ExceptionHandler.handleException(e, "Could not clear favorite values in db.");
}
}
public void cleanupAfterImport()
{
addedRowsList.clear();
duplicateMap.clear();
}
}

View File

@ -53,38 +53,26 @@ public class GamebaseImporter
String joyBase = ":JU,JD,JL,JR,JF,JF,SP,EN,,F1,F3,F5,,,";
String joy1config;
String joy2config;
//Setup advanced string (system, sid, pal, truedrive etc)
String advanced = "sid6581";
if (isC64)
{
advanced = "64," + advanced;
}
else
{
advanced = "vic," + advanced;
}
try (Connection connection = DriverManager.getConnection(databaseURL))
{
Statement statement = connection.createStatement();
//Get views
//
// String sql = "SELECT * FROM ViewData";
//
// ResultSet result = statement.executeQuery(sql);
// while (result.next())
// {
// String title = result.getString("Title");
// System.out.println("view: " + title);
// }
String sql = "SELECT * FROM ViewData";
String sql =
"SELECT TOP 300 Games.Name, Musicians.Musician, Genres.Genre, Publishers.Publisher, Games.Filename, Games.ScrnshotFilename, Years.Year, Games.GA_Id, Games.Control, Games.V_PalNTSC, Games.V_TrueDriveEmu, Games.Gemus\r\n" +
"FROM Years INNER JOIN (Publishers INNER JOIN ((Games INNER JOIN Musicians ON Games.MU_Id = Musicians.MU_Id) INNER JOIN Genres ON Games.GE_Id = Genres.GE_Id) ON Publishers.PU_Id = Games.PU_Id) ON Years.YE_Id = Games.YE_Id\r\n" +
"WHERE (((Games.Name) LIKE 'a*'));";
ResultSet result = statement.executeQuery(sql);
while (result.next())
{
String title = result.getString("Title");
System.out.println("view: " + title);
}
sql =
"SELECT Games.Name, Musicians.Musician, Genres.Genre, Publishers.Publisher, Games.Filename, Games.ScrnshotFilename, Years.Year, Games.GA_Id, Games.Control, Games.V_PalNTSC, Games.V_TrueDriveEmu, Games.Gemus\r\n" +
"FROM Years INNER JOIN (Publishers INNER JOIN ((Games INNER JOIN Musicians ON Games.MU_Id = Musicians.MU_Id) INNER JOIN Genres ON Games.GE_Id = Genres.GE_Id) ON Publishers.PU_Id = Games.PU_Id) ON Years.YE_Id = Games.YE_Id\r\n" +
"WHERE (((Games.Name) LIKE 'alien attack'));";
result = statement.executeQuery(sql);
int gameCount = 0;
while (result.next())
{
@ -110,18 +98,13 @@ public class GamebaseImporter
continue;
}
//Setup video mode
//0=PAL, 1=BOTH, 2=NTSC, 3=PAL[+NTSC?]
String video = (palOrNtsc == 2) ? "ntsc" : "pal";
advanced = advanced + "," + video;
//Setup truedrive
if (trueDriveEmu > 0 || "vte=yes".equalsIgnoreCase(gemus))
{
advanced = advanced + "," + "driveicon,accuratedisk";
}
//Setup advanced string (system, sid, pal, truedrive etc)
String advanced = constructAdvancedString(palOrNtsc, trueDriveEmu, gemus);
//Control: 0=JoyPort2, 1=JoyPort1, 2=Keyboard, 3=PaddlePort2, 4=PaddlePort1, 5=Mouse, 6=LightPen, 7=KoalaPad, 8=LightGun
//Setup joystick port
String joy1config;
String joy2config;
if (control == 1)
{
//1 means joystick port 1 in the gb database
@ -158,8 +141,7 @@ public class GamebaseImporter
{
coverFile = gbDatabasePath.toString() + "\\extras\\" + coverFile;
}
//Get cartridge if available, easyflash is preferred
String cartridgeSql =
"SELECT Extras.Name, Extras.Path\r\n" + "FROM Games INNER JOIN Extras ON Games.GA_Id = Extras.GA_Id\r\n" +
@ -188,8 +170,7 @@ public class GamebaseImporter
//Fix game file
gamefile = getFileToInclude(gbDatabasePath, gamefile);
importManager.addFromGamebaseImporter(title,
year,
publisher,
@ -219,6 +200,30 @@ public class GamebaseImporter
}
return builder;
}
private String constructAdvancedString(int palOrNtsc, int trueDriveEmu, String gemus)
{
//Setup advanced string (system, sid, pal, truedrive etc)
String advanced = "sid6581";
if (isC64)
{
advanced = "64," + advanced;
}
else
{
advanced = "vic," + advanced;
}
//Setup video mode
//0=PAL, 1=BOTH, 2=NTSC, 3=PAL[+NTSC?]
String video = (palOrNtsc == 2) ? "ntsc" : "pal";
advanced = advanced + "," + video;
//Setup truedrive
if (trueDriveEmu > 0 || "vte=yes".equalsIgnoreCase(gemus))
{
advanced = advanced + "," + "driveicon,accuratedisk";
}
return advanced;
}
private String getScreen2(String screen1)
{

View File

@ -1,5 +1,6 @@
package se.lantz.gui.imports;
import java.util.ArrayList;
import java.util.List;
import javax.swing.SwingWorker;
@ -30,13 +31,17 @@ public class CarouselImportWorker extends SwingWorker<Void, String>
importManager.convertIntoDbRows(infoBuilder);
publish(infoBuilder.toString());
publish("Importing to db...");
publish(importManager.insertRowsIntoDb().toString());
publish("Copying screenshots, covers and game files...");
for (List<String> rowList : importManager.getDbRowReadChunks())
{
publish(importManager.copyFiles(false, rowList).toString());
//Copy the list to avoid modifying it when reading several chunks
ArrayList<String> copyList = new ArrayList<>();
copyList.addAll(rowList);
publish(importManager.insertRowsIntoDb(copyList).toString());
publish("Copying screenshots, covers and game files...");
publish(importManager.copyFiles(false, copyList).toString());
}
importManager.clearAfterImport();
int numberOfGamesProcessed = importManager.clearAfterImport();
publish("Imported " + numberOfGamesProcessed + " games.");
publish("Done!");
return null;
}

View File

@ -1,5 +1,6 @@
package se.lantz.gui.imports;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
@ -28,13 +29,17 @@ public class GamebaseImportWorker extends SwingWorker<Void, String>
publish("Reading from gamebase db...");
publish(gbInporter.importFromGamebase().toString());
publish("Importing to db...");
publish(importManager.insertRowsIntoDb().toString());
publish("Copying screenshots, covers and game files...");
for (List<String> rowList : importManager.getDbRowReadChunks())
{
publish(importManager.copyFiles(true, rowList).toString());
//Copy the list to avoid modifying it when reading several chunks
ArrayList<String> copyList = new ArrayList<>();
copyList.addAll(rowList);
publish(importManager.insertRowsIntoDb(copyList).toString());
publish("Copying screenshots, covers and game files...");
publish(importManager.copyFiles(true, copyList).toString());
}
importManager.clearAfterImport();
int numberOfGamesProcessed = importManager.clearAfterImport();
publish("Imported " + numberOfGamesProcessed + " games.");
publish("Done!");
return null;
}

View File

@ -98,6 +98,11 @@ public class ImportOptionsPanel extends JPanel
if (overwriteRadioButton == null) {
overwriteRadioButton = new JRadioButton("Overwrite with imported game");
buttonGroup.add(overwriteRadioButton);
if (!this.isCarouselImport)
{
//Too complex to overwrite several duplicates, don't allow it.
overwriteRadioButton.setVisible(false);
}
}
return overwriteRadioButton;
}

View File

@ -1,8 +1,5 @@
package se.lantz.manager;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
@ -32,6 +29,10 @@ import se.lantz.util.FileManager;
public class ImportManager
{
/**
* The size of each chunk when importing games
*/
private static final int DB_ROW_CHUNK_SIZE = 50;
public enum Options
{
SKIP, OVERWRITE, ADD;
@ -133,11 +134,11 @@ public class ImportManager
gameInfoFilesMap.values().stream().forEach(list -> extractInfoIntoRowString(list, infoBuilder));
}
public StringBuilder insertRowsIntoDb()
public StringBuilder insertRowsIntoDb(List<String> rowList)
{
return uiModel.importGameInfo(dbRowDataList, selectedOption, addAsFavorite);
return uiModel.importGameInfo(rowList, selectedOption, addAsFavorite);
}
private void extractInfoIntoRowString(List<String> fileLines, StringBuilder infoBuilder)
{
String title = "";
@ -468,7 +469,7 @@ public class ImportManager
public List<List<String>> getDbRowReadChunks()
{
return Lists.partition(dbRowDataList, 50);
return Lists.partition(dbRowDataList, DB_ROW_CHUNK_SIZE);
}
public StringBuilder copyFiles(boolean gamebaseImport, List<String> rowList)
@ -592,9 +593,12 @@ public class ImportManager
}
}
public void clearAfterImport()
public int clearAfterImport()
{
int size = dbRowDataList.size();
dbRowDataList.clear();
gameInfoFilesMap.clear();
uiModel.cleanupAfterImport();
return size;
}
}

View File

@ -192,6 +192,11 @@ public class MainViewModel extends AbstractModel
{
return dbConnector.importRowsInGameInfoTable(rowValues, option, addAsFavorite);
}
public void cleanupAfterImport()
{
dbConnector.cleanupAfterImport();
}
public List<GameDetails> readGameDetailsForExport(StringBuilder infoBuilder, List<GameListData> gamesList)
{