Improved new version cleanup and more:

* fixed db cleanup on new version (sets + cards);
 * fixed empty sets list after update;
 * fixed NPE errors in sets list on new install/version;
 * added joke sets filter to deckeditor.
This commit is contained in:
Oleg Agafonov 2019-01-06 15:41:30 +04:00
parent 554e8076cf
commit f01b3d3ca3
11 changed files with 243 additions and 112 deletions

View file

@ -3,6 +3,7 @@ package mage.client;
import mage.cards.action.ActionCallback; import mage.cards.action.ActionCallback;
import mage.cards.decks.Deck; import mage.cards.decks.Deck;
import mage.cards.repository.CardRepository; import mage.cards.repository.CardRepository;
import mage.cards.repository.RepositoryUtil;
import mage.client.cards.BigCard; import mage.client.cards.BigCard;
import mage.client.chat.ChatPanelBasic; import mage.client.chat.ChatPanelBasic;
import mage.client.components.*; import mage.client.components.*;
@ -212,6 +213,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
LOGGER.fatal(null, ex); LOGGER.fatal(null, ex);
} }
RepositoryUtil.bootstrapLocalDb();
ManaSymbols.loadImages(); ManaSymbols.loadImages();
Plugins.instance.loadPlugins(); Plugins.instance.loadPlugins();
@ -281,7 +283,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
if (Plugins.instance.isCounterPluginLoaded()) { if (Plugins.instance.isCounterPluginLoaded()) {
int i = Plugins.instance.getGamesPlayed(); int i = Plugins.instance.getGamesPlayed();
JLabel label = new JLabel(" Games played: " + String.valueOf(i)); JLabel label = new JLabel(" Games played: " + i);
desktopPane.add(label, JLayeredPane.DEFAULT_LAYER + 1); desktopPane.add(label, JLayeredPane.DEFAULT_LAYER + 1);
label.setVisible(true); label.setVisible(true);
label.setForeground(Color.white); label.setForeground(Color.white);
@ -1160,7 +1162,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
/** /**
* @param args the command line arguments * @param args the command line arguments
*/ */
public static void main(final String args[]) { public static void main(final String[] args) {
// Workaround for #451 // Workaround for #451
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true"); System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
LOGGER.info("Starting MAGE client version " + VERSION); LOGGER.info("Starting MAGE client version " + VERSION);

View file

@ -1,17 +1,15 @@
package mage.client.util.gui; package mage.client.util.gui;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.client.dialog.CheckBoxList;
import mage.client.dialog.PickCheckBoxDialog; import mage.client.dialog.PickCheckBoxDialog;
import mage.client.dialog.PickChoiceDialog; import mage.client.dialog.PickChoiceDialog;
import mage.client.dialog.CheckBoxList;
import javax.swing.*; import javax.swing.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/** /**
*
* @author JayDi85 * @author JayDi85
*/ */
public class FastSearchUtil { public class FastSearchUtil {
@ -19,27 +17,28 @@ public class FastSearchUtil {
public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion"; public static String DEFAULT_EXPANSION_SEARCH_MESSAGE = "Select set or expansion";
public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion"; public static String DEFAULT_EXPANSION_TOOLTIP_MESSAGE = "Fast search set or expansion";
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage){ public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage) {
showFastSearchForStringComboBox(combo, chooseMessage, 300, 500); showFastSearchForStringComboBox(combo, chooseMessage, 300, 500);
} }
/** /**
* Show fast choice modal dialog with incremental searching for any string combobox components * Show fast choice modal dialog with incremental searching for any string combobox components
* @param combo combobox control with default data model *
* @param combo combobox control with default data model
* @param chooseMessage caption message for dialog * @param chooseMessage caption message for dialog
*/ */
public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage, int windowWidth, int windowHeight){ public static void showFastSearchForStringComboBox(JComboBox combo, String chooseMessage, int windowWidth, int windowHeight) {
// fast search/choice dialog for string combobox // fast search/choice dialog for string combobox
mage.choices.Choice choice = new ChoiceImpl(false); mage.choices.Choice choice = new ChoiceImpl(false);
// collect data from expansion combobox (String) // collect data from expansion combobox (String)
DefaultComboBoxModel comboModel = (DefaultComboBoxModel)combo.getModel(); DefaultComboBoxModel comboModel = (DefaultComboBoxModel) combo.getModel();
Map<String, String> choiceItems = new HashMap<>(comboModel.getSize()); Map<String, String> choiceItems = new HashMap<>(comboModel.getSize());
Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize()); Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize());
String item; String item;
for(int i = 0; i < comboModel.getSize(); i++){ for (int i = 0; i < comboModel.getSize(); i++) {
item = comboModel.getElementAt(i).toString(); item = comboModel.getElementAt(i).toString();
choiceItems.put(item, item); choiceItems.put(item, item);
choiceSorting.put(item, i); // need so sorting choiceSorting.put(item, i); // need so sorting
@ -57,12 +56,12 @@ public class FastSearchUtil {
PickChoiceDialog dlg = new PickChoiceDialog(); PickChoiceDialog dlg = new PickChoiceDialog();
dlg.setWindowSize(windowWidth, windowHeight); dlg.setWindowSize(windowWidth, windowHeight);
dlg.showDialog(choice, needSelectValue); dlg.showDialog(choice, needSelectValue);
if(choice.isChosen()){ if (choice.isChosen()) {
item = choice.getChoiceKey(); item = choice.getChoiceKey();
// compatible select for object's models (use setSelectedIndex instead setSelectedObject) // compatible select for object's models (use setSelectedIndex instead setSelectedObject)
for(int i = 0; i < comboModel.getSize(); i++){ for (int i = 0; i < comboModel.getSize(); i++) {
if(comboModel.getElementAt(i).toString().equals(item)){ if (comboModel.getElementAt(i).toString().equals(item)) {
combo.setSelectedIndex(i); combo.setSelectedIndex(i);
} }
} }
@ -71,21 +70,22 @@ public class FastSearchUtil {
/** /**
* Show fast choice modal dialog with incremental searching for any string CheckBoxList components * Show fast choice modal dialog with incremental searching for any string CheckBoxList components
* @param combo CheckBoxList control with default data model *
* @param combo CheckBoxList control with default data model
* @param chooseMessage caption message for dialog * @param chooseMessage caption message for dialog
*/ */
public static void showFastSearchForStringComboBox(CheckBoxList combo, String chooseMessage){ public static void showFastSearchForStringComboBox(CheckBoxList combo, String chooseMessage) {
// fast search/choice dialog for string combobox // fast search/choice dialog for string combobox
mage.choices.Choice choice = new ChoiceImpl(false); mage.choices.Choice choice = new ChoiceImpl(false);
// collect data from expansion combobox (String) // collect data from expansion combobox (String)
DefaultListModel comboModel = (DefaultListModel)combo.getModel(); DefaultListModel comboModel = (DefaultListModel) combo.getModel();
Map<String, String> choiceItems = new HashMap<>(comboModel.getSize()); Map<String, String> choiceItems = new HashMap<>(comboModel.getSize());
Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize()); Map<String, Integer> choiceSorting = new HashMap<>(comboModel.getSize());
String item; String item;
for(int i = 0; i < comboModel.size(); i++){ for (int i = 0; i < comboModel.size(); i++) {
item = comboModel.getElementAt(i).toString(); item = comboModel.getElementAt(i).toString();
choiceItems.put(item, item); choiceItems.put(item, item);
choiceSorting.put(item, i); // need so sorting choiceSorting.put(item, i); // need so sorting
@ -96,21 +96,22 @@ public class FastSearchUtil {
choice.setMessage(chooseMessage); choice.setMessage(chooseMessage);
// current selection value restore // current selection value restore
String needSelectValue; String needSelectValue = null;
needSelectValue = comboModel.firstElement().toString(); if (comboModel.size() > 0) {
needSelectValue = comboModel.firstElement().toString();
}
// ask for new value // ask for new value
PickCheckBoxDialog dlg = new PickCheckBoxDialog(combo);
PickCheckBoxDialog dlg = new PickCheckBoxDialog(combo);
dlg.setWindowSize(300, 500); dlg.setWindowSize(300, 500);
dlg.showDialog(choice, needSelectValue); dlg.showDialog(choice, needSelectValue);
if(choice.isChosen()){ if (choice.isChosen()) {
item = choice.getChoiceKey(); item = choice.getChoiceKey();
// compatible select for object's models (use setSelectedIndex instead setSelectedObject) // compatible select for object's models (use setSelectedIndex instead setSelectedObject)
for(int i = 0; i < comboModel.getSize(); i++){ for (int i = 0; i < comboModel.getSize(); i++) {
if(comboModel.getElementAt(i).toString().equals(item)){ if (comboModel.getElementAt(i).toString().equals(item)) {
combo.setSelectedIndex(i); combo.setSelectedIndex(i);
} }
} }

View file

@ -1,17 +1,13 @@
package mage.client.util.sets; package mage.client.util.sets;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mage.cards.repository.ExpansionInfo; import mage.cards.repository.ExpansionInfo;
import mage.cards.repository.ExpansionRepository; import mage.cards.repository.ExpansionRepository;
import mage.cards.repository.RepositoryEvent;
import mage.constants.SetType; import mage.constants.SetType;
import static mage.constants.SetType.EXPANSION;
import static mage.constants.SetType.SUPPLEMENTAL;
import mage.deck.Standard; import mage.deck.Standard;
import mage.game.events.Listener;
import java.util.*;
/** /**
* Utility class for constructed formats (expansions and other editions). * Utility class for constructed formats (expansions and other editions).
@ -26,11 +22,36 @@ public final class ConstructedFormats {
public static final String FRONTIER = "- Frontier"; public static final String FRONTIER = "- Frontier";
public static final String MODERN = "- Modern"; public static final String MODERN = "- Modern";
public static final String VINTAGE_LEGACY = "- Vintage / Legacy"; public static final String VINTAGE_LEGACY = "- Vintage / Legacy";
public static final String JOKE = "- Joke Sets";
public static final String CUSTOM = "- Custom"; public static final String CUSTOM = "- Custom";
public static final Standard STANDARD_CARDS = new Standard(); public static final Standard STANDARD_CARDS = new Standard();
// Attention -Month is 0 Based so Feb = 1 for example. //
private static final Date extendedDate = new GregorianCalendar(2009, 7, 20).getTime();
private static final Date frontierDate = new GregorianCalendar(2014, 6, 17).getTime();
private static final Date modernDate = new GregorianCalendar(2003, 6, 20).getTime();
// for all sets just return empty list
private static final List<String> all = new ArrayList<>();
private static final Map<String, List<String>> underlyingSetCodesPerFormat = new HashMap<>(); private static final Map<String, List<String>> underlyingSetCodesPerFormat = new HashMap<>();
private static final List<String> formats = new ArrayList<>(); private static final List<String> formats = new ArrayList<>();
private static final Listener<RepositoryEvent> setsDbListener;
static {
buildLists();
// auto-update sets list on changes
setsDbListener = new Listener<RepositoryEvent>() {
@Override
public void event(RepositoryEvent event) {
if (event.getEventType().equals(RepositoryEvent.RepositoryEventType.DB_UPDATED)) {
buildLists();
}
}
};
ExpansionRepository.instance.subscribe(setsDbListener);
}
private ConstructedFormats() { private ConstructedFormats() {
} }
@ -57,12 +78,13 @@ public final class ConstructedFormats {
} }
} }
private static void buildLists() { public static void buildLists() {
underlyingSetCodesPerFormat.put(STANDARD, new ArrayList<>()); underlyingSetCodesPerFormat.put(STANDARD, new ArrayList<>());
underlyingSetCodesPerFormat.put(EXTENDED, new ArrayList<>()); underlyingSetCodesPerFormat.put(EXTENDED, new ArrayList<>());
underlyingSetCodesPerFormat.put(FRONTIER, new ArrayList<>()); underlyingSetCodesPerFormat.put(FRONTIER, new ArrayList<>());
underlyingSetCodesPerFormat.put(MODERN, new ArrayList<>()); underlyingSetCodesPerFormat.put(MODERN, new ArrayList<>());
underlyingSetCodesPerFormat.put(VINTAGE_LEGACY, new ArrayList<>()); underlyingSetCodesPerFormat.put(VINTAGE_LEGACY, new ArrayList<>());
underlyingSetCodesPerFormat.put(JOKE, new ArrayList<>());
underlyingSetCodesPerFormat.put(CUSTOM, new ArrayList<>()); underlyingSetCodesPerFormat.put(CUSTOM, new ArrayList<>());
final Map<String, ExpansionInfo> expansionInfo = new HashMap<>(); final Map<String, ExpansionInfo> expansionInfo = new HashMap<>();
formats.clear(); // prevent NPE on sorting if this is not the first try formats.clear(); // prevent NPE on sorting if this is not the first try
@ -85,6 +107,10 @@ public final class ConstructedFormats {
underlyingSetCodesPerFormat.get(CUSTOM).add(set.getCode()); underlyingSetCodesPerFormat.get(CUSTOM).add(set.getCode());
continue; continue;
} }
if (set.getType() == SetType.JOKESET) {
underlyingSetCodesPerFormat.get(JOKE).add(set.getCode());
continue;
}
underlyingSetCodesPerFormat.get(VINTAGE_LEGACY).add(set.getCode()); underlyingSetCodesPerFormat.get(VINTAGE_LEGACY).add(set.getCode());
if (set.getType() == SetType.CORE || set.getType() == SetType.EXPANSION || set.getType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) { if (set.getType() == SetType.CORE || set.getType() == SetType.EXPANSION || set.getType() == SetType.SUPPLEMENTAL_STANDARD_LEGAL) {
if (STANDARD_CARDS.getSetCodes().contains(set.getCode())) { if (STANDARD_CARDS.getSetCodes().contains(set.getCode())) {
@ -211,12 +237,12 @@ public final class ConstructedFormats {
}); });
if (!formats.isEmpty()) { if (!formats.isEmpty()) {
formats.add(0, CUSTOM); formats.add(0, CUSTOM);
formats.add(0, JOKE);
formats.add(0, VINTAGE_LEGACY); formats.add(0, VINTAGE_LEGACY);
formats.add(0, MODERN); formats.add(0, MODERN);
formats.add(0, EXTENDED);
formats.add(0, FRONTIER); formats.add(0, FRONTIER);
formats.add(0, EXTENDED);
formats.add(0, STANDARD); formats.add(0, STANDARD);
} }
formats.add(0, ALL); formats.add(0, ALL);
} }
@ -224,15 +250,4 @@ public final class ConstructedFormats {
private static String getBlockDisplayName(String blockName) { private static String getBlockDisplayName(String blockName) {
return "* " + blockName + " Block"; return "* " + blockName + " Block";
} }
// Attention -Month is 0 Based so Feb = 1 for example.
private static final Date extendedDate = new GregorianCalendar(2009, 7, 20).getTime();
private static final Date frontierDate = new GregorianCalendar(2014, 6, 17).getTime();
private static final Date modernDate = new GregorianCalendar(2003, 6, 20).getTime();
// for all sets just return empty list
private static final List<String> all = new ArrayList<>();
static {
buildLists();
}
} }

View file

@ -80,7 +80,7 @@ public class SessionImpl implements Session {
// handling. // handling.
public interface RemotingTask { public interface RemotingTask {
public boolean run() throws Throwable; boolean run() throws Throwable;
} }
// handleRemotingTaskExceptions runs the given task and handles exceptions appropriately. This // handleRemotingTaskExceptions runs the given task and handles exceptions appropriately. This
@ -223,7 +223,7 @@ public class SessionImpl implements Session {
@Override @Override
public Optional<String> getServerHostname() { public Optional<String> getServerHostname() {
return isConnected() ? Optional.of(connection.getHost()) : Optional.<String>empty(); return isConnected() ? Optional.of(connection.getHost()) : Optional.empty();
} }
@Override @Override
@ -392,26 +392,22 @@ public class SessionImpl implements Session {
} }
private void updateDatabase(boolean forceDBComparison, ServerState serverState) { private void updateDatabase(boolean forceDBComparison, ServerState serverState) {
long cardDBVersion = CardRepository.instance.getContentVersionFromDB(); // sets
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
List<String> classNames = CardRepository.instance.getClassNames();
List<CardInfo> cards = server.getMissingCardsData(classNames);
CardRepository.instance.addCards(cards);
CardRepository.instance.setContentVersion(serverState.getCardsContentVersion());
logger.info("Updating client cards DB - existing cards: " + classNames.size() + " new cards: " + cards.size()
+ " content versions - server: " + serverState.getCardsContentVersion() + " client: " + cardDBVersion);
}
long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB(); long expansionDBVersion = ExpansionRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getExpansionsContentVersion() > expansionDBVersion) { if (forceDBComparison || serverState.getExpansionsContentVersion() > expansionDBVersion) {
List<String> setCodes = ExpansionRepository.instance.getSetCodes(); List<String> setCodes = ExpansionRepository.instance.getSetCodes();
List<ExpansionInfo> expansions = server.getMissingExpansionData(setCodes); List<ExpansionInfo> expansions = server.getMissingExpansionData(setCodes);
for (ExpansionInfo expansion : expansions) { logger.info("DB: updating sets... Founded new: " + expansions.size());
ExpansionRepository.instance.add(expansion); ExpansionRepository.instance.saveSets(expansions, null, serverState.getExpansionsContentVersion());
} }
ExpansionRepository.instance.setContentVersion(serverState.getExpansionsContentVersion());
logger.info("Updating client expansions DB - existing sets: " + setCodes.size() + " new sets: " + expansions.size() // cards
+ " content versions - server: " + serverState.getExpansionsContentVersion() + " client: " + expansionDBVersion); long cardDBVersion = CardRepository.instance.getContentVersionFromDB();
if (forceDBComparison || serverState.getCardsContentVersion() > cardDBVersion) {
List<String> classNames = CardRepository.instance.getClassNames();
List<CardInfo> cards = server.getMissingCardsData(classNames);
logger.info("DB: updating cards... Founded new: " + cards.size());
CardRepository.instance.saveCards(cards, serverState.getCardsContentVersion());
} }
} }

View file

@ -4,6 +4,7 @@ import mage.cards.ExpansionSet;
import mage.cards.Sets; import mage.cards.Sets;
import mage.cards.repository.CardScanner; import mage.cards.repository.CardScanner;
import mage.cards.repository.PluginClassloaderRegistery; import mage.cards.repository.PluginClassloaderRegistery;
import mage.cards.repository.RepositoryUtil;
import mage.game.match.MatchType; import mage.game.match.MatchType;
import mage.game.tournament.TournamentType; import mage.game.tournament.TournamentType;
import mage.interfaces.MageServer; import mage.interfaces.MageServer;
@ -88,6 +89,10 @@ public final class Main {
logger.info("Done."); logger.info("Done.");
} }
// db init and updates checks (e.g. cleanup cards db on new version)
RepositoryUtil.bootstrapLocalDb();
logger.info("Done.");
logger.info("Loading extension packages..."); logger.info("Loading extension packages...");
if (!extensionFolder.exists()) { if (!extensionFolder.exists()) {
if (!extensionFolder.mkdirs()) { if (!extensionFolder.mkdirs()) {

View file

@ -14,6 +14,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SetType; import mage.constants.SetType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.game.events.Listener;
import mage.util.RandomUtil; import mage.util.RandomUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -22,12 +23,14 @@ import java.sql.SQLException;
import java.util.*; import java.util.*;
/** /**
* @author North * @author North, JayDi85
*/ */
public enum CardRepository { public enum CardRepository {
instance; instance;
private static final Logger logger = Logger.getLogger(CardRepository.class);
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE"; private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "card"; private static final String VERSION_ENTITY_NAME = "card";
// raise this if db structure was changed // raise this if db structure was changed
@ -36,6 +39,7 @@ public enum CardRepository {
private static final long CARD_CONTENT_VERSION = 123; private static final long CARD_CONTENT_VERSION = 123;
private Dao<CardInfo, Object> cardDao; private Dao<CardInfo, Object> cardDao;
private Set<String> classNames; private Set<String> classNames;
private RepositoryEventSource eventSource = new RepositoryEventSource();
CardRepository() { CardRepository() {
File file = new File("db"); File file = new File("db");
@ -48,32 +52,50 @@ public enum CardRepository {
boolean isObsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, CARD_DB_VERSION); boolean isObsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, CARD_DB_VERSION);
boolean isNewBuild = RepositoryUtil.isNewBuildRun(connectionSource, VERSION_ENTITY_NAME, CardRepository.class); // recreate db on new build boolean isNewBuild = RepositoryUtil.isNewBuildRun(connectionSource, VERSION_ENTITY_NAME, CardRepository.class); // recreate db on new build
if (isObsolete || isNewBuild) { if (isObsolete || isNewBuild) {
//System.out.println("Local cards db is outdated, cleaning...");
TableUtils.dropTable(connectionSource, CardInfo.class, true); TableUtils.dropTable(connectionSource, CardInfo.class, true);
} }
TableUtils.createTableIfNotExists(connectionSource, CardInfo.class); TableUtils.createTableIfNotExists(connectionSource, CardInfo.class);
cardDao = DaoManager.createDao(connectionSource, CardInfo.class); cardDao = DaoManager.createDao(connectionSource, CardInfo.class);
eventSource.fireRepositoryDbLoaded();
} catch (SQLException ex) { } catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error creating card repository - ", ex); Logger.getLogger(CardRepository.class).error("Error creating card repository - ", ex);
} }
} }
public void addCards(final List<CardInfo> cards) { public void subscribe(Listener<RepositoryEvent> listener) {
eventSource.addListener(listener);
}
public void saveCards(final List<CardInfo> newCards, long newContentVersion) {
try { try {
cardDao.callBatchTasks(() -> { cardDao.callBatchTasks(() -> {
try { // add
for (CardInfo card : cards) { if (newCards != null && newCards.size() > 0) {
cardDao.create(card); logger.info("DB: need to add " + newCards.size() + " new cards");
if (classNames != null) { try {
classNames.add(card.getClassName()); for (CardInfo card : newCards) {
cardDao.create(card);
if (classNames != null) {
classNames.add(card.getClassName());
}
} }
} catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error adding cards to DB - ", ex);
} }
} catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error adding cards to DB - ", ex);
} }
// no card updates
return null; return null;
}); });
setContentVersion(newContentVersion);
eventSource.fireRepositoryDbUpdated();
} catch (Exception ex) { } catch (Exception ex) {
//
} }
} }

View file

@ -1,13 +1,12 @@
package mage.cards.repository; package mage.cards.repository;
import java.util.ArrayList;
import java.util.List;
import mage.cards.*; import mage.cards.*;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
/** /**
*
* @author North * @author North
*/ */
public final class CardScanner { public final class CardScanner {
@ -27,14 +26,15 @@ public final class CardScanner {
scanned = true; scanned = true;
List<CardInfo> cardsToAdd = new ArrayList<>(); List<CardInfo> cardsToAdd = new ArrayList<>();
int setsUpdatedCount = 0; List<ExpansionInfo> setsToAdd = new ArrayList<>();
int setsAddedCount = 0; List<ExpansionInfo> setsToUpdate = new ArrayList<>();
// check sets
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(set.getCode()); ExpansionInfo expansionInfo = ExpansionRepository.instance.getSetByCode(set.getCode());
if (expansionInfo == null) { if (expansionInfo == null) {
setsAddedCount += 1; // need add
ExpansionRepository.instance.add(new ExpansionInfo(set)); setsToAdd.add(new ExpansionInfo(set));
} else if (!expansionInfo.name.equals(set.getName()) } else if (!expansionInfo.name.equals(set.getName())
|| !expansionInfo.code.equals(set.getCode()) || !expansionInfo.code.equals(set.getCode())
|| (expansionInfo.blockName == null ? set.getBlockName() != null : !expansionInfo.blockName.equals(set.getBlockName())) || (expansionInfo.blockName == null ? set.getBlockName() != null : !expansionInfo.blockName.equals(set.getBlockName()))
@ -42,22 +42,17 @@ public final class CardScanner {
|| expansionInfo.type != set.getSetType() || expansionInfo.type != set.getSetType()
|| expansionInfo.boosters != set.hasBoosters() || expansionInfo.boosters != set.hasBoosters()
|| expansionInfo.basicLands != set.hasBasicLands()) { || expansionInfo.basicLands != set.hasBasicLands()) {
setsUpdatedCount += 1; // need update
ExpansionRepository.instance.update(expansionInfo); setsToUpdate.add(expansionInfo);
} }
} }
ExpansionRepository.instance.setContentVersion(ExpansionRepository.instance.getContentVersionConstant()); ExpansionRepository.instance.saveSets(setsToAdd, setsToUpdate, ExpansionRepository.instance.getContentVersionConstant());
if (setsAddedCount > 0) {
logger.info("DB: need to add " + setsAddedCount + " new sets");
}
if (setsUpdatedCount > 0) {
logger.info("DB: need to update " + setsUpdatedCount + " sets");
}
// check cards (only add mode, without updates)
for (ExpansionSet set : Sets.getInstance().values()) { for (ExpansionSet set : Sets.getInstance().values()) {
for (ExpansionSet.SetCardInfo setInfo : set.getSetCardInfo()) { for (ExpansionSet.SetCardInfo setInfo : set.getSetCardInfo()) {
if (CardRepository.instance.findCard(set.getCode(), setInfo.getCardNumber()) == null) { if (CardRepository.instance.findCard(set.getCode(), setInfo.getCardNumber()) == null) {
// need add
Card card = CardImpl.createCard( Card card = CardImpl.createCard(
setInfo.getCardClass(), setInfo.getCardClass(),
new CardSetInfo(setInfo.getName(), set.getCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()), new CardSetInfo(setInfo.getName(), set.getCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()),
@ -73,11 +68,6 @@ public final class CardScanner {
} }
} }
} }
CardRepository.instance.saveCards(cardsToAdd, CardRepository.instance.getContentVersionConstant());
if (!cardsToAdd.isEmpty()) {
logger.info("DB: need to add " + cardsToAdd.size() + " new cards");
CardRepository.instance.addCards(cardsToAdd);
}
CardRepository.instance.setContentVersion(CardRepository.instance.getContentVersionConstant());
} }
} }

View file

@ -8,6 +8,7 @@ import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.SelectArg; import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils; import com.j256.ormlite.table.TableUtils;
import mage.game.events.Listener;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.File; import java.io.File;
@ -18,7 +19,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
/** /**
* @author North * @author North, JayDi85
*/ */
public enum ExpansionRepository { public enum ExpansionRepository {
@ -32,7 +33,7 @@ public enum ExpansionRepository {
private static final long EXPANSION_CONTENT_VERSION = 17; private static final long EXPANSION_CONTENT_VERSION = 17;
private Dao<ExpansionInfo, Object> expansionDao; private Dao<ExpansionInfo, Object> expansionDao;
private RepositoryEventSource eventSource = new RepositoryEventSource();
public boolean instanceInitialized = false; public boolean instanceInitialized = false;
ExpansionRepository() { ExpansionRepository() {
@ -46,31 +47,59 @@ public enum ExpansionRepository {
boolean isObsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, EXPANSION_DB_VERSION); boolean isObsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, EXPANSION_DB_VERSION);
boolean isNewBuild = RepositoryUtil.isNewBuildRun(connectionSource, VERSION_ENTITY_NAME, ExpansionRepository.class); // recreate db on new build boolean isNewBuild = RepositoryUtil.isNewBuildRun(connectionSource, VERSION_ENTITY_NAME, ExpansionRepository.class); // recreate db on new build
if (isObsolete || isNewBuild) { if (isObsolete || isNewBuild) {
//System.out.println("Local sets db is outdated, cleaning...");
TableUtils.dropTable(connectionSource, ExpansionInfo.class, true); TableUtils.dropTable(connectionSource, ExpansionInfo.class, true);
} }
TableUtils.createTableIfNotExists(connectionSource, ExpansionInfo.class); TableUtils.createTableIfNotExists(connectionSource, ExpansionInfo.class);
expansionDao = DaoManager.createDao(connectionSource, ExpansionInfo.class); expansionDao = DaoManager.createDao(connectionSource, ExpansionInfo.class);
instanceInitialized = true; instanceInitialized = true;
eventSource.fireRepositoryDbLoaded();
} catch (SQLException ex) { } catch (SQLException ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
} }
public void add(ExpansionInfo expansion) { public void subscribe(Listener<RepositoryEvent> listener) {
try { eventSource.addListener(listener);
expansionDao.create(expansion);
} catch (SQLException ex) {
logger.error(ex);
}
} }
public void update(ExpansionInfo expansion) { public void saveSets(final List<ExpansionInfo> newSets, final List<ExpansionInfo> updatedSets, long newContentVersion) {
try { try {
expansionDao.update(expansion); expansionDao.callBatchTasks(() -> {
} catch (SQLException ex) { // add
logger.error(ex); if (newSets != null && newSets.size() > 0) {
logger.info("DB: need to add " + newSets.size() + " new sets");
try {
for (ExpansionInfo exp : newSets) {
expansionDao.create(exp);
}
} catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error adding expansions to DB - ", ex);
}
}
// update
if (updatedSets != null && updatedSets.size() > 0) {
logger.info("DB: need to update " + updatedSets.size() + " sets");
try {
for (ExpansionInfo exp : updatedSets) {
expansionDao.update(exp);
}
} catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error adding expansions to DB - ", ex);
}
}
return null;
});
setContentVersion(newContentVersion);
eventSource.fireRepositoryDbUpdated();
} catch (Exception ex) {
//
} }
} }

View file

@ -0,0 +1,27 @@
package mage.cards.repository;
import mage.game.events.ExternalEvent;
import java.io.Serializable;
import java.util.EventObject;
/**
* @author JayDi85
*/
public class RepositoryEvent extends EventObject implements ExternalEvent, Serializable {
public enum RepositoryEventType {
DB_LOADED, DB_UPDATED
}
private RepositoryEventType eventType;
public RepositoryEvent(RepositoryEventType eventType) {
super(eventType);
this.eventType = eventType;
}
public RepositoryEventType getEventType() {
return eventType;
}
}

View file

@ -0,0 +1,34 @@
package mage.cards.repository;
import mage.game.events.EventDispatcher;
import mage.game.events.EventSource;
import mage.game.events.Listener;
import java.io.Serializable;
/**
* @author JayDi85
*/
public class RepositoryEventSource implements EventSource<RepositoryEvent>, Serializable {
protected final EventDispatcher<RepositoryEvent> dispatcher = new EventDispatcher<RepositoryEvent>() {
};
@Override
public void addListener(Listener<RepositoryEvent> listener) {
dispatcher.addListener(listener);
}
@Override
public void removeAllListener() {
dispatcher.removeAllListener();
}
public void fireRepositoryDbLoaded() {
dispatcher.fireEvent(new RepositoryEvent(RepositoryEvent.RepositoryEventType.DB_LOADED));
}
public void fireRepositoryDbUpdated() {
dispatcher.fireEvent(new RepositoryEvent(RepositoryEvent.RepositoryEventType.DB_UPDATED));
}
}

View file

@ -8,16 +8,25 @@ import com.j256.ormlite.stmt.SelectArg;
import com.j256.ormlite.support.ConnectionSource; import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.TableUtils; import com.j256.ormlite.table.TableUtils;
import mage.util.JarVersion; import mage.util.JarVersion;
import org.apache.log4j.Logger;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
/** /**
* * @author North, JayDi85
* @author North
*/ */
public final class RepositoryUtil { public final class RepositoryUtil {
private static final Logger logger = Logger.getLogger(RepositoryUtil.class);
public static void bootstrapLocalDb() {
// call local db to init all sets and cards repository (need for correct updates cycle, not on random request)
logger.info("Loading database...");
ExpansionRepository.instance.getContentVersionConstant();
CardRepository.instance.getContentVersionConstant();
}
public static boolean isDatabaseObsolete(ConnectionSource connectionSource, String entityName, long version) throws SQLException { public static boolean isDatabaseObsolete(ConnectionSource connectionSource, String entityName, long version) throws SQLException {
TableUtils.createTableIfNotExists(connectionSource, DatabaseVersion.class); TableUtils.createTableIfNotExists(connectionSource, DatabaseVersion.class);
Dao<DatabaseVersion, Object> dbVersionDao = DaoManager.createDao(connectionSource, DatabaseVersion.class); Dao<DatabaseVersion, Object> dbVersionDao = DaoManager.createDao(connectionSource, DatabaseVersion.class);
@ -37,6 +46,7 @@ public final class RepositoryUtil {
public static boolean isNewBuildRun(ConnectionSource connectionSource, String entityName, Class clazz) throws SQLException { public static boolean isNewBuildRun(ConnectionSource connectionSource, String entityName, Class clazz) throws SQLException {
// build time checks only for releases, not runtime (e.g. IDE debug) // build time checks only for releases, not runtime (e.g. IDE debug)
// that's check uses for cards db cleanup on new version/build
String currentBuild = JarVersion.getBuildTime(clazz); String currentBuild = JarVersion.getBuildTime(clazz);
if (!JarVersion.isBuildTimeOk(currentBuild)) { if (!JarVersion.isBuildTimeOk(currentBuild)) {
return false; return false;