From 9c33e1e13acaca88067ca2e583f2624e45dd4d70 Mon Sep 17 00:00:00 2001 From: Syrent Date: Fri, 4 Apr 2025 19:09:07 +0330 Subject: [PATCH] fix: a lot of stuff --- .../sayandev/stickynote/bukkit/StickyNote.kt | 1 + .../core/database/sqlite/SQLiteDatabase.kt | 8 +- .../core/database/sqlite/SQLiteExecutor.kt | 105 +++++++++++++----- .../plugin/StickyNoteProjectPlugin.kt | 5 +- .../loader/bukkit/StickyNoteBukkitLoader.java | 2 +- .../loader/bungee/StickyNoteBungeeLoader.java | 2 +- .../loader/common/StickyNoteLoader.java | 44 ++++---- .../velocity/StickyNoteVelocityLoader.java | 2 +- 8 files changed, 107 insertions(+), 62 deletions(-) diff --git a/stickynote-bukkit/src/main/kotlin/org/sayandev/stickynote/bukkit/StickyNote.kt b/stickynote-bukkit/src/main/kotlin/org/sayandev/stickynote/bukkit/StickyNote.kt index ec647cba..8f866c1e 100644 --- a/stickynote-bukkit/src/main/kotlin/org/sayandev/stickynote/bukkit/StickyNote.kt +++ b/stickynote-bukkit/src/main/kotlin/org/sayandev/stickynote/bukkit/StickyNote.kt @@ -4,6 +4,7 @@ import com.github.shynixn.mccoroutine.bukkit.registerSuspendingEvents import com.github.shynixn.mccoroutine.folia.launch import com.google.common.util.concurrent.ThreadFactoryBuilder import kotlinx.coroutines.* +import org.bukkit.Location import org.bukkit.entity.Player import org.bukkit.event.HandlerList import org.bukkit.event.Listener diff --git a/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteDatabase.kt b/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteDatabase.kt index 1258849a..85383810 100644 --- a/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteDatabase.kt +++ b/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteDatabase.kt @@ -5,7 +5,7 @@ import java.io.File import java.util.concurrent.CompletableFuture import java.util.logging.Logger -class SQLiteDatabase(dbFile: File, logger: Logger) : SQLiteExecutor(dbFile, logger) { +class SQLiteDatabase(dbFile: File, logger: Logger, maxConnectionPool: Int = 5) : SQLiteExecutor(dbFile, logger, maxConnectionPool) { override fun connect() { super.connect() startQueue() @@ -23,10 +23,6 @@ class SQLiteDatabase(dbFile: File, logger: Logger) : SQLiteExecutor(dbFile, logg return future } - override fun shutdown() { - connection?.close() - } - private fun startQueue() { Thread { while (!isQueueEmpty) { @@ -43,4 +39,4 @@ class SQLiteDatabase(dbFile: File, logger: Logger) : SQLiteExecutor(dbFile, logg override fun onQueryRemoveDueToFail(query: Query) { //ignored } -} +} \ No newline at end of file diff --git a/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteExecutor.kt b/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteExecutor.kt index 0e16bcb5..df26b002 100644 --- a/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteExecutor.kt +++ b/stickynote-core/src/main/kotlin/org/sayandev/stickynote/core/database/sqlite/SQLiteExecutor.kt @@ -1,5 +1,7 @@ package org.sayandev.stickynote.core.database.sqlite +import com.zaxxer.hikari.HikariConfig +import com.zaxxer.hikari.HikariDataSource import org.sayandev.stickynote.core.database.Database import org.sayandev.stickynote.core.database.Priority import org.sayandev.stickynote.core.database.Query @@ -7,14 +9,15 @@ import org.sayandev.stickynote.core.database.QueryResult import java.io.File import java.io.IOException import java.sql.Connection -import java.sql.DriverManager import java.sql.ResultSet import java.sql.SQLException +import java.util.concurrent.TimeUnit import java.util.logging.Logger -abstract class SQLiteExecutor protected constructor(protected val dbFile: File, private val logger: Logger) : Database() { +abstract class SQLiteExecutor protected constructor(protected val dbFile: File, private val logger: Logger, val maxConnectionPool: Int = 5) : Database() { - protected var connection: Connection? = null + private var dataSource: HikariDataSource? = null + protected val connectionTimeout = TimeUnit.SECONDS.toMillis(30) init { try { @@ -30,13 +33,53 @@ abstract class SQLiteExecutor protected constructor(protected val dbFile: File, override fun connect() { try { - Class.forName("org.sqlite.JDBC") - if (this.connection == null) { - this.connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.path) + if (dataSource == null) { + val config = HikariConfig() + config.jdbcUrl = "jdbc:sqlite:${dbFile.path}" + config.driverClassName = "org.sqlite.JDBC" + config.connectionTimeout = connectionTimeout + config.idleTimeout = 5000 + config.maxLifetime = 1800000 + config.maximumPoolSize = maxConnectionPool + config.minimumIdle = 1 + config.poolName = "stickynote-sqlite-pool" + + config.addDataSourceProperty("socketTimeout", TimeUnit.SECONDS.toMillis(30).toString()) + config.addDataSourceProperty("cachePrepStmts", "true") + config.addDataSourceProperty("prepStmtCacheSize", "250") + config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048") + config.addDataSourceProperty("useServerPrepStmts", "true") + config.addDataSourceProperty("useLocalSessionState", "true") + config.addDataSourceProperty("rewriteBatchedStatements", "true") + config.addDataSourceProperty("cacheResultSetMetadata", "true") + config.addDataSourceProperty("cacheServerConfiguration", "true") + config.addDataSourceProperty("elideSetAutoCommits", "true") + config.addDataSourceProperty("maintainTimeStats", "false") + config.addDataSourceProperty("alwaysSendSetIsolation", "false") + config.addDataSourceProperty("cacheCallableStmts", "true") + config.addDataSourceProperty("allowPublicKeyRetrieval", "true") + config.addDataSourceProperty("characterEncoding", "utf8") + + config.addDataSourceProperty("foreign_keys", "true") + config.addDataSourceProperty("journal_mode", "WAL") + config.addDataSourceProperty("synchronous", "NORMAL") + + dataSource = HikariDataSource(config) + logger.info("Successfully configured SQLite connection pool") } + } catch (e: Exception) { + logger.severe("Failed to create connection pool: ${e.message}") + e.printStackTrace() + } + } + + protected fun getConnection(): Connection? { + return try { + dataSource?.connection } catch (e: SQLException) { - logger.severe(e.message) + logger.severe("Failed to get connection from pool: ${e.message}") e.printStackTrace() + null } } @@ -45,26 +88,31 @@ abstract class SQLiteExecutor protected constructor(protected val dbFile: File, } fun executeQuerySync(query: Query): QueryResult { - try { - val preparedStatement = query.createPreparedStatement(connection) - var resultSet: ResultSet? = null - - if (query.statement.startsWith("INSERT") || - query.statement.startsWith("UPDATE") || - query.statement.startsWith("DELETE") || - query.statement.startsWith("CREATE") || - query.statement.startsWith("ALTER") - ) { - preparedStatement.executeUpdate() - preparedStatement.close() - } - else resultSet = preparedStatement.executeQuery() + val connection = getConnection() ?: return QueryResult(Query.StatusCode.FAILED, null) - if (resultSet != null) { - query.complete(resultSet) + try { + connection.use { conn -> + val preparedStatement = query.createPreparedStatement(conn) + var resultSet: ResultSet? = null + + if (query.statement.startsWith("INSERT") || + query.statement.startsWith("UPDATE") || + query.statement.startsWith("DELETE") || + query.statement.startsWith("CREATE") || + query.statement.startsWith("ALTER") + ) { + preparedStatement.executeUpdate() + preparedStatement.close() + } else { + resultSet = preparedStatement.executeQuery() + } + + if (resultSet != null) { + query.complete(resultSet) + } + + return QueryResult(Query.StatusCode.FINISHED, resultSet) } - - return QueryResult(Query.StatusCode.FINISHED, resultSet) } catch (e: SQLException) { onQueryFail(query) e.printStackTrace() @@ -90,8 +138,11 @@ abstract class SQLiteExecutor protected constructor(protected val dbFile: File, } } + override fun shutdown() { + dataSource?.close() + } + protected abstract fun onQueryFail(query: Query) protected abstract fun onQueryRemoveDueToFail(query: Query) - -} +} \ No newline at end of file diff --git a/stickynote-loader/src/main/kotlin/org/sayandev/plugin/StickyNoteProjectPlugin.kt b/stickynote-loader/src/main/kotlin/org/sayandev/plugin/StickyNoteProjectPlugin.kt index 084745fa..3f71dfef 100644 --- a/stickynote-loader/src/main/kotlin/org/sayandev/plugin/StickyNoteProjectPlugin.kt +++ b/stickynote-loader/src/main/kotlin/org/sayandev/plugin/StickyNoteProjectPlugin.kt @@ -14,7 +14,7 @@ class StickyNoteProjectPlugin : Plugin { * Exclude dependency from relocations. should be the same in StickyNoteLoader * @see org.sayandev.loader.common.StickyNoteLoader * */ - val relocateExclusion = setOf("kotlin-stdlib", "kotlin-reflect", "kotlin", "kotlin-stdlib-jdk8", "kotlin-stdlib-jdk7", /*"kotlinx", "kotlinx-coroutines", "kotlinx-coroutines-core-jvm",*/ "takenaka", "mappings", "gson") + val relocateExclusion = setOf("kotlin-stdlib", "kotlin-reflect", "kotlin", "kotlin-stdlib-jdk8", "kotlin-stdlib-jdk7", "kotlinx", "kotlinx-coroutines", "kotlinx-coroutines-core-jvm", "takenaka", "mappings", "gson") @KotlinPoetJavaPoetPreview override fun apply(target: Project) { @@ -115,7 +115,8 @@ class StickyNoteProjectPlugin : Plugin { relocate("org.sayandev.loader", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.loader") relocate("org.sayandev.stickynote", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.stickynote") relocate("com.mysql", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.mysql") - relocate("kotlinx.coroutines", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.kotlinx.coroutines") + relocate("org.jetbrains.exposed", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.exposed") +// relocate("kotlinx.coroutines", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.kotlinx.coroutines") // relocate("com.github.benmanes.caffeine", "${target.rootProject.group}.${target.rootProject.name.lowercase()}.lib.caffeine") for (bundleAlias in libs.bundleAliases.filter { config.modules.get().map { "implementation.".plus(it.type.artifact.removePrefix("stickynote-").replace("-", ".")) }.contains(it) }) { val bundle = libs.findBundle(bundleAlias).get().get() diff --git a/stickynote-loader/stickynote-loader-bukkit/src/main/java/org/sayandev/stickynote/loader/bukkit/StickyNoteBukkitLoader.java b/stickynote-loader/stickynote-loader-bukkit/src/main/java/org/sayandev/stickynote/loader/bukkit/StickyNoteBukkitLoader.java index 9f07d856..474ed16a 100644 --- a/stickynote-loader/stickynote-loader-bukkit/src/main/java/org/sayandev/stickynote/loader/bukkit/StickyNoteBukkitLoader.java +++ b/stickynote-loader/stickynote-loader-bukkit/src/main/java/org/sayandev/stickynote/loader/bukkit/StickyNoteBukkitLoader.java @@ -22,7 +22,7 @@ public StickyNoteBukkitLoader(JavaPlugin javaPlugin) throws NoSuchFieldException } public StickyNoteBukkitLoader(JavaPlugin javaPlugin, boolean reloadStickyNote) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException { - super(); + super(javaPlugin.getName()); this.javaPlugin = javaPlugin; File dataFolder = javaPlugin.getDataFolder(); diff --git a/stickynote-loader/stickynote-loader-bungeecord/src/main/java/org/sayandev/stickynote/loader/bungee/StickyNoteBungeeLoader.java b/stickynote-loader/stickynote-loader-bungeecord/src/main/java/org/sayandev/stickynote/loader/bungee/StickyNoteBungeeLoader.java index f55c4b96..a8ccebc0 100644 --- a/stickynote-loader/stickynote-loader-bungeecord/src/main/java/org/sayandev/stickynote/loader/bungee/StickyNoteBungeeLoader.java +++ b/stickynote-loader/stickynote-loader-bungeecord/src/main/java/org/sayandev/stickynote/loader/bungee/StickyNoteBungeeLoader.java @@ -14,7 +14,7 @@ public class StickyNoteBungeeLoader extends StickyNoteLoader { Plugin plugin; public StickyNoteBungeeLoader(Plugin plugin) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException { - super(); + super(plugin.getDescription().getName()); this.plugin = plugin; File dataFolder = plugin.getDataFolder(); diff --git a/stickynote-loader/stickynote-loader-common/src/main/java/org/sayandev/loader/common/StickyNoteLoader.java b/stickynote-loader/stickynote-loader-common/src/main/java/org/sayandev/loader/common/StickyNoteLoader.java index fec48632..3b78510b 100644 --- a/stickynote-loader/stickynote-loader-common/src/main/java/org/sayandev/loader/common/StickyNoteLoader.java +++ b/stickynote-loader/stickynote-loader-common/src/main/java/org/sayandev/loader/common/StickyNoteLoader.java @@ -6,12 +6,8 @@ import com.alessiodp.libby.transitive.ExcludedDependency; import com.alessiodp.libby.transitive.TransitiveDependencyHelper; -import javax.swing.text.html.parser.Entity; import java.io.*; import java.nio.file.FileSystemException; -import java.nio.file.FileVisitOption; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.*; import java.util.concurrent.*; import java.util.logging.Logger; @@ -23,11 +19,11 @@ public abstract class StickyNoteLoader { private static final ConcurrentHashMap> loadingLibraries = new ConcurrentHashMap<>(); private static final ExecutorService executorService = Executors.newWorkStealingPool(Runtime.getRuntime().availableProcessors()); private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - public static final List exclusions = Arrays.asList("kotlin-stdlib", "kotlin-reflect", "kotlin", "kotlin-stdlib-jdk8", "kotlin-stdlib-jdk7"/*, "kotlinx", "kotlinx-coroutines", "kotlinx-coroutines-core-jvm"*/, "takenaka", "mappings", "gson"); + public static final List exclusions = Arrays.asList("kotlin-stdlib", "kotlin-reflect", "kotlin", "kotlin-stdlib-jdk8", "kotlin-stdlib-jdk7", "kotlinx", "kotlinx-coroutines", "kotlinx-coroutines-core-jvm", "takenaka", "mappings", "gson"); public static final Map relocations = new HashMap<>(); // name - group - public static final Map transitiveDownloadExclusions = new HashMap<>(); + public static final Map transitiveLoadExclusion = new HashMap<>(); private static final String LIB_FOLDER = "lib"; @@ -36,21 +32,21 @@ public abstract class StickyNoteLoader { protected StickyNoteLoader(String projectName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { this.projectName = projectName; - transitiveDownloadExclusions.put("kotlinx-coroutines-core-jvm", "org{}jetbrains{}kotlinx".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlinx-coroutines-core", "org{}jetbrains{}kotlinx".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlin-reflect", "org{}jetbrains{}kotlin".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlin-stdlib", "org{}jetbrains{}kotlin".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlin-stdlib-common", "org{}jetbrains{}kotlin".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlin-stdlib-jdk7", "org{}jetbrains{}kotlin".replace("{}", ".")); - transitiveDownloadExclusions.put("kotlin-stdlib-jdk8", "org{}jetbrains{}kotlin".replace("{}", ".")); - transitiveDownloadExclusions.put("annotations", "org{}jetbrains".replace("{}", ".")); - transitiveDownloadExclusions.put("checker-qual", "org{}checkerframework".replace("{}", ".")); - transitiveDownloadExclusions.put("javassist", "org{}javassist".replace("{}", ".")); - transitiveDownloadExclusions.put("snakeyaml", "org{}yaml".replace("{}", ".")); - transitiveDownloadExclusions.put("gson", "com{}google{}gson".replace("{}", ".")); - transitiveDownloadExclusions.put("error_prone_annotations", "com{}google{}errorprone".replace("{}", ".")); - transitiveDownloadExclusions.put("geantyref", "io{}leangen{}geantyref".replace("{}", ".")); - transitiveDownloadExclusions.put("sqlite-jdbc", "org{}xerial".replace("{}", ".")); + transitiveLoadExclusion.put("kotlinx-coroutines-core-jvm", "org{}jetbrains{}kotlinx".replace("{}", ".")); + transitiveLoadExclusion.put("kotlinx-coroutines-core", "org{}jetbrains{}kotlinx".replace("{}", ".")); + transitiveLoadExclusion.put("kotlin-reflect", "org{}jetbrains{}kotlin".replace("{}", ".")); + transitiveLoadExclusion.put("kotlin-stdlib", "org{}jetbrains{}kotlin".replace("{}", ".")); + transitiveLoadExclusion.put("kotlin-stdlib-common", "org{}jetbrains{}kotlin".replace("{}", ".")); + transitiveLoadExclusion.put("kotlin-stdlib-jdk7", "org{}jetbrains{}kotlin".replace("{}", ".")); + transitiveLoadExclusion.put("kotlin-stdlib-jdk8", "org{}jetbrains{}kotlin".replace("{}", ".")); + transitiveLoadExclusion.put("annotations", "org{}jetbrains".replace("{}", ".")); + transitiveLoadExclusion.put("checker-qual", "org{}checkerframework".replace("{}", ".")); + transitiveLoadExclusion.put("javassist", "org{}javassist".replace("{}", ".")); + transitiveLoadExclusion.put("snakeyaml", "org{}yaml".replace("{}", ".")); + transitiveLoadExclusion.put("gson", "com{}google{}gson".replace("{}", ".")); + transitiveLoadExclusion.put("error_prone_annotations", "com{}google{}errorprone".replace("{}", ".")); + transitiveLoadExclusion.put("geantyref", "io{}leangen{}geantyref".replace("{}", ".")); + transitiveLoadExclusion.put("sqlite-jdbc", "org{}xerial".replace("{}", ".")); } protected abstract void onComplete(); @@ -85,7 +81,7 @@ public void load(String id, File dataDirectory, Logger logger, LibraryManager li relocations.put("com{}mysql", relocationTo + "{}lib{}mysql"); // relocations.put("kotlinx{}coroutines", relocationTo + "{}lib{}kotlinx{}coroutines"); -// relocations.put("org{}jetbrains{}exposed", relocationTo + "{}lib{}exposed"); + relocations.put("org{}jetbrains{}exposed", relocationTo + "{}lib{}exposed"); // relocations.put("org{}yaml", relocationTo + "{}lib{}yaml"); // relocations.put("org{}spongepowered{}configurate", relocationTo + "{}lib{}configurate"); // relocations.put("org{}slf4j", relocationTo + "{}lib{}slf4j"); @@ -296,7 +292,7 @@ private Library.Builder createLibraryBuilder(Dependency dependency) { .version(dependency.getVersion()) .resolveTransitiveDependencies(false); - for (Map.Entry downloadExclusion : transitiveDownloadExclusions.entrySet()) { + for (Map.Entry downloadExclusion : transitiveLoadExclusion.entrySet()) { libraryBuilder.excludeTransitiveDependency(new ExcludedDependency(downloadExclusion.getValue(), downloadExclusion.getKey())); } @@ -333,7 +329,7 @@ private List resolveTransitiveLibraries(String id, TransitiveDependency } private void updateDependencyCache(File libDirectory, Set dependencies) { - for (Map.Entry downloadExclusions : transitiveDownloadExclusions.entrySet()) { + for (Map.Entry downloadExclusions : transitiveLoadExclusion.entrySet()) { String group = downloadExclusions.getValue(); String name = downloadExclusions.getKey(); List allVersions = getAllVersions(libDirectory, group, name); diff --git a/stickynote-loader/stickynote-loader-velocity/src/main/java/org/sayandev/stickynote/loader/velocity/StickyNoteVelocityLoader.java b/stickynote-loader/stickynote-loader-velocity/src/main/java/org/sayandev/stickynote/loader/velocity/StickyNoteVelocityLoader.java index 6c8678ce..3576a954 100644 --- a/stickynote-loader/stickynote-loader-velocity/src/main/java/org/sayandev/stickynote/loader/velocity/StickyNoteVelocityLoader.java +++ b/stickynote-loader/stickynote-loader-velocity/src/main/java/org/sayandev/stickynote/loader/velocity/StickyNoteVelocityLoader.java @@ -25,7 +25,7 @@ public StickyNoteVelocityLoader(Object plugin, String id, ProxyServer server, Lo } public StickyNoteVelocityLoader(Object plugin, String id, ProxyServer server, Logger logger, Path dataDirectory, SuspendingPluginContainer suspendingPluginContainer) throws NoSuchFieldException, ClassNotFoundException, IllegalAccessException { - super(); + super(id); this.plugin = plugin; this.id = id; this.server = server;