diff --git a/pom.xml b/pom.xml
index 2e199e5b..06e8cca1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,6 +7,7 @@
false
+ 0.31.0
4.1.0
6.0.1
5.2.10.Final
@@ -262,6 +263,53 @@
+
+
+ io.fabric8
+ docker-maven-plugin
+ ${docker.maven.plugin.fabric8.version}
+
+ default
+ true
+
+
+
+ db
+ postgres:9
+
+
+ database system is ready to accept connections
+
+
+
+ DB
+ yellow
+
+
+
+
+
+
+
+
+
+ start
+ pre-integration-test
+
+ build
+ start
+
+
+
+ stop
+ post-integration-test
+
+ stop
+
+
+
+
+
org.jacoco
jacoco-maven-plugin
@@ -303,6 +351,20 @@
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.0.0-M3
+
+
+
+ integration-test
+ verify
+
+
+
+
+
org.apache.felix
maven-bundle-plugin
diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java
index 11983409..db8b12bf 100644
--- a/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java
+++ b/src/main/java/com/zaxxer/hikari/pool/ProxyConnection.java
@@ -287,6 +287,7 @@ public abstract class ProxyConnection implements Connection
return ProxyFactory.getProxyStatement(this, trackStatement(delegate.createStatement(resultSetType, concurrency, holdability)));
}
+
/** {@inheritDoc} */
@Override
public CallableStatement prepareCall(String sql) throws SQLException
@@ -355,7 +356,7 @@ public abstract class ProxyConnection implements Connection
public DatabaseMetaData getMetaData() throws SQLException
{
markCommitStateDirty();
- return delegate.getMetaData();
+ return ProxyFactory.getProxyDatabaseMetaData(this, delegate.getMetaData());
}
/** {@inheritDoc} */
diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyDatabaseMetaData.java b/src/main/java/com/zaxxer/hikari/pool/ProxyDatabaseMetaData.java
new file mode 100644
index 00000000..dd406bb7
--- /dev/null
+++ b/src/main/java/com/zaxxer/hikari/pool/ProxyDatabaseMetaData.java
@@ -0,0 +1,242 @@
+package com.zaxxer.hikari.pool;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public abstract class ProxyDatabaseMetaData implements DatabaseMetaData
+{
+ protected final ProxyConnection connection;
+
+ @SuppressWarnings("WeakerAccess")
+ protected final DatabaseMetaData delegate;
+
+ ProxyDatabaseMetaData(ProxyConnection connection, DatabaseMetaData metaData)
+ {
+ this.connection = connection;
+ this.delegate = metaData;
+ }
+
+ @SuppressWarnings("unused")
+ final SQLException checkException(SQLException e)
+ {
+ return connection.checkException(e);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final String toString()
+ {
+ final String delegateToString = delegate.toString();
+ return this.getClass().getSimpleName() + '@' + System.identityHashCode(this) + " wrapping " + delegateToString;
+ }
+
+ // **********************************************************************
+ // Overridden java.sql.DatabaseMetaData Methods
+ // **********************************************************************
+
+ /** {@inheritDoc} */
+ @Override
+ public final Connection getConnection()
+ {
+ return connection;
+ }
+
+ @Override
+ public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getProcedures(catalog, schemaPattern, procedureNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getProcedureColumns(catalog, schemaPattern, procedureNamePattern, columnNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
+ ResultSet resultSet = delegate.getTables(catalog, schemaPattern, tableNamePattern, types);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getSchemas() throws SQLException {
+ ResultSet resultSet = delegate.getSchemas();
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getCatalogs() throws SQLException {
+ ResultSet resultSet = delegate.getCatalogs();
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getTableTypes() throws SQLException {
+ ResultSet resultSet = delegate.getTableTypes();
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getColumnPrivileges(catalog, schema, table, columnNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getTablePrivileges(catalog, schemaPattern, tableNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
+ ResultSet resultSet = delegate.getBestRowIdentifier(catalog, schema, table, scope, nullable);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
+ ResultSet resultSet = delegate.getVersionColumns(catalog, schema, table);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
+ ResultSet resultSet = delegate.getPrimaryKeys(catalog, schema, table);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
+ ResultSet resultSet = delegate.getImportedKeys(catalog, schema, table);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
+ ResultSet resultSet = delegate.getExportedKeys(catalog, schema, table);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
+ ResultSet resultSet = delegate.getCrossReference(parentCatalog, parentSchema, parentTable, foreignCatalog, foreignSchema, foreignTable);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getTypeInfo() throws SQLException {
+ ResultSet resultSet = delegate.getTypeInfo();
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
+ ResultSet resultSet = delegate.getIndexInfo(catalog, schema, table, unique, approximate);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
+ ResultSet resultSet = delegate.getUDTs(catalog, schemaPattern, typeNamePattern, types);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getSuperTypes(catalog, schemaPattern, typeNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getSuperTables(catalog, schemaPattern, tableNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getAttributes(catalog, schemaPattern, typeNamePattern, attributeNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
+ ResultSet resultSet = delegate.getSchemas(catalog, schemaPattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getClientInfoProperties() throws SQLException {
+ ResultSet resultSet = delegate.getClientInfoProperties();
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getFunctions(catalog, schemaPattern, functionNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getFunctionColumns(catalog, schemaPattern, functionNamePattern, columnNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ @Override
+ public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
+ ResultSet resultSet = delegate.getPseudoColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);
+ ProxyStatement statement = (ProxyStatement) ProxyFactory.getProxyStatement(connection, resultSet.getStatement());
+ return ProxyFactory.getProxyResultSet(connection, statement, resultSet);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @SuppressWarnings("unchecked")
+ public final T unwrap(Class iface) throws SQLException
+ {
+ if (iface.isInstance(delegate)) {
+ return (T) delegate;
+ }
+ else if (delegate != null) {
+ return delegate.unwrap(iface);
+ }
+
+ throw new SQLException("Wrapped DatabaseMetaData is not an instance of " + iface);
+ }
+}
diff --git a/src/main/java/com/zaxxer/hikari/pool/ProxyFactory.java b/src/main/java/com/zaxxer/hikari/pool/ProxyFactory.java
index 4a074da7..467d15f9 100644
--- a/src/main/java/com/zaxxer/hikari/pool/ProxyFactory.java
+++ b/src/main/java/com/zaxxer/hikari/pool/ProxyFactory.java
@@ -16,11 +16,7 @@
package com.zaxxer.hikari.pool;
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Statement;
+import java.sql.*;
import com.zaxxer.hikari.util.FastList;
@@ -78,4 +74,10 @@ public final class ProxyFactory
// Body is replaced (injected) by JavassistProxyFactory
throw new IllegalStateException("You need to run the CLI build and you need target/classes in your classpath to run.");
}
+
+ static DatabaseMetaData getProxyDatabaseMetaData(final ProxyConnection connection, final DatabaseMetaData metaData)
+ {
+ // Body is replaced (injected) by JavassistProxyFactory
+ throw new IllegalStateException("You need to run the CLI build and you need target/classes in your classpath to run.");
+ }
}
diff --git a/src/main/java/com/zaxxer/hikari/util/JavassistProxyFactory.java b/src/main/java/com/zaxxer/hikari/util/JavassistProxyFactory.java
index 5a09e271..d31abf21 100644
--- a/src/main/java/com/zaxxer/hikari/util/JavassistProxyFactory.java
+++ b/src/main/java/com/zaxxer/hikari/util/JavassistProxyFactory.java
@@ -18,23 +18,14 @@ package com.zaxxer.hikari.util;
import java.io.IOException;
import java.lang.reflect.Array;
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.Statement;
+import java.sql.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import com.zaxxer.hikari.pool.ProxyCallableStatement;
-import com.zaxxer.hikari.pool.ProxyConnection;
-import com.zaxxer.hikari.pool.ProxyFactory;
-import com.zaxxer.hikari.pool.ProxyPreparedStatement;
-import com.zaxxer.hikari.pool.ProxyResultSet;
-import com.zaxxer.hikari.pool.ProxyStatement;
+import com.zaxxer.hikari.pool.*;
import javassist.*;
import javassist.bytecode.ClassFile;
@@ -66,6 +57,7 @@ public final class JavassistProxyFactory
generateProxyClass(Connection.class, ProxyConnection.class.getName(), methodBody);
generateProxyClass(Statement.class, ProxyStatement.class.getName(), methodBody);
generateProxyClass(ResultSet.class, ProxyResultSet.class.getName(), methodBody);
+ generateProxyClass(DatabaseMetaData.class, ProxyDatabaseMetaData.class.getName(), methodBody);
// For these we have to cast the delegate
methodBody = "{ try { return ((cast) delegate).method($$); } catch (SQLException e) { throw checkException(e); } }";
@@ -82,24 +74,27 @@ public final class JavassistProxyFactory
CtClass proxyCt = classPool.getCtClass("com.zaxxer.hikari.pool.ProxyFactory");
for (CtMethod method : proxyCt.getMethods()) {
switch (method.getName()) {
- case "getProxyConnection":
- method.setBody("{return new " + packageName + ".HikariProxyConnection($$);}");
- break;
- case "getProxyStatement":
- method.setBody("{return new " + packageName + ".HikariProxyStatement($$);}");
- break;
- case "getProxyPreparedStatement":
- method.setBody("{return new " + packageName + ".HikariProxyPreparedStatement($$);}");
- break;
- case "getProxyCallableStatement":
- method.setBody("{return new " + packageName + ".HikariProxyCallableStatement($$);}");
- break;
- case "getProxyResultSet":
- method.setBody("{return new " + packageName + ".HikariProxyResultSet($$);}");
- break;
- default:
- // unhandled method
- break;
+ case "getProxyConnection":
+ method.setBody("{return new " + packageName + ".HikariProxyConnection($$);}");
+ break;
+ case "getProxyStatement":
+ method.setBody("{return new " + packageName + ".HikariProxyStatement($$);}");
+ break;
+ case "getProxyPreparedStatement":
+ method.setBody("{return new " + packageName + ".HikariProxyPreparedStatement($$);}");
+ break;
+ case "getProxyCallableStatement":
+ method.setBody("{return new " + packageName + ".HikariProxyCallableStatement($$);}");
+ break;
+ case "getProxyResultSet":
+ method.setBody("{return new " + packageName + ".HikariProxyResultSet($$);}");
+ break;
+ case "getProxyDatabaseMetaData":
+ method.setBody("{return new " + packageName + ".HikariProxyDatabaseMetaData($$);}");
+ break;
+ default:
+ // unhandled method
+ break;
}
}