Wrappers for PreparedStatement and ResultSet
This commit is contained in:
parent
a33ecc068c
commit
0c553c7c3d
@ -0,0 +1,357 @@
|
||||
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 ru.landrafhomyak.utility.reference_counter.CloseableReferenceCounter
|
||||
|
||||
@Suppress("UsePropertyAccessSyntax")
|
||||
internal abstract class PreparedStatementWrapper(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
|
||||
|
||||
protected abstract fun _onClose()
|
||||
|
||||
override fun close() {
|
||||
this._refcnt.close("Can't close prepared statement while it's in use")
|
||||
this._onClose()
|
||||
}
|
||||
|
||||
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 <T : Any?> unwrap(iface: Class<T?>): 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?) =
|
||||
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<out String?>?): 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<out String?>?): Boolean =
|
||||
throw SQLException("execute(String, String[]) not allowed on PreparedStatement")
|
||||
|
||||
override fun getResultSetHoldability(): Int =
|
||||
this._refcnt.withRef(this._orig::getResultSetHoldability)
|
||||
|
||||
override fun isClosed(): Boolean =
|
||||
this._refcnt.withRef(this._orig::isClosed)
|
||||
|
||||
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
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package ru.langrafhomyak.db.jdbc_resources_manager
|
||||
|
||||
import java.sql.Clob
|
||||
import java.sql.ResultSet
|
||||
import java.sql.ResultSetMetaData
|
||||
import java.sql.SQLType
|
||||
import java.sql.Statement
|
||||
|
||||
internal abstract class ResultSetWrapper(protected val _orig: ResultSet) : ResultSet by _orig {
|
||||
abstract override fun close()
|
||||
|
||||
abstract override fun getStatement(): Statement?
|
||||
|
||||
override fun updateObject(columnIndex: Int, x: Any?, targetSqlType: SQLType?, scaleOrLength: Int) {
|
||||
this._orig.updateObject(columnIndex, x, targetSqlType, scaleOrLength)
|
||||
}
|
||||
|
||||
override fun updateObject(columnLabel: String?, x: Any?, targetSqlType: SQLType?, scaleOrLength: Int) {
|
||||
this._orig.updateObject(columnLabel, x, targetSqlType, scaleOrLength)
|
||||
}
|
||||
|
||||
override fun updateObject(columnIndex: Int, x: Any?, targetSqlType: SQLType?) {
|
||||
this._orig.updateObject(columnIndex, x, targetSqlType)
|
||||
}
|
||||
|
||||
override fun updateObject(columnLabel: String?, x: Any?, targetSqlType: SQLType?) {
|
||||
this._orig.updateObject(columnLabel, x, targetSqlType)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user