From 50c03c9f63db844f309e801e2f4a9e1994d0479f Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Wed, 26 Mar 2025 05:08:40 +0300 Subject: [PATCH] PreparedStatementWrapper rewritten to java --- sandbox/src/commonMain/kotlin/main.kt | 2 +- ...aredStatementsCompilationPhantomCache.java | 2 +- .../_PreparedStatementWrapper.java | 832 ++++++++++++++++++ .../PreparedStatementWrapper.kt | 358 -------- .../ResultSetWrapper.kt | 21 +- 5 files changed, 852 insertions(+), 363 deletions(-) create mode 100644 src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/_PreparedStatementWrapper.java delete mode 100644 src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementWrapper.kt diff --git a/sandbox/src/commonMain/kotlin/main.kt b/sandbox/src/commonMain/kotlin/main.kt index 6bacc5d..4237d38 100644 --- a/sandbox/src/commonMain/kotlin/main.kt +++ b/sandbox/src/commonMain/kotlin/main.kt @@ -4,7 +4,7 @@ import ru.langrafhomyak.db.jdbc_resources_manager.PreparedStatementsCompilationP val someStmt = PreparedStatementsCompilationPhantomCache("SELECT * FROM sqlite_master") fun main() { - for (i in 0..10) { + for (i in 0..1000) { DriverManager.getConnection("jdbc:sqlite::memory:").use { connection -> someStmt.preparedStatementForConnection(connection).use { ps -> ps.executeQuery().use { rs -> diff --git a/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementsCompilationPhantomCache.java b/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementsCompilationPhantomCache.java index dc4c832..0c37f00 100644 --- a/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementsCompilationPhantomCache.java +++ b/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementsCompilationPhantomCache.java @@ -98,7 +98,7 @@ public class PreparedStatementsCompilationPhantomCache /*implements ReadOnlyProp } } - private static class BoundPreparedStatementWrapper extends PreparedStatementWrapper { + private static class BoundPreparedStatementWrapper extends _PreparedStatementWrapper { @NotNull private final ConnectionsMapNode _node; diff --git a/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/_PreparedStatementWrapper.java b/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/_PreparedStatementWrapper.java new file mode 100644 index 0000000..b9e1ef5 --- /dev/null +++ b/src/jvmMain/java/ru/langrafhomyak/db/jdbc_resources_manager/_PreparedStatementWrapper.java @@ -0,0 +1,832 @@ +package ru.langrafhomyak.db.jdbc_resources_manager; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import ru.landrafhomyak.utility.reference_counter.CloseableReferenceCounter; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.ParameterMetaData; +import java.sql.PreparedStatement; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.Map; +import java.util.Objects; + +/* package */ abstract class _PreparedStatementWrapper implements PreparedStatement { + @NotNull + protected final PreparedStatement _orig; + @NotNull + private final CloseableReferenceCounter _refcnt; + @NotNull + private final Object _sync; + private ResultSet _currentQuery = null; + private boolean _closeOnCompletion = false; + + _PreparedStatementWrapper(@NotNull PreparedStatement orig) { + this._orig = orig; + this._refcnt = new CloseableReferenceCounter("This prepared statement was returned to pool to be used in future"); + this._sync = new Object(); + } + + protected abstract void _onClose() throws SQLException; + + @Override + public void close() throws SQLException { + synchronized (this._sync) { + this._refcnt.close("Can't close prepared statement while it's in use"); + this._onClose(); + } + } + + @Override + public boolean isClosed() { + return this._refcnt.isClosed(); + } + + @Override + public void closeOnCompletion() { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._closeOnCompletion = true; + } + } + + @Override + public boolean isCloseOnCompletion() { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._closeOnCompletion; + } + } + + private class _BoundResultSetWrapper extends ResultSetWrapper { + + public _BoundResultSetWrapper(@NotNull ResultSet orig) { + super(orig); + } + + @Override + public void close() throws SQLException { + if (this._orig.isClosed()) + return; + this._orig.close(); + _PreparedStatementWrapper.this._currentQuery = null; + if (_PreparedStatementWrapper.this._closeOnCompletion) + _PreparedStatementWrapper.this.close(); + } + + @Override + public Statement getStatement() { + return _PreparedStatementWrapper.this; + } + + } + + @NotNull + private ResultSet _prepareRS(@Nullable ResultSet orig) { + Objects.requireNonNull(orig, "Underlying PreparedStatement didn't returned ResultSet"); + ResultSet wrapped = this.new _BoundResultSetWrapper(orig); + this._currentQuery = wrapped; + return wrapped; + } + + @Override + public ResultSet executeQuery() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._prepareRS(this._orig.executeQuery()); + } + } + + @Override + public ResultSet getResultSet() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._prepareRS(this._orig.getResultSet()); + } + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._prepareRS(this._orig.getGeneratedKeys()); + } + } + + + @Override + public T unwrap(java.lang.Class iface) throws SQLException { + return iface.isInstance(this) ? iface.cast(this) : this._orig.unwrap(iface); + } + + @Override + public boolean isWrapperFor(java.lang.Class iface) throws SQLException { + return iface.isInstance(this) || this._orig.isWrapperFor(iface); + } + + + @Override + public void setPoolable(boolean value) throws SQLException { + throw new SQLException("Disabling pooling not allowed on prepared statements driven by PreparedStatementsCompilationCache"); + + } + + @Override + public boolean isPoolable() { + return true; + } + + + @Override + public void cancel() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.cancel(); + } + } + + @Override + public int executeUpdate() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.executeUpdate(); + } + } + + @Override + public void setNull(int parameterIndex, int sqlType) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNull(parameterIndex, sqlType); + } + } + + @Override + public void setBoolean(int parameterIndex, boolean x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBoolean(parameterIndex, x); + } + } + + @Override + public void setByte(int parameterIndex, byte x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setByte(parameterIndex, x); + } + } + + @Override + public void setShort(int parameterIndex, short x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setShort(parameterIndex, x); + } + } + + @Override + public void setInt(int parameterIndex, int x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setInt(parameterIndex, x); + } + } + + @Override + public void setLong(int parameterIndex, long x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setLong(parameterIndex, x); + } + } + + @Override + public void setFloat(int parameterIndex, float x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setFloat(parameterIndex, x); + } + } + + @Override + public void setDouble(int parameterIndex, double x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setDouble(parameterIndex, x); + } + } + + @Override + public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBigDecimal(parameterIndex, x); + } + } + + @Override + public void setString(int parameterIndex, String x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setString(parameterIndex, x); + } + } + + @Override + public void setBytes(int parameterIndex, byte[] x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBytes(parameterIndex, x); + } + } + + @Override + public void setDate(int parameterIndex, Date x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setDate(parameterIndex, x); + } + } + + @Override + public void setTime(int parameterIndex, Time x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setTime(parameterIndex, x); + } + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setTimestamp(parameterIndex, x); + } + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setAsciiStream(parameterIndex, x, length); + } + } + + @Override + @SuppressWarnings({"deprecation"}) + public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setUnicodeStream(parameterIndex, x, length); + } + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBinaryStream(parameterIndex, x); + } + } + + @Override + public void clearParameters() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.clearParameters(); + } + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setObject(parameterIndex, x, targetSqlType); + } + } + + @Override + public void setObject(int parameterIndex, Object x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setObject(parameterIndex, x); + } + } + + @Override + public boolean execute() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.execute(); + } + } + + @Override + public void addBatch() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.addBatch(); + } + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setCharacterStream(parameterIndex, reader, length); + } + } + + @Override + public void setRef(int parameterIndex, Ref x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setRef(parameterIndex, x); + } + } + + @Override + public void setBlob(int parameterIndex, Blob x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBlob(parameterIndex, x); + } + } + + @Override + public void setClob(int parameterIndex, Clob x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setClob(parameterIndex, x); + } + } + + @Override + public void setArray(int parameterIndex, Array x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setArray(parameterIndex, x); + } + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getMetaData(); + } + } + + @Override + public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setDate(parameterIndex, x); + } + } + + @Override + public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setTime(parameterIndex, x); + } + } + + @Override + public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setTimestamp(parameterIndex, x); + } + } + + @Override + public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNull(parameterIndex, sqlType, typeName); + } + } + + @Override + public void setURL(int parameterIndex, URL x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setURL(parameterIndex, x); + } + } + + @Override + public ParameterMetaData getParameterMetaData() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getParameterMetaData(); + } + } + + @Override + public void setRowId(int parameterIndex, RowId x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setRowId(parameterIndex, x); + } + } + + @Override + public void setNString(int parameterIndex, String value) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNString(parameterIndex, value); + } + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNCharacterStream(parameterIndex, value, length); + } + } + + @Override + public void setNClob(int parameterIndex, NClob value) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNClob(parameterIndex, value); + } + } + + @Override + public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setClob(parameterIndex, reader, length); + } + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBlob(parameterIndex, inputStream, length); + } + } + + @Override + public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNClob(parameterIndex, reader, length); + } + } + + @Override + public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setSQLXML(parameterIndex, xmlObject); + } + } + + @Override + public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setObject(parameterIndex, x, targetSqlType, scaleOrLength); + } + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setAsciiStream(parameterIndex, x, length); + } + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBinaryStream(parameterIndex, x, length); + } + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setCharacterStream(parameterIndex, reader, length); + } + } + + @Override + public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setAsciiStream(parameterIndex, x); + } + } + + @Override + public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBinaryStream(parameterIndex, x); + } + } + + @Override + public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setCharacterStream(parameterIndex, reader); + } + } + + @Override + public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNCharacterStream(parameterIndex, value); + } + } + + @Override + public void setClob(int parameterIndex, Reader reader) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setClob(parameterIndex, reader); + } + } + + @Override + public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setBlob(parameterIndex, inputStream); + } + } + + @Override + public void setNClob(int parameterIndex, Reader reader) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setNClob(parameterIndex, reader); + } + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + throw new SQLException("executeQuery(String) not allowed on PreparedStatement"); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + throw new SQLException("executeUpdate(String) not allowed on PreparedStatement"); + } + + @Override + public int getMaxFieldSize() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getMaxFieldSize(); + } + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setMaxFieldSize(max); + } + } + + @Override + public int getMaxRows() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getMaxRows(); + } + } + + @Override + public void setMaxRows(int max) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setMaxRows(max); + } + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setEscapeProcessing(enable); + } + } + + @Override + public int getQueryTimeout() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getQueryTimeout(); + } + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setQueryTimeout(seconds); + } + } + + @Override + public SQLWarning getWarnings() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getWarnings(); + } + } + + @Override + public void clearWarnings() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.clearWarnings(); + } + } + + @Override + public void setCursorName(String name) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setCursorName(name); + } + } + + + @Override + public boolean execute(String sql) throws SQLException { + throw new SQLException("execute(String) not allowed on PreparedStatement"); + } + + + @Override + public int getUpdateCount() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getUpdateCount(); + } + } + + @Override + public boolean getMoreResults() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getMoreResults(); + } + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setFetchDirection(direction); + } + } + + @Override + public int getFetchDirection() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getFetchDirection(); + } + } + + @Override + public void setFetchSize(int rows) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.setFetchSize(rows); + } + } + + @Override + public int getFetchSize() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getFetchSize(); + } + } + + @Override + public int getResultSetConcurrency() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getResultSetConcurrency(); + } + } + + @Override + public int getResultSetType() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getResultSetType(); + } + } + + @Override + public void addBatch(String sql) throws SQLException { + throw new SQLException("addBatch(String) not allowed on PreparedStatement"); + } + + @Override + public void clearBatch() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + this._orig.clearBatch(); + } + } + + @Override + public int[] executeBatch() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.executeBatch(); + } + } + + @Override + public Connection getConnection() throws SQLException { + return this._orig.getConnection(); + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getMoreResults(current); + } + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + throw new SQLException("executeUpdate(String, int) not allowed on PreparedStatement"); + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + throw new SQLException("executeUpdate(String, int[]) not allowed on PreparedStatement"); + } + + @Override + public int executeUpdate(String sql, String[] columnIndexes) throws SQLException { + throw new SQLException("executeUpdate(String, String[]) not allowed on PreparedStatement"); + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + throw new SQLException("executeUpdate(String, int) not allowed on PreparedStatement"); + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + throw new SQLException("executeUpdate(String, int[]) not allowed on PreparedStatement"); + } + + @Override + public boolean execute(String sql, String[] columnIndexes) throws SQLException { + throw new SQLException("executeUpdate(String, String[]) not allowed on PreparedStatement"); + } + + @Override + public int getResultSetHoldability() throws SQLException { + synchronized (this._sync) { + this._refcnt.assertNotClosed(); + return this._orig.getResultSetHoldability(); + } + } +} diff --git a/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementWrapper.kt b/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementWrapper.kt deleted file mode 100644 index 45aae5b..0000000 --- a/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/PreparedStatementWrapper.kt +++ /dev/null @@ -1,358 +0,0 @@ -package ru.langrafhomyak.db.jdbc_resources_manager - -import java.io.InputStream -import java.io.Reader -import java.math.BigDecimal -import java.net.URL -import java.sql.Array -import java.sql.Blob -import java.sql.Clob -import java.sql.Connection -import java.sql.Date -import java.sql.NClob -import java.sql.ParameterMetaData -import java.sql.PreparedStatement -import java.sql.Ref -import java.sql.ResultSet -import java.sql.ResultSetMetaData -import java.sql.RowId -import java.sql.SQLException -import java.sql.SQLWarning -import java.sql.SQLXML -import java.sql.Statement -import java.sql.Time -import java.sql.Timestamp -import java.util.Calendar -import kotlin.jvm.Throws -import ru.landrafhomyak.utility.reference_counter.CloseableReferenceCounter - -@Suppress("UsePropertyAccessSyntax") -internal abstract class PreparedStatementWrapper(@JvmField protected val _orig: PreparedStatement) : PreparedStatement { - private val _refcnt = CloseableReferenceCounter("This prepared statement was returned to pool to be used in future") - private var _currentQuery: ResultSetWrapper? = null - private var _closeOnCompletion: Boolean = false - - @Throws(SQLException::class) - protected abstract fun _onClose() - - override fun close() { - this._refcnt.close("Can't close prepared statement while it's in use") - this._onClose() - } - - override fun isClosed(): Boolean = this._refcnt.isClosed - - override fun closeOnCompletion() = - this._refcnt.withRef { this._closeOnCompletion = true } - - - override fun isCloseOnCompletion(): Boolean = - this._refcnt.withRef { this._closeOnCompletion } - - private inner class _BoundResultSetWrapper(orig: ResultSet) : ResultSetWrapper(orig) { - override fun close() { - if (this._orig.isClosed) - return - this._orig.close() - this@PreparedStatementWrapper._currentQuery = null - if (this@PreparedStatementWrapper._closeOnCompletion) - this@PreparedStatementWrapper.close() - } - - override fun getStatement(): Statement? = this@PreparedStatementWrapper - } - - private fun _prepareRS(rs: ResultSet): ResultSet { - val wrapped = this._BoundResultSetWrapper(rs) - this._currentQuery = wrapped - return wrapped - } - - override fun executeQuery(): ResultSet? = - this._refcnt.withRef { this._orig.executeQuery()?.let(this::_prepareRS) } - - override fun getResultSet(): ResultSet? = - this._refcnt.withRef { this._orig.getResultSet()?.let(this::_prepareRS) } - - override fun getGeneratedKeys(): ResultSet? = - this._refcnt.withRef { this._orig.getGeneratedKeys()?.let(this::_prepareRS) } - - override fun unwrap(iface: Class): T? = - iface.cast(this) ?: this._orig.unwrap(iface) - - override fun isWrapperFor(iface: Class<*>): Boolean = - iface.isInstance(this) || this._orig.isWrapperFor(iface) - - override fun cancel() = - this._refcnt.withRef(this._orig::cancel) - - override fun executeUpdate(): Int = - this._refcnt.withRef(this._orig::executeUpdate) - - override fun setNull(parameterIndex: Int, sqlType: Int) = - this._refcnt.withRef { this._orig.setNull(parameterIndex, sqlType) } - - override fun setBoolean(parameterIndex: Int, x: Boolean) = - this._refcnt.withRef { this._orig.setBoolean(parameterIndex, x) } - - override fun setByte(parameterIndex: Int, x: Byte) = - this._refcnt.withRef { this._orig.setByte(parameterIndex, x) } - - override fun setShort(parameterIndex: Int, x: Short) = - this._refcnt.withRef { this._orig.setShort(parameterIndex, x) } - - override fun setInt(parameterIndex: Int, x: Int) = - this._refcnt.withRef { this._orig.setInt(parameterIndex, x) } - - override fun setLong(parameterIndex: Int, x: Long) = - this._refcnt.withRef { this._orig.setLong(parameterIndex, x) } - - override fun setFloat(parameterIndex: Int, x: Float) = - this._refcnt.withRef { this._orig.setFloat(parameterIndex, x) } - - override fun setDouble(parameterIndex: Int, x: Double) = - this._refcnt.withRef { this._orig.setDouble(parameterIndex, x) } - - override fun setBigDecimal(parameterIndex: Int, x: BigDecimal?) = - this._refcnt.withRef { this._orig.setBigDecimal(parameterIndex, x) } - - override fun setString(parameterIndex: Int, x: String?) = - this._refcnt.withRef { this._orig.setString(parameterIndex, x) } - - override fun setBytes(parameterIndex: Int, x: ByteArray?) = - this._refcnt.withRef { this._orig.setBytes(parameterIndex, x) } - - override fun setDate(parameterIndex: Int, x: Date?) = - this._refcnt.withRef { this._orig.setDate(parameterIndex, x) } - - override fun setTime(parameterIndex: Int, x: Time?) = - this._refcnt.withRef { this._orig.setTime(parameterIndex, x) } - - override fun setTimestamp(parameterIndex: Int, x: Timestamp?) = - this._refcnt.withRef { this._orig.setTimestamp(parameterIndex, x) } - - override fun setAsciiStream(parameterIndex: Int, x: InputStream?, length: Int) = - this._refcnt.withRef { this._orig.setAsciiStream(parameterIndex, x, length) } - - @Deprecated("Deprecated in Java") - override fun setUnicodeStream(parameterIndex: Int, x: InputStream?, length: Int) = - this._refcnt.withRef { this._orig.setUnicodeStream(parameterIndex, x, length) } - - override fun setBinaryStream(parameterIndex: Int, x: InputStream?, length: Int) = - this._refcnt.withRef { this._orig.setBinaryStream(parameterIndex, x) } - - override fun clearParameters() = - this._refcnt.withRef(this._orig::clearParameters) - - override fun setObject(parameterIndex: Int, x: Any?, targetSqlType: Int) = - this._refcnt.withRef { this._orig.setObject(parameterIndex, x, targetSqlType) } - - override fun setObject(parameterIndex: Int, x: Any?) = - this._refcnt.withRef { this._orig.setObject(parameterIndex, x) } - - override fun execute(): Boolean = - this._refcnt.withRef(this._orig::execute) - - override fun addBatch() = - this._refcnt.withRef(this._orig::addBatch) - - override fun setCharacterStream(parameterIndex: Int, reader: Reader?, length: Int) = - this._refcnt.withRef { this._orig.setCharacterStream(parameterIndex, reader, length) } - - override fun setRef(parameterIndex: Int, x: Ref?) = - this._refcnt.withRef { this._orig.setRef(parameterIndex, x) } - - override fun setBlob(parameterIndex: Int, x: Blob?) = - this._refcnt.withRef { this._orig.setBlob(parameterIndex, x) } - - override fun setClob(parameterIndex: Int, x: Clob?) = - this._refcnt.withRef { this._orig.setClob(parameterIndex, x) } - - override fun setArray(parameterIndex: Int, x: Array?) = - this._refcnt.withRef { this._orig.setArray(parameterIndex, x) } - - override fun getMetaData(): ResultSetMetaData? = - this._refcnt.withRef(this._orig::getMetaData) - - override fun setDate(parameterIndex: Int, x: Date?, cal: Calendar?) = - this._refcnt.withRef { this._orig.setDate(parameterIndex, x) } - - override fun setTime(parameterIndex: Int, x: Time?, cal: Calendar?) = - this._refcnt.withRef { this._orig.setTime(parameterIndex, x) } - - override fun setTimestamp(parameterIndex: Int, x: Timestamp?, cal: Calendar?) = - this._refcnt.withRef { this._orig.setTimestamp(parameterIndex, x) } - - override fun setNull(parameterIndex: Int, sqlType: Int, typeName: String?) = - this._refcnt.withRef { this._orig.setNull(parameterIndex, sqlType, typeName) } - - override fun setURL(parameterIndex: Int, x: URL?) = - this._refcnt.withRef { this._orig.setURL(parameterIndex, x) } - - override fun getParameterMetaData(): ParameterMetaData? = - this._refcnt.withRef(this._orig::getParameterMetaData) - - override fun setRowId(parameterIndex: Int, x: RowId?) = - this._refcnt.withRef { this._orig.setRowId(parameterIndex, x) } - - override fun setNString(parameterIndex: Int, value: String?) = - this._refcnt.withRef { this._orig.setNString(parameterIndex, value) } - - override fun setNCharacterStream(parameterIndex: Int, value: Reader?, length: Long) = - this._refcnt.withRef { this._orig.setNCharacterStream(parameterIndex, value, length) } - - override fun setNClob(parameterIndex: Int, value: NClob?) = - this._refcnt.withRef { this._orig.setNClob(parameterIndex, value) } - - override fun setClob(parameterIndex: Int, reader: Reader?, length: Long) = - this._refcnt.withRef { this._orig.setClob(parameterIndex, reader, length) } - - override fun setBlob(parameterIndex: Int, inputStream: InputStream?, length: Long) = - this._refcnt.withRef { this._orig.setBlob(parameterIndex, inputStream, length) } - - override fun setNClob(parameterIndex: Int, reader: Reader?, length: Long) = - this._refcnt.withRef { this._orig.setNClob(parameterIndex, reader, length) } - - override fun setSQLXML(parameterIndex: Int, xmlObject: SQLXML?) = - this._refcnt.withRef { this._orig.setSQLXML(parameterIndex, xmlObject) } - - override fun setObject(parameterIndex: Int, x: Any?, targetSqlType: Int, scaleOrLength: Int) = - this._refcnt.withRef { this._orig.setObject(parameterIndex, x, targetSqlType, scaleOrLength) } - - override fun setAsciiStream(parameterIndex: Int, x: InputStream?, length: Long) = - this._refcnt.withRef { this._orig.setAsciiStream(parameterIndex, x, length) } - - override fun setBinaryStream(parameterIndex: Int, x: InputStream?, length: Long) = - this._refcnt.withRef { this._orig.setBinaryStream(parameterIndex, x, length) } - - override fun setCharacterStream(parameterIndex: Int, reader: Reader?, length: Long) = - this._refcnt.withRef { this._orig.setCharacterStream(parameterIndex, reader, length) } - - override fun setAsciiStream(parameterIndex: Int, x: InputStream?) = - this._refcnt.withRef { this._orig.setAsciiStream(parameterIndex, x) } - - override fun setBinaryStream(parameterIndex: Int, x: InputStream?) = - this._refcnt.withRef { this._orig.setBinaryStream(parameterIndex, x) } - - override fun setCharacterStream(parameterIndex: Int, reader: Reader?) = - this._refcnt.withRef { this._orig.setCharacterStream(parameterIndex, reader) } - - override fun setNCharacterStream(parameterIndex: Int, value: Reader?) = - this._refcnt.withRef { this._orig.setNCharacterStream(parameterIndex, value) } - - override fun setClob(parameterIndex: Int, reader: Reader?) = - this._refcnt.withRef { this._orig.setClob(parameterIndex, reader) } - - override fun setBlob(parameterIndex: Int, inputStream: InputStream?) = - this._refcnt.withRef { this._orig.setBlob(parameterIndex, inputStream) } - - override fun setNClob(parameterIndex: Int, reader: Reader?) = - this._refcnt.withRef { this._orig.setNClob(parameterIndex, reader) } - - override fun executeQuery(sql: String?): ResultSet? = - throw SQLException("executeQuery(String) not allowed on PreparedStatement") - - override fun executeUpdate(sql: String?): Int = - throw SQLException("executeUpdate(String) not allowed on PreparedStatement") - - override fun getMaxFieldSize(): Int = - this._refcnt.withRef(this._orig::getMaxFieldSize) - - override fun setMaxFieldSize(max: Int) = - this._refcnt.withRef { this._orig.setMaxFieldSize(max) } - - override fun getMaxRows(): Int = - this._refcnt.withRef(this._orig::getMaxRows) - - override fun setMaxRows(max: Int) = - this._refcnt.withRef { this._orig.setMaxRows(max) } - - override fun setEscapeProcessing(enable: Boolean) = - this._refcnt.withRef { this._orig.setEscapeProcessing(enable) } - - override fun getQueryTimeout(): Int = - this._refcnt.withRef(this._orig::getQueryTimeout) - - override fun setQueryTimeout(seconds: Int) = - this._refcnt.withRef { this._orig.setQueryTimeout(seconds) } - - override fun getWarnings(): SQLWarning? = - this._refcnt.withRef(this._orig::getWarnings) - - override fun clearWarnings() = - this._refcnt.withRef(this._orig::clearWarnings) - - override fun setCursorName(name: String?) = - this._refcnt.withRef { this._orig.setCursorName(name) } - - override fun execute(sql: String?): Boolean = - throw SQLException("execute(String) not allowed on PreparedStatement") - - override fun getUpdateCount(): Int = - this._refcnt.withRef(this._orig::getUpdateCount) - - override fun getMoreResults() = - this._refcnt.withRef(this._orig::getMoreResults) - - override fun setFetchDirection(direction: Int) = - this._refcnt.withRef { this._orig.setFetchDirection(direction) } - - override fun getFetchDirection() = - this._refcnt.withRef(this._orig::getFetchDirection) - - override fun setFetchSize(rows: Int) = - this._refcnt.withRef { this._orig.setFetchSize(rows) } - - override fun getFetchSize() = - this._refcnt.withRef(this._orig::getFetchSize) - - override fun getResultSetConcurrency() = - this._refcnt.withRef(this._orig::getFetchSize) - - override fun getResultSetType() = - this._refcnt.withRef(this._orig::getFetchSize) - - override fun addBatch(sql: String?): Unit = - throw SQLException("addBatch(String) not allowed on PreparedStatement") - - override fun clearBatch() = - this._refcnt.withRef(this._orig::clearBatch) - - override fun executeBatch(): IntArray? = - this._refcnt.withRef(this._orig::executeBatch) - - override fun getConnection(): Connection? = - this._orig.getConnection() - - override fun getMoreResults(current: Int): Boolean = - this._refcnt.withRef { this._orig.getMoreResults(current) } - - override fun executeUpdate(sql: String?, autoGeneratedKeys: Int): Int = - throw SQLException("executeUpdate(String, int) not allowed on PreparedStatement") - - override fun executeUpdate(sql: String?, columnIndexes: IntArray?): Int = - throw SQLException("executeUpdate(String, int[]) not allowed on PreparedStatement") - - override fun executeUpdate(sql: String?, columnNames: kotlin.Array?): Int = - throw SQLException("executeUpdate(String, String[]) not allowed on PreparedStatement") - - override fun execute(sql: String?, autoGeneratedKeys: Int): Boolean = - throw SQLException("execute(String, int) not allowed on PreparedStatement") - - override fun execute(sql: String?, columnIndexes: IntArray?): Boolean = - throw SQLException("executeUpdate(String, int[]) not allowed on PreparedStatement") - - override fun execute(sql: String?, columnNames: kotlin.Array?): Boolean = - throw SQLException("execute(String, String[]) not allowed on PreparedStatement") - - override fun getResultSetHoldability(): Int = - this._refcnt.withRef(this._orig::getResultSetHoldability) - - override fun setPoolable(poolable: Boolean) { - if (poolable) - return - throw SQLException("Disabling pooling not allowed on prepared statements driven by PreparedStatementsCompilationCache") - } - - override fun isPoolable(): Boolean = true -} \ No newline at end of file diff --git a/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/ResultSetWrapper.kt b/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/ResultSetWrapper.kt index ce462c5..2dc6d8d 100644 --- a/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/ResultSetWrapper.kt +++ b/src/jvmMain/kotlin/ru/langrafhomyak/db/jdbc_resources_manager/ResultSetWrapper.kt @@ -1,29 +1,44 @@ package ru.langrafhomyak.db.jdbc_resources_manager -import java.sql.Clob import java.sql.ResultSet -import java.sql.ResultSetMetaData +import java.sql.SQLException import java.sql.SQLType import java.sql.Statement -internal abstract class ResultSetWrapper(protected val _orig: ResultSet) : ResultSet by _orig { +internal abstract class ResultSetWrapper(@JvmField protected val _orig: ResultSet) : ResultSet by _orig { + @Throws(SQLException::class) abstract override fun close() + @Throws(SQLException::class) abstract override fun getStatement(): Statement? + @Throws(SQLException::class) override fun updateObject(columnIndex: Int, x: Any?, targetSqlType: SQLType?, scaleOrLength: Int) { this._orig.updateObject(columnIndex, x, targetSqlType, scaleOrLength) } + @Throws(SQLException::class) override fun updateObject(columnLabel: String?, x: Any?, targetSqlType: SQLType?, scaleOrLength: Int) { this._orig.updateObject(columnLabel, x, targetSqlType, scaleOrLength) } + @Throws(SQLException::class) override fun updateObject(columnIndex: Int, x: Any?, targetSqlType: SQLType?) { this._orig.updateObject(columnIndex, x, targetSqlType) } + @Throws(SQLException::class) override fun updateObject(columnLabel: String?, x: Any?, targetSqlType: SQLType?) { this._orig.updateObject(columnLabel, x, targetSqlType) } + + @Throws(SQLException::class) + override fun getObject(columnIndex: Int, map: MutableMap?>?): Any? { + return this._orig.getObject(columnIndex, map) + } + + @Throws(SQLException::class) + override fun getObject(columnLabel: String?, map: MutableMap?>?): Any? { + return this._orig.getObject(columnLabel, map) + } } \ No newline at end of file