diff --git a/.gitignore b/.gitignore index 04cd85f..13ca599 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ # maven /target +dependency-reduced-pom.xml # vim .*.sw[a-p] diff --git a/pom.xml b/pom.xml index 0049f46..324213b 100644 --- a/pom.xml +++ b/pom.xml @@ -43,6 +43,7 @@ org.bukkit bukkit 1.7.2-R0.3 + provided ${project.groupId} @@ -55,6 +56,7 @@ com.sk89q worldedit 6.0.0-SNAPSHOT + provided junit @@ -62,8 +64,13 @@ 4.11 test - - + + com.zaxxer + HikariCP-java6 + 2.3.4 + compile + + repobo-snap @@ -117,7 +124,7 @@ org.apache.maven.plugins maven-compiler-plugin - 2.5.1 + 3.2 1.6 1.6 @@ -143,7 +150,21 @@ - + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + + + package + + shade + + + + diff --git a/src/main/java/de/diddiz/LogBlock/config/Config.java b/src/main/java/de/diddiz/LogBlock/config/Config.java index aa27336..e02217f 100644 --- a/src/main/java/de/diddiz/LogBlock/config/Config.java +++ b/src/main/java/de/diddiz/LogBlock/config/Config.java @@ -135,7 +135,7 @@ public class Config if (!config.contains(e.getKey())) config.set(e.getKey(), e.getValue()); logblock.saveConfig(); - url = "jdbc:mysql://" + config.getString("mysql.host") + ":" + config.getInt("mysql.port") + "/" + getStringIncludingInts(config, "mysql.database") + "?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true"; + url = "jdbc:mysql://" + config.getString("mysql.host") + ":" + config.getInt("mysql.port") + "/" + getStringIncludingInts(config, "mysql.database"); user = getStringIncludingInts(config, "mysql.user"); password = getStringIncludingInts(config, "mysql.password"); delayBetweenRuns = config.getInt("consumer.delayBetweenRuns", 2); diff --git a/src/main/java/de/diddiz/util/MySQLConnectionPool.java b/src/main/java/de/diddiz/util/MySQLConnectionPool.java index a986976..23706d4 100644 --- a/src/main/java/de/diddiz/util/MySQLConnectionPool.java +++ b/src/main/java/de/diddiz/util/MySQLConnectionPool.java @@ -1,437 +1,43 @@ package de.diddiz.util; -import static de.diddiz.LogBlock.config.Config.mb4; +import com.zaxxer.hikari.HikariDataSource; +import de.diddiz.LogBlock.config.Config; + import java.io.Closeable; -import java.sql.Array; -import java.sql.Blob; -import java.sql.CallableStatement; -import java.sql.Clob; import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.NClob; -import java.sql.PreparedStatement; -import java.sql.SQLClientInfoException; import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.SQLXML; -import java.sql.Savepoint; -import java.sql.Statement; -import java.sql.Struct; -import java.util.Enumeration; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.Vector; -import java.util.concurrent.Executor; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; public class MySQLConnectionPool implements Closeable { - private final static int poolSize = 10; - private final static long timeToLive = 300000; - private final Vector connections; - private final String url, user, password; - private final Lock lock = new ReentrantLock(); + + private final HikariDataSource ds; public MySQLConnectionPool(String url, String user, String password) throws ClassNotFoundException { - Class.forName("com.mysql.jdbc.Driver"); - this.url = url; - this.user = user; - this.password = password; - connections = new Vector(poolSize); - ConnectionReaper reaper = new ConnectionReaper(); - new Thread(reaper, "MySQL Connection Reaper Thread - LogBlock").start(); + this.ds = new HikariDataSource(); + ds.setJdbcUrl(url); + ds.setUsername(user); + ds.setPassword(password); + + ds.addDataSourceProperty("useUnicode", "true"); + ds.addDataSourceProperty("characterEncoding", "utf-8"); + ds.addDataSourceProperty("rewriteBatchedStatements", "true"); + + ds.addDataSourceProperty("cachePrepStmts", "true"); + ds.addDataSourceProperty("prepStmtCacheSize", "250"); + ds.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); } @Override public void close() { - lock.lock(); - final Enumeration conns = connections.elements(); - while (conns.hasMoreElements()) { - final JDCConnection conn = conns.nextElement(); - connections.remove(conn); - conn.terminate(); - } - lock.unlock(); + ds.close(); } public Connection getConnection() throws SQLException { - lock.lock(); - try { - final Enumeration conns = connections.elements(); - while (conns.hasMoreElements()) { - final JDCConnection conn = conns.nextElement(); - if (conn.lease()) { - if (conn.isValid()) - return conn; - connections.remove(conn); - conn.terminate(); - } - } - final JDCConnection conn = new JDCConnection(DriverManager.getConnection(url, user, password)); - conn.lease(); - if (!conn.isValid()) { - conn.terminate(); - throw new SQLException("Failed to validate a brand new connection"); - } - connections.add(conn); - if (mb4) conn.createStatement().executeQuery("SET NAMES utf8mb4"); - return conn; - } finally { - lock.unlock(); + Connection connection = ds.getConnection(); + if (Config.mb4) { + connection.createStatement().executeQuery("SET NAMES utf8mb4"); } + return connection; } - private void reapConnections() { - lock.lock(); - final long stale = System.currentTimeMillis() - timeToLive; - final Iterator itr = connections.iterator(); - while (itr.hasNext()) { - final JDCConnection conn = itr.next(); - if (conn.inUse() && stale > conn.getLastUse() && !conn.isValid()) - itr.remove(); - } - lock.unlock(); - } - - private class ConnectionReaper implements Runnable - { - @Override - public void run() { - while (true) { - try { - Thread.sleep(300000); - } catch (final InterruptedException e) { - } - reapConnections(); - } - } - } - - private class JDCConnection implements Connection - { - private final Connection conn; - private boolean inUse; - private long timestamp; - private int networkTimeout; - private String schema; - - JDCConnection(Connection conn) { - this.conn = conn; - inUse = false; - timestamp = 0; - networkTimeout = 30; - schema = "default"; - } - - @Override - public void clearWarnings() throws SQLException { - conn.clearWarnings(); - } - - @Override - public void close() { - inUse = false; - try { - if (!conn.getAutoCommit()) - conn.setAutoCommit(true); - } catch (final SQLException ex) { - connections.remove(this); - terminate(); - } - } - - @Override - public void commit() throws SQLException { - conn.commit(); - } - - @Override - public Array createArrayOf(String typeName, Object[] elements) throws SQLException { - return conn.createArrayOf(typeName, elements); - } - - @Override - public Blob createBlob() throws SQLException { - return conn.createBlob(); - } - - @Override - public Clob createClob() throws SQLException { - return conn.createClob(); - } - - @Override - public NClob createNClob() throws SQLException { - return conn.createNClob(); - } - - @Override - public SQLXML createSQLXML() throws SQLException { - return conn.createSQLXML(); - } - - @Override - public Statement createStatement() throws SQLException { - return conn.createStatement(); - } - - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { - return conn.createStatement(resultSetType, resultSetConcurrency); - } - - @Override - public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return conn.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); - } - - @Override - public Struct createStruct(String typeName, Object[] attributes) throws SQLException { - return conn.createStruct(typeName, attributes); - } - - @Override - public boolean getAutoCommit() throws SQLException { - return conn.getAutoCommit(); - } - - @Override - public String getCatalog() throws SQLException { - return conn.getCatalog(); - } - - @Override - public Properties getClientInfo() throws SQLException { - return conn.getClientInfo(); - } - - @Override - public String getClientInfo(String name) throws SQLException { - return conn.getClientInfo(name); - } - - @Override - public int getHoldability() throws SQLException { - return conn.getHoldability(); - } - - @Override - public DatabaseMetaData getMetaData() throws SQLException { - return conn.getMetaData(); - } - - @Override - public int getTransactionIsolation() throws SQLException { - return conn.getTransactionIsolation(); - } - - @Override - public Map> getTypeMap() throws SQLException { - return conn.getTypeMap(); - } - - @Override - public SQLWarning getWarnings() throws SQLException { - return conn.getWarnings(); - } - - @Override - public boolean isClosed() throws SQLException { - return conn.isClosed(); - } - - @Override - public boolean isReadOnly() throws SQLException { - return conn.isReadOnly(); - } - - @Override - public boolean isValid(int timeout) throws SQLException { - return conn.isValid(timeout); - } - - @Override - public boolean isWrapperFor(Class iface) throws SQLException { - return conn.isWrapperFor(iface); - } - - @Override - public String nativeSQL(String sql) throws SQLException { - return conn.nativeSQL(sql); - } - - @Override - public CallableStatement prepareCall(String sql) throws SQLException { - return conn.prepareCall(sql); - } - - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - return conn.prepareCall(sql, resultSetType, resultSetConcurrency); - } - - @Override - public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return conn.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); - } - - @Override - public PreparedStatement prepareStatement(String sql) throws SQLException { - return conn.prepareStatement(sql); - } - - @Override - public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { - return conn.prepareStatement(sql, autoGeneratedKeys); - } - - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { - return conn.prepareStatement(sql, resultSetType, resultSetConcurrency); - } - - @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - return conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); - } - - @Override - public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { - return conn.prepareStatement(sql, columnIndexes); - } - - @Override - public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { - return conn.prepareStatement(sql, columnNames); - } - - @Override - public void releaseSavepoint(Savepoint savepoint) throws SQLException { - conn.releaseSavepoint(savepoint); - } - - @Override - public void rollback() throws SQLException { - conn.rollback(); - } - - @Override - public void rollback(Savepoint savepoint) throws SQLException { - conn.rollback(savepoint); - } - - @Override - public void setAutoCommit(boolean autoCommit) throws SQLException { - conn.setAutoCommit(autoCommit); - } - - @Override - public void setCatalog(String catalog) throws SQLException { - conn.setCatalog(catalog); - } - - @Override - public void setClientInfo(Properties properties) throws SQLClientInfoException { - conn.setClientInfo(properties); - } - - @Override - public void setClientInfo(String name, String value) throws SQLClientInfoException { - conn.setClientInfo(name, value); - } - - @Override - public void setHoldability(int holdability) throws SQLException { - conn.setHoldability(holdability); - } - - @Override - public void setReadOnly(boolean readOnly) throws SQLException { - conn.setReadOnly(readOnly); - } - - @Override - public Savepoint setSavepoint() throws SQLException { - return conn.setSavepoint(); - } - - @Override - public Savepoint setSavepoint(String name) throws SQLException { - return conn.setSavepoint(name); - } - - @Override - public void setTransactionIsolation(int level) throws SQLException { - conn.setTransactionIsolation(level); - } - - @Override - public void setTypeMap(Map> map) throws SQLException { - conn.setTypeMap(map); - } - - @Override - public T unwrap(Class iface) throws SQLException { - return conn.unwrap(iface); - } - - @SuppressWarnings("unused") - public int getNetworkTimeout() throws SQLException { - return networkTimeout; - } - - @SuppressWarnings("unused") - public void setNetworkTimeout(Executor exec, int timeout) throws SQLException { - networkTimeout = timeout; - } - - @SuppressWarnings("unused") - public void abort(Executor exec) throws SQLException { - // Not implemented really... - } - - @SuppressWarnings("unused") - public String getSchema() throws SQLException { - return schema; - } - - @SuppressWarnings("unused") - public void setSchema(String str) throws SQLException { - schema = str; - } - - long getLastUse() { - return timestamp; - } - - boolean inUse() { - return inUse; - } - - boolean isValid() { - try { - return conn.isValid(1); - } catch (final SQLException ex) { - return false; - } - } - - synchronized boolean lease() { - if (inUse) - return false; - inUse = true; - timestamp = System.currentTimeMillis(); - return true; - } - - void terminate() { - try { - conn.close(); - } catch (final SQLException ex) { - } - } - } }