make jooq use my db connection pool

This commit is contained in:
mykola2312 2024-04-19 09:01:09 +03:00
parent 5ff35527a2
commit 68909c3102
4 changed files with 99 additions and 28 deletions

View file

@ -45,11 +45,19 @@ public class Main {
}
if (config.db == null) {
logger.fatal("no database configuration. exiting.");
logger.fatal("no database configuration. shutting down.");
System.exit(1);
return;
}
try {
DB.setupFromConfig(config.db);
} catch (RuntimeException e) {
logger.fatal("setupFromConfig", e);
logger.fatal("failed to initialize database. shutting down");
System.exit(1);
return;
}
DB.setupFromConfig(config.db);
MainFrame frame = new MainFrame();
frame.create(config.frame);
@ -62,16 +70,12 @@ public class Main {
);
flyway.migrate();
try (Connection conn = DB.getConnection()) {
DSLContext create = DSL.using(conn, SQLDialect.SQLITE);
Result<Record> result = create.select().from(TEST).fetch();
for (Record r : result) {
Integer id = r.getValue(TEST.ID);
String value = r.getValue(TEST.VALUE);
System.out.printf("%d: %s\n", id, value);
}
} catch (Exception e) {
e.printStackTrace();
DSLContext create = DSL.using(DB.CONFIG);
Result<Record> result = create.select().from(TEST).fetch();
for (Record r : result) {
Integer id = r.getValue(TEST.ID);
String value = r.getValue(TEST.VALUE);
System.out.printf("%d: %s\n", id, value);
}
logger.info("mptv started");

View file

@ -4,6 +4,10 @@ import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.jooq.Configuration;
import org.jooq.SQLDialect;
import org.jooq.impl.DefaultConfiguration;
import com.mykola2312.mptv.config.DBConfig;
public class DB {
@ -11,10 +15,18 @@ public class DB {
public static String USER = "";
public static String PASSWORD = "";
public static void setupFromConfig(DBConfig config) {
public static DBPool POOL;
public static Configuration CONFIG;
public static void setupFromConfig(DBConfig config) throws RuntimeException {
URL = config.url;
USER = config.user;
PASSWORD = config.password;
POOL = new DBPool(URL);
CONFIG = new DefaultConfiguration()
.set(POOL)
.set(SQLDialect.SQLITE);
}
public static Connection getConnection() throws SQLException {

View file

@ -1,9 +1,12 @@
package com.mykola2312.mptv.db;
import org.apache.log4j.Logger;
import org.checkerframework.checker.nullness.qual.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import org.jooq.ConnectionProvider;
import org.jooq.exception.DataAccessException;
@ -11,32 +14,82 @@ import org.jooq.exception.DataAccessException;
// I can't believe that in 2024 I have to do it myself
public class DBPool implements ConnectionProvider {
private String url;
private String user;
private String password;
public static final int POOL_LIMIT = 4;
private LinkedList<Connection> connections;
private static final Logger logger = Logger.getLogger(DBPool.class);
public DBPool(String url, String user, String password) {
public static final int POOL_LOW_CAP = 4;
private class DBConnection {
public final Connection connection;
public boolean beingUsed;
public DBConnection(Connection connection, boolean beingUsed) {
this.connection = connection;
this.beingUsed = beingUsed;
}
}
private LinkedList<DBConnection> connections = new LinkedList<DBConnection>();
public DBPool(String url) throws RuntimeException {
this.url = url;
this.user = user;
this.password = password;
connections = new LinkedList<Connection>();
// allocate pool now
try {
for (int i = 0; i < POOL_LOW_CAP; i++) {
spawnConnection();
}
} catch (SQLException e) {
throw new RuntimeException("failed to allocate pool", e);
}
}
protected Connection spawnConnection() throws SQLException {
return null;
protected DBConnection spawnConnection() throws SQLException {
DBConnection conn = new DBConnection(DriverManager.getConnection(url), false);
connections.add(conn);
logger.debug(String.format("spawned connection %s", conn.toString()));
return conn;
}
@Override
public @Nullable Connection acquire() throws DataAccessException {
throw new UnsupportedOperationException("Unimplemented method 'acquire'");
DBConnection conn;
try {
conn = connections
.stream()
.filter(db -> !db.beingUsed)
.findFirst()
.get();
} catch (NoSuchElementException e) {
try {
conn = spawnConnection();
} catch (SQLException e1) {
throw new DataAccessException("failed to spawn connection", e1);
}
}
conn.beingUsed = true;
logger.debug(String.format("allocated connection %s", conn.toString()));
return conn.connection;
}
@Override
public void release(Connection arg0) throws DataAccessException {
throw new UnsupportedOperationException("Unimplemented method 'release'");
public void release(Connection conn) throws DataAccessException {
try {
DBConnection db = connections
.stream()
.filter(dbConn -> conn == dbConn.connection)
.findFirst()
.get();
db.beingUsed = false;
if (connections.size() > POOL_LOW_CAP) {
connections.remove(db);
}
} catch (NoSuchElementException e) {
throw new DataAccessException("connection is not present in pool");
}
}
}

View file

@ -1,8 +1,9 @@
log4j.rootLogger=INFO, file, stdout
log4j.rootLogger=DEBUG, file, stdout
# log_out
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=log/log_out.log
log4j.appender.File.Threshold=INFO
log4j.appender.file.MaxFileSize=1024KB
log4j.appender.file.MaxBackupIndex=2
log4j.appender.file.layout=org.apache.log4j.PatternLayout
@ -10,6 +11,7 @@ log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:
# stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Threshold=DEBUG
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n