Skip to content

Commit

Permalink
sql #32: moved blocking.Eager implementation details to new Eager.k…
Browse files Browse the repository at this point in the history
…t, moved `cellByteStream` to `Blocking`
  • Loading branch information
Miha-x64 committed Mar 13, 2020
1 parent 56ae950 commit 2755d76
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 95 deletions.
101 changes: 6 additions & 95 deletions sql/src/main/kotlin/net/aquadc/persistence/sql/blocking/Blocking.kt
Expand Up @@ -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
Expand All @@ -30,6 +28,12 @@ interface Blocking<CUR : AutoCloseable> {
fun <T> cellAt(cursor: CUR, col: Int, type: DataType<T>): T
fun rowByName(cursor: CUR, columns: Array<out StoredNamedLens<*, *, *>>): Array<Any?>
fun rowByPosition(cursor: CUR, columns: Array<out StoredNamedLens<*, *, *>>): Array<Any?>

companion object {
// neither eager nor lazy… let it be just Blocking.cellByteStream()
inline fun cellByteStream(): Fetch<Blocking<ResultSet>, InputStream> =
InputStreamFromResultSet // ^^^^^^^^^ JDBC-only. Not supported by Android SQLite
}
}

object Eager {
Expand All @@ -50,99 +54,6 @@ object Eager {

inline fun <CUR : AutoCloseable, SCH : Schema<SCH>> structList(table: Table<SCH, *, *>, bindBy: BindBy): Fetch<Blocking<CUR>, List<StructSnapshot<SCH>>> =
FetchStructListEagerly(table, bindBy)

inline fun cellByteStream(): Fetch<Blocking<ResultSet>, InputStream> =
InputStreamFromResultSet // ^^^^^^^^^ JDBC-only. Not supported by Android SQLite
}

@PublishedApi internal class FetchCellEagerly<CUR : AutoCloseable, R>(
private val rt: DataType<R>
) : Fetch<Blocking<CUR>, R> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): R =
from.cell(query, argumentTypes, arguments, rt)
}

@PublishedApi internal class FetchColEagerly<CUR : AutoCloseable, R>(
private val et: DataType<R>
) : Fetch<Blocking<CUR>, List<R>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): List<R> {
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<R>(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<SCH : Schema<SCH>, CUR : AutoCloseable>(
private val table: Table<SCH, *, *>,
private val bindBy: BindBy
) : Fetch<Blocking<CUR>, StructSnapshot<SCH>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): StructSnapshot<SCH> {
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<SCH>
} finally {
cur.close()
}
}
}

@PublishedApi internal class FetchStructListEagerly<CUR : AutoCloseable, SCH : Schema<SCH>>(
private val table: Table<SCH, *, *>,
private val bindBy: BindBy
) : Fetch<Blocking<CUR>, List<StructSnapshot<SCH>>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): List<StructSnapshot<SCH>> {
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<StructSnapshot<SCH>>(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<CUR>.mapRow(cur: CUR, cols: Array<out StoredNamedLens<SCH, *, *>>, recipe: Array<out Table.Nesting>): StructSnapshot<SCH> {
val firstValues = row(cur, cols, bindBy); inflate(recipe, firstValues, 0, 0, 0)
@Suppress("UNCHECKED_CAST")
return firstValues[0] as StructSnapshot<SCH>
}
}

@PublishedApi internal object InputStreamFromResultSet : Fetch<Blocking<ResultSet>, InputStream> {
Expand Down
101 changes: 101 additions & 0 deletions 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<CUR : AutoCloseable, R>(
private val rt: DataType<R>
) : Fetch<Blocking<CUR>, R> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): R =
from.cell(query, argumentTypes, arguments, rt)
}

@PublishedApi internal class FetchColEagerly<CUR : AutoCloseable, R>(
private val et: DataType<R>
) : Fetch<Blocking<CUR>, List<R>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): List<R> {
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<R>(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<SCH : Schema<SCH>, CUR : AutoCloseable>(
private val table: Table<SCH, *, *>,
private val bindBy: BindBy
) : Fetch<Blocking<CUR>, StructSnapshot<SCH>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): StructSnapshot<SCH> {
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<SCH>
} finally {
cur.close()
}
}
}

@PublishedApi internal class FetchStructListEagerly<CUR : AutoCloseable, SCH : Schema<SCH>>(
private val table: Table<SCH, *, *>,
private val bindBy: BindBy
) : Fetch<Blocking<CUR>, List<StructSnapshot<SCH>>> {

override fun fetch(
from: Blocking<CUR>, query: String, argumentTypes: Array<out DataType.Simple<*>>, arguments: Array<out Any>
): List<StructSnapshot<SCH>> {
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<StructSnapshot<SCH>>(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<CUR>.mapRow(cur: CUR, cols: Array<out StoredNamedLens<SCH, *, *>>, recipe: Array<out Table.Nesting>): StructSnapshot<SCH> {
val firstValues = row(cur, cols, bindBy); inflate(recipe, firstValues, 0, 0, 0)
@Suppress("UNCHECKED_CAST")
return firstValues[0] as StructSnapshot<SCH>
}
}

0 comments on commit 2755d76

Please sign in to comment.