Coverage Summary for Class: CommonUtilKt (com.kotlinorm.utils)
Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
CommonUtilKt |
100%
(9/9)
|
63.2%
(24/38)
|
90.6%
(48/53)
|
81.8%
(229/280)
|
CommonUtilKt$WhenMappings |
|
Total |
100%
(9/9)
|
63.2%
(24/38)
|
90.6%
(48/53)
|
81.8%
(229/280)
|
/**
* Copyright 2022-2025 kronos-orm
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.kotlinorm.utils
import com.kotlinorm.Kronos.defaultDateFormat
import com.kotlinorm.Kronos.serializeProcessor
import com.kotlinorm.Kronos.strictSetValue
import com.kotlinorm.beans.config.KronosCommonStrategy
import com.kotlinorm.beans.dsl.Field
import com.kotlinorm.beans.transformers.TransformerManager.getValueTransformed
import com.kotlinorm.enums.DBType
import com.kotlinorm.enums.KColumnType
import com.kotlinorm.interfaces.KPojo
import com.kotlinorm.interfaces.KronosDataSourceWrapper
import com.kotlinorm.utils.DateTimeUtil.currentDateTime
import kotlin.reflect.KClass
/**
*@program: kronos-orm
*@author: Jieyao Lu
*@description:
*@create: 2024/5/7 16:01
**/
fun KronosCommonStrategy.execute(
timeStrategy: Boolean = false,
defaultValue: Any = 0,
afterExecute: KronosCommonStrategy.(field: Field, value: Any?) -> Unit
) {
if (timeStrategy) {
val format = field.dateFormat ?: defaultDateFormat
afterExecute(field, currentDateTime(format))
} else {
afterExecute(field, defaultValue)
}
}
fun <T> Collection<T>.toLinkedSet(): LinkedHashSet<T> = linkedSetOf<T>().apply { addAll(this@toLinkedSet) }
/**
* Converts a given value to a type-safe value based on the provided Kotlin type.
*
* @param kotlinType The target Kotlin type to convert the value to.
* @param value The value to be converted.
* @param superTypes A list of super types for the value's class.
* @param dateTimeFormat An optional date-time format to use for date-time conversions.
* @param kClassOfVal The KClass of the value.
* @return The converted value, or null if the conversion is not possible.
*/
fun getTypeSafeValue(
kotlinType: String,
value: Any,
superTypes: List<String> = listOf(),
dateTimeFormat: String? = null,
kClassOfVal: KClass<*> = value::class
): Any = getValueTransformed(
kotlinType,
value,
superTypes,
dateTimeFormat,
kClassOfVal
)
/**
* getSafeValue
* 1.类型转换 Any->String,Long->Int, Short->Int, Int->Short, Int->Boolean...
*
* 2.日期转换 String->Date, Long->Date, String-> LocalDateTime, Long->LocalDateTime
*
* 3.将String使用serialize resolver转为指定类型
*
* 4.若columnLabel在map中的值为null,尝试查找columnName在map中的值存入KPojo
*
* @param kPojo
* @param kClass
* @param superTypes
* @param map
* @param key
* @param serializable
* @return
*/
@Suppress("UNUSED")
fun getSafeValue(
kPojo: KPojo,
kClass: KClass<*>,
superTypes: List<String>,
map: Map<String, Any?>,
key: String,
serializable: Boolean
): Any? {
if (strictSetValue) {
return map[key]
}
return map[key]?.let { value ->
val kClassOfVal = value::class
if (kClass != kClassOfVal) {
if (serializable) {
serializeProcessor.deserialize(
value.toString(), kClass
)
} else {
val column = kPojo.kronosColumns().find { it.name == key }!!
getTypeSafeValue(
kClass.qualifiedName!!,
value,
superTypes,
column.dateFormat,
kClassOfVal
)
}
} else {
value
}
}
}
fun String.trimWhitespace(): String {
return replace("\\s+".toRegex(), " ").trim()
}
/**
* Extracts numbers enclosed in parentheses from the input string.
*
* The function looks for patterns in the format `(number[,number])` where:
* - `number` is one or more digits.
* - The second number (after a comma) is optional.
*
* @param input The input string to search for the pattern.
* @return A `Pair` of integers:
* - The first integer corresponds to the first number inside the parentheses.
* - The second integer corresponds to the second number inside the parentheses, or 0 if it is not present.
* - If no match is found, returns `(0, 0)`.
*/
fun extractNumberInParentheses(input: String): Pair<Int, Int> {
val regex = Regex("""\s*\(\s*(\d+)\s*(?:,\s*(\d+)\s*)?\)\s*""") // Regular expression to match the pattern.
val matchResult = regex.find(input) // Finds the first match in the input string.
if (matchResult != null) {
val (length, scale) = matchResult.destructured // Extracts matched groups.
return Pair(length.toInt(), scale.toIntOrNull() ?: 0) // Converts to integers and handles optional second number.
}
return Pair(0, 0) // Returns default values if no match is found.
}
private fun Field.isTimestampOrPostgresDatetime(wrapper: KronosDataSourceWrapper): Boolean {
return type == KColumnType.TIMESTAMP ||
(wrapper.dbType == DBType.Postgres && type == KColumnType.DATETIME)
}
fun processParams(
wrapper: KronosDataSourceWrapper,
field: Field,
value: Any?
): Any? {
if (value == null) return null
if (field.serializable) return serializeProcessor.serialize(value)
return when {
field.isTimestampOrPostgresDatetime(wrapper) ->
getTypeSafeValue("java.sql.Timestamp", value, field.superTypes, field.dateFormat)
wrapper.dbType == DBType.Postgres && field.type == KColumnType.BIT ->
getTypeSafeValue("kotlin.Boolean", value, field.superTypes, field.dateFormat)
else -> value
}
}
fun getDefaultBoolean(
wrapper: KronosDataSourceWrapper,
boolean: Boolean
): Any {
return when (wrapper.dbType) {
DBType.Postgres -> boolean
else -> {
if (boolean) 1 else 0
}
}
}