DatabaseManager.java 2.53 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
package emu.grasscutter.database;

import com.mongodb.MongoCommandException;
KingRainbow44's avatar
KingRainbow44 committed
4
5
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
Melledy's avatar
Melledy committed
6
7
8
9
10
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoIterable;

import dev.morphia.Datastore;
import dev.morphia.Morphia;
KingRainbow44's avatar
KingRainbow44 committed
11
12
import dev.morphia.mapping.MapperOptions;
import dev.morphia.query.experimental.filters.Filters;
Melledy's avatar
Melledy committed
13
14
15
16
17
18
19
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.friends.Friendship;
import emu.grasscutter.game.inventory.GenshinItem;

KingRainbow44's avatar
KingRainbow44 committed
20
public final class DatabaseManager {
Melledy's avatar
Melledy committed
21
22
23
	private static MongoClient mongoClient;
	private static Datastore datastore;
	
KingRainbow44's avatar
KingRainbow44 committed
24
	private static final Class<?>[] mappedClasses = new Class<?>[] {
Melledy's avatar
Melledy committed
25
26
27
28
29
30
31
32
33
34
35
36
37
		DatabaseCounter.class, Account.class, GenshinPlayer.class, GenshinAvatar.class, GenshinItem.class, Friendship.class
	};
    
    public static Datastore getDatastore() {
    	return datastore;
    }
    
    public static MongoDatabase getDatabase() {
    	return getDatastore().getDatabase();
    }
	
	public static void initialize() {
		// Initialize
KingRainbow44's avatar
KingRainbow44 committed
38
		mongoClient = MongoClients.create(Grasscutter.getConfig().DatabaseUrl);
Melledy's avatar
Melledy committed
39
		
KingRainbow44's avatar
KingRainbow44 committed
40
41
42
43
44
45
46
		// Set mapper options.
		MapperOptions mapperOptions = MapperOptions.builder()
				.storeEmpties(true).storeNulls(false).build();
		// Create data store.
		datastore = Morphia.createDatastore(mongoClient, Grasscutter.getConfig().DatabaseCollection, mapperOptions);
		// Map classes.
		datastore.getMapper().map(mappedClasses);
Melledy's avatar
Melledy committed
47
48
49
50
		
		// Ensure indexes
		try {
			datastore.ensureIndexes();
KingRainbow44's avatar
KingRainbow44 committed
51
52
		} catch (MongoCommandException exception) {
			Grasscutter.getLogger().info("Mongo index error: ", exception);
Melledy's avatar
Melledy committed
53
			// Duplicate index error
KingRainbow44's avatar
KingRainbow44 committed
54
			if (exception.getCode() == 85) {
Melledy's avatar
Melledy committed
55
56
57
58
59
60
61
62
63
64
				// Drop all indexes and re add them
				MongoIterable<String> collections = datastore.getDatabase().listCollectionNames();
				for (String name : collections) {
					datastore.getDatabase().getCollection(name).dropIndexes();
				}
				// Add back indexes
				datastore.ensureIndexes();
			}
		}
	}
KingRainbow44's avatar
KingRainbow44 committed
65

Melledy's avatar
Melledy committed
66
	public static synchronized int getNextId(Class<?> c) {
KingRainbow44's avatar
KingRainbow44 committed
67
		DatabaseCounter counter = getDatastore().find(DatabaseCounter.class).filter(Filters.eq("_id", c.getName())).first();
Melledy's avatar
Melledy committed
68
69
70
71
72
73
74
75
76
		if (counter == null) {
			counter = new DatabaseCounter(c.getSimpleName());
		}
		try {
			return counter.getNextId();
		} finally {
			getDatastore().save(counter);
		}
	}
KingRainbow44's avatar
KingRainbow44 committed
77

Melledy's avatar
Melledy committed
78
79
80
81
	public static synchronized int getNextId(Object o) {
		return getNextId(o.getClass());
	}
}