├── .github ├── dependabot.yml └── workflows │ └── maven.yml ├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main ├── java └── me │ └── hteppl │ └── data │ ├── DataManager.java │ ├── database │ ├── Database.java │ ├── MySQLDatabase.java │ └── SQLiteDatabase.java │ └── utils │ ├── Create.java │ └── Settings.java └── resources ├── config.yml └── plugin.yml /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "maven" 4 | directory: "/" 5 | open-pull-requests-limit: 10 6 | schedule: 7 | interval: "daily" 8 | time: "10:00" 9 | 10 | - package-ecosystem: "github-actions" 11 | directory: "/" 12 | schedule: 13 | interval: "daily" 14 | time: "10:00" 15 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Set up JDK 17 19 | uses: actions/setup-java@v4 20 | with: 21 | java-version: 17 22 | distribution: "zulu" 23 | - name: Build with Maven 24 | run: mvn package -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | /.idea/ 3 | /src/test/ 4 | /target/ 5 | dependency-reduced-pom.xml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 hteppl 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DataManager 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | [![jitpack](https://jitpack.io/v/hteppl/DataManager.svg)](https://jitpack.io/#hteppl/DataManager) 5 | 6 | DataManager is a simple library plugin for [PowerNukkitX](https://github.com/PowerNukkitX/PowerNukkitX) Minecraft 7 | Bedrock core, that will help you to create and 8 | manage your SQL connections with ease. 9 | 10 | ## Build JAR File 11 | 12 | ```shell 13 | $ git clone https://github.com/hteppl/DataManager 14 | $ cd DataManager 15 | $ mvn clean package 16 | ``` 17 | 18 | ## How to install 19 | 20 | If any plugin requires a DataManager, you just need to download and put it in `plugins` folder. Usually it will be 21 | enough. Also, you can configure some default database settings in `config.yml`. 22 | 23 | ### Maven 24 | 25 | ```xml 26 | 27 | 28 | jitpack.io 29 | https://jitpack.io 30 | 31 | 32 | ``` 33 | 34 | ```xml 35 | 36 | com.github.hteppl 37 | DataManager 38 | 2.2.0-SNAPSHOT 39 | 40 | ``` 41 | 42 | ### Gradle 43 | 44 | ```groovy 45 | allprojects { 46 | repositories { 47 | maven { url 'https://jitpack.io' } 48 | } 49 | } 50 | ``` 51 | 52 | ```groovy 53 | dependencies { 54 | implementation 'com.github.hteppl:DataManager:2.2.0-SNAPSHOT' 55 | } 56 | ``` 57 | 58 | ## Configuration 59 | 60 | Default plugin `config.yml` settings. 61 | 62 | ```yaml 63 | # sqlite directory name for anonymous databases 64 | # set empty, for creating database file in plugin's folder by default 65 | sqlite-directory: "database" 66 | 67 | # default mysql connection properties 68 | mysql-properties: "useSSL=false&autoReconnect=true&useUnicode=true&serverTimezone=UTC" 69 | 70 | # Hikari connection pool settings (https://github.com/brettwooldridge/HikariCP) 71 | hikari: 72 | auto-commit: true 73 | connection-timeout: 30000 74 | idle-timeout: 600000 75 | keepalive-time: 0 76 | max-lifetime: 1800000 77 | maximum-pool-size: 10 78 | ``` 79 | 80 | ## How to use 81 | 82 | Firstly we recommend to read: 83 | 84 | - [*Jdbi Developer Guide*](http://jdbi.org/) 85 | - [*HikariCP Configuration*](https://github.com/brettwooldridge/HikariCP#gear-configuration-knobs-baby) 86 | 87 | Very basic example of MySQL database class: 88 | 89 | ```java 90 | import me.hteppl.data.database.MySQLDatabase; 91 | import org.jdbi.v3.core.Handle; 92 | 93 | public class MyDatabase extends MySQLDatabase { 94 | 95 | public MyDatabase() { 96 | super("host", "database", "user", "password"); 97 | 98 | try (Handle handle = this.getHandle()) { 99 | handle.createUpdate("...") 100 | .bind("var1", "data1") 101 | .bind("var2", "data2") 102 | .execute(); 103 | } 104 | } 105 | } 106 | ``` 107 | 108 | Example of SQLite database class: 109 | 110 | ```java 111 | import me.hteppl.data.database.SQLiteDatabase; 112 | import org.jdbi.v3.core.Handle; 113 | 114 | public class MyDatabase extends SQLiteDatabase { 115 | 116 | public MyDatabase() { 117 | super("database"); 118 | 119 | try (Handle handle = this.getHandle()) { 120 | handle.createUpdate("...") 121 | .bind("var1", "data1") 122 | .bind("var2", "data2") 123 | .execute(); 124 | } 125 | } 126 | } 127 | ``` 128 | 129 | After that, you can easily do what you want with your [*Jdbi*](http://jdbi.org/) handles: 130 | 131 | ```java 132 | /* import your database class */ 133 | 134 | public class Main { 135 | 136 | public static void main(String[] args) { 137 | MyDatabase database = new MyDatabase(); 138 | 139 | try (Handle handle = database.getHandle()) { 140 | handle.createUpdate("...") 141 | .bind("var1", "data1") 142 | .bind("var2", "data2") 143 | .execute(); 144 | } 145 | } 146 | } 147 | ``` 148 | 149 | ## Libraries 150 | 151 | [**PowerNukkitX**](https://github.com/PowerNukkitX/PowerNukkitX) is a branch version based on PowerNukkit, 152 | developed and maintained by PowerNukkitX. 153 | 154 | [**MariaDB Connector**](https://github.com/mariadb-corporation/mariadb-connector-j) MariaDB Connector/J is a Type 4 JDBC 155 | driver. It was developed specifically as a lightweight JDBC connector for use with MariaDB and MySQL database servers. 156 | 157 | [**Jdbi**](https://github.com/jdbi/jdbi) The Jdbi library provides convenient, idiomatic access to relational databases 158 | in Java. 159 | 160 | [**HikariCP**](https://github.com/brettwooldridge/HikariCP) is a "zero-overhead" production ready JDBC connection pool. 161 | At roughly 130Kb, the library is very light. 162 | 163 | ## License 164 | 165 | This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | me.hteppl 8 | DataManager 9 | 2.2.0-SNAPSHOT 10 | 11 | 12 | 17 13 | 17 14 | UTF-8 15 | UTF-8 16 | 17 | 18 | 19 | 20 | hteppl 21 | Oleg Kraev 22 | https://github.com/hteppl 23 | 24 | 25 | IWareQ 26 | Dmitry Luk 27 | https://github.com/IWareQ 28 | 29 | 30 | 31 | 32 | 33 | 34 | ${basedir}/src/main/resources/ 35 | true 36 | . 37 | 38 | plugin.yml 39 | 40 | 41 | 42 | ${basedir}/src/main/resources/ 43 | . 44 | 45 | config.yml 46 | 47 | 48 | 49 | clean package 50 | 51 | 52 | maven-resources-plugin 53 | 3.3.1 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-compiler-plugin 58 | 3.11.0 59 | 60 | ${maven.compiler.source} 61 | ${maven.compiler.target} 62 | 63 | 64 | 65 | org.apache.maven.plugins 66 | maven-shade-plugin 67 | 3.5.1 68 | 69 | false 70 | 71 | 72 | 73 | package 74 | 75 | shade 76 | 77 | 78 | true 79 | 80 | 81 | *:* 82 | 83 | META-INF/** 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | cn.powernukkitx 97 | powernukkitx 98 | 1.20.40-r1 99 | provided 100 | 101 | 102 | org.jdbi 103 | jdbi3-core 104 | 3.42.0 105 | 106 | 107 | org.mariadb.jdbc 108 | mariadb-java-client 109 | 3.3.1 110 | 111 | 112 | com.zaxxer 113 | HikariCP 114 | 5.1.0 115 | 116 | 117 | org.xerial 118 | sqlite-jdbc 119 | 3.44.1.0 120 | 121 | 122 | org.projectlombok 123 | lombok 124 | 1.18.30 125 | provided 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/DataManager.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data; 2 | 3 | import cn.nukkit.plugin.PluginBase; 4 | import lombok.Getter; 5 | import me.hteppl.data.utils.Settings; 6 | 7 | public class DataManager extends PluginBase { 8 | 9 | @Getter 10 | private static Settings settings; 11 | 12 | @Override 13 | public void onEnable() { 14 | this.saveDefaultConfig(); 15 | settings = new Settings(this.getConfig(), this.getDataFolder().getPath()); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/database/Database.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data.database; 2 | 3 | import lombok.Getter; 4 | import org.jdbi.v3.core.Handle; 5 | import org.jdbi.v3.core.Jdbi; 6 | import org.jdbi.v3.core.mapper.reflect.BeanMapper; 7 | import org.jdbi.v3.core.mapper.reflect.ConstructorMapper; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | @Getter 13 | public abstract class Database { 14 | 15 | private final Jdbi jdbi; 16 | 17 | public Database(Jdbi jdbi) { 18 | this.jdbi = jdbi; 19 | this.registerRowMappers(); 20 | this.registerConstructorMappers(); 21 | } 22 | 23 | public Handle getHandle() { 24 | return jdbi.open(); 25 | } 26 | 27 | private void registerRowMappers() { 28 | List> mappers = new ArrayList<>(); 29 | this.getRowMappers(mappers); 30 | for (Class aClass : mappers) { 31 | jdbi.registerRowMapper(BeanMapper.factory(aClass)); 32 | } 33 | } 34 | 35 | private void registerConstructorMappers() { 36 | List> mappers = new ArrayList<>(); 37 | this.getConstructorMappers(mappers); 38 | for (Class aClass : mappers) { 39 | jdbi.registerRowMapper(ConstructorMapper.factory(aClass)); 40 | } 41 | } 42 | 43 | protected void getRowMappers(List> classList) { 44 | } 45 | 46 | protected void getConstructorMappers(List> classList) { 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/database/MySQLDatabase.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data.database; 2 | 3 | import me.hteppl.data.utils.Create; 4 | 5 | import javax.sql.DataSource; 6 | 7 | public class MySQLDatabase extends Database { 8 | 9 | public MySQLDatabase(String host, String database, String user, String password) { 10 | this(host, 3306, database, user, password); 11 | } 12 | 13 | public MySQLDatabase(String host, int port, String database, String user, String password) { 14 | super(Create.createMySQL(host, port, database, user, password)); 15 | } 16 | 17 | public MySQLDatabase(String host, int port, String database, String user, String password, String properties) { 18 | super(Create.createMySQL(host, port, database, user, password, properties)); 19 | } 20 | 21 | public MySQLDatabase(DataSource ds) { 22 | super(Create.createByDataSource(ds)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/database/SQLiteDatabase.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data.database; 2 | 3 | import me.hteppl.data.utils.Create; 4 | 5 | import javax.sql.DataSource; 6 | 7 | public class SQLiteDatabase extends Database { 8 | 9 | public SQLiteDatabase(String database) { 10 | super(Create.createSQLite(database)); 11 | } 12 | 13 | public SQLiteDatabase(String folder, String database) { 14 | super(Create.createSQLite(folder, database)); 15 | } 16 | 17 | public SQLiteDatabase(DataSource ds) { 18 | super(Create.createByDataSource(ds)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/utils/Create.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data.utils; 2 | 3 | import com.zaxxer.hikari.HikariConfig; 4 | import com.zaxxer.hikari.HikariDataSource; 5 | import lombok.extern.log4j.Log4j2; 6 | import me.hteppl.data.DataManager; 7 | import org.jdbi.v3.core.Jdbi; 8 | 9 | import javax.sql.DataSource; 10 | import java.io.IOException; 11 | import java.nio.file.Files; 12 | import java.nio.file.Paths; 13 | 14 | @Log4j2 15 | public class Create { 16 | 17 | public static Jdbi createSQLite(String database) { 18 | return createSQLite(DataManager.getSettings().getSqliteDirectory(), database); 19 | } 20 | 21 | public static Jdbi createSQLite(String folder, String database) { 22 | try { 23 | Class.forName("org.sqlite.JDBC"); 24 | Files.createDirectories(Paths.get(folder)); 25 | } catch (ClassNotFoundException ex) { 26 | throw new RuntimeException("Error while trying to load SQLite driver", ex); 27 | } catch (IOException ex) { 28 | throw new RuntimeException("Error while trying to create " + folder, ex); 29 | } 30 | 31 | return Jdbi.create("jdbc:sqlite:" + folder + "/" + database + ".db"); 32 | } 33 | 34 | public static Jdbi createMySQL(String host, int port, String database, String user, String password) { 35 | return createMySQL(host, port, database, user, password, null); 36 | } 37 | 38 | public static Jdbi createMySQL(String host, int port, String database, String user, String password, String properties) { 39 | try { 40 | Class.forName("org.mariadb.jdbc.Driver"); 41 | } catch (ClassNotFoundException ex) { 42 | throw new RuntimeException("Error while trying to load MariaDB driver", ex); 43 | } 44 | 45 | try { 46 | var settings = DataManager.getSettings(); 47 | var hikari = settings.getHikari(); 48 | var config = new HikariConfig(); 49 | 50 | properties = properties != null && !properties.trim().isEmpty() ? "?" + properties : settings.getMysqlProperties(); 51 | 52 | config.setJdbcUrl("jdbc:mariadb://" + host + ":" + port + "/" + database + properties); 53 | config.setUsername(user); 54 | config.setPassword(password); 55 | config.setAutoCommit(hikari.autoCommit); 56 | config.setConnectionTimeout(hikari.connectionTimeout); 57 | config.setIdleTimeout(hikari.idleTimeout); 58 | config.setKeepaliveTime(hikari.keepaliveTime); 59 | config.setMaxLifetime(hikari.maxLifetime); 60 | config.setMaximumPoolSize(hikari.maximumPoolSize); 61 | 62 | return createByDataSource(new HikariDataSource(config)); 63 | } catch (Exception ex) { 64 | throw new RuntimeException(ex); 65 | } 66 | } 67 | 68 | public static Jdbi createByDataSource(DataSource ds) { 69 | return Jdbi.create(ds); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/me/hteppl/data/utils/Settings.java: -------------------------------------------------------------------------------- 1 | package me.hteppl.data.utils; 2 | 3 | import cn.nukkit.utils.Config; 4 | import cn.nukkit.utils.ConfigSection; 5 | import lombok.Getter; 6 | 7 | @Getter 8 | public class Settings { 9 | 10 | private final String sqliteDirectory; 11 | private final String mysqlProperties; 12 | private final HikariSettings hikari; 13 | 14 | public Settings(Config config, String pluginPath) { 15 | String dir = config.getString("sqlite-directory", "database"); 16 | this.sqliteDirectory = dir.trim().isEmpty() ? pluginPath : dir; 17 | this.mysqlProperties = config.getString("mysql-properties", ""); 18 | this.hikari = new HikariSettings(config.getSection("hikari")); 19 | } 20 | 21 | @Getter 22 | public static class HikariSettings { 23 | 24 | public final boolean autoCommit; 25 | public final int connectionTimeout; 26 | public final int idleTimeout; 27 | public final int keepaliveTime; 28 | public final int maxLifetime; 29 | public final int maximumPoolSize; 30 | 31 | public HikariSettings(ConfigSection section) { 32 | this.autoCommit = section.getBoolean("auto-commit", true); 33 | this.connectionTimeout = section.getInt("connection-timeout", 30000); 34 | this.idleTimeout = section.getInt("idle-timeout", 600000); 35 | this.keepaliveTime = section.getInt("keepalive-time", 0); 36 | this.maxLifetime = section.getInt("max-lifetime", 1800000); 37 | this.maximumPoolSize = section.getInt("maximum-pool-size", 10); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | # sqlite directory name for anonymous databases 2 | # set empty, for creating database file in plugin's folder by default 3 | sqlite-directory: "database" 4 | 5 | # default mysql connection properties 6 | mysql-properties: "sslMode=DISABLED&autoReconnect=true&useUnicode=true&serverTimezone=UTC" 7 | 8 | # Hikari connection pool settings (https://github.com/brettwooldridge/HikariCP) 9 | hikari: 10 | auto-commit: true 11 | connection-timeout: 30000 12 | idle-timeout: 600000 13 | keepalive-time: 0 14 | max-lifetime: 1800000 15 | maximum-pool-size: 10 16 | -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: DataManager 2 | main: me.hteppl.data.DataManager 3 | version: "${pom.version}" 4 | api: 1.0.13 5 | load: STARTUP 6 | authors: 7 | - "https://github.com/hteppl" 8 | - "https://github.com/IWareQ" 9 | website: "https://github.com/hteppl/DataManager" --------------------------------------------------------------------------------