Refactor SQL storage - towards #77

This commit is contained in:
Luck 2016-12-23 16:55:35 +00:00
parent b35f3b4375
commit a35b0915ab
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
8 changed files with 297 additions and 262 deletions

View File

@ -28,12 +28,13 @@ import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.backing.AbstractBacking;
import me.lucko.luckperms.common.storage.backing.H2Backing;
import me.lucko.luckperms.common.storage.backing.JSONBacking;
import me.lucko.luckperms.common.storage.backing.MongoDBBacking;
import me.lucko.luckperms.common.storage.backing.MySQLBacking;
import me.lucko.luckperms.common.storage.backing.SQLiteBacking;
import me.lucko.luckperms.common.storage.backing.SQLBacking;
import me.lucko.luckperms.common.storage.backing.YAMLBacking;
import me.lucko.luckperms.common.storage.backing.sqlprovider.H2Provider;
import me.lucko.luckperms.common.storage.backing.sqlprovider.MySQLProvider;
import me.lucko.luckperms.common.storage.backing.sqlprovider.SQLiteProvider;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import java.io.File;
@ -119,11 +120,11 @@ public class StorageFactory {
private static AbstractBacking makeBacking(StorageType method, LuckPermsPlugin plugin) {
switch (method) {
case MYSQL:
return new MySQLBacking(plugin, plugin.getConfiguration().getDatabaseValues());
return new SQLBacking(plugin, new MySQLProvider(plugin.getConfiguration().getDatabaseValues()));
case SQLITE:
return new SQLiteBacking(plugin, new File(plugin.getDataFolder(), "luckperms.sqlite"));
return new SQLBacking(plugin, new SQLiteProvider(new File(plugin.getDataFolder(), "luckperms.sqlite")));
case H2:
return new H2Backing(plugin, new File(plugin.getDataFolder(), "luckperms.db"));
return new SQLBacking(plugin, new H2Provider(new File(plugin.getDataFolder(), "luckperms.db")));
case MONGODB:
return new MongoDBBacking(plugin, plugin.getConfiguration().getDatabaseValues());
case YAML:

View File

@ -1,139 +0,0 @@
/*
* 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.common.storage.backing;
import me.lucko.luckperms.common.LuckPermsPlugin;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class H2Backing extends SQLBacking {
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 final Object connectionLock = new Object();
private Connection connection = null;
public H2Backing(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(String query, QueryPS queryPS) {
boolean success = false;
PreparedStatement preparedStatement = null;
try {
Connection connection = getConnection();
if (connection == null || connection.isClosed()) {
throw new IllegalStateException("SQL connection is null");
}
preparedStatement = connection.prepareStatement(query);
queryPS.onRun(preparedStatement);
preparedStatement.execute();
success = true;
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(preparedStatement);
}
return success;
}
@Override
boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
boolean success = false;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Connection connection = getConnection();
if (connection == null || connection.isClosed()) {
throw new IllegalStateException("SQL connection is null");
}
preparedStatement = connection.prepareStatement(query);
queryPS.onRun(preparedStatement);
resultSet = preparedStatement.executeQuery();
success = queryRS.onResult(resultSet);
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(resultSet);
close(preparedStatement);
}
return success;
}
@Override
public void shutdown() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
Connection getConnection() throws SQLException {
synchronized (connectionLock) {
if (connection == null || connection.isClosed()) {
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException ignored) {
}
connection = DriverManager.getConnection("jdbc:h2:" + file.getAbsolutePath());
}
}
return connection;
}
}

View File

@ -22,6 +22,7 @@
package me.lucko.luckperms.common.storage.backing;
import com.google.common.collect.ImmutableMap;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@ -35,12 +36,11 @@ import me.lucko.luckperms.common.data.Log;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.impl.GenericUserManager;
import me.lucko.luckperms.common.storage.backing.sqlprovider.H2Provider;
import me.lucko.luckperms.common.storage.backing.sqlprovider.MySQLProvider;
import me.lucko.luckperms.common.storage.backing.sqlprovider.SQLProvider;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@ -49,13 +49,37 @@ import java.util.Set;
import java.util.UUID;
import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLegacy;
import static me.lucko.luckperms.common.storage.backing.sqlprovider.SQLProvider.QueryPS;
import static me.lucko.luckperms.common.storage.backing.sqlprovider.SQLProvider.QueryRS;
abstract class SQLBacking extends AbstractBacking {
private static final QueryPS EMPTY_PS = preparedStatement -> {};
public class SQLBacking extends AbstractBacking {
private static final Type NM_TYPE = new TypeToken<Map<String, Boolean>>() {}.getType();
private static final Type T_TYPE = new TypeToken<List<String>>() {}.getType();
private static final String MYSQL_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 MYSQL_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 MYSQL_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 MYSQL_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 MYSQL_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 static final String H2_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 H2_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 H2_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 H2_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 H2_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 static final String SQLITE_CREATETABLE_UUID = "CREATE TABLE IF NOT EXISTS `lp_uuid` (`name` VARCHAR(16) NOT NULL, `uuid` VARCHAR(36) NOT NULL, PRIMARY KEY (`name`));";
private static final String SQLITE_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`));";
private static final String SQLITE_CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`));";
private static final String SQLITE_CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`));";
private static final String SQLITE_CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INTEGER PRIMARY KEY NOT NULL, `time` BIG INT 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);";
private static final Map<Class<? extends SQLProvider>, String[]> INIT_QUERIES = ImmutableMap.<Class<? extends SQLProvider>, String[]>builder()
.put(MySQLProvider.class, new String[]{MYSQL_CREATETABLE_UUID, MYSQL_CREATETABLE_USERS, MYSQL_CREATETABLE_GROUPS, MYSQL_CREATETABLE_TRACKS, MYSQL_CREATETABLE_ACTION})
.put(H2Provider.class, new String[]{H2_CREATETABLE_UUID, H2_CREATETABLE_USERS, H2_CREATETABLE_GROUPS, H2_CREATETABLE_TRACKS, H2_CREATETABLE_ACTION})
.put(SQLProvider.class, new String[]{SQLITE_CREATETABLE_UUID, SQLITE_CREATETABLE_USERS, SQLITE_CREATETABLE_GROUPS, SQLITE_CREATETABLE_TRACKS, SQLITE_CREATETABLE_ACTION})
.build();
private static final String USER_INSERT = "INSERT INTO lp_users VALUES(?, ?, ?, ?)";
private static final String USER_SELECT = "SELECT * FROM lp_users WHERE uuid=?";
private static final String USER_SELECT_ALL = "SELECT uuid FROM lp_users";
@ -83,37 +107,32 @@ abstract class SQLBacking extends AbstractBacking {
private static final String ACTION_INSERT = "INSERT INTO lp_actions(`time`, `actor_uuid`, `actor_name`, `type`, `acted_uuid`, `acted_name`, `action`) VALUES(?, ?, ?, ?, ?, ?, ?)";
private static final String ACTION_SELECT_ALL = "SELECT * FROM lp_actions";
protected static void close(AutoCloseable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception ignored) {
}
}
}
private final Gson gson;
private final SQLProvider provider;
SQLBacking(LuckPermsPlugin plugin, String name) {
super(plugin, name);
public SQLBacking(LuckPermsPlugin plugin, SQLProvider provider) {
super(plugin, provider.getName());
this.provider = provider;
gson = new Gson();
}
abstract Connection getConnection() throws SQLException;
abstract boolean runQuery(String query, QueryPS queryPS);
abstract boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS);
boolean runQuery(String query) {
return runQuery(query, EMPTY_PS);
private boolean runQuery(String query, QueryPS queryPS) {
return provider.runQuery(query, queryPS);
}
boolean runQuery(String query, QueryRS queryRS) {
return runQuery(query, EMPTY_PS, queryRS);
private boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
return provider.runQuery(query, queryPS, queryRS);
}
boolean setupTables(String... tableQueries) {
private boolean runQuery(String query) {
return provider.runQuery(query);
}
private boolean runQuery(String query, QueryRS queryRS) {
return provider.runQuery(query, queryRS);
}
private boolean setupTables(String[] tableQueries) {
boolean success = true;
for (String q : tableQueries) {
if (!runQuery(q)) success = false;
@ -122,6 +141,32 @@ abstract class SQLBacking extends AbstractBacking {
return success && cleanupUsers();
}
@Override
public void init() {
try {
provider.init();
if (!setupTables(INIT_QUERIES.get(provider.getClass()))) {
plugin.getLog().severe("Error occurred whilst initialising the database.");
shutdown();
} else {
setAcceptingLogins(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void shutdown() {
try {
provider.shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean logAction(LogEntry entry) {
return runQuery(ACTION_INSERT, preparedStatement -> {
@ -635,12 +680,4 @@ abstract class SQLBacking extends AbstractBacking {
return success ? name[0] : null;
}
interface QueryPS {
void onRun(PreparedStatement preparedStatement) throws SQLException;
}
interface QueryRS {
boolean onResult(ResultSet resultSet) throws SQLException;
}
}

View File

@ -20,9 +20,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage.backing;
import me.lucko.luckperms.common.LuckPermsPlugin;
package me.lucko.luckperms.common.storage.backing.sqlprovider;
import java.io.File;
import java.sql.Connection;
@ -30,36 +28,55 @@ import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.locks.ReentrantLock;
public class SQLiteBacking extends SQLBacking {
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`));";
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`));";
private static final String CREATETABLE_GROUPS = "CREATE TABLE IF NOT EXISTS `lp_groups` (`name` VARCHAR(36) NOT NULL, `perms` TEXT NULL, PRIMARY KEY (`name`));";
private static final String CREATETABLE_TRACKS = "CREATE TABLE IF NOT EXISTS `lp_tracks` (`name` VARCHAR(36) NOT NULL, `groups` TEXT NULL, PRIMARY KEY (`name`));";
private static final String CREATETABLE_ACTION = "CREATE TABLE IF NOT EXISTS `lp_actions` (`id` INTEGER PRIMARY KEY NOT NULL, `time` BIG INT 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);";
public abstract class FlatfileProvider extends SQLProvider {
private final File file;
private final Object connectionLock = new Object();
private Connection connection = null;
private final ReentrantLock lock = new ReentrantLock();
private Connection connection;
public SQLiteBacking(LuckPermsPlugin plugin, File file) {
super(plugin, "SQLite");
public FlatfileProvider(String name, File file) {
super(name);
this.file = file;
}
protected abstract String getDriverClass();
protected abstract String getDriverId();
@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);
public void init() throws Exception {
}
@Override
public void shutdown() throws Exception {
if (connection != null && !connection.isClosed()) {
connection.close();
}
}
@Override
boolean runQuery(String query, QueryPS queryPS) {
public Connection getConnection() throws SQLException {
lock.lock();
try {
if (connection == null || connection.isClosed()) {
try {
Class.forName(getDriverClass());
} catch (ClassNotFoundException ignored) {}
connection = DriverManager.getConnection(getDriverId() + ":" + file.getAbsolutePath());
}
} finally {
lock.unlock();
}
return connection;
}
@Override
public boolean runQuery(String query, QueryPS queryPS) {
boolean success = false;
PreparedStatement preparedStatement = null;
@ -84,7 +101,7 @@ public class SQLiteBacking extends SQLBacking {
}
@Override
boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
public boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
boolean success = false;
PreparedStatement preparedStatement = null;
@ -109,31 +126,4 @@ public class SQLiteBacking extends SQLBacking {
}
return success;
}
@Override
public void shutdown() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
Connection getConnection() throws SQLException {
synchronized (connectionLock) {
if (connection == null || connection.isClosed()) {
try {
Class.forName("org.sqlite.JDBC");
} catch (ClassNotFoundException ignored) {
}
connection = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath());
}
}
return connection;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.common.storage.backing.sqlprovider;
import java.io.File;
public class H2Provider extends FlatfileProvider {
public H2Provider(File file) {
super("H2", file);
}
@Override
protected String getDriverClass() {
return "org.h2.Driver";
}
@Override
protected String getDriverId() {
return "jdbc:h2";
}
}

View File

@ -20,12 +20,11 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.storage.backing;
package me.lucko.luckperms.common.storage.backing.sqlprovider;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.DatastoreConfiguration;
import java.sql.Connection;
@ -34,24 +33,18 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
public class MySQLBacking extends SQLBacking {
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;";
public class MySQLProvider extends SQLProvider {
private final DatastoreConfiguration configuration;
private HikariDataSource hikari;
public MySQLBacking(LuckPermsPlugin plugin, DatastoreConfiguration configuration) {
super(plugin, "MySQL");
public MySQLProvider(DatastoreConfiguration configuration) {
super("MySQL");
this.configuration = configuration;
}
@Override
public void init() {
public void init() throws Exception {
HikariConfig config = new HikariConfig();
String address = configuration.getAddress();
@ -87,17 +80,22 @@ public class MySQLBacking extends SQLBacking {
config.setConnectionTestQuery("/* LuckPerms ping */ SELECT 1");
hikari = new HikariDataSource(config);
}
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
public void shutdown() throws Exception {
if (hikari != null) {
hikari.close();
}
}
@Override
boolean runQuery(String query, QueryPS queryPS) {
public Connection getConnection() throws SQLException {
return hikari.getConnection();
}
@Override
public boolean runQuery(String query, QueryPS queryPS) {
boolean success = false;
Connection connection = null;
@ -124,7 +122,7 @@ public class MySQLBacking extends SQLBacking {
}
@Override
boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
public boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS) {
boolean success = false;
Connection connection = null;
@ -151,16 +149,4 @@ public class MySQLBacking extends SQLBacking {
}
return success;
}
@Override
public void shutdown() {
if (hikari != null) {
hikari.close();
}
}
@Override
Connection getConnection() throws SQLException {
return hikari.getConnection();
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.common.storage.backing.sqlprovider;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@RequiredArgsConstructor
public abstract class SQLProvider {
private static final QueryPS EMPTY_PS = preparedStatement -> {};
static void close(AutoCloseable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (Exception ignored) {
}
}
}
@Getter
private final String name;
public abstract void init() throws Exception;
public abstract void shutdown() throws Exception;
public abstract Connection getConnection() throws SQLException;
public abstract boolean runQuery(String query, QueryPS queryPS);
public abstract boolean runQuery(String query, QueryPS queryPS, QueryRS queryRS);
public boolean runQuery(String query) {
return runQuery(query, EMPTY_PS);
}
public boolean runQuery(String query, QueryRS queryRS) {
return runQuery(query, EMPTY_PS, queryRS);
}
@FunctionalInterface
public interface QueryPS {
void onRun(PreparedStatement preparedStatement) throws SQLException;
}
@FunctionalInterface
public interface QueryRS {
boolean onResult(ResultSet resultSet) throws SQLException;
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.common.storage.backing.sqlprovider;
import java.io.File;
public class SQLiteProvider extends FlatfileProvider {
public SQLiteProvider(File file) {
super("SQLite", file);
}
@Override
protected String getDriverClass() {
return "org.sqlite.JDBC";
}
@Override
protected String getDriverId() {
return "jdbc:sqlite";
}
}