66import java.nio.file.Files;
77import java.sql.SQLException;
88import java.util.Collection;
9- import java.util.HashMap ;
9+ import java.util.HashSet ;
1010import java.util.List;
1111import java.util.Map;
12+ import java.util.Set;
1213import java.util.TimerTask;
1314import java.util.UUID;
15+ import java.util.concurrent.ConcurrentHashMap;
1416import java.util.concurrent.Executors;
1517import java.util.concurrent.ScheduledExecutorService;
1618import java.util.concurrent.TimeUnit;
2022import com.j256.ormlite.dao.Dao;
2123import com.j256.ormlite.dao.DaoManager;
2224import com.j256.ormlite.jdbc.JdbcConnectionSource;
23- import com.j256.ormlite.support.ConnectionSource;
2425import com.j256.ormlite.table.TableUtils;
2526
2627import lombok.NoArgsConstructor;
2728import ovh.mythmc.banco.api.Banco;
29+ import ovh.mythmc.banco.api.accounts.database.MySQLConnectionSource;
30+ import ovh.mythmc.banco.api.accounts.database.SQLiteConnectionSource;
2831import ovh.mythmc.banco.api.logger.LoggerWrapper;
2932
3033@NoArgsConstructor
@@ -34,7 +37,11 @@ public final class AccountDatabase {
3437
3538 private Dao<Account, UUID> accountsDao;
3639
37- private final Map<AccountIdentifierKey, Account> cache = new HashMap<>();
40+ private JdbcConnectionSource connectionSource;
41+
42+ private final Map<AccountIdentifierKey, Account> cache = new ConcurrentHashMap<>();
43+
44+ private final Collection<AccountIdentifierKey> accountIdentifierCache = new HashSet<>();
3845
3946 private boolean firstBoot = false;
4047
@@ -58,13 +65,17 @@ public void error(final String message, final Object... args) {
5865 };
5966
6067 public void initialize(@NotNull String path) throws SQLException {
61- ConnectionSource connectionSource = new JdbcConnectionSource("jdbc:sqlite:" + path);
68+ this.connectionSource = switch (Banco.get().getSettings().get().getDatabase().getType()) {
69+ case SQLITE -> new SQLiteConnectionSource(path);
70+ case MYSQL -> new MySQLConnectionSource();
71+ };
72+
6273 TableUtils.createTableIfNotExists(connectionSource, Account.class);
63- accountsDao = DaoManager.createDao(connectionSource, Account.class);
74+ this. accountsDao = DaoManager.createDao(connectionSource, Account.class);
6475
6576 this.path = path;
6677
67- firstBoot = !Banco.get().getSettings().get().getDatabase().isInitialized() &&
78+ this. firstBoot = !Banco.get().getSettings().get().getDatabase().isInitialized() &&
6879 Banco.get().getSettings().get().getDatabase().getDatabaseVersion() == 0;
6980
7081 backup("backup");
@@ -75,7 +86,19 @@ public void initialize(@NotNull String path) throws SQLException {
7586 if (Banco.get().getSettings().get().isDebug())
7687 Banco.get().getLogger().info("Loaded a total amount of " + get().size() + " accounts! (using V3 format)");
7788
78- Banco.get().getSettings().get().getDatabase().setDatabaseInitialized();
89+ accountIdentifierCache.addAll(get().stream().map(Account::getIdentifier).toList());
90+
91+ Banco.get().getSettings().setDatabaseInitialized();
92+ }
93+
94+ private Dao<Account, UUID> getDao() {
95+ try {
96+ this.connectionSource.initialize(); // Reopen connection if necessary
97+ } catch (SQLException e) {
98+ e.printStackTrace(System.err);
99+ }
100+
101+ return this.accountsDao;
79102 }
80103
81104 public void backup(String differentiator) {
@@ -96,15 +119,20 @@ public void shutdown() {
96119
97120 public void create(@NotNull Account account) {
98121 try {
99- accountsDao.createIfNotExists(account);
122+ getDao().createIfNotExists(account);
123+ // Cache name and account
124+ accountIdentifierCache.add(account.getIdentifier());
125+ cache.put(account.getIdentifier(), account);
100126 } catch (SQLException e) {
101127 logger.error("Exception while creating account {}", e);
102128 }
103129 }
104130
105131 public void delete(@NotNull Account account) {
106132 try {
107- accountsDao.delete(account);
133+ getDao().delete(account);
134+ // Delete cached name
135+ accountIdentifierCache.remove(account.getIdentifier());
108136 } catch (SQLException e) {
109137 logger.error("Exception while deleting account {}", e);
110138 }
@@ -142,7 +170,7 @@ private void updateAllDatabaseEntries() {
142170
143171 private void updateDatabaseEntry(@NotNull Account account) {
144172 try {
145- accountsDao .update(account);
173+ getDao() .update(account);
146174
147175 // Clear cache value
148176 cache.remove(account.getIdentifier());
@@ -155,9 +183,13 @@ public Collection<Account> getCachedAccounts() {
155183 return cache.values();
156184 }
157185
186+ public Collection<AccountIdentifierKey> getAccountIdentifierCache() {
187+ return this.accountIdentifierCache;
188+ }
189+
158190 public List<Account> get() {
159191 try {
160- return accountsDao .queryForAll();
192+ return getDao() .queryForAll();
161193 } catch (SQLException e) {
162194 logger.error("Exception while getting every account {}", e);
163195 }
@@ -171,7 +203,7 @@ public Account getByUuid(@NotNull UUID uuid) {
171203 return cachedAccount;
172204
173205 try {
174- Account account = accountsDao .queryForId(uuid);
206+ Account account = getDao() .queryForId(uuid);
175207 if (account == null)
176208 return null;
177209
@@ -190,7 +222,7 @@ public Account getByName(@NotNull String name) {
190222 return cachedAccount;
191223
192224 try {
193- List<Account> accounts = accountsDao .queryBuilder()
225+ List<Account> accounts = getDao() .queryBuilder()
194226 .where()
195227 .like("name", name)
196228 .query();
@@ -214,7 +246,7 @@ public Account getByNameOrUuid(@NotNull String name, UUID uuid) {
214246 return cachedAccount;
215247
216248 try {
217- List<Account> accounts = accountsDao .queryBuilder()
249+ List<Account> accounts = getDao() .queryBuilder()
218250 .where()
219251 .like("name", name)
220252 .query();
@@ -234,35 +266,37 @@ public Account getByNameOrUuid(@NotNull String name, UUID uuid) {
234266 }
235267
236268 private Account findCachedAccountByUuid(@NotNull UUID uuid) {
237- return cache.entrySet().stream()
269+ return Set.copyOf( cache.entrySet() ).stream()
238270 .filter(entry -> entry.getKey().uuid().equals(uuid))
239271 .map(entry -> entry.getValue())
240272 .findFirst().orElse(null);
241273 }
242274
243275 private Account findCachedAccountByName(@NotNull String name) {
244- return cache.entrySet().stream()
276+ return Set.copyOf( cache.entrySet() ).stream()
245277 .filter(entry -> entry.getKey().name() != null)
246278 .filter(entry -> entry.getKey().name().equalsIgnoreCase(name))
247279 .map(entry -> entry.getValue())
248280 .findFirst().orElse(null);
249281 }
250282
251283 public void upgrade() {
284+ // Janky fix to upgrade from v1.0.3 to v1.1.0 since the 'initialized' variable wasn't properly set to true
285+ int oldVersion = Banco.get().getSettings().get().getDatabase().getDatabaseVersion();
286+ if(oldVersion == 1) {
287+ try {
288+ logger.info("Upgrading database...");
289+ getDao().executeRaw("ALTER TABLE `accounts` ADD COLUMN name STRING;");
290+ logger.info("Done!");
291+ } catch (SQLException e) {
292+ logger.error("Exception while upgrading database: {}", e);
293+ }
294+ }
295+
252296 if (!firstBoot) {
253- int oldVersion = Banco.get().getSettings().get().getDatabase().getDatabaseVersion();
254- if(oldVersion < 1) {
255- try {
256- logger.info("Upgrading database...");
257- accountsDao.executeRaw("ALTER TABLE `accounts` ADD COLUMN name STRING;");
258- logger.info("Done!");
259- } catch (SQLException e) {
260- logger.error("Exception while upgrading database: {}", e);
261- }
262- }
263297 }
264298
265- Banco.get().getSettings().updateVersion(1 );
299+ Banco.get().getSettings().updateVersion(2 );
266300 }
267301
268302}
0 commit comments