Use reflection to map database classes and add missing mapped classes to the dispatch datastore

This commit is contained in:
Melledy 2022-09-18 20:46:28 -07:00
parent 794350aa63
commit 0d64e2e810
No known key found for this signature in database
GPG Key ID: 2A8E7A1D64737CCB

View File

@ -10,34 +10,21 @@ import com.mongodb.client.MongoIterable;
import dev.morphia.Datastore; import dev.morphia.Datastore;
import dev.morphia.Morphia; import dev.morphia.Morphia;
import dev.morphia.annotations.Entity;
import dev.morphia.mapping.Mapper;
import dev.morphia.mapping.MapperOptions; import dev.morphia.mapping.MapperOptions;
import dev.morphia.query.experimental.filters.Filters; import dev.morphia.query.experimental.filters.Filters;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.Grasscutter.ServerRunMode; import emu.grasscutter.Grasscutter.ServerRunMode;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.game.activity.PlayerActivityData;
import emu.grasscutter.game.activity.musicgame.MusicGameBeatmap; import org.reflections.Reflections;
import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.battlepass.BattlePassManager;
import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.gacha.GachaRecord;
import emu.grasscutter.game.home.GameHome;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.quest.GameMainQuest;
import emu.grasscutter.game.quest.GameQuest;
public final class DatabaseManager { public final class DatabaseManager {
private static Datastore gameDatastore; private static Datastore gameDatastore;
private static Datastore dispatchDatastore; private static Datastore dispatchDatastore;
private static final Class<?>[] mappedClasses = new Class<?>[] {
DatabaseCounter.class, Account.class, Player.class, Avatar.class, GameItem.class, Friendship.class,
GachaRecord.class, Mail.class, GameMainQuest.class, GameHome.class, BattlePassManager.class,
PlayerActivityData.class, MusicGameBeatmap.class
};
public static Datastore getGameDatastore() { public static Datastore getGameDatastore() {
return gameDatastore; return gameDatastore;
} }
@ -63,47 +50,54 @@ public final class DatabaseManager {
// Set mapper options. // Set mapper options.
MapperOptions mapperOptions = MapperOptions.builder() MapperOptions mapperOptions = MapperOptions.builder()
.storeEmpties(true).storeNulls(false).build(); .storeEmpties(true).storeNulls(false).build();
// Create data store. // Create data store.
gameDatastore = Morphia.createDatastore(gameMongoClient, DATABASE.game.collection, mapperOptions); gameDatastore = Morphia.createDatastore(gameMongoClient, DATABASE.game.collection, mapperOptions);
// Map classes.
gameDatastore.getMapper().map(mappedClasses);
// Ensure indexes // Map classes.
try { Class<?>[] entities = new Reflections(Grasscutter.class.getPackageName())
gameDatastore.ensureIndexes(); .getTypesAnnotatedWith(Entity.class)
} catch (MongoCommandException exception) { .stream()
Grasscutter.getLogger().info("Mongo index error: ", exception); .filter(cls -> {
// Duplicate index error Entity e = cls.getAnnotation(Entity.class);
if (exception.getCode() == 85) { return e != null && !e.value().equals(Mapper.IGNORED_FIELDNAME);
// Drop all indexes and re add them })
MongoIterable<String> collections = gameDatastore.getDatabase().listCollectionNames(); .toArray(Class<?>[]::new);
for (String name : collections) {
gameDatastore.getDatabase().getCollection(name).dropIndexes(); gameDatastore.getMapper().map(entities);
}
// Add back indexes // Ensure indexes for the game datastore
gameDatastore.ensureIndexes(); ensureIndexes(gameDatastore);
}
}
if (SERVER.runMode == ServerRunMode.GAME_ONLY) { if (SERVER.runMode == ServerRunMode.GAME_ONLY) {
MongoClient dispatchMongoClient = MongoClients.create(DATABASE.server.connectionUri); MongoClient dispatchMongoClient = MongoClients.create(DATABASE.server.connectionUri);
dispatchDatastore = Morphia.createDatastore(dispatchMongoClient, DATABASE.server.collection);
// Ensure indexes for dispatch server dispatchDatastore = Morphia.createDatastore(dispatchMongoClient, DATABASE.server.collection, mapperOptions);
dispatchDatastore.getMapper().map(new Class<?>[] {DatabaseCounter.class, Account.class});
// Ensure indexes for dispatch datastore
ensureIndexes(dispatchDatastore);
}
}
/**
* Ensures the database indexes exist and rebuilds them if there is an error with them
* @param datastore The datastore to ensure indexes on
*/
private static void ensureIndexes(Datastore datastore) {
try { try {
dispatchDatastore.ensureIndexes(); datastore.ensureIndexes();
} catch (MongoCommandException e) { } catch (MongoCommandException e) {
Grasscutter.getLogger().info("Mongo index error: ", e); Grasscutter.getLogger().info("Mongo index error: ", e);
// Duplicate index error // Duplicate index error
if (e.getCode() == 85) { if (e.getCode() == 85) {
// Drop all indexes and re add them // Drop all indexes and re add them
MongoIterable<String> collections = dispatchDatastore.getDatabase().listCollectionNames(); MongoIterable<String> collections = datastore.getDatabase().listCollectionNames();
for (String name : collections) { for (String name : collections) {
dispatchDatastore.getDatabase().getCollection(name).dropIndexes(); datastore.getDatabase().getCollection(name).dropIndexes();
} }
// Add back indexes // Add back indexes
dispatchDatastore.ensureIndexes(); datastore.ensureIndexes();
}
} }
} }
} }