android support! thanks to TachiWeb devs.

This commit is contained in:
Aria Moradi
2021-01-02 04:57:20 +03:30
parent ced07d4e1e
commit 1e46a0c78c
291 changed files with 68699 additions and 16 deletions
@@ -0,0 +1,841 @@
package xyz.nulldev.androidcompat.db
import java.io.InputStream
import java.io.Reader
import java.math.BigDecimal
import java.net.URL
import java.sql.*
import java.sql.Array
import java.sql.Date
import java.util.*
class ScrollableResultSet(val parent: ResultSet) : ResultSet by parent {
private val cachedContent = mutableListOf<ResultSetEntry>()
private val columnCache = mutableMapOf<String, Int>()
private var lastReturnWasNull = false
private var cursor = 0
var resultSetLength = 0
val parentMetadata = parent.metaData
val columnCount = parentMetadata.columnCount
val columnLabels = (1 .. columnCount).map {
parentMetadata.getColumnLabel(it)
}.toTypedArray()
init {
val columnCount = columnCount
// TODO
// Profiling reveals that this is a bottleneck (average ms for this call is: 48ms)
// How can we optimize this?
// We need to fill the cache as the set is loaded
//Fill cache
while(parent.next()) {
cachedContent += ResultSetEntry().apply {
for(i in 1 .. columnCount)
data += parent.getObject(i)
}
resultSetLength++
}
}
private fun notImplemented(): Nothing {
throw UnsupportedOperationException("This class currently does not support this operation!")
}
private fun cursorValid(): Boolean {
return isAfterLast || isBeforeFirst
}
private fun internalMove(row: Int) {
if(cursor < 0) cursor = 0
else if(cursor > resultSetLength + 1) cursor = resultSetLength + 1
else cursor = row
}
private fun obj(column: Int): Any? {
val obj = cachedContent[cursor - 1].data[column - 1]
lastReturnWasNull = obj == null
return obj
}
private fun obj(column: String?): Any? {
return obj(cachedFindColumn(column))
}
private fun cachedFindColumn(column: String?)
= columnCache.getOrPut(column!!, {
findColumn(column)
})
override fun getNClob(columnIndex: Int): NClob {
return obj(columnIndex) as NClob
}
override fun getNClob(columnLabel: String?): NClob {
return obj(columnLabel) as NClob
}
override fun updateNString(columnIndex: Int, nString: String?) {
notImplemented()
}
override fun updateNString(columnLabel: String?, nString: String?) {
notImplemented()
}
override fun updateBinaryStream(columnIndex: Int, x: InputStream?, length: Int) {
notImplemented()
}
override fun updateBinaryStream(columnLabel: String?, x: InputStream?, length: Int) {
notImplemented()
}
override fun updateBinaryStream(columnIndex: Int, x: InputStream?, length: Long) {
notImplemented()
}
override fun updateBinaryStream(columnLabel: String?, x: InputStream?, length: Long) {
notImplemented()
}
override fun updateBinaryStream(columnIndex: Int, x: InputStream?) {
notImplemented()
}
override fun updateBinaryStream(columnLabel: String?, x: InputStream?) {
notImplemented()
}
override fun updateTimestamp(columnIndex: Int, x: Timestamp?) {
notImplemented()
}
override fun updateTimestamp(columnLabel: String?, x: Timestamp?) {
notImplemented()
}
override fun updateNCharacterStream(columnIndex: Int, x: Reader?, length: Long) {
notImplemented()
}
override fun updateNCharacterStream(columnLabel: String?, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateNCharacterStream(columnIndex: Int, x: Reader?) {
notImplemented()
}
override fun updateNCharacterStream(columnLabel: String?, reader: Reader?) {
notImplemented()
}
override fun updateInt(columnIndex: Int, x: Int) {
notImplemented()
}
override fun updateInt(columnLabel: String?, x: Int) {
notImplemented()
}
override fun moveToInsertRow() {
notImplemented()
}
override fun getDate(columnIndex: Int): Date {
//TODO Maybe?
notImplemented()
}
override fun getDate(columnLabel: String?): Date {
//TODO Maybe?
notImplemented()
}
override fun getDate(columnIndex: Int, cal: Calendar?): Date {
//TODO Maybe?
notImplemented()
}
override fun getDate(columnLabel: String?, cal: Calendar?): Date {
//TODO Maybe?
notImplemented()
}
override fun beforeFirst() {
//TODO Maybe?
notImplemented()
}
override fun updateFloat(columnIndex: Int, x: Float) {
notImplemented()
}
override fun updateFloat(columnLabel: String?, x: Float) {
notImplemented()
}
override fun getBoolean(columnIndex: Int): Boolean {
return obj(columnIndex) as Boolean
}
override fun getBoolean(columnLabel: String?): Boolean {
return obj(columnLabel) as Boolean
}
override fun isFirst(): Boolean {
return cursor - 1 < resultSetLength
}
override fun getBigDecimal(columnIndex: Int, scale: Int): BigDecimal {
//TODO Maybe?
notImplemented()
}
override fun getBigDecimal(columnLabel: String?, scale: Int): BigDecimal {
//TODO Maybe?
notImplemented()
}
override fun getBigDecimal(columnIndex: Int): BigDecimal {
return obj(columnIndex) as BigDecimal
}
override fun getBigDecimal(columnLabel: String?): BigDecimal {
return obj(columnLabel) as BigDecimal
}
override fun updateBytes(columnIndex: Int, x: ByteArray?) {
notImplemented()
}
override fun updateBytes(columnLabel: String?, x: ByteArray?) {
notImplemented()
}
override fun isLast(): Boolean {
return cursor == resultSetLength
}
override fun insertRow() {
notImplemented()
}
override fun getTime(columnIndex: Int): Time {
//TODO Maybe?
notImplemented()
}
override fun getTime(columnLabel: String?): Time {
//TODO Maybe?
notImplemented()
}
override fun getTime(columnIndex: Int, cal: Calendar?): Time {
//TODO Maybe?
notImplemented()
}
override fun getTime(columnLabel: String?, cal: Calendar?): Time {
//TODO Maybe?
notImplemented()
}
override fun rowDeleted() = false
override fun last(): Boolean {
internalMove(resultSetLength)
return cursorValid()
}
override fun isAfterLast(): Boolean {
return cursor > resultSetLength
}
override fun relative(rows: Int): Boolean {
internalMove(cursor + rows)
return cursorValid()
}
override fun absolute(row: Int): Boolean {
if(row > 0) {
internalMove(row)
} else {
last()
for(i in 1 .. row)
previous()
}
return cursorValid()
}
override fun getSQLXML(columnIndex: Int): SQLXML? {
//TODO Maybe?
notImplemented()
}
override fun getSQLXML(columnLabel: String?): SQLXML? {
//TODO Maybe?
notImplemented()
}
override fun <T : Any?> unwrap(iface: Class<T>?): T {
if(thisIsWrapperFor(iface))
return this as T
else
return parent.unwrap(iface)
}
override fun next(): Boolean {
internalMove(cursor + 1)
return cursorValid()
}
override fun getFloat(columnIndex: Int): Float {
return obj(columnIndex) as Float
}
override fun getFloat(columnLabel: String?): Float {
return obj(columnLabel) as Float
}
override fun wasNull() = lastReturnWasNull
override fun getRow(): Int {
return cursor
}
override fun first(): Boolean {
internalMove(1)
return cursorValid()
}
override fun updateAsciiStream(columnIndex: Int, x: InputStream?, length: Int) {
notImplemented()
}
override fun updateAsciiStream(columnLabel: String?, x: InputStream?, length: Int) {
notImplemented()
}
override fun updateAsciiStream(columnIndex: Int, x: InputStream?, length: Long) {
notImplemented()
}
override fun updateAsciiStream(columnLabel: String?, x: InputStream?, length: Long) {
notImplemented()
}
override fun updateAsciiStream(columnIndex: Int, x: InputStream?) {
notImplemented()
}
override fun updateAsciiStream(columnLabel: String?, x: InputStream?) {
notImplemented()
}
override fun getURL(columnIndex: Int): URL {
return obj(columnIndex) as URL
}
override fun getURL(columnLabel: String?): URL {
return obj(columnLabel) as URL
}
override fun updateShort(columnIndex: Int, x: Short) {
notImplemented()
}
override fun updateShort(columnLabel: String?, x: Short) {
notImplemented()
}
override fun getType() = ResultSet.TYPE_SCROLL_INSENSITIVE
override fun updateNClob(columnIndex: Int, nClob: NClob?) {
notImplemented()
}
override fun updateNClob(columnLabel: String?, nClob: NClob?) {
notImplemented()
}
override fun updateNClob(columnIndex: Int, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateNClob(columnLabel: String?, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateNClob(columnIndex: Int, reader: Reader?) {
notImplemented()
}
override fun updateNClob(columnLabel: String?, reader: Reader?) {
notImplemented()
}
override fun updateRef(columnIndex: Int, x: Ref?) {
notImplemented()
}
override fun updateRef(columnLabel: String?, x: Ref?) {
notImplemented()
}
override fun updateObject(columnIndex: Int, x: Any?, scaleOrLength: Int) {
notImplemented()
}
override fun updateObject(columnIndex: Int, x: Any?) {
notImplemented()
}
override fun updateObject(columnLabel: String?, x: Any?, scaleOrLength: Int) {
notImplemented()
}
override fun updateObject(columnLabel: String?, x: Any?) {
notImplemented()
}
override fun afterLast() {
internalMove(resultSetLength + 1)
}
override fun updateLong(columnIndex: Int, x: Long) {
notImplemented()
}
override fun updateLong(columnLabel: String?, x: Long) {
notImplemented()
}
override fun getBlob(columnIndex: Int): Blob {
//TODO Maybe?
notImplemented()
}
override fun getBlob(columnLabel: String?): Blob {
//TODO Maybe?
notImplemented()
}
override fun updateClob(columnIndex: Int, x: Clob?) {
notImplemented()
}
override fun updateClob(columnLabel: String?, x: Clob?) {
notImplemented()
}
override fun updateClob(columnIndex: Int, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateClob(columnLabel: String?, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateClob(columnIndex: Int, reader: Reader?) {
notImplemented()
}
override fun updateClob(columnLabel: String?, reader: Reader?) {
notImplemented()
}
override fun getByte(columnIndex: Int): Byte {
return obj(columnIndex) as Byte
}
override fun getByte(columnLabel: String?): Byte {
return obj(columnLabel) as Byte
}
override fun getString(columnIndex: Int): String? {
return obj(columnIndex) as String?
}
override fun getString(columnLabel: String?): String? {
return obj(columnLabel) as String?
}
override fun updateSQLXML(columnIndex: Int, xmlObject: SQLXML?) {
notImplemented()
}
override fun updateSQLXML(columnLabel: String?, xmlObject: SQLXML?) {
notImplemented()
}
override fun updateDate(columnIndex: Int, x: Date?) {
notImplemented()
}
override fun updateDate(columnLabel: String?, x: Date?) {
notImplemented()
}
override fun getObject(columnIndex: Int): Any? {
return obj(columnIndex)
}
override fun getObject(columnLabel: String?): Any? {
return obj(columnLabel)
}
override fun getObject(columnIndex: Int, map: MutableMap<String, Class<*>>?): Any {
//TODO Maybe?
notImplemented()
}
override fun getObject(columnLabel: String?, map: MutableMap<String, Class<*>>?): Any {
//TODO Maybe?
notImplemented()
}
override fun <T : Any?> getObject(columnIndex: Int, type: Class<T>?): T {
return obj(columnIndex) as T
}
override fun <T : Any?> getObject(columnLabel: String?, type: Class<T>?): T {
return obj(columnLabel) as T
}
override fun previous(): Boolean {
internalMove(cursor - 1)
return cursorValid()
}
override fun updateDouble(columnIndex: Int, x: Double) {
notImplemented()
}
override fun updateDouble(columnLabel: String?, x: Double) {
notImplemented()
}
private fun castToLong(obj: Any?): Long {
if(obj == null) return 0
else if(obj is Long) return obj
else if(obj is Number) return obj.toLong()
else throw IllegalStateException("Object is not a long!")
}
override fun getLong(columnIndex: Int): Long {
return castToLong(obj(columnIndex))
}
override fun getLong(columnLabel: String?): Long {
return castToLong(obj(columnLabel))
}
override fun getClob(columnIndex: Int): Clob {
//TODO Maybe?
notImplemented()
}
override fun getClob(columnLabel: String?): Clob {
//TODO Maybe?
notImplemented()
}
override fun updateBlob(columnIndex: Int, x: Blob?) {
notImplemented()
}
override fun updateBlob(columnLabel: String?, x: Blob?) {
notImplemented()
}
override fun updateBlob(columnIndex: Int, inputStream: InputStream?, length: Long) {
notImplemented()
}
override fun updateBlob(columnLabel: String?, inputStream: InputStream?, length: Long) {
notImplemented()
}
override fun updateBlob(columnIndex: Int, inputStream: InputStream?) {
notImplemented()
}
override fun updateBlob(columnLabel: String?, inputStream: InputStream?) {
notImplemented()
}
override fun updateByte(columnIndex: Int, x: Byte) {
notImplemented()
}
override fun updateByte(columnLabel: String?, x: Byte) {
notImplemented()
}
override fun updateRow() {
notImplemented()
}
override fun deleteRow() {
notImplemented()
}
override fun getNString(columnIndex: Int): String {
return obj(columnIndex) as String
}
override fun getNString(columnLabel: String?): String {
return obj(columnLabel) as String
}
override fun getArray(columnIndex: Int): Array {
//TODO Maybe?
notImplemented()
}
override fun getArray(columnLabel: String?): Array {
//TODO Maybe?
notImplemented()
}
override fun cancelRowUpdates() {
notImplemented()
}
override fun updateString(columnIndex: Int, x: String?) {
notImplemented()
}
override fun updateString(columnLabel: String?, x: String?) {
notImplemented()
}
override fun setFetchDirection(direction: Int) {
notImplemented()
}
override fun getCharacterStream(columnIndex: Int): Reader {
return getNCharacterStream(columnIndex)
}
override fun getCharacterStream(columnLabel: String?): Reader {
return getNCharacterStream(columnLabel)
}
override fun isBeforeFirst(): Boolean {
return cursor - 1 < resultSetLength
}
override fun updateBoolean(columnIndex: Int, x: Boolean) {
notImplemented()
}
override fun updateBoolean(columnLabel: String?, x: Boolean) {
notImplemented()
}
override fun refreshRow() {
notImplemented()
}
override fun rowUpdated() = false
override fun updateBigDecimal(columnIndex: Int, x: BigDecimal?) {
notImplemented()
}
override fun updateBigDecimal(columnLabel: String?, x: BigDecimal?) {
notImplemented()
}
override fun getShort(columnIndex: Int): Short {
return obj(columnIndex) as Short
}
override fun getShort(columnLabel: String?): Short {
return obj(columnLabel) as Short
}
override fun getAsciiStream(columnIndex: Int): InputStream {
return getBinaryStream(columnIndex)
}
override fun getAsciiStream(columnLabel: String?): InputStream {
return getBinaryStream(columnLabel)
}
override fun updateTime(columnIndex: Int, x: Time?) {
notImplemented()
}
override fun updateTime(columnLabel: String?, x: Time?) {
notImplemented()
}
override fun getTimestamp(columnIndex: Int): Timestamp {
//TODO Maybe?
notImplemented()
}
override fun getTimestamp(columnLabel: String?): Timestamp {
//TODO Maybe?
notImplemented()
}
override fun getTimestamp(columnIndex: Int, cal: Calendar?): Timestamp {
//TODO Maybe?
notImplemented()
}
override fun getTimestamp(columnLabel: String?, cal: Calendar?): Timestamp {
//TODO Maybe?
notImplemented()
}
override fun getRef(columnIndex: Int): Ref {
//TODO Maybe?
notImplemented()
}
override fun getRef(columnLabel: String?): Ref {
//TODO Maybe?
notImplemented()
}
override fun getConcurrency() = ResultSet.CONCUR_READ_ONLY
override fun updateRowId(columnIndex: Int, x: RowId?) {
notImplemented()
}
override fun updateRowId(columnLabel: String?, x: RowId?) {
notImplemented()
}
override fun getNCharacterStream(columnIndex: Int): Reader {
return getBinaryStream(columnIndex).reader()
}
override fun getNCharacterStream(columnLabel: String?): Reader {
return getBinaryStream(columnLabel).reader()
}
override fun updateArray(columnIndex: Int, x: Array?) {
notImplemented()
}
override fun updateArray(columnLabel: String?, x: Array?) {
notImplemented()
}
override fun getBytes(columnIndex: Int): ByteArray {
return obj(columnIndex) as ByteArray
}
override fun getBytes(columnLabel: String?): ByteArray {
return obj(columnLabel) as ByteArray
}
override fun getDouble(columnIndex: Int): Double {
return obj(columnIndex) as Double
}
override fun getDouble(columnLabel: String?): Double {
return obj(columnLabel) as Double
}
override fun getUnicodeStream(columnIndex: Int): InputStream {
return getBinaryStream(columnIndex)
}
override fun getUnicodeStream(columnLabel: String?): InputStream {
return getBinaryStream(columnLabel)
}
override fun rowInserted() = false
private fun thisIsWrapperFor(iface: Class<*>?) = this.javaClass.isInstance(iface)
override fun isWrapperFor(iface: Class<*>?): Boolean {
return thisIsWrapperFor(iface) || parent.isWrapperFor(iface)
}
override fun getInt(columnIndex: Int): Int {
return obj(columnIndex) as Int
}
override fun getInt(columnLabel: String?): Int {
return obj(columnLabel) as Int
}
override fun updateNull(columnIndex: Int) {
notImplemented()
}
override fun updateNull(columnLabel: String?) {
notImplemented()
}
override fun getRowId(columnIndex: Int): RowId {
//TODO Maybe?
notImplemented()
}
override fun getRowId(columnLabel: String?): RowId {
//TODO Maybe?
notImplemented()
}
override fun getMetaData(): ResultSetMetaData {
return object : ResultSetMetaData by parentMetadata {
override fun isReadOnly(column: Int) = true
override fun isWritable(column: Int) = false
override fun isDefinitelyWritable(column: Int) = false
override fun getColumnCount() = this@ScrollableResultSet.columnCount
override fun getColumnLabel(column: Int): String {
return columnLabels[column - 1]
}
}
}
override fun getBinaryStream(columnIndex: Int): InputStream {
return (obj(columnIndex) as ByteArray).inputStream()
}
override fun getBinaryStream(columnLabel: String?): InputStream {
return (obj(columnLabel) as ByteArray).inputStream()
}
override fun updateCharacterStream(columnIndex: Int, x: Reader?, length: Int) {
notImplemented()
}
override fun updateCharacterStream(columnLabel: String?, reader: Reader?, length: Int) {
notImplemented()
}
override fun updateCharacterStream(columnIndex: Int, x: Reader?, length: Long) {
notImplemented()
}
override fun updateCharacterStream(columnLabel: String?, reader: Reader?, length: Long) {
notImplemented()
}
override fun updateCharacterStream(columnIndex: Int, x: Reader?) {
notImplemented()
}
override fun updateCharacterStream(columnLabel: String?, reader: Reader?) {
notImplemented()
}
class ResultSetEntry {
val data = mutableListOf<Any?>()
}
}