Add support for MongoDB and H2 database formats

This commit is contained in:
Luck
2016-08-19 18:21:16 +01:00
Unverified
parent 31cef46b56
commit a15a0752f4
26 changed files with 877 additions and 137 deletions
@@ -96,6 +96,11 @@ public interface LuckPermsPlugin {
*/
File getMainDir();
/**
* @return the platforms data folder
*/
File getDataFolder();
/**
* @return the importer instance for the platform
*/
@@ -126,6 +131,12 @@ public interface LuckPermsPlugin {
*/
List<Sender> getSenders();
/**
* Gets the console sender of the instance
* @return a the console sender of the instance
*/
Sender getConsoleSender();
/**
* Gets all possible permission nodes, used for resolving wildcards
* @return a {@link List} of permission nodes
@@ -24,6 +24,7 @@ package me.lucko.luckperms.api.implementation.internal;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.LPConfiguration;
import me.lucko.luckperms.api.data.DatastoreConfiguration;
import me.lucko.luckperms.api.data.MySQLConfiguration;
/**
@@ -78,8 +79,14 @@ public class LPConfigurationLink implements LPConfiguration {
return master.getApplyShorthand();
}
@SuppressWarnings("deprecation")
@Override
public MySQLConfiguration getDatabaseValues() {
return getDatastoreConfig();
}
@Override
public DatastoreConfiguration getDatastoreConfig() {
return master.getDatabaseValues();
}
@@ -26,7 +26,7 @@ import lombok.AccessLevel;
import lombok.Getter;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.constants.Patterns;
import me.lucko.luckperms.storage.MySQLConfiguration;
import me.lucko.luckperms.storage.DatastoreConfiguration;
public abstract class LPConfiguration<T extends LuckPermsPlugin> {
@@ -70,7 +70,7 @@ public abstract class LPConfiguration<T extends LuckPermsPlugin> {
}
public int getSyncTime() {
return getInt("sql.sync-minutes", 3);
return getInt("data.sync-minutes", 3);
}
public String getDefaultGroupNode() {
@@ -101,12 +101,12 @@ public abstract class LPConfiguration<T extends LuckPermsPlugin> {
return getBoolean("apply-shorthand", true);
}
public MySQLConfiguration getDatabaseValues() {
return new MySQLConfiguration(
getString("sql.address", null),
getString("sql.database", null),
getString("sql.username", null),
getString("sql.password", null)
public DatastoreConfiguration getDatabaseValues() {
return new DatastoreConfiguration(
getString("data.address", null),
getString("data.database", null),
getString("data.username", null),
getString("data.password", null)
);
}
@@ -31,6 +31,9 @@ import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.users.User;
import java.util.List;
import java.util.stream.Collectors;
public class LogEntry extends me.lucko.luckperms.api.LogEntry {
public static LogEntryBuilder build() {
return new LogEntryBuilder();
@@ -45,8 +48,12 @@ public class LogEntry extends me.lucko.luckperms.api.LogEntry {
final String msg = super.getFormatted();
plugin.getSenders().stream()
List<Sender> senders = plugin.getSenders().stream()
.filter(Permission.LOG_NOTIFY::isAuthorized)
.collect(Collectors.toList());
senders.add(plugin.getConsoleSender());
senders.stream()
.filter(s -> !plugin.getIgnoringLogs().contains(s.getUuid()))
.forEach(s -> Message.LOG.send(s, msg));
}
@@ -27,7 +27,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public class MySQLConfiguration implements me.lucko.luckperms.api.data.MySQLConfiguration {
public class DatastoreConfiguration implements me.lucko.luckperms.api.data.DatastoreConfiguration {
private final String address;
private final String database;
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.storage;
import com.google.common.collect.ImmutableSet;
import lombok.experimental.UtilityClass;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.storage.methods.*;
import java.io.File;
import java.util.Set;
@UtilityClass
public class StorageFactory {
private static final Set<String> TYPES = ImmutableSet.of("flatfile", "mongodb", "mysql", "sqlite", "h2");
public static Datastore getDatastore(LuckPermsPlugin plugin, String defaultMethod) {
Datastore datastore;
plugin.getLog().info("Detecting storage method...");
String storageMethod = plugin.getConfiguration().getStorageMethod().toLowerCase();
if (!TYPES.contains(storageMethod)) {
plugin.getLog().severe("Storage method '" + storageMethod + "' not recognised. Using the default instead.");
storageMethod = defaultMethod;
}
switch (storageMethod) {
case "mysql":
plugin.getLog().info("Using MySQL as storage method.");
datastore = new MySQLDatastore(plugin, plugin.getConfiguration().getDatabaseValues());
break;
case "sqlite":
plugin.getLog().info("Using SQLite as storage method.");
datastore = new SQLiteDatastore(plugin, new File(plugin.getDataFolder(), "luckperms.sqlite"));
break;
case "h2":
plugin.getLog().info("Using H2 as storage method.");
datastore = new H2Datastore(plugin, new File(plugin.getDataFolder(), "luckperms.db"));
break;
case "mongodb":
plugin.getLog().info("Using MongoDB as storage method.");
datastore = new MongoDBDatastore(plugin, plugin.getConfiguration().getDatabaseValues());
break;
default:
plugin.getLog().info("Using Flatfile (JSON) as storage method.");
datastore = new FlatfileDatastore(plugin, plugin.getDataFolder());
break;
}
plugin.getLog().info("Initialising datastore...");
datastore.init();
return datastore;
}
}
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.storage.methods;
import lombok.Cleanup;
import me.lucko.luckperms.LuckPermsPlugin;
import java.io.File;
import java.sql.*;
public class H2Datastore extends SQLDatastore {
private static final String CREATETABLE_UUID = "CREATE TABLE IF NOT EXISTS `lp_uuid` (`name` VARCHAR(16) NOT NULL, `uuid` VARCHAR(36) NOT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;";
private static final String CREATETABLE_USERS = "CREATE TABLE IF NOT EXISTS `lp_users` (`uuid` VARCHAR(36) NOT NULL, `name` VARCHAR(16) NOT NULL, `primary_group` VARCHAR(36) NOT NULL, `perms` TEXT NOT NULL, PRIMARY KEY (`uuid`)) DEFAULT CHARSET=utf8;";
private static final String CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;";
private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;";
private static final String CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INT AUTO_INCREMENT NOT NULL, `time` BIGINT NOT NULL, `actor_uuid` VARCHAR(36) NOT NULL, `actor_name` VARCHAR(16) NOT NULL, `type` CHAR(1) NOT NULL, `acted_uuid` VARCHAR(36) NOT NULL, `acted_name` VARCHAR(36) NOT NULL, `action` VARCHAR(256) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;";
private final File file;
private Connection connection = null;
public H2Datastore(LuckPermsPlugin plugin, File file) {
super(plugin, "H2");
this.file = file;
}
@Override
public void init() {
if (!setupTables(CREATETABLE_UUID, CREATETABLE_USERS, CREATETABLE_GROUPS, CREATETABLE_TRACKS, CREATETABLE_ACTION)) {
plugin.getLog().severe("Error occurred whilst initialising the database.");
shutdown();
} else {
setAcceptingLogins(true);
}
}
@Override
boolean runQuery(QueryPS queryPS) {
boolean success = false;
try {
Connection connection = getConnection();
if (connection == null || connection.isClosed()) {
throw new IllegalStateException("SQL connection is null");
}
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(queryPS.getQuery());
queryPS.onRun(preparedStatement);
preparedStatement.execute();
success = true;
} catch (SQLException e) {
e.printStackTrace();
}
return success;
}
@Override
boolean runQuery(QueryRS queryRS) {
boolean success = false;
try {
Connection connection = getConnection();
if (connection == null || connection.isClosed()) {
throw new IllegalStateException("SQL connection is null");
}
@Cleanup PreparedStatement preparedStatement = connection.prepareStatement(queryRS.getQuery());
queryRS.onRun(preparedStatement);
preparedStatement.execute();
@Cleanup ResultSet resultSet = preparedStatement.executeQuery();
success = queryRS.onResult(resultSet);
} catch (SQLException e) {
e.printStackTrace();
}
return success;
}
@Override
public void shutdown() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
Connection getConnection() throws SQLException {
if (connection == null || connection.isClosed()) {
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException ignored) {}
connection = DriverManager.getConnection("jdbc:h2:" + file.getAbsolutePath());
}
return connection;
}
}
@@ -0,0 +1,453 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.storage.methods;
import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.model.InsertOneOptions;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.data.Log;
import me.lucko.luckperms.groups.Group;
import me.lucko.luckperms.groups.GroupManager;
import me.lucko.luckperms.storage.Datastore;
import me.lucko.luckperms.storage.DatastoreConfiguration;
import me.lucko.luckperms.tracks.Track;
import me.lucko.luckperms.tracks.TrackManager;
import me.lucko.luckperms.users.User;
import org.bson.Document;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
@SuppressWarnings("unchecked")
public class MongoDBDatastore extends Datastore {
private final DatastoreConfiguration configuration;
private MongoClient mongoClient;
private MongoDatabase database;
public MongoDBDatastore(LuckPermsPlugin plugin, DatastoreConfiguration configuration) {
super(plugin, "MongoDB");
this.configuration = configuration;
}
@Override
public void init() {
MongoCredential credential = MongoCredential.createCredential(
configuration.getUsername(),
configuration.getDatabase(),
configuration.getPassword().toCharArray()
);
ServerAddress address = new ServerAddress(
configuration.getAddress().split(":")[0],
Integer.parseInt(configuration.getAddress().split(":")[1])
);
mongoClient = new MongoClient(address, Collections.singletonList(credential));
database = mongoClient.getDatabase(configuration.getDatabase());
setAcceptingLogins(true);
}
@Override
public void shutdown() {
if (mongoClient != null) {
mongoClient.close();
}
}
@Override
public boolean logAction(LogEntry entry) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("action");
Document doc = new Document()
.append("timestamp", entry.getTimestamp())
.append("actor", entry.getActor())
.append("actorName", entry.getActorName())
.append("type", Character.toString(entry.getType()))
.append("actedName", entry.getActedName())
.append("action", entry.getAction());
if (entry.getActed() != null) {
doc.append("acted", entry.getActed());
}
c.insertOne(doc, new InsertOneOptions());
return true;
}, false);
}
@Override
public Log getLog() {
return call(() -> {
final Log.Builder log = Log.builder();
MongoCollection<Document> c = database.getCollection("action");
try (MongoCursor<Document> cursor = c.find().iterator()) {
while (cursor.hasNext()) {
Document d = cursor.next();
UUID actedUuid = null;
if (d.containsKey("acted")) {
actedUuid = d.get("acted", UUID.class);
}
LogEntry e = new LogEntry(
d.getLong("timestamp"),
d.get("actor", UUID.class),
d.getString("actorName"),
d.getString("type").toCharArray()[0],
actedUuid,
d.getString("actedName"),
d.getString("action")
);
log.add(e);
}
}
return log.build();
}, null);
}
@Override
public boolean loadOrCreateUser(UUID uuid, String username) {
User user = plugin.getUserManager().make(uuid, username);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("users");
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
if (!cursor.hasNext()) {
plugin.getUserManager().giveDefaults(user);
c.insertOne(fromUser(user));
} else {
Document d = cursor.next();
user.setPrimaryGroup(d.getString("primaryGroup"));
user.setNodes(revert((Map<String, Boolean>) d.get("perms")));
if (!d.getString("name").equals(user.getName())) {
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
}
}
}
return true;
}, false);
if (success) plugin.getUserManager().updateOrSet(user);
return success;
}
@Override
public boolean loadUser(UUID uuid) {
User user = plugin.getUserManager().make(uuid);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("users");
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
if (cursor.hasNext()) {
Document d = cursor.next();
user.setName(d.getString("name"));
user.setPrimaryGroup(d.getString("primaryGroup"));
user.setNodes(revert((Map<String, Boolean>) d.get("perms")));
return true;
}
return false;
}
}, false);
if (success) plugin.getUserManager().updateOrSet(user);
return success;
}
@Override
public boolean saveUser(User user) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("users");
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
return true;
}, false);
}
@Override
public boolean createAndLoadGroup(String name) {
Group group = plugin.getGroupManager().make(name);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("groups");
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
if (!cursor.hasNext()) {
c.insertOne(fromGroup(group));
} else {
Document d = cursor.next();
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
}
}
return true;
}, false);
if (success) plugin.getGroupManager().updateOrSet(group);
return success;
}
@Override
public boolean loadGroup(String name) {
Group group = plugin.getGroupManager().make(name);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("groups");
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
if (cursor.hasNext()) {
Document d = cursor.next();
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
return true;
}
return false;
}
}, false);
if (success) plugin.getGroupManager().updateOrSet(group);
return success;
}
@Override
public boolean loadAllGroups() {
List<Group> groups = new ArrayList<>();
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("groups");
try (MongoCursor<Document> cursor = c.find().iterator()) {
while (cursor.hasNext()) {
Document d = cursor.next();
Group group = plugin.getGroupManager().make(d.getString("_id"));
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
groups.add(group);
}
}
return true;
}, false);
if (success) {
GroupManager gm = plugin.getGroupManager();
gm.unloadAll();
groups.forEach(gm::set);
}
return success;
}
@Override
public boolean saveGroup(Group group) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("groups");
return c.replaceOne(new Document("_id", group.getName()), fromGroup(group)).wasAcknowledged();
}, false);
}
@Override
public boolean deleteGroup(Group group) {
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("groups");
return c.deleteOne(new Document("_id", group.getName())).wasAcknowledged();
}, false);
if (success) plugin.getGroupManager().unload(group);
return success;
}
@Override
public boolean createAndLoadTrack(String name) {
Track track = plugin.getTrackManager().make(name);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("tracks");
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
if (!cursor.hasNext()) {
c.insertOne(fromTrack(track));
} else {
Document d = cursor.next();
track.setGroups((List<String>) d.get("groups"));
}
}
return true;
}, false);
if (success) plugin.getTrackManager().updateOrSet(track);
return success;
}
@Override
public boolean loadTrack(String name) {
Track track = plugin.getTrackManager().make(name);
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("tracks");
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
if (cursor.hasNext()) {
Document d = cursor.next();
track.setGroups((List<String>) d.get("groups"));
return true;
}
return false;
}
}, false);
if (success) plugin.getTrackManager().updateOrSet(track);
return success;
}
@Override
public boolean loadAllTracks() {
List<Track> tracks = new ArrayList<>();
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("tracks");
try (MongoCursor<Document> cursor = c.find().iterator()) {
while (cursor.hasNext()) {
Document d = cursor.next();
Track track = plugin.getTrackManager().make(d.getString("_id"));
track.setGroups((List<String>) d.get("groups"));
tracks.add(track);
}
}
return true;
}, false);
if (success) {
TrackManager tm = plugin.getTrackManager();
tm.unloadAll();
tracks.forEach(tm::set);
}
return success;
}
@Override
public boolean saveTrack(Track track) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("tracks");
return c.replaceOne(new Document("_id", track.getName()), fromTrack(track)).wasAcknowledged();
}, false);
}
@Override
public boolean deleteTrack(Track track) {
boolean success = call(() -> {
MongoCollection<Document> c = database.getCollection("tracks");
return c.deleteOne(new Document("_id", track.getName())).wasAcknowledged();
}, false);
if (success) plugin.getTrackManager().unload(track);
return success;
}
@Override
public boolean saveUUIDData(String username, UUID uuid) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("uuid");
try (MongoCursor<Document> cursor = c.find(new Document("_id", uuid)).iterator()) {
if (cursor.hasNext()) {
c.replaceOne(new Document("_id", uuid), new Document("_id", uuid).append("name", username.toLowerCase()));
} else {
c.insertOne(new Document("_id", uuid).append("name", username.toLowerCase()));
}
}
return true;
}, false);
}
@Override
public UUID getUUID(String username) {
return call(() -> {
MongoCollection<Document> c = database.getCollection("uuid");
try (MongoCursor<Document> cursor = c.find(new Document("name", username.toLowerCase())).iterator()) {
if (cursor.hasNext()) {
return cursor.next().get("_id", UUID.class);
}
}
return null;
}, null);
}
private static <T> T call(Callable<T> c, T def) {
try {
return c.call();
} catch (Exception e) {
e.printStackTrace();
return def;
}
}
/* MongoDB does not allow '.' or '$' in key names.
See: https://docs.mongodb.com/manual/reference/limits/#Restrictions-on-Field-Names
The following two methods convert the node maps so they can be stored. */
private static <V> Map<String, V> convert(Map<String, V> map) {
return map.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey().replace(".", "[**DOT**]").replace("$", "[**DOLLAR**]"), e.getValue()))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
}
private static <V> Map<String, V> revert(Map<String, V> map) {
return map.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<>(e.getKey().replace("[**DOT**]", ".").replace("[**DOLLAR**]", "$"), e.getValue()))
.collect(Collectors.toMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue));
}
private static Document fromUser(User user) {
Document main = new Document("_id", user.getUuid())
.append("name", user.getName())
.append("primaryGroup", user.getPrimaryGroup());
Document perms = new Document();
for (Map.Entry<String, Boolean> e : convert(user.getNodes()).entrySet()) {
perms.append(e.getKey(), e.getValue());
}
main.append("perms", perms);
return main;
}
private static Document fromGroup(Group group) {
Document main = new Document("_id", group.getName());
Document perms = new Document();
for (Map.Entry<String, Boolean> e : convert(group.getNodes()).entrySet()) {
perms.append(e.getKey(), e.getValue());
}
main.append("perms", perms);
return main;
}
private static Document fromTrack(Track track) {
return new Document("_id", track.getName()).append("groups", track.getGroups());
}
}
@@ -25,7 +25,7 @@ package me.lucko.luckperms.storage.methods;
import com.zaxxer.hikari.HikariDataSource;
import lombok.Cleanup;
import me.lucko.luckperms.LuckPermsPlugin;
import me.lucko.luckperms.storage.MySQLConfiguration;
import me.lucko.luckperms.storage.DatastoreConfiguration;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -40,10 +40,10 @@ public class MySQLDatastore extends SQLDatastore {
private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`)) DEFAULT CHARSET=utf8;";
private static final String CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INT AUTO_INCREMENT NOT NULL, `time` BIGINT NOT NULL, `actor_uuid` VARCHAR(36) NOT NULL, `actor_name` VARCHAR(16) NOT NULL, `type` CHAR(1) NOT NULL, `acted_uuid` VARCHAR(36) NOT NULL, `acted_name` VARCHAR(36) NOT NULL, `action` VARCHAR(256) NOT NULL, PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;";
private final MySQLConfiguration configuration;
private final DatastoreConfiguration configuration;
private HikariDataSource hikari;
public MySQLDatastore(LuckPermsPlugin plugin, MySQLConfiguration configuration) {
public MySQLDatastore(LuckPermsPlugin plugin, DatastoreConfiguration configuration) {
super(plugin, "MySQL");
this.configuration = configuration;
}
@@ -109,7 +109,7 @@ abstract class SQLDatastore extends Datastore {
boolean onResult(ResultSet resultSet) throws SQLException {
if (resultSet.next()) {
user.setName(resultSet.getString("name"));
user.getNodes().putAll(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
user.setNodes(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
user.setPrimaryGroup(resultSet.getString("primary_group"));
return true;
}
@@ -193,7 +193,7 @@ abstract class SQLDatastore extends Datastore {
}
});
} else {
user.getNodes().putAll(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
user.setNodes(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
user.setPrimaryGroup(resultSet.getString("primary_group"));
if (!resultSet.getString("name").equals(user.getName())) {
@@ -251,7 +251,7 @@ abstract class SQLDatastore extends Datastore {
}
});
} else {
group.getNodes().putAll(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
group.setNodes(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
}
return success;
}
@@ -273,7 +273,7 @@ abstract class SQLDatastore extends Datastore {
@Override
boolean onResult(ResultSet resultSet) throws SQLException {
if (resultSet.next()) {
group.getNodes().putAll(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
group.setNodes(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
return true;
}
return false;
@@ -297,7 +297,7 @@ abstract class SQLDatastore extends Datastore {
boolean onResult(ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
Group group = plugin.getGroupManager().make(resultSet.getString("name"));
group.getNodes().putAll(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
group.setNodes(gson.fromJson(resultSet.getString("perms"), NM_TYPE));
groups.add(group);
}
return true;