From 5518205d68c2a531b5266ecd764926b217da792b Mon Sep 17 00:00:00 2001 From: david Date: Tue, 24 Dec 2024 18:17:32 +0100 Subject: [PATCH] Add support for bulk account retrieval and asynchronous loading Enhanced the account system by implementing methods to retrieve all accounts synchronously and asynchronously. Updated associated interfaces, controllers, and SQL queries to support these operations. Also, upgraded the service dependency to version 2.2.0. --- .../economist/api/EconomyController.java | 16 +++++++++++++ .../economist/command/AccountCommand.java | 2 +- .../EconomistEconomyController.java | 18 ++++++++++++++- .../controller/data/DataController.java | 8 +++++-- .../controller/data/SQLController.java | 23 +++++++++++++++++-- .../service/ServiceEconomyController.java | 17 ++++++++++++++ 6 files changed, 78 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/net/thenextlvl/economist/api/EconomyController.java b/api/src/main/java/net/thenextlvl/economist/api/EconomyController.java index 26dd20e..fd66f60 100644 --- a/api/src/main/java/net/thenextlvl/economist/api/EconomyController.java +++ b/api/src/main/java/net/thenextlvl/economist/api/EconomyController.java @@ -45,6 +45,22 @@ public interface EconomyController { */ String getCurrencySymbol(); + /** + * Loads all accounts asynchronously. + * + * @return a {@link CompletableFuture} that, when completed, will provide a {@link Set} of {@link Account} objects representing + * all the accounts available. + */ + CompletableFuture<@Unmodifiable Set> loadAccounts(); + + /** + * Retrieves all the accounts currently available. + * + * @return a set of accounts + */ + @Unmodifiable + Set getAccounts(); + /** * Retrieve the account for the specified player. * diff --git a/src/main/java/net/thenextlvl/economist/command/AccountCommand.java b/src/main/java/net/thenextlvl/economist/command/AccountCommand.java index 8a310d4..6d45669 100644 --- a/src/main/java/net/thenextlvl/economist/command/AccountCommand.java +++ b/src/main/java/net/thenextlvl/economist/command/AccountCommand.java @@ -133,7 +133,7 @@ private LiteralArgumentBuilder prune() { private int prune(CommandContext context, @Nullable World world) { var duration = context.getArgument("time", Duration.class); - CompletableFuture.supplyAsync(() -> plugin.dataController().getAccounts(world)) + CompletableFuture.supplyAsync(() -> plugin.dataController().getAccountOwners(world)) .thenApply(accounts -> accounts.stream().map(plugin.getServer()::getOfflinePlayer)) .thenApply(players -> players.filter(player -> !player.isConnected()) .filter(player -> player.getLastSeen() < Instant.now().minus(duration).toEpochMilli())) diff --git a/src/main/java/net/thenextlvl/economist/controller/EconomistEconomyController.java b/src/main/java/net/thenextlvl/economist/controller/EconomistEconomyController.java index 8a983f9..fccd172 100644 --- a/src/main/java/net/thenextlvl/economist/controller/EconomistEconomyController.java +++ b/src/main/java/net/thenextlvl/economist/controller/EconomistEconomyController.java @@ -12,7 +12,13 @@ import java.math.RoundingMode; import java.text.NumberFormat; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; import java.util.concurrent.CompletableFuture; @NullMarked @@ -71,6 +77,16 @@ public String getCurrencySymbol() { return plugin.config().currency().symbol(); } + @Override + public CompletableFuture<@Unmodifiable Set> loadAccounts() { + return CompletableFuture.supplyAsync(() -> dataController().getAccounts(null)); + } + + @Override + public @Unmodifiable Set getAccounts() { + return Set.copyOf(cache.values()); + } + @Override public Optional getAccount(UUID uuid) { return Optional.ofNullable(cache.get(new Identifier(uuid, null))); diff --git a/src/main/java/net/thenextlvl/economist/controller/data/DataController.java b/src/main/java/net/thenextlvl/economist/controller/data/DataController.java index 9acfc89..975a903 100644 --- a/src/main/java/net/thenextlvl/economist/controller/data/DataController.java +++ b/src/main/java/net/thenextlvl/economist/controller/data/DataController.java @@ -7,11 +7,15 @@ import java.math.BigDecimal; import java.util.List; +import java.util.Set; import java.util.UUID; @NullMarked public interface DataController { - @Nullable Account getAccount(UUID uuid, @Nullable World world); + @Nullable + Account getAccount(UUID uuid, @Nullable World world); + + Set getAccounts(@Nullable World world); Account createAccount(UUID uuid, @Nullable World world); @@ -19,7 +23,7 @@ public interface DataController { List getOrdered(@Nullable World world, int start, int limit); - List getAccounts(@Nullable World world); + Set getAccountOwners(@Nullable World world); boolean deleteAccounts(List accounts, @Nullable World world); diff --git a/src/main/java/net/thenextlvl/economist/controller/data/SQLController.java b/src/main/java/net/thenextlvl/economist/controller/data/SQLController.java index d15f809..cb2fb36 100644 --- a/src/main/java/net/thenextlvl/economist/controller/data/SQLController.java +++ b/src/main/java/net/thenextlvl/economist/controller/data/SQLController.java @@ -15,9 +15,11 @@ import java.sql.SQLException; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.Set; import java.util.UUID; @NullMarked @@ -88,12 +90,12 @@ SELECT SUM(balance) as total_balance FROM accounts WHERE (world = ? OR (? IS NUL @Override @SneakyThrows - public List getAccounts(@Nullable World world) { + public Set getAccountOwners(@Nullable World world) { var name = world != null ? world.key().asString() : null; return Objects.requireNonNull(executeQuery(""" SELECT uuid FROM accounts WHERE (world = ? OR (? IS NULL AND world IS NULL)) """, resultSet -> { - var accounts = new ArrayList(); + var accounts = new HashSet(); while (resultSet.next()) { var owner = UUID.fromString(resultSet.getString("uuid")); accounts.add(owner); @@ -114,6 +116,23 @@ SELECT uuid FROM accounts WHERE (world = ? OR (? IS NULL AND world IS NULL)) }, uuid, name, name); } + @Override + @SneakyThrows + public Set getAccounts(@Nullable World world) { + var name = world != null ? world.key().asString() : null; + return Objects.requireNonNull(executeQuery(""" + SELECT uuid, balance FROM accounts WHERE (world = ? OR (? IS NULL AND world IS NULL)) + """, resultSet -> { + var accounts = new HashSet(); + while (resultSet.next()) { + var owner = UUID.fromString(resultSet.getString("uuid")); + var balance = resultSet.getBigDecimal("balance"); + accounts.add(new EconomistAccount(balance, world, owner)); + } + return accounts; + }, name, name)); + } + @Override @SneakyThrows public boolean save(Account account) { diff --git a/src/main/java/net/thenextlvl/economist/service/ServiceEconomyController.java b/src/main/java/net/thenextlvl/economist/service/ServiceEconomyController.java index 3bc28b9..a4ab96d 100644 --- a/src/main/java/net/thenextlvl/economist/service/ServiceEconomyController.java +++ b/src/main/java/net/thenextlvl/economist/service/ServiceEconomyController.java @@ -9,13 +9,16 @@ import net.thenextlvl.service.api.economy.bank.BankController; import org.bukkit.World; import org.bukkit.plugin.ServicePriority; +import org.jetbrains.annotations.Unmodifiable; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import java.util.Locale; import java.util.Optional; +import java.util.Set; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; @NullMarked @RequiredArgsConstructor @@ -54,6 +57,20 @@ public String getCurrencySymbol() { return economyController().getCurrencySymbol(); } + @Override + public CompletableFuture<@Unmodifiable Set> loadAccounts() { + return economyController().loadAccounts().thenApply(accounts -> accounts.stream() + .map(ServiceAccount::new) + .collect(Collectors.toUnmodifiableSet())); + } + + @Override + public @Unmodifiable Set getAccounts() { + return economyController().getAccounts().stream() + .map(ServiceAccount::new) + .collect(Collectors.toUnmodifiableSet()); + } + @Override public Optional getAccount(UUID uuid) { return economyController().getAccount(uuid).map(ServiceAccount::new);