mass player collection testing is now possible
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
ALTER TABLE collection ADD CONSTRAINT fk_collection_player_id FOREIGN KEY (player_id) REFERENCES player(id);
|
||||
|
||||
ALTER TABLE collection ADD `extra_info` VARCHAR(5000) NULL;
|
||||
|
||||
ALTER TABLE collection ADD CONSTRAINT uq_collection_player_type UNIQUE (player_id, type);
|
||||
|
||||
|
||||
CREATE TABLE `collection_entries` (
|
||||
`collection_id` int(11) NOT NULL,
|
||||
@@ -15,4 +19,27 @@ CREATE TABLE `collection_entries` (
|
||||
`notes` varchar(100) DEFAULT NULL,
|
||||
PRIMARY KEY (`collection_id`, `product`),
|
||||
CONSTRAINT `collection_entries_ibfk_1` FOREIGN KEY (`collection_id`) REFERENCES `collection` (`id`)
|
||||
) ;
|
||||
) ;
|
||||
|
||||
|
||||
SELECT *
|
||||
FROM collection c
|
||||
WHERE player_id = 31040
|
||||
|
||||
SELECT *
|
||||
FROM collection_entries
|
||||
WHERE collection_id = 64643
|
||||
|
||||
SELECT *
|
||||
FROM player p
|
||||
LEFT JOIN collection c
|
||||
ON c.player_id = p.id
|
||||
WHERE c.id IS NULL
|
||||
ORDER BY p.name
|
||||
|
||||
SELECT count(*)
|
||||
FROM collection_entries
|
||||
GROUP BY collection_id
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -42,6 +42,13 @@ public class DBDefs {
|
||||
|
||||
}
|
||||
|
||||
public static class Collection {
|
||||
public int id;
|
||||
public int player_id;
|
||||
public String type;
|
||||
public String extra_info;
|
||||
}
|
||||
|
||||
public static class CollectionEntry {
|
||||
public int collection_id;
|
||||
public int quantity;
|
||||
@@ -53,4 +60,9 @@ public class DBDefs {
|
||||
public LocalDateTime modified_date;
|
||||
public String notes;
|
||||
}
|
||||
|
||||
public static class Player {
|
||||
public int id;
|
||||
public String name;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gempukku.lotro.collection;
|
||||
|
||||
import com.gempukku.lotro.cache.Cached;
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.db.CollectionDAO;
|
||||
import com.gempukku.lotro.game.CardCollection;
|
||||
import org.apache.commons.collections.map.LRUMap;
|
||||
@@ -8,6 +9,7 @@ import org.apache.commons.collections.map.LRUMap;
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CachedCollectionDAO implements CollectionDAO, Cached {
|
||||
@@ -60,8 +62,13 @@ public class CachedCollectionDAO implements CollectionDAO, Cached {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCollection(int playerId, String type, CardCollection collection, String source) {
|
||||
_delegate.addToCollection(playerId, type, collection, source);
|
||||
public List<DBDefs.Collection> getAllCollectionsForPlayer(int playerId) {
|
||||
return _delegate.getAllCollectionsForPlayer(playerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToCollectionContents(int playerId, String type, CardCollection collection, String source) {
|
||||
_delegate.addToCollectionContents(playerId, type, collection, source);
|
||||
String id = constructCacheKey(playerId, type);
|
||||
if(!_playerCollections.containsKey(id)) {
|
||||
_playerCollections.put(id, collection);
|
||||
@@ -73,7 +80,7 @@ public class CachedCollectionDAO implements CollectionDAO, Cached {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFromCollection(int playerId, String type, CardCollection collection, String source) {
|
||||
_delegate.removeFromCollection(playerId, type, collection, source);
|
||||
public void removeFromCollectionContents(int playerId, String type, CardCollection collection, String source) {
|
||||
_delegate.removeFromCollectionContents(playerId, type, collection, source);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.cache.Cached;
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.game.Player;
|
||||
import org.apache.commons.collections.map.LRUMap;
|
||||
|
||||
@@ -132,6 +133,11 @@ public class CachedPlayerDAO implements PlayerDAO, Cached {
|
||||
_delegate.updateLastLoginIp(login, remoteAddr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DBDefs.Player> getAllPlayers() {
|
||||
return _delegate.getAllPlayers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateLastReward(Player player, int previousReward, int currentReward) throws SQLException {
|
||||
boolean updated = _delegate.updateLastReward(player, previousReward, currentReward);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.game.CardCollection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface CollectionDAO {
|
||||
@@ -15,7 +17,9 @@ public interface CollectionDAO {
|
||||
|
||||
void convertCollection(int playerId, String type) throws SQLException, IOException;
|
||||
|
||||
void addToCollection(int playerId, String type, CardCollection collection, String source);
|
||||
List<DBDefs.Collection> getAllCollectionsForPlayer(int playerId);
|
||||
|
||||
void removeFromCollection(int playerId, String type, CardCollection collection, String source);
|
||||
void addToCollectionContents(int playerId, String type, CardCollection collection, String source);
|
||||
|
||||
void removeFromCollectionContents(int playerId, String type, CardCollection collection, String source);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.collection.CollectionSerializer;
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.game.CardCollection;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@@ -11,6 +13,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DbCollectionDAO implements CollectionDAO {
|
||||
@@ -92,6 +95,30 @@ public class DbCollectionDAO implements CollectionDAO {
|
||||
public int ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DBDefs.Collection> getAllCollectionsForPlayer(int playerId) {
|
||||
|
||||
try {
|
||||
Sql2o db = new Sql2o(_dbAccess.getDataSource());
|
||||
|
||||
try (org.sql2o.Connection conn = db.open()) {
|
||||
String sql = """
|
||||
SELECT
|
||||
id, player_id, type, extra_info
|
||||
FROM collection
|
||||
WHERE player_id = :playerID
|
||||
""";
|
||||
List<DBDefs.Collection> result = conn.createQuery(sql)
|
||||
.addParameter("playerID", playerId)
|
||||
.executeAndFetch(DBDefs.Collection.class);
|
||||
|
||||
return result;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Unable to retrieve collection types", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public int getCollectionID(int playerId, String type) {
|
||||
try {
|
||||
|
||||
@@ -119,45 +146,72 @@ public class DbCollectionDAO implements CollectionDAO {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCollection(int playerId, String type, CardCollection collection, String source) {
|
||||
public void upsertCollection(int playerId, String type, CardCollection collection) {
|
||||
String sql = """
|
||||
INSERT INTO collection(player_id, type, extra_info)
|
||||
VALUES (:playerId, :type, :extraInfo)
|
||||
ON DUPLICATE KEY UPDATE extra_info = :extraInfo;
|
||||
""";
|
||||
String json = "";
|
||||
try {
|
||||
Sql2o db = new Sql2o(_dbAccess.getDataSource());
|
||||
|
||||
var jsonObj = new JSONObject();
|
||||
jsonObj.putAll(collection.getExtraInformation());
|
||||
json = jsonObj.toJSONString();
|
||||
|
||||
try (org.sql2o.Connection conn = db.beginTransaction()) {
|
||||
Query query = conn.createQuery(sql, true);
|
||||
query.addParameter("playerId", playerId)
|
||||
.addParameter("type", type)
|
||||
.addParameter("extraInfo", json);
|
||||
query.executeUpdate();
|
||||
conn.commit();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Unable to upsert collection", ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateCollectionContents(int playerId, String type, CardCollection collection, String source) {
|
||||
String sql = """
|
||||
INSERT INTO collection_entries(collection_id, quantity, product_type, product, source)
|
||||
VALUES (:collid, :quantity, :type, :product, :source)
|
||||
ON DUPLICATE KEY UPDATE quantity = :quantity, source = :source;
|
||||
""";
|
||||
String error = "Unable to update product via upsert into collection_entries.";
|
||||
updateCollection(playerId, type, collection, source, sql, error);
|
||||
updateCollectionContents(playerId, type, collection, source, sql, error);
|
||||
}
|
||||
|
||||
public void addToCollection(int playerId, String type, CardCollection collection, String source) {
|
||||
public void addToCollectionContents(int playerId, String type, CardCollection collection, String source) {
|
||||
String sql = """
|
||||
INSERT INTO collection_entries(collection_id, quantity, product_type, product, source)
|
||||
VALUES (:collid, :quantity, :type, :product, :source)
|
||||
ON DUPLICATE KEY UPDATE quantity = quantity + :quantity, source = :source;
|
||||
""";
|
||||
String error = "Unable to add product via upsert into collection_entries.";
|
||||
updateCollection(playerId, type, collection, source, sql, error);
|
||||
updateCollectionContents(playerId, type, collection, source, sql, error);
|
||||
}
|
||||
|
||||
public void removeFromCollection(int playerId, String type, CardCollection collection, String source) {
|
||||
public void removeFromCollectionContents(int playerId, String type, CardCollection collection, String source) {
|
||||
String sql = """
|
||||
INSERT INTO collection_entries(collection_id, quantity, product_type, product, source)
|
||||
VALUES (:collid, :quantity, :type, :product, :source)
|
||||
ON DUPLICATE KEY UPDATE quantity = GREATEST(quantity - :quantity, 0), source = :source;
|
||||
""";
|
||||
String error = "Unable to remove product via upsert into collection_entries.";
|
||||
updateCollection(playerId, type, collection, source, sql, error);
|
||||
updateCollectionContents(playerId, type, collection, source, sql, error);
|
||||
}
|
||||
|
||||
public void convertCollection(int playerId, String type) throws SQLException, IOException {
|
||||
CardCollection oldCollection = getPlayerCollection(playerId, type);
|
||||
updateCollection(playerId, type, oldCollection, "Initial Convert");
|
||||
updateCollectionContents(playerId, type, oldCollection, "Initial Convert");
|
||||
}
|
||||
|
||||
|
||||
//TODO:
|
||||
// - Convert currency to an extra info entry
|
||||
// - add data field to the original collection table to hold the extra info as json
|
||||
// + Convert currency to an extra info entry
|
||||
// + add data field to the original collection table to hold the extra info as json
|
||||
// - create player-looping function to convert all collections and see if it blows up via test
|
||||
// - add CollectionsManager mirror functions to read/writing into the new table
|
||||
// - write unit tests to convert and compare a bajillion collections
|
||||
@@ -165,7 +219,8 @@ public class DbCollectionDAO implements CollectionDAO {
|
||||
// - test a: draft, new art card reward, my cards reward, pack openings
|
||||
// - write script to back up db and delete the old binary blob column
|
||||
// - write script to convert all leagues to use IDs instead of names
|
||||
private void updateCollection(int playerId, String type, CardCollection collection, String source, String sql, String error) {
|
||||
private void updateCollectionContents(int playerId, String type, CardCollection collection, String source, String sql, String error) {
|
||||
upsertCollection(playerId, type, collection);
|
||||
int collID = getCollectionID(playerId, type);
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.game.Player;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.sql.Connection;
|
||||
@@ -318,4 +320,23 @@ public class DbPlayerDAO implements PlayerDAO {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DBDefs.Player> getAllPlayers() {
|
||||
|
||||
try {
|
||||
|
||||
Sql2o db = new Sql2o(_dbAccess.getDataSource());
|
||||
|
||||
try (org.sql2o.Connection conn = db.open()) {
|
||||
String sql = "SELECT id, name FROM player";
|
||||
List<DBDefs.Player> result = conn.createQuery(sql)
|
||||
.executeAndFetch(DBDefs.Player.class);
|
||||
|
||||
return result;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException("Unable to retrieve players", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.gempukku.lotro.db;
|
||||
|
||||
import com.gempukku.lotro.common.DBDefs;
|
||||
import com.gempukku.lotro.game.Player;
|
||||
|
||||
import java.sql.SQLException;
|
||||
@@ -32,4 +33,6 @@ public interface PlayerDAO {
|
||||
public boolean registerUser(String login, String password, String remoteAddr) throws SQLException, LoginInvalidException;
|
||||
|
||||
public void updateLastLoginIp(String login, String remoteAddr) throws SQLException;
|
||||
|
||||
List<DBDefs.Player> getAllPlayers();
|
||||
}
|
||||
|
||||
@@ -22,8 +22,15 @@ public class DefaultCardCollection implements MutableCardCollection {
|
||||
_extraInformation.putAll(cardCollection.getExtraInformation());
|
||||
}
|
||||
|
||||
public synchronized void setExtraInformation(Map<String, Object> extraInformation) {
|
||||
_extraInformation = extraInformation;
|
||||
public synchronized void setExtraInformation(Map<String, Object> extraInfo) {
|
||||
_extraInformation.putAll(extraInfo);
|
||||
//Some deserialization defaults to making the currency a Long rather than an Integer
|
||||
if(extraInfo.containsKey(CurrencyKey)) {
|
||||
var input = extraInfo.get(CurrencyKey);
|
||||
if(input instanceof Long linput) {
|
||||
_extraInformation.put(CurrencyKey, linput.intValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -74,7 +74,7 @@ public class CollectionSerializerTest {
|
||||
assertEquals(3, resultCollection.getItemCount("15_2"));
|
||||
assertEquals(3, resultCollection.getItemCount("15_4*"));
|
||||
assertEquals(2, resultCollection.getItemCount("FotR - Booster"));
|
||||
assertEquals(1, resultCollection.getExtraInformation().size());
|
||||
assertEquals(2, resultCollection.getExtraInformation().size());
|
||||
assertEquals("b", resultCollection.getExtraInformation().get("a"));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
@@ -93,7 +93,8 @@ public class CollectionSerializerTest {
|
||||
assertEquals(12, resultCollection.getCurrency());
|
||||
assertEquals(1, Iterables.size(resultCollection.getAll()));
|
||||
assertEquals(2, resultCollection.getItemCount("15_4*"));
|
||||
assertEquals(1, resultCollection.getExtraInformation().size());
|
||||
//added entry + the default currency storage
|
||||
assertEquals(2, resultCollection.getExtraInformation().size());
|
||||
assertEquals("b", resultCollection.getExtraInformation().get("a"));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.gempukku.lotro.collection;
|
||||
|
||||
import com.gempukku.lotro.db.DbAccess;
|
||||
import com.gempukku.lotro.db.DbCollectionDAO;
|
||||
import com.gempukku.lotro.db.DbPlayerDAO;
|
||||
import com.gempukku.lotro.game.CardNotFoundException;
|
||||
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
// Tidings of Erebor
|
||||
public class NewCollectionManagerTests
|
||||
{
|
||||
private static DbAccess dbAccess = new DbAccess("jdbc:mysql://localhost:35001/gemp_db",
|
||||
"root", "rootpass", false);
|
||||
|
||||
@Test
|
||||
public void ConvertCollectionTest() throws DecisionResultInvalidException, CardNotFoundException, IOException, SQLException {
|
||||
var collDAO = new DbCollectionDAO(dbAccess, new CollectionSerializer());
|
||||
|
||||
collDAO.convertCollection(31040, "trophy");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ConvertAllPlayerCollectionsTest() throws DecisionResultInvalidException, CardNotFoundException, IOException, SQLException {
|
||||
var collDAO = new DbCollectionDAO(dbAccess, new CollectionSerializer());
|
||||
var playerDAO = new DbPlayerDAO(dbAccess);
|
||||
|
||||
var players = playerDAO.getAllPlayers();
|
||||
|
||||
for (var player : players) {
|
||||
var collections = collDAO.getAllCollectionsForPlayer(player.id);
|
||||
for(var coll : collections) {
|
||||
collDAO.convertCollection(player.id, coll.type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user