From 2755d760014c13242742f668870f61354bdcdc7a Mon Sep 17 00:00:00 2001 From: Miha_x64 Date: Fri, 13 Mar 2020 18:46:43 +0300 Subject: [PATCH] sql #32: moved `blocking.Eager` implementation details to new Eager.kt, moved `cellByteStream` to `Blocking` --- .../persistence/sql/blocking/Blocking.kt | 101 ++---------------- .../aquadc/persistence/sql/blocking/Eager.kt | 101 ++++++++++++++++++ 2 files changed, 107 insertions(+), 95 deletions(-) create mode 100644 sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Eager.kt diff --git a/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Blocking.kt b/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Blocking.kt index e2c3535a..0d25f55c 100644 --- a/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Blocking.kt +++ b/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Blocking.kt @@ -4,8 +4,6 @@ package net.aquadc.persistence.sql.blocking import net.aquadc.persistence.sql.BindBy import net.aquadc.persistence.sql.Fetch import net.aquadc.persistence.sql.Table -import net.aquadc.persistence.sql.inflate -import net.aquadc.persistence.sql.row import net.aquadc.persistence.struct.Schema import net.aquadc.persistence.struct.StoredNamedLens import net.aquadc.persistence.struct.StructSnapshot @@ -30,6 +28,12 @@ interface Blocking { fun cellAt(cursor: CUR, col: Int, type: DataType): T fun rowByName(cursor: CUR, columns: Array>): Array fun rowByPosition(cursor: CUR, columns: Array>): Array + + companion object { + // neither eager nor lazy… let it be just Blocking.cellByteStream() + inline fun cellByteStream(): Fetch, InputStream> = + InputStreamFromResultSet // ^^^^^^^^^ JDBC-only. Not supported by Android SQLite + } } object Eager { @@ -50,99 +54,6 @@ object Eager { inline fun > structList(table: Table, bindBy: BindBy): Fetch, List>> = FetchStructListEagerly(table, bindBy) - - inline fun cellByteStream(): Fetch, InputStream> = - InputStreamFromResultSet // ^^^^^^^^^ JDBC-only. Not supported by Android SQLite -} - -@PublishedApi internal class FetchCellEagerly( - private val rt: DataType -) : Fetch, R> { - - override fun fetch( - from: Blocking, query: String, argumentTypes: Array>, arguments: Array - ): R = - from.cell(query, argumentTypes, arguments, rt) -} - -@PublishedApi internal class FetchColEagerly( - private val et: DataType -) : Fetch, List> { - - override fun fetch( - from: Blocking, query: String, argumentTypes: Array>, arguments: Array - ): List { - val cur = from.select(query, argumentTypes, arguments, 1) - try { - return if (from.next(cur)) { - val first = from.cellAt(cur, 0, et) - if (from.next(cur)) { - ArrayList(from.sizeHint(cur).let { if (it < 0) 10 else it }).also { - it.add(first) - do it.add(from.cellAt(cur, 0, et)) while (from.next(cur)) - } - } else listOf(first) - } else emptyList() - } finally { - cur.close() - } - } -} - -@PublishedApi internal class FetchStructEagerly, CUR : AutoCloseable>( - private val table: Table, - private val bindBy: BindBy -) : Fetch, StructSnapshot> { - - override fun fetch( - from: Blocking, query: String, argumentTypes: Array>, arguments: Array - ): StructSnapshot { - val cur = from.select(query, argumentTypes, arguments, table.columns.size) - try { - check(from.next(cur)) - val values = from.row(cur, table.columnsMappedToFields, bindBy) - check(!from.next(cur)) // single row expected - inflate(table.recipe, values, 0, 0, 0) - @Suppress("UNCHECKED_CAST") - return values[0] as StructSnapshot - } finally { - cur.close() - } - } -} - -@PublishedApi internal class FetchStructListEagerly>( - private val table: Table, - private val bindBy: BindBy -) : Fetch, List>> { - - override fun fetch( - from: Blocking, query: String, argumentTypes: Array>, arguments: Array - ): List> { - val cols = table.columnsMappedToFields - val recipe = table.recipe - - val cur = from.select(query, argumentTypes, arguments, cols.size) - try { - return if (from.next(cur)) { - val first = from.mapRow(cur, cols, recipe) - if (from.next(cur)) { - ArrayList>(from.sizeHint(cur).let { if (it < 0) 10 else it }).also { - it.add(first) - do it.add(from.mapRow(cur, cols, recipe)) while (from.next(cur)) - } - } else listOf(first) - } else emptyList() - } finally { - cur.close() - } - } - - private fun Blocking.mapRow(cur: CUR, cols: Array>, recipe: Array): StructSnapshot { - val firstValues = row(cur, cols, bindBy); inflate(recipe, firstValues, 0, 0, 0) - @Suppress("UNCHECKED_CAST") - return firstValues[0] as StructSnapshot - } } @PublishedApi internal object InputStreamFromResultSet : Fetch, InputStream> { diff --git a/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Eager.kt b/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Eager.kt new file mode 100644 index 00000000..eccb3c14 --- /dev/null +++ b/sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Eager.kt @@ -0,0 +1,101 @@ +package net.aquadc.persistence.sql.blocking + +import net.aquadc.persistence.sql.BindBy +import net.aquadc.persistence.sql.Fetch +import net.aquadc.persistence.sql.Table +import net.aquadc.persistence.sql.inflate +import net.aquadc.persistence.sql.row +import net.aquadc.persistence.struct.Schema +import net.aquadc.persistence.struct.StoredNamedLens +import net.aquadc.persistence.struct.StructSnapshot +import net.aquadc.persistence.type.DataType + +@PublishedApi internal class FetchCellEagerly( + private val rt: DataType +) : Fetch, R> { + + override fun fetch( + from: Blocking, query: String, argumentTypes: Array>, arguments: Array + ): R = + from.cell(query, argumentTypes, arguments, rt) +} + +@PublishedApi internal class FetchColEagerly( + private val et: DataType +) : Fetch, List> { + + override fun fetch( + from: Blocking, query: String, argumentTypes: Array>, arguments: Array + ): List { + val cur = from.select(query, argumentTypes, arguments, 1) + try { + return if (from.next(cur)) { + val first = from.cellAt(cur, 0, et) + if (from.next(cur)) { + ArrayList(from.sizeHint(cur).let { if (it < 0) 10 else it }).also { + it.add(first) + do it.add(from.cellAt(cur, 0, et)) while (from.next(cur)) + } + } else listOf(first) + } else emptyList() + } finally { + cur.close() + } + } +} + +@PublishedApi internal class FetchStructEagerly, CUR : AutoCloseable>( + private val table: Table, + private val bindBy: BindBy +) : Fetch, StructSnapshot> { + + override fun fetch( + from: Blocking, query: String, argumentTypes: Array>, arguments: Array + ): StructSnapshot { + val cur = from.select(query, argumentTypes, arguments, table.columns.size) + try { + check(from.next(cur)) + val values = from.row(cur, table.columnsMappedToFields, bindBy) + check(!from.next(cur)) // single row expected + inflate(table.recipe, values, 0, 0, 0) + @Suppress("UNCHECKED_CAST") + return values[0] as StructSnapshot + } finally { + cur.close() + } + } +} + +@PublishedApi internal class FetchStructListEagerly>( + private val table: Table, + private val bindBy: BindBy +) : Fetch, List>> { + + override fun fetch( + from: Blocking, query: String, argumentTypes: Array>, arguments: Array + ): List> { + val cols = table.columnsMappedToFields + val recipe = table.recipe + + val cur = from.select(query, argumentTypes, arguments, cols.size) + try { + return if (from.next(cur)) { + val first = from.mapRow(cur, cols, recipe) + if (from.next(cur)) { + ArrayList>(from.sizeHint(cur).let { if (it < 0) 10 else it }).also { + it.add(first) + do it.add(from.mapRow(cur, cols, recipe)) while (from.next(cur)) + } + } else listOf(first) + } else emptyList() + } finally { + cur.close() + } + } + + private fun Blocking.mapRow(cur: CUR, cols: Array>, recipe: Array): StructSnapshot { + val firstValues = row(cur, cols, bindBy); inflate(recipe, firstValues, 0, 0, 0) + @Suppress("UNCHECKED_CAST") + return firstValues[0] as StructSnapshot + } +}