package tools; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.DriverManager; import java.sql.SQLException; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import config.YamlConfig; /** * @author Frz (Big Daddy) * @author The Real Spookster - some modifications to this beautiful code * @author Ronan - some connection pool to this beautiful code */ public class DatabaseConnection { private static HikariDataSource ds; public static Connection getConnection() throws SQLException { if(ds != null) { try { return ds.getConnection(); } catch (SQLException sqle) { sqle.printStackTrace(); } } int denies = 0; while(true) { // There is no way it can pass with a null out of here? try { return DriverManager.getConnection(YamlConfig.config.server.DB_URL, YamlConfig.config.server.DB_USER, YamlConfig.config.server.DB_PASS); } catch (SQLException sqle) { denies++; if(denies == 3) { // Give up, throw exception. Nothing good will come from this. FilePrinter.printError(FilePrinter.SQL_EXCEPTION, "SQL Driver refused to give a connection after " + denies + " tries. Problem: " + sqle.getMessage()); throw sqle; } } } } private static int getNumberOfAccounts() { try { Connection con = DriverManager.getConnection(YamlConfig.config.server.DB_URL, YamlConfig.config.server.DB_USER, YamlConfig.config.server.DB_PASS); try (PreparedStatement ps = con.prepareStatement("SELECT count(*) FROM accounts")) { try (ResultSet rs = ps.executeQuery()) { rs.next(); return rs.getInt(1); } } finally { con.close(); } } catch(SQLException sqle) { return 20; } } public DatabaseConnection() { try { Class.forName("com.mysql.jdbc.Driver"); // touch the mysql driver } catch (ClassNotFoundException e) { System.out.println("[SEVERE] SQL Driver Not Found. Consider death by clams."); e.printStackTrace(); } ds = null; if(YamlConfig.config.server.DB_CONNECTION_POOL) { // Connection Pool on database ftw! HikariConfig config = new HikariConfig(); config.setJdbcUrl(YamlConfig.config.server.DB_URL); config.setUsername(YamlConfig.config.server.DB_USER); config.setPassword(YamlConfig.config.server.DB_PASS); // Make sure pool size is comfortable for the worst case scenario. // Under 100 accounts? Make it 10. Over 10000 accounts? Make it 30. int poolSize = (int)Math.ceil(0.00202020202 * getNumberOfAccounts() + 9.797979798); if(poolSize < 10) poolSize = 10; else if(poolSize > 30) poolSize = 30; config.setConnectionTimeout(30 * 1000); config.setMaximumPoolSize(poolSize); config.addDataSourceProperty("cachePrepStmts", true); config.addDataSourceProperty("prepStmtCacheSize", 25); config.addDataSourceProperty("prepStmtCacheSqlLimit", 2048); ds = new HikariDataSource(config); } } }