Skip to content

Instantly share code, notes, and snippets.

@webcrawls
Created October 21, 2020 17:46
Show Gist options
  • Save webcrawls/0d9a1e2319ed9c6b1b84579c8cfb8c21 to your computer and use it in GitHub Desktop.
Save webcrawls/0d9a1e2319ed9c6b1b84579c8cfb8c21 to your computer and use it in GitHub Desktop.
Database method using CompletableFutures
/**
* Fetches user data and constructs a {@link User} for the given UUID.
* Will create a new object if none exists.
*
* @param uuid UUID of player to get
*/
// JDBI is just a wrapper around JDBC, I use HikariCP. You can replace JDBI with the appropriate HikariCP methods :pog:
// This won't really be fit for your use case, the main takeaway here is the use of CompletableFuture
// Check the other file to see how I use it in my PlayerManager
public @NonNull CompletableFuture<User> getUser(@NonNull final UUID uuid,
@NonNull final String playerName) {
return CompletableFuture.supplyAsync(() -> jdbi.withHandle(handle -> {
Optional<User> userOpt = handle.select("SELECT * FROM global WHERE uuid = ?")
.bind(0, uuid.toString())
.map(new UserMapper(uuid, playerName))
.findFirst();
User user = userOpt.orElseGet(() -> new User.Builder(uuid, playerName).build());
Optional<UserConfig> userConfigOpt =
handle.select("SELECT * FROM user_settings WHERE user_id = ?")
.bind(0, user.getUserId())
.map(new UserConfigMapper())
.findFirst();
UserConfig userConfig = userConfigOpt.orElseGet(() -> new UserConfig.Builder().build());
for (var entry : requestedGameDataClasses.entrySet()) {
try {
String id = entry.getKey();
Optional<Map<String, Object>> mapOptional =
handle.select("SELECT * FROM " + id + " WHERE user_id = ?")
.bind(0, user.getUserId())
.map(new MapMapper())
.findFirst();
Map<String, Object> map;
map = mapOptional.orElseGet(HashMap::new);
Class<? extends GameData> clazz = entry.getValue();
GameData gameData = clazz.getConstructor().newInstance();
gameData.load(map);
user.getGameDataMap().put(id, gameData);
} catch (ReflectiveOperationException e) {
e.printStackTrace();
}
}
user.setConfig(userConfig);
return user;
})).whenComplete((v, err) -> {
if (err != null) {
err.printStackTrace();
}
});
}
// playerMap is a ConcurrentHashMap because we access it asynchronously
this.playerMap = new ConcurrentHashMap<>();
/**
* Loads the user into the internal user map
*
* @param uuid UUID of the player to load
*/
public CompletableFuture<User> loadUser(UUID uuid, String playerName) {
return databaseManager.getUser(uuid, playerName)
.thenApplyAsync(user -> {
playerMap.put(uuid, user);
return user;
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment