use thread context class loader
This commit is contained in:
parent
c2b05476f2
commit
6c064531ab
11 changed files with 160 additions and 97 deletions
|
@ -1,3 +1,3 @@
|
|||
group = org.xbib
|
||||
name = database
|
||||
version = 2.0.2
|
||||
version = 2.0.3
|
||||
|
|
|
@ -118,7 +118,8 @@ public class Pool implements BagStateListener {
|
|||
*
|
||||
* @param config the config
|
||||
*/
|
||||
public Pool(PoolConfig config) throws ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
public Pool(PoolConfig config) throws ClassNotFoundException,
|
||||
NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
config.validate();
|
||||
this.config = config;
|
||||
logger.log(Level.INFO, () -> "starting new pool: " + config.getPoolName());
|
||||
|
@ -146,18 +147,26 @@ public class Pool implements BagStateListener {
|
|||
checkFailFast(initializationTimeout);
|
||||
}
|
||||
ThreadFactory threadFactory = config.getThreadFactory();
|
||||
ClassLoader contextClassLoader = config.getContextClassLoader();
|
||||
int maxPoolSize = config.getMaximumPoolSize();
|
||||
LinkedBlockingQueue<Runnable> addConnectionQueue = new LinkedBlockingQueue<>(maxPoolSize);
|
||||
this.addConnectionQueueReadOnlyView = Collections.unmodifiableCollection(addConnectionQueue);
|
||||
this.addConnectionExecutor = createThreadPoolExecutor(addConnectionQueue,
|
||||
poolName + " connection adder", threadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
poolName + " connection adder",
|
||||
threadFactory,
|
||||
contextClassLoader,
|
||||
new ThreadPoolExecutor.DiscardOldestPolicy());
|
||||
this.closeConnectionExecutor = createThreadPoolExecutor(maxPoolSize,
|
||||
poolName + " connection closer", threadFactory, new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
poolName + " connection closer",
|
||||
threadFactory,
|
||||
contextClassLoader,
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
this.leakTaskFactory = new ProxyLeakTaskFactory(config.getLeakDetectionThreshold(), houseKeepingExecutorService);
|
||||
this.houseKeeperTask = houseKeepingExecutorService.scheduleWithFixedDelay(new HouseKeeper(this), 100L, config.getHousekeepingPeriodMs(), TimeUnit.MILLISECONDS);
|
||||
if (Boolean.getBoolean("org.xbib.jdbc.connection.pool.blockUntilFilled") && config.getInitializationFailTimeout() > 1) {
|
||||
addConnectionExecutor.setCorePoolSize(Math.min(16, Runtime.getRuntime().availableProcessors()));
|
||||
addConnectionExecutor.setMaximumPoolSize(Math.min(16, Runtime.getRuntime().availableProcessors()));
|
||||
int procs = Math.min(16, Runtime.getRuntime().availableProcessors());
|
||||
addConnectionExecutor.setCorePoolSize(procs);
|
||||
addConnectionExecutor.setMaximumPoolSize(procs);
|
||||
final long startTime = ClockSource.currentTime();
|
||||
while (ClockSource.elapsedMillis(startTime) < config.getInitializationFailTimeout() && getTotalConnections() < config.getMinimumIdle()) {
|
||||
quietlySleep(TimeUnit.MILLISECONDS.toMillis(100));
|
||||
|
@ -305,8 +314,11 @@ public class Pool implements BagStateListener {
|
|||
addConnectionExecutor.awaitTermination(getLoginTimeout(), TimeUnit.SECONDS);
|
||||
destroyHouseKeepingExecutorService();
|
||||
bag.close();
|
||||
final ExecutorService assassinExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(), poolName + " connection assassinator",
|
||||
config.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
final ExecutorService assassinExecutor = createThreadPoolExecutor(config.getMaximumPoolSize(),
|
||||
poolName + " connection assassinator",
|
||||
config.getThreadFactory(),
|
||||
config.getContextClassLoader(),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
try {
|
||||
final long start = ClockSource.currentTime();
|
||||
do {
|
||||
|
@ -415,6 +427,7 @@ public class Pool implements BagStateListener {
|
|||
if (ds == null) {
|
||||
String dsClassName = config.getDataSourceClassName();
|
||||
if (dsClassName != null) {
|
||||
// we must use the system class loader
|
||||
Class<?> clazz = Class.forName(dsClassName, true, ClassLoader.getSystemClassLoader());
|
||||
ds = (DataSource) clazz.getDeclaredConstructor().newInstance();
|
||||
} else if (url != null) {
|
||||
|
@ -816,7 +829,8 @@ public class Pool implements BagStateListener {
|
|||
private ScheduledExecutorService initializeHouseKeepingExecutorService() {
|
||||
if (config.getScheduledExecutor() == null) {
|
||||
ThreadFactory threadFactory = Optional.ofNullable(config.getThreadFactory()).orElseGet(() ->
|
||||
new DefaultThreadFactory(poolName + "-housekeeper", true));
|
||||
new DefaultThreadFactory(poolName + "-housekeeper",
|
||||
Thread.currentThread().getContextClassLoader(), true));
|
||||
ScheduledThreadPoolExecutor executor =
|
||||
new ScheduledThreadPoolExecutor(1, threadFactory,
|
||||
new ThreadPoolExecutor.DiscardPolicy());
|
||||
|
@ -869,16 +883,18 @@ public class Pool implements BagStateListener {
|
|||
*
|
||||
* @param queueSize the queue size
|
||||
* @param threadName the thread name
|
||||
* @param threadFactory an optional ThreadFactory
|
||||
* @param threadFactory an optional ThreadFactory, if null, a DefaultThreadFactory will be used
|
||||
* @param contextClassLoader the context class loader if the thread factory is null
|
||||
* @param policy the RejectedExecutionHandler policy
|
||||
* @return a ThreadPoolExecutor
|
||||
*/
|
||||
private ThreadPoolExecutor createThreadPoolExecutor(int queueSize,
|
||||
String threadName,
|
||||
ThreadFactory threadFactory,
|
||||
ClassLoader contextClassLoader,
|
||||
RejectedExecutionHandler policy) {
|
||||
if (threadFactory == null) {
|
||||
threadFactory = new DefaultThreadFactory(threadName, true);
|
||||
threadFactory = new DefaultThreadFactory(threadName, contextClassLoader, true);
|
||||
}
|
||||
LinkedBlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(queueSize);
|
||||
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,
|
||||
|
@ -899,9 +915,10 @@ public class Pool implements BagStateListener {
|
|||
private ThreadPoolExecutor createThreadPoolExecutor(BlockingQueue<Runnable> queue,
|
||||
String threadName,
|
||||
ThreadFactory threadFactory,
|
||||
ClassLoader contextClassLoader,
|
||||
RejectedExecutionHandler policy) {
|
||||
if (threadFactory == null) {
|
||||
threadFactory = new DefaultThreadFactory(threadName, true);
|
||||
threadFactory = new DefaultThreadFactory(threadName, contextClassLoader, true);
|
||||
}
|
||||
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,
|
||||
5, TimeUnit.SECONDS, queue, threadFactory, policy);
|
||||
|
@ -977,7 +994,7 @@ public class Pool implements BagStateListener {
|
|||
*
|
||||
* @return true if we should create a connection, false if the need has disappeared
|
||||
*/
|
||||
synchronized boolean shouldCreateAnotherConnection() {
|
||||
public synchronized boolean shouldCreateAnotherConnection() {
|
||||
return getTotalConnections() < config.getMaximumPoolSize() &&
|
||||
(bag.getWaitingThreadCount() > 0 || getIdleConnections() < config.getMinimumIdle());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.xbib.jdbc.connection.pool;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.Connection;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
@ -74,6 +75,8 @@ public class PoolConfig {
|
|||
|
||||
private ThreadFactory threadFactory;
|
||||
|
||||
private ClassLoader contextClassLoader;
|
||||
|
||||
private ScheduledExecutorService scheduledExecutor;
|
||||
|
||||
/**
|
||||
|
@ -297,15 +300,6 @@ public class PoolConfig {
|
|||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the JDBC {@link DataSource} class used to create Connections.
|
||||
*
|
||||
* @return the fully qualified name of the JDBC {@link DataSource} class
|
||||
*/
|
||||
public String getDataSourceClassName() {
|
||||
return dataSourceClassName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the fully qualified class name of the JDBC {@link DataSource} that will be used create Connections.
|
||||
*
|
||||
|
@ -315,6 +309,15 @@ public class PoolConfig {
|
|||
this.dataSourceClassName = className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the JDBC {@link DataSource} class used to create Connections.
|
||||
*
|
||||
* @return the fully qualified name of the JDBC {@link DataSource} class
|
||||
*/
|
||||
public String getDataSourceClassName() {
|
||||
return dataSourceClassName;
|
||||
}
|
||||
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
@ -324,23 +327,47 @@ public class PoolConfig {
|
|||
}
|
||||
|
||||
public void setDriverClassName(String driverClassName) {
|
||||
Class<?> driverClass = attemptFromContextLoader(driverClassName);
|
||||
Class<?> driverClass = null;
|
||||
ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (threadContextClassLoader != null) {
|
||||
try {
|
||||
driverClass = threadContextClassLoader.loadClass(driverClassName);
|
||||
if (driverClass != null) {
|
||||
logger.log(Level.FINE, () -> "driver class found in thread context class loader:" + driverClassName);
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.FINE, () -> "failed to load driver class from thread context class loader" + driverClassName);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (driverClass == null) {
|
||||
driverClass = this.getClass().getClassLoader().loadClass(driverClassName);
|
||||
logger.log(Level.FINE, () -> "driver class found in the PoolConfig class classloader: " + driverClassName + " " + this.getClass().getClassLoader());
|
||||
driverClass = getClass().getClassLoader().loadClass(driverClassName);
|
||||
if (driverClass != null) {
|
||||
logger.log(Level.FINE, () -> "driver class found in the class classloader: " + driverClassName);
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.SEVERE, "failed to load driver class from PoolConfig class classloader: " + driverClassName + " " + this.getClass().getClassLoader());
|
||||
logger.log(Level.FINE, () -> "failed to load driver class from class classloader: " + driverClassName);
|
||||
}
|
||||
try {
|
||||
if (driverClass == null) {
|
||||
driverClass = ClassLoader.getSystemClassLoader().loadClass(driverClassName);
|
||||
if (driverClass != null) {
|
||||
logger.log(Level.FINE, () -> "driver class found in the system class classloader: " + driverClassName);
|
||||
|
||||
}
|
||||
}
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.SEVERE, () -> "failed to load driver class from system class classloader: " + driverClassName);
|
||||
}
|
||||
if (driverClass == null) {
|
||||
throw new RuntimeException("failed to load driver class " + driverClassName + " in either of PoolConfig class loader or Thread context classloader");
|
||||
throw new IllegalStateException("failed to load driver class " + driverClassName);
|
||||
}
|
||||
try {
|
||||
driverClass.getConstructor().newInstance();
|
||||
this.driverClassName = driverClassName;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to instantiate class " + driverClassName, e);
|
||||
} catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalStateException("failed to instantiate class " + driverClassName, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -549,15 +576,6 @@ public class PoolConfig {
|
|||
return housekeepingPeriodMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the thread factory used to create threads.
|
||||
*
|
||||
* @return the thread factory (may be null, in which case the default thread factory is used)
|
||||
*/
|
||||
public ThreadFactory getThreadFactory() {
|
||||
return threadFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the thread factory to be used to create threads.
|
||||
*
|
||||
|
@ -567,20 +585,21 @@ public class PoolConfig {
|
|||
this.threadFactory = threadFactory;
|
||||
}
|
||||
|
||||
private Class<?> attemptFromContextLoader(String driverClassName) {
|
||||
ClassLoader threadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
if (threadContextClassLoader != null) {
|
||||
try {
|
||||
Class<?> driverClass = threadContextClassLoader.loadClass(driverClassName);
|
||||
logger.log(Level.FINE, "Driver class found in Thread context class loader:" +
|
||||
driverClassName + " " + threadContextClassLoader);
|
||||
return driverClass;
|
||||
} catch (ClassNotFoundException e) {
|
||||
logger.log(Level.FINE, "Driver class not found in Thread context class loader, trying classloader: " +
|
||||
driverClassName + " " + threadContextClassLoader + " " + this.getClass().getClassLoader());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
/**
|
||||
* Get the thread factory used to create threads.
|
||||
*
|
||||
* @return the thread factory (may be null, in which case the default thread factory is used)
|
||||
*/
|
||||
public ThreadFactory getThreadFactory() {
|
||||
return threadFactory;
|
||||
}
|
||||
|
||||
public void setContextClassLoader(ClassLoader contextClassLoader) {
|
||||
this.contextClassLoader = contextClassLoader;
|
||||
}
|
||||
|
||||
public ClassLoader getContextClassLoader() {
|
||||
return contextClassLoader != null ? contextClassLoader : Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
|
|
|
@ -31,7 +31,8 @@ public class PoolEntryCreator implements Callable<Boolean> {
|
|||
final PoolEntry poolEntry = pool.createPoolEntry();
|
||||
if (poolEntry != null) {
|
||||
pool.bag.add(poolEntry);
|
||||
logger.log(Level.FINE, () -> MessageFormat.format("{0}: added connection {1} ", pool.poolName, poolEntry.getConnection()));
|
||||
logger.log(Level.FINE, () -> MessageFormat.format("{0}: added connection {1} ",
|
||||
pool.poolName, poolEntry.getConnection()));
|
||||
if (loggingPrefix != null) {
|
||||
pool.logPoolState(loggingPrefix);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,15 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||
|
||||
private final String threadName;
|
||||
|
||||
private final ClassLoader contextClassLoader;
|
||||
|
||||
private final boolean daemon;
|
||||
|
||||
public DefaultThreadFactory(String threadName, boolean daemon) {
|
||||
public DefaultThreadFactory(String threadName,
|
||||
ClassLoader contextClassLoader,
|
||||
boolean daemon) {
|
||||
this.threadName = threadName;
|
||||
this.contextClassLoader = contextClassLoader;
|
||||
this.daemon = daemon;
|
||||
}
|
||||
|
||||
|
@ -17,6 +22,7 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r, threadName);
|
||||
thread.setDaemon(daemon);
|
||||
thread.setContextClassLoader(contextClassLoader);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,16 +17,21 @@ public class DriverDataSource implements DataSource {
|
|||
|
||||
private static final Logger logger = Logger.getLogger(DriverDataSource.class.getName());
|
||||
|
||||
static {
|
||||
DriverManager.setLogWriter(new PrintWriter(new LoggingOutputStream(logger)));
|
||||
DriverManager.drivers().forEach(d -> logger.log(Level.INFO, "found driver " + d));
|
||||
}
|
||||
|
||||
private static final String PASSWORD = "password";
|
||||
|
||||
private static final String USER = "user";
|
||||
|
||||
private static final String AUTOCOMMIT = "autocommit";
|
||||
|
||||
private String jdbcUrl;
|
||||
|
||||
private final Properties driverProperties;
|
||||
|
||||
private String jdbcUrl;
|
||||
|
||||
private Driver driver;
|
||||
|
||||
public DriverDataSource(String jdbcUrl,
|
||||
|
@ -39,7 +44,9 @@ public class DriverDataSource implements DataSource {
|
|||
for (Entry<Object, Object> entry : properties.entrySet()) {
|
||||
driverProperties.setProperty(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
logger.log(Level.INFO, "DriverManager looking for JDBC URL " + jdbcUrl);
|
||||
if (jdbcUrl != null) {
|
||||
logger.log(Level.INFO, () -> "DriverManager looking for JDBC URL " + jdbcUrl);
|
||||
}
|
||||
if (username != null) {
|
||||
setUser(username);
|
||||
}
|
||||
|
@ -85,16 +92,17 @@ public class DriverDataSource implements DataSource {
|
|||
}
|
||||
}
|
||||
}
|
||||
final String sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1<masked>");
|
||||
try {
|
||||
if (driver == null) {
|
||||
if (driver == null && jdbcUrl != null) {
|
||||
final String sanitizedUrl = jdbcUrl.replaceAll("([?&;][^&#;=]*[pP]assword=)[^&#;]*", "$1<masked>");
|
||||
try {
|
||||
driver = DriverManager.getDriver(jdbcUrl);
|
||||
logger.log(Level.FINE, "Loaded driver with class name for jdbcUrl " + driver.getClass().getName() + " " + sanitizedUrl);
|
||||
} else if (!driver.acceptsURL(jdbcUrl)) {
|
||||
throw new RuntimeException("Driver " + driverClassName + " claims to not accept jdbcUrl " + sanitizedUrl);
|
||||
if (!driver.acceptsURL(sanitizedUrl)) {
|
||||
throw new RuntimeException("Driver " + driverClassName + " claims to not accept jdbcUrl " + sanitizedUrl);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to get driver instance for jdbcUrl " + sanitizedUrl, e);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException("Failed to get driver instance for jdbcUrl " + sanitizedUrl, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package org.xbib.jdbc.connection.pool.util;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class LoggingOutputStream extends ByteArrayOutputStream {
|
||||
|
||||
private final Logger logger;
|
||||
|
||||
public LoggingOutputStream(Logger logger) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
super.flush();
|
||||
String s = new String(buf, 0, count);
|
||||
if (!s.isEmpty()) {
|
||||
logger.log(Level.FINE, s);
|
||||
}
|
||||
reset();
|
||||
}
|
||||
}
|
|
@ -17,8 +17,10 @@ public class HouseKeeperCleanupTest {
|
|||
private ScheduledThreadPoolExecutor executor;
|
||||
|
||||
@BeforeEach
|
||||
public void before() throws Exception {
|
||||
ThreadFactory threadFactory = new DefaultThreadFactory("global-housekeeper", true);
|
||||
public void before() {
|
||||
ThreadFactory threadFactory = new DefaultThreadFactory("global-housekeeper",
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
true);
|
||||
executor = new ScheduledThreadPoolExecutor(1, threadFactory,
|
||||
new ThreadPoolExecutor.DiscardPolicy());
|
||||
executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
|
||||
|
|
|
@ -27,7 +27,6 @@ public class MariaDBTest extends CommonTest {
|
|||
static MariaDBContainer<?> mariaDBContainer;
|
||||
|
||||
static {
|
||||
// mariadb 10.3.6
|
||||
mariaDBContainer = new MariaDBContainer<>("mariadb")
|
||||
.withDatabaseName("testDB")
|
||||
.withUsername("testUser")
|
||||
|
@ -45,7 +44,7 @@ public class MariaDBTest extends CommonTest {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected DatabaseProvider createDatabaseProvider(OptionsOverride options) throws Exception {
|
||||
protected DatabaseProvider createDatabaseProvider(OptionsOverride options) {
|
||||
Config config = ConfigSupplier.of()
|
||||
.property("database.url", mariaDBContainer.getJdbcUrl())
|
||||
.property("database.user", "testUser")
|
||||
|
@ -95,12 +94,14 @@ public class MariaDBTest extends CommonTest {
|
|||
}
|
||||
|
||||
@Disabled("MariaDB temporarily disabled")
|
||||
@Test
|
||||
@Override
|
||||
public void intervals() {
|
||||
super.intervals();
|
||||
}
|
||||
|
||||
@Disabled("MariaDB temporarily disabled")
|
||||
@Test
|
||||
@Override
|
||||
public void metadataColumnTypes() {
|
||||
super.metadataColumnTypes();
|
||||
|
@ -251,5 +252,4 @@ public class MariaDBTest extends CommonTest {
|
|||
+ " str_varchar, str_fixed, str_lob, bin_blob, boolean_flag, date_millis, local_date from dbtest2 order by 1")
|
||||
.queryMany(SqlArgs::readRow));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,13 +18,8 @@ import java.util.logging.Logger;
|
|||
* to prevent SQL injection or any other bad things.
|
||||
*/
|
||||
public class DebugSql {
|
||||
public static final String PARAM_SQL_SEPARATOR = "\tParamSql:\t";
|
||||
|
||||
public static String printDebugOnlySqlString(String sql, Object[] args, Options options) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
printSql(buf, sql, args, false, true, options);
|
||||
return buf.toString();
|
||||
}
|
||||
public static final String PARAM_SQL_SEPARATOR = "\tParamSql:\t";
|
||||
|
||||
public static void printSql(StringBuilder buf, String sql, Object[] args, Options options) {
|
||||
printSql(buf, sql, args, true, options.isLogParameters(), options);
|
||||
|
@ -65,8 +60,7 @@ public class DebugSql {
|
|||
for (int i = 0; i < argsToPrint.length; i++) {
|
||||
buf.append(removeTabs(sqlParts[i]));
|
||||
Object argToPrint = argsToPrint[i];
|
||||
if (argToPrint instanceof String) {
|
||||
String argToPrintString = (String) argToPrint;
|
||||
if (argToPrint instanceof String argToPrintString) {
|
||||
int maxLength = options.maxStringLengthParam();
|
||||
if (argToPrintString.length() > maxLength && maxLength > 0) {
|
||||
buf.append("'").append(argToPrintString, 0, maxLength).append("...'");
|
||||
|
@ -77,16 +71,12 @@ public class DebugSql {
|
|||
}
|
||||
} else if (argToPrint instanceof SqlNull || argToPrint == null) {
|
||||
buf.append("null");
|
||||
} else if (argToPrint instanceof java.sql.Timestamp) {
|
||||
java.sql.Timestamp timestamp = (java.sql.Timestamp) argToPrint;
|
||||
} else if (argToPrint instanceof java.sql.Timestamp timestamp) {
|
||||
LocalDateTime localDateTime = timestamp.toLocalDateTime();
|
||||
buf.append(localDateTime.toString());
|
||||
//buf.append(options.flavor().dateAsSqlFunction((Timestamp) argToPrint, options.calendarForTimestamps()));
|
||||
} else if (argToPrint instanceof java.sql.Date) {
|
||||
java.sql.Date date = (java.sql.Date) argToPrint;
|
||||
} else if (argToPrint instanceof java.sql.Date date) {
|
||||
LocalDate localDate = date.toLocalDate();
|
||||
buf.append(localDate.toString());
|
||||
//buf.append(options.flavor().localDateAsSqlFunction((java.sql.Date) argToPrint));
|
||||
} else if (argToPrint instanceof Number) {
|
||||
buf.append(argToPrint);
|
||||
} else if (argToPrint instanceof Boolean) {
|
||||
|
@ -144,25 +134,22 @@ public class DebugSql {
|
|||
}
|
||||
|
||||
public static void logSuccess(String sqlType, Logger log, Metric metric, String sql, Object[] args, Options options) {
|
||||
if (log.isLoggable(Level.FINE)) {
|
||||
String msg = logMiddle('\t', sqlType, metric, null, sql, args, options);
|
||||
log.fine(msg);
|
||||
if (log.isLoggable(Level.FINEST)) {
|
||||
log.log(Level.FINEST, () -> logMiddle('\t', sqlType, metric, null, sql, args, options));
|
||||
}
|
||||
}
|
||||
|
||||
public static void logWarning(String sqlType, Logger log, Metric metric, String errorCode, String sql, Object[] args,
|
||||
Options options, Throwable t) {
|
||||
if (log.isLoggable(Level.WARNING)) {
|
||||
String msg = logMiddle(' ', sqlType, metric, errorCode, sql, args, options);
|
||||
log.log(Level.WARNING, msg, t);
|
||||
log.log(Level.WARNING, logMiddle(' ', sqlType, metric, errorCode, sql, args, options), t);
|
||||
}
|
||||
}
|
||||
|
||||
public static void logError(String sqlType, Logger log, Metric metric, String errorCode, String sql, Object[] args,
|
||||
Options options, Throwable t) {
|
||||
if (log.isLoggable(Level.SEVERE)) {
|
||||
String msg = logMiddle(' ', sqlType, metric, errorCode, sql, args, options);
|
||||
log.log(Level.SEVERE, msg, t);
|
||||
log.log(Level.SEVERE, logMiddle(' ', sqlType, metric, errorCode, sql, args, options), t);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@ dependencyResolutionManagement {
|
|||
versionCatalogs {
|
||||
libs {
|
||||
version('gradle', '8.5')
|
||||
library('mariadb', 'org.mariadb.jdbc', 'mariadb-java-client').version('3.1.3')
|
||||
library('oracle', 'com.oracle.database.jdbc','ojdbc11').version('23.2.0.0')
|
||||
library('postgresql', 'org.postgresql', 'postgresql').version('42.6.0')
|
||||
library('mariadb', 'org.mariadb.jdbc', 'mariadb-java-client').version('3.3.3')
|
||||
library('oracle', 'com.oracle.database.jdbc', 'ojdbc11').version('23.3.0.23.09')
|
||||
library('postgresql', 'org.postgresql', 'postgresql').version('42.7.3')
|
||||
}
|
||||
testLibs {
|
||||
version('junit', '5.10.1')
|
||||
version('junit', '5.10.2')
|
||||
version('testcontainers', '1.19.1')
|
||||
library('junit-jupiter-api', 'org.junit.jupiter', 'junit-jupiter-api').versionRef('junit')
|
||||
library('junit-jupiter-params', 'org.junit.jupiter', 'junit-jupiter-params').versionRef('junit')
|
||||
|
@ -18,9 +18,6 @@ dependencyResolutionManagement {
|
|||
library('derby', 'org.apache.derby', 'derby').version('10.16.1.1')
|
||||
library('hsqldb', 'org.hsqldb', 'hsqldb').version('2.7.1')
|
||||
library('h2', 'com.h2database', 'h2').version('2.1.214')
|
||||
library('mariadb', 'org.mariadb.jdbc', 'mariadb-java-client').version('3.1.3')
|
||||
library('oracle', 'com.oracle.database.jdbc','ojdbc11').version('23.2.0.0')
|
||||
library('postgresql', 'org.postgresql', 'postgresql').version('42.6.0')
|
||||
library('mockito-core', 'org.mockito', 'mockito-core').version('5.3.1')
|
||||
library('testcontainers', 'org.testcontainers', 'testcontainers').versionRef('testcontainers')
|
||||
library('testcontainers-junit-jupiter', 'org.testcontainers', 'junit-jupiter').versionRef('testcontainers')
|
||||
|
|
Loading…
Reference in a new issue