Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* This is free and unencumbered software released into the public domain, following
*/
package org.ufoss.kotysa
import org.ufoss.kotysa.columns.AbstractColumn
import java.math.BigDecimal
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.reflect.KClass
@Suppress("UNCHECKED_CAST")
public fun Tables.getTable(table: Table): KotysaTable =
requireNotNull(this.allTables[table]) { "Requested table \"$table\" is not mapped" } as KotysaTable
@Suppress("UNCHECKED_CAST")
public fun Tables.getTable(tableClass: KClass): KotysaTable =
requireNotNull(this.allTables.values.first { kotysaTable -> kotysaTable.tableClass == tableClass }) as KotysaTable
public fun DefaultSqlClientCommon.Properties.dbValues(): List = with(this) {
parameters
.map { value ->
when (value) {
null -> null
is Set<*> ->
// create new Set with transformed values
mutableSetOf().apply {
value.forEach { dbVal ->
add(tables.getDbValue(dbVal))
}
}
else -> tables.getDbValue(value)
}
}
}
@Suppress("UNCHECKED_CAST")
public operator fun > V.get(alias: String): V =
(this as AbstractColumn).clone().apply { (this as AbstractColumn).alias = alias } as V
@Suppress("UNCHECKED_CAST")
public operator fun > U.get(alias: String): U {
// set tableAlias on all columns
(this as AbstractTable).kotysaColumns.forEach { column -> column.tableAlias = alias }
return this
}
@Suppress("UNCHECKED_CAST")
internal fun Table.getKotysaTable(availableTables: Map
, KotysaTable<*>>): KotysaTable {
return requireNotNull(availableTables[this]) { "Requested table \"$this\" is not mapped" } as KotysaTable
}
@Suppress("UNCHECKED_CAST")
internal fun Column.getKotysaColumn(
availableColumns: Map, KotysaColumn<*, *>>
): KotysaColumn {
return requireNotNull(availableColumns[this]) { "Requested column \"$this\" is not mapped" } as KotysaColumn
}
internal fun Column.toField(
properties: DefaultSqlClientCommon.Properties,
classifier: FieldClassifier,
): ColumnField = ColumnField(properties, this, classifier)
public fun AbstractTable.toField(
availableColumns: Map, KotysaColumn<*, *>>,
availableTables: Map
, KotysaTable<*>>,
dbType: DbType,
): Field =
TableField(availableColumns, availableTables, this, dbType)
internal fun Field<*>.getFieldName(dbType: DbType): String {
var fieldName = fieldNames.joinToString()
if (alias != null) {
val aliasPart = when (dbType) {
DbType.MSSQL, DbType.POSTGRESQL -> " AS $alias"
else -> " AS `$alias`"
}
fieldName += aliasPart
}
return fieldName
}
internal fun Column<*, *>.getFieldName(
availableColumns: Map, KotysaColumn<*, *>>,
dbType: DbType,
): String {
if ((this as AbstractColumn<*, *>).alias != null) {
return when (dbType) {
DbType.MSSQL, DbType.POSTGRESQL -> alias!!
else -> "`${alias!!}`"
}
}
val kotysaColumn = getKotysaColumn(availableColumns)
val tablePart = if (tableAlias != null) {
tableAlias!!
} else {
kotysaColumn.table.name
}
return "$tablePart.${kotysaColumn.name}"
}
internal fun Table<*>.getFieldName(availableTables: Map
, KotysaTable<*>>) =
getKotysaTable(availableTables).name
@Suppress("UNCHECKED_CAST")
internal fun DefaultSqlClientCommon.Properties.executeSubQuery(
dsl: SqlClientSubQuery.Scope.() -> SqlClientSubQuery.Return,
): SubQueryResult {
val subQuery = SqlClientSubQueryImpl.Scope(this)
// invoke sub-query
val result = dsl(subQuery)
// add all sub-query parameters, if any, to parent's properties
if (subQuery.properties.parameters.isNotEmpty()) {
parameters.addAll(subQuery.properties.parameters)
}
// update parent's properties with index value
index = subQuery.properties.index
return SubQueryResult(subQuery.properties as DefaultSqlClientSelect.Properties, result)
}
internal fun Any?.dbValue(dbType: DbType): String = when (this) {
null -> "null"
is String, is UUID, is Int, is Long, is Float, is Double, is BigDecimal -> "$this"
is Boolean -> when (dbType) {
DbType.SQLITE, DbType.MSSQL -> if (this) "1" else "0"
else -> "$this"
}
is LocalDate -> this.format(DateTimeFormatter.ISO_LOCAL_DATE)
is LocalDateTime -> this.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
is LocalTime -> this.format(DateTimeFormatter.ISO_LOCAL_TIME)
is OffsetDateTime -> this.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
else -> when (this::class.qualifiedName) {
"kotlinx.datetime.LocalDate", "kotlinx.datetime.LocalTime" -> this.toString()
"kotlinx.datetime.LocalDateTime" -> {
val kotlinxLocalDateTime = this as kotlinx.datetime.LocalDateTime
if (kotlinxLocalDateTime.second == 0 && kotlinxLocalDateTime.nanosecond == 0) {
"$kotlinxLocalDateTime:00" // missing seconds
} else {
kotlinxLocalDateTime.toString()
}
}
else -> throw RuntimeException("${this.javaClass.canonicalName} is not supported yet")
}
}
internal fun Any?.defaultValue(dbType: DbType): String = when (this) {
is Boolean -> if (DbType.SQLITE == dbType) {
if (this) "'1'" else "'0'"
} else {
this.dbValue(dbType)
}
is Int -> "$this"
is Long -> "$this"
else -> "'${this.dbValue(dbType)}'"
}
internal fun DefaultSqlClientCommon.Properties.variable() = when {
module == Module.SQLITE || module == Module.JDBC
|| (module == Module.R2DBC && tables.dbType == DbType.MYSQL)
|| (module == Module.VERTX_SQL_CLIENT && (tables.dbType == DbType.MYSQL || tables.dbType == DbType.MARIADB))
-> "?"
module.isR2dbcOrVertxSqlClient() && (tables.dbType == DbType.H2 || tables.dbType == DbType.POSTGRESQL)
-> "$${++index}"
module.isR2dbcOrVertxSqlClient() && tables.dbType == DbType.MSSQL -> "@p${++index}"
else -> ":k${index++}"
}
@Suppress("UNCHECKED_CAST")
internal fun > V.getOrClone(
availableColumns: Map, KotysaColumn<*, *>>,
): V =
if ((this as AbstractColumn<*, *>).tableAlias != null) {
// make a clone to keep its tableAlias
val clonedColumn = this.clone() as V
val kotysaColumn = getKotysaColumn(availableColumns)
// remove tableAlias on all columns
(kotysaColumn.table.table as AbstractTable<*>).kotysaColumns.forEach { tableColumn ->
tableColumn.tableAlias = null
}
clonedColumn
} else {
this
}