com.dbobjekts.statement.customsql.CustomSQLStatementBuilder.kt Maven / Gradle / Ivy
package com.dbobjekts.statement.customsql
import com.dbobjekts.api.*
import com.dbobjekts.jdbc.ConnectionAdapter
import com.dbobjekts.metadata.ColumnFactory
import com.dbobjekts.metadata.column.Column
import com.dbobjekts.metadata.column.NonNullableColumn
import com.dbobjekts.metadata.column.NullableColumn
import com.dbobjekts.statement.Semaphore
import com.dbobjekts.util.StatementLogger
import java.math.BigDecimal
import java.sql.Blob
import java.sql.Clob
import java.time.*
class CustomSQLStatementBuilder(
private val semaphore: Semaphore,
private val conn: ConnectionAdapter,
private val sql: String,
private val args: List,
private val statementLog: StatementLogger
) {
fun execute(): Long = SQLStatementExecutor>(semaphore, conn, sql, args.toList()).execute()
fun withResultTypes() = CustomSQLSelectStatementBuilder(semaphore, conn, sql, args)
}
class CustomSQLSelectStatementBuilder(
private val semaphore: Semaphore,
private val conn: ConnectionAdapter,
private val sql: String,
private val args: List
) {
fun > custom(clz: Class): Returns1 = Returns1(ColumnFactory.forClass(clz), semaphore, conn, sql, args)
fun > customNil(clz: Class): Returns1 = Returns1(ColumnFactory.forClassAsNullable(clz), semaphore, conn, sql, args)
fun string(): Returns1 = Returns1(ColumnFactory.VARCHAR, semaphore, conn, sql, args)
fun stringNil(): Returns1 = Returns1(ColumnFactory.VARCHAR_NIL, semaphore, conn, sql, args)
fun long(): Returns1 = Returns1(ColumnFactory.LONG, semaphore, conn, sql, args)
fun longNil(): Returns1 = Returns1(ColumnFactory.LONG_NIL, semaphore, conn, sql, args)
fun int(): Returns1 = Returns1(ColumnFactory.INTEGER, semaphore, conn, sql, args)
fun intNil(): Returns1 = Returns1(ColumnFactory.INTEGER_NIL, semaphore, conn, sql, args)
fun byteArray(): Returns1 = Returns1(ColumnFactory.BYTE_ARRAY, semaphore, conn, sql, args)
fun byteArrayNil(): Returns1 = Returns1(ColumnFactory.BYTE_ARRAY_NIL, semaphore, conn, sql, args)
fun blob(): Returns1 = Returns1(ColumnFactory.BLOB, semaphore, conn, sql, args)
fun blobNil(): Returns1 = Returns1(ColumnFactory.BLOB_NIL, semaphore, conn, sql, args)
fun clob(): Returns1 = Returns1(ColumnFactory.CLOB, semaphore, conn, sql, args)
fun clobNil(): Returns1 = Returns1(ColumnFactory.CLOB_NIL, semaphore, conn, sql, args)
fun byte(): Returns1 = Returns1(ColumnFactory.BYTE, semaphore, conn, sql, args)
fun byteNil(): Returns1 = Returns1(ColumnFactory.BYTE_NIL, semaphore, conn, sql, args)
fun boolean(): Returns1 = Returns1(ColumnFactory.BOOLEAN, semaphore, conn, sql, args)
fun booleanNil(): Returns1 = Returns1(ColumnFactory.BOOLEAN_NIL, semaphore, conn, sql, args)
fun double(): Returns1 = Returns1(ColumnFactory.DOUBLE, semaphore, conn, sql, args)
fun doubleNil(): Returns1 = Returns1(ColumnFactory.DOUBLE_NIL, semaphore, conn, sql, args)
fun float(): Returns1 = Returns1(ColumnFactory.FLOAT, semaphore, conn, sql, args)
fun floatNil(): Returns1 = Returns1(ColumnFactory.FLOAT_NIL, semaphore, conn, sql, args)
fun bigDecimal(): Returns1 = Returns1(ColumnFactory.BIGDECIMAL, semaphore, conn, sql, args)
fun bigDecimalNil(): Returns1 = Returns1(ColumnFactory.BIGDECIMAL_NIL, semaphore, conn, sql, args)
fun date(): Returns1 = Returns1(ColumnFactory.DATE, semaphore, conn, sql, args)
fun dateNil(): Returns1 = Returns1(ColumnFactory.DATE_NIL, semaphore, conn, sql, args)
fun dateTime(): Returns1 = Returns1(ColumnFactory.DATETIME, semaphore, conn, sql, args)
fun dateTimeNil(): Returns1 = Returns1(ColumnFactory.DATETIME_NIL, semaphore, conn, sql, args)
fun time(): Returns1 = Returns1(ColumnFactory.TIME, semaphore, conn, sql, args)
fun timeNil(): Returns1 = Returns1(ColumnFactory.TIME_NIL, semaphore, conn, sql, args)
fun timeStamp(): Returns1 = Returns1(ColumnFactory.TIMESTAMP, semaphore, conn, sql, args)
fun timeStampNil(): Returns1 = Returns1(ColumnFactory.TIMESTAMP_NIL, semaphore, conn, sql, args)
fun offsetDateTime(): Returns1 = Returns1(ColumnFactory.OFFSET_DATETIME, semaphore, conn, sql, args)
fun offsetDateTimeNil(): Returns1 = Returns1(ColumnFactory.OFFSET_DATETIME_NIL, semaphore, conn, sql, args)
}
class Returns1(
internal val column1: Column,
private val semaphore: Semaphore, private val conn: ConnectionAdapter,
private val sql: String,
private val args: List
) {
/**
* Adds a custom non-nullable Column type as the next column in the result row.
* @param clz a subclass of NonNullableColumn<*>
*/
fun > custom(clz: Class): Returns2 = Returns2(column1, ColumnFactory.forClass(clz), semaphore, conn, sql, args)
/**
* Adds a custom nullable Column type as the next column in the result row.
* @param clz a subclass of NullableColumn<*>
*/
fun > customNil(clz: Class): Returns2 = Returns2(column1, ColumnFactory.forClassAsNullable(clz), semaphore, conn, sql, args)
/**
* Adds a String type as the next column in the result row
*/
fun string(): Returns2 = Returns2(column1, ColumnFactory.VARCHAR, semaphore, conn, sql, args)
/**
* Adds a String? type as the next column in the result row
*/
fun stringNil(): Returns2 = Returns2(column1, ColumnFactory.VARCHAR_NIL, semaphore, conn, sql, args)
/**
* Adds a Long type as the next column in the result row
*/
fun long(): Returns2 = Returns2(column1, ColumnFactory.LONG, semaphore, conn, sql, args)
/**
* Adds a Long? type as the next column in the result row
*/
fun longNil(): Returns2 = Returns2(column1, ColumnFactory.LONG_NIL, semaphore, conn, sql, args)
/**
* Adds a Int type as the next column in the result row
*/
fun int(): Returns2 = Returns2(column1, ColumnFactory.INTEGER, semaphore, conn, sql, args)
/**
* Adds a Int? type as the next column in the result row
*/
fun intNil(): Returns2 = Returns2(column1, ColumnFactory.INTEGER_NIL, semaphore, conn, sql, args)
/**
* Adds a ByteArray type as the next column in the result row
*/
fun byteArray(): Returns2 = Returns2(column1, ColumnFactory.BYTE_ARRAY, semaphore, conn, sql, args)
/**
* Adds a ByteArray? type as the next column in the result row
*/
fun byteArrayNil(): Returns2 = Returns2(column1, ColumnFactory.BYTE_ARRAY_NIL, semaphore, conn, sql, args)
/**
* Adds a [java.sql.Blob] type as the next column in the result row
*/
fun blob(): Returns2 = Returns2(column1, ColumnFactory.BLOB, semaphore, conn, sql, args)
/**
* Adds a [java.sql.Blob]? type as the next column in the result row
*/
fun blobNil(): Returns2 = Returns2(column1, ColumnFactory.BLOB_NIL, semaphore, conn, sql, args)
/**
* Adds a [java.sql.Clob] type as the next column in the result row
*/
fun clob(): Returns2 = Returns2(column1, ColumnFactory.CLOB, semaphore, conn, sql, args)
/**
* Adds a [java.sql.Clob]? type as the next column in the result row
*/
fun clobNil(): Returns2 = Returns2(column1, ColumnFactory.CLOB_NIL, semaphore, conn, sql, args)
/**
* Adds a Byte type as the next column in the result row
*/
fun byte(): Returns2 = Returns2(column1, ColumnFactory.BYTE, semaphore, conn, sql, args)
/**
* Adds a Byte? type as the next column in the result row
*/
fun byteNil(): Returns2 = Returns2(column1, ColumnFactory.BYTE_NIL, semaphore, conn, sql, args)
/**
* Adds a Boolean type as the next column in the result row
*/
fun boolean(): Returns2 = Returns2(column1, ColumnFactory.BOOLEAN, semaphore, conn, sql, args)
/**
* Adds a Boolean? type as the next column in the result row
*/
fun booleanNil(): Returns2 = Returns2(column1, ColumnFactory.BOOLEAN_NIL, semaphore, conn, sql, args)
/**
* Adds a Double type as the next column in the result row
*/
fun double(): Returns2 = Returns2(column1, ColumnFactory.DOUBLE, semaphore, conn, sql, args)
/**
* Adds a Double? type as the next column in the result row
*/
fun doubleNil(): Returns2 = Returns2(column1, ColumnFactory.DOUBLE_NIL, semaphore, conn, sql, args)
/**
* Adds a Float type as the next column in the result row
*/
fun float(): Returns2 = Returns2(column1, ColumnFactory.FLOAT, semaphore, conn, sql, args)
/**
* Adds a Float? type as the next column in the result row
*/
fun floatNil(): Returns2 = Returns2(column1, ColumnFactory.FLOAT_NIL, semaphore, conn, sql, args)
/**
* Adds a BigDecimal type as the next column in the result row
*/
fun bigDecimal(): Returns2 = Returns2(column1, ColumnFactory.BIGDECIMAL, semaphore, conn, sql, args)
/**
* Adds a BigDecimal? type as the next column in the result row
*/
fun bigDecimalNil(): Returns2 = Returns2(column1, ColumnFactory.BIGDECIMAL_NIL, semaphore, conn, sql, args)
/**
* Adds a [LocalDate] type as the next column in the result row
*/
fun date(): Returns2 = Returns2(column1, ColumnFactory.DATE, semaphore, conn, sql, args)
/**
* Adds a [LocalDate]? type as the next column in the result row
*/
fun dateNil(): Returns2 = Returns2(column1, ColumnFactory.DATE_NIL, semaphore, conn, sql, args)
/**
* Adds a [LocalDateTime] type as the next column in the result row
*/
fun dateTime(): Returns2 = Returns2(column1, ColumnFactory.DATETIME, semaphore, conn, sql, args)
/**
* Adds a [LocalDateTime]? type as the next column in the result row
*/
fun dateTimeNil(): Returns2 = Returns2(column1, ColumnFactory.DATETIME_NIL, semaphore, conn, sql, args)
/**
* Adds a [LocalTime] type as the next column in the result row
*/
fun time(): Returns2 = Returns2(column1, ColumnFactory.TIME, semaphore, conn, sql, args)
/**
* Adds a [LocalTime]? type as the next column in the result row
*/
fun timeNil(): Returns2 = Returns2(column1, ColumnFactory.TIME_NIL, semaphore, conn, sql, args)
/**
* Adds a [Instant] type as the next column in the result row
*/
fun timeStamp(): Returns2 = Returns2(column1, ColumnFactory.TIMESTAMP, semaphore, conn, sql, args)
/**
* Adds a Instant? type as the next column in the result row
*/
fun timeStampNil(): Returns2 = Returns2(column1, ColumnFactory.TIMESTAMP_NIL, semaphore, conn, sql, args)
/**
* Adds a [OffsetDateTime] type as the next column in the result row
*/
fun offsetDateTime(): Returns2 = Returns2(column1, ColumnFactory.OFFSET_DATETIME, semaphore, conn, sql, args)
/**
* Adds a [OffsetDateTime]? type as the next column in the result row
*/
fun offsetDateTimeNil(): Returns2 =
Returns2(column1, ColumnFactory.OFFSET_DATETIME_NIL, semaphore, conn, sql, args)
private fun execute() = SQLStatementExecutor(semaphore, conn, sql, args.toList(), listOf(column1), ResultRow1())
/**
* Executes the select statement, fetches all rows and returns them as a list of tuples
*/
fun asList() = execute().asList()
/**
* Executes the statement, fetches all rows and returns the first result.
* @throws IllegalStateException if there are no results. To prevent this, use [firstOrNull]
*/
fun first() = execute().first()
/**
* Executes the select statement, fetches all rows and returns the first result, or null if there is no match.
* For better performance, use this only when you expect a single result, or use the [limit] clause in addition.
*/
fun firstOrNull() = execute().firstOrNull()
/**
* Executes the query and lets you step through the results with a custom function that receives the current row data
* and returns a Boolean to indicate whether to proceed or not. Example:
* ```kotlin
* transaction.select("query").forEachRow({ row ->
* buffer.add(row)
* !buffer.memoryFull()
* })
* ```
*
* This can be useful for huge result sets that would run into memory problems when fetched at once into a list.
*/
fun forEachRow(mapper: (Int, T1) -> Boolean) {
semaphore.clear()
return execute().forEachRow(mapper)
}
/**
* Returns a [ResultSetIterator], which implements [Iterator].
*
* This delegates to the underlying [ResultSet] for each call to `next()`, which makes it more memory-efficient for very large data sets by not loading all rows into a single list.
*
* WARNING: You cannot return a [ResultSetIterator] from a transaction block, as the underlying [Connection] has been already closed.
*
* ```kotlin
* // this will fail at runtime
* val iterator = tm { it.select(Employee).iterator() }
* ```
*/
fun iterator(): ResultSetIterator> = execute().iterator()
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy