<commit_before>package com.firefly.kotlin.ext.db

import com.firefly.db.RecordNotFound
import com.firefly.db.SQLConnection
import com.firefly.db.SQLResultSet
import com.firefly.kotlin.ext.log.KtLogger
import com.firefly.utils.function.Func1
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.future.await
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import java.util.concurrent.TimeUnit

/**
 * @author <NAME>
 */

val sysLogger = KtLogger.getLogger("firefly-system")


// query for single column
suspend fun <T> SQLConnection.asyncQueryForSingleColumn(sql: String, vararg params: Any): T =
    this.queryForSingleColumn<T>(sql, *params).await()

suspend fun <T> SQLConnection.asyncNamedQueryForSingleColumn(sql: String, paramMap: Map<String, Any>): T =
    this.namedQueryForSingleColumn<T>(sql, paramMap).await()

suspend fun <T> SQLConnection.asyncNamedQueryForSingleColumn(sql: String, paramObject: Any): T =
    this.namedQueryForSingleColumn<T>(sql, paramObject).await()


// query for object
suspend inline fun <reified T> SQLConnection.asyncQueryForObject(sql: String, vararg params: Any): T =
    this.queryForObject<T>(sql, T::class.java, *params).await()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForObject(sql: String, paramMap: Map<String, Any>): T =
    this.namedQueryForObject(sql, T::class.java, paramMap).await()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForObject(sql: String, paramObject: Any): T =
    this.namedQueryForObject(sql, T::class.java, paramObject).await()


// query by id
suspend inline fun <reified T> SQLConnection.asyncQueryById(id: Any): T = this.queryById(id, T::class.java).await()


// query for bean map
suspend inline fun <K, reified V> SQLConnection.asyncQueryForBeanMap(sql: String, vararg params: Any): Map<K, V> =
    this.queryForBeanMap<K, V>(sql, V::class.java, *params).await() ?: mapOf()

suspend inline fun <K, reified V> SQLConnection.asyncNamedQueryForBeanMap(
    sql: String,
    paramMap: Map<String, Any>
                                                                         ): Map<K, V> =
    this.namedQueryForBeanMap<K, V>(sql, V::class.java, paramMap).await() ?: mapOf()

suspend inline fun <K, reified V> SQLConnection.asyncNamedQueryForBeanMap(sql: String, paramObject: Any): Map<K, V> =
    this.namedQueryForBeanMap<K, V>(sql, V::class.java, paramObject).await() ?: mapOf()


// query for list
suspend inline fun <reified T> SQLConnection.asyncQueryForList(sql: String, vararg params: Any): List<T> =
    this.queryForList<T>(sql, T::class.java, *params).await() ?: listOf()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForList(sql: String, paramMap: Map<String, Any>): List<T> =
    this.namedQueryForList(sql, T::class.java, paramMap).await() ?: listOf()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForList(sql: String, paramObject: Any): List<T> =
    this.namedQueryForList(sql, T::class.java, paramObject).await() ?: listOf()


// query
suspend fun <T> SQLConnection.asyncQuery(sql: String, rsh: (rs: SQLResultSet) -> T, vararg params: Any): T =
    this.query(sql, Func1<SQLResultSet, T> { rsh.invoke(it) }, *params).await()

suspend fun <T> SQLConnection.asyncNamedQuery(
    sql: String,
    rsh: (rs: SQLResultSet) -> T,
    paramMap: Map<String, Any>
                                             ): T =
    this.namedQuery(sql, { rsh.invoke(it) }, paramMap).await()

suspend fun <T> SQLConnection.asyncNamedQuery(sql: String, rsh: (rs: SQLResultSet) -> T, paramObject: Any): T =
    this.namedQuery(sql, { rsh.invoke(it) }, paramObject).await()


// update
suspend fun SQLConnection.asyncUpdate(sql: String, vararg params: Any): Int {
    return this.update(sql, *params).await() ?: 0
}

suspend fun SQLConnection.asyncNamedUpdate(sql: String, paramMap: Map<String, Any>): Int =
    this.namedUpdate(sql, paramMap).await() ?: 0

suspend fun SQLConnection.asyncNamedUpdate(sql: String, paramObject: Any): Int =
    this.namedUpdate(sql, paramObject).await() ?: 0


// update mapped object
suspend fun <T> SQLConnection.asyncUpdateObject(obj: T): Int {
    return this.updateObject(obj).await() ?: 0
}


// insert
suspend fun <R> SQLConnection.asyncInsert(sql: String, vararg params: Any): R = this.insert<R>(sql, *params).await()

suspend fun <R> SQLConnection.asyncNamedInsert(sql: String, paramMap: Map<String, Any>): R =
    this.namedInsert<R>(sql, paramMap).await()

suspend fun <R> SQLConnection.asyncNamedInsert(sql: String, paramObject: Any): R =
    this.namedInsert<R>(sql, paramObject).await()

suspend fun <T, R> SQLConnection.asyncInsertObject(obj: T): R = this.insertObject<T, R>(obj).await()

suspend inline fun <reified T, R> SQLConnection.asyncInsertObjectBatch(list: List<T>, rsh: Func1<SQLResultSet, R?>): R =
    this.insertObjectBatch<T, R>(list, T::class.java, rsh).await()

suspend inline fun <reified T, R> SQLConnection.asyncInsertObjectBatch(list: List<T>): List<R> =
    this.insertObjectBatch<T, R>(list, T::class.java).await() ?: listOf()


// delete
suspend inline fun <reified T> SQLConnection.asyncDeleteById(id: Any): Int =
    this.deleteById(id, T::class.java).await() ?: 0


suspend fun <T> SQLConnection.execSQL(
    time: Long = 10000L, unit: TimeUnit = TimeUnit.MILLISECONDS,
    handler: suspend (conn: SQLConnection) -> T
                                     ): T {
    beginTransaction().await()
    return try {
        val ret = withTimeout(unit.toMillis(time)) { handler.invoke(this@execSQL) }
        commitAndEndTransaction().await()
        ret
    } catch (e: RecordNotFound) {
        sysLogger.warn("execute SQL exception. record not found", e)
        commitAndEndTransaction().await()
        throw e
    } catch (e: TimeoutCancellationException) {
        sysLogger.error("execute SQL exception. timeout", e)
        rollbackAndEndTransaction().await()
        throw e
    } catch (e: Exception) {
        sysLogger.error("execute SQL exception", e)
        rollbackAndEndTransaction().await()
        throw e
    }
}

suspend fun <T : SQLConnection, R> T.safeUse(block: suspend (T) -> R): R {
    try {
        return block(this)
    } finally {
        withContext(NonCancellable) {
            close().await()
        }
    }
}<commit_msg>[fix]: dirty commit state on close()<commit_after>package com.firefly.kotlin.ext.db

import com.firefly.db.RecordNotFound
import com.firefly.db.SQLConnection
import com.firefly.db.SQLResultSet
import com.firefly.kotlin.ext.log.KtLogger
import com.firefly.utils.function.Func1
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.future.await
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeout
import java.util.concurrent.TimeUnit

/**
 * @author <NAME>
 */

val sysLogger = KtLogger.getLogger("firefly-system")


// query for single column
suspend fun <T> SQLConnection.asyncQueryForSingleColumn(sql: String, vararg params: Any): T =
    this.queryForSingleColumn<T>(sql, *params).await()

suspend fun <T> SQLConnection.asyncNamedQueryForSingleColumn(sql: String, paramMap: Map<String, Any>): T =
    this.namedQueryForSingleColumn<T>(sql, paramMap).await()

suspend fun <T> SQLConnection.asyncNamedQueryForSingleColumn(sql: String, paramObject: Any): T =
    this.namedQueryForSingleColumn<T>(sql, paramObject).await()


// query for object
suspend inline fun <reified T> SQLConnection.asyncQueryForObject(sql: String, vararg params: Any): T =
    this.queryForObject<T>(sql, T::class.java, *params).await()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForObject(sql: String, paramMap: Map<String, Any>): T =
    this.namedQueryForObject(sql, T::class.java, paramMap).await()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForObject(sql: String, paramObject: Any): T =
    this.namedQueryForObject(sql, T::class.java, paramObject).await()


// query by id
suspend inline fun <reified T> SQLConnection.asyncQueryById(id: Any): T = this.queryById(id, T::class.java).await()


// query for bean map
suspend inline fun <K, reified V> SQLConnection.asyncQueryForBeanMap(sql: String, vararg params: Any): Map<K, V> =
    this.queryForBeanMap<K, V>(sql, V::class.java, *params).await() ?: mapOf()

suspend inline fun <K, reified V> SQLConnection.asyncNamedQueryForBeanMap(
    sql: String,
    paramMap: Map<String, Any>
                                                                         ): Map<K, V> =
    this.namedQueryForBeanMap<K, V>(sql, V::class.java, paramMap).await() ?: mapOf()

suspend inline fun <K, reified V> SQLConnection.asyncNamedQueryForBeanMap(sql: String, paramObject: Any): Map<K, V> =
    this.namedQueryForBeanMap<K, V>(sql, V::class.java, paramObject).await() ?: mapOf()


// query for list
suspend inline fun <reified T> SQLConnection.asyncQueryForList(sql: String, vararg params: Any): List<T> =
    this.queryForList<T>(sql, T::class.java, *params).await() ?: listOf()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForList(sql: String, paramMap: Map<String, Any>): List<T> =
    this.namedQueryForList(sql, T::class.java, paramMap).await() ?: listOf()

suspend inline fun <reified T> SQLConnection.asyncNamedQueryForList(sql: String, paramObject: Any): List<T> =
    this.namedQueryForList(sql, T::class.java, paramObject).await() ?: listOf()


// query
suspend fun <T> SQLConnection.asyncQuery(sql: String, rsh: (rs: SQLResultSet) -> T, vararg params: Any): T =
    this.query(sql, Func1<SQLResultSet, T> { rsh.invoke(it) }, *params).await()

suspend fun <T> SQLConnection.asyncNamedQuery(
    sql: String,
    rsh: (rs: SQLResultSet) -> T,
    paramMap: Map<String, Any>
                                             ): T =
    this.namedQuery(sql, { rsh.invoke(it) }, paramMap).await()

suspend fun <T> SQLConnection.asyncNamedQuery(sql: String, rsh: (rs: SQLResultSet) -> T, paramObject: Any): T =
    this.namedQuery(sql, { rsh.invoke(it) }, paramObject).await()


// update
suspend fun SQLConnection.asyncUpdate(sql: String, vararg params: Any): Int {
    return this.update(sql, *params).await() ?: 0
}

suspend fun SQLConnection.asyncNamedUpdate(sql: String, paramMap: Map<String, Any>): Int =
    this.namedUpdate(sql, paramMap).await() ?: 0

suspend fun SQLConnection.asyncNamedUpdate(sql: String, paramObject: Any): Int =
    this.namedUpdate(sql, paramObject).await() ?: 0


// update mapped object
suspend fun <T> SQLConnection.asyncUpdateObject(obj: T): Int {
    return this.updateObject(obj).await() ?: 0
}


// insert
suspend fun <R> SQLConnection.asyncInsert(sql: String, vararg params: Any): R = this.insert<R>(sql, *params).await()

suspend fun <R> SQLConnection.asyncNamedInsert(sql: String, paramMap: Map<String, Any>): R =
    this.namedInsert<R>(sql, paramMap).await()

suspend fun <R> SQLConnection.asyncNamedInsert(sql: String, paramObject: Any): R =
    this.namedInsert<R>(sql, paramObject).await()

suspend fun <T, R> SQLConnection.asyncInsertObject(obj: T): R = this.insertObject<T, R>(obj).await()

suspend inline fun <reified T, R> SQLConnection.asyncInsertObjectBatch(list: List<T>, rsh: Func1<SQLResultSet, R?>): R =
    this.insertObjectBatch<T, R>(list, T::class.java, rsh).await()

suspend inline fun <reified T, R> SQLConnection.asyncInsertObjectBatch(list: List<T>): List<R> =
    this.insertObjectBatch<T, R>(list, T::class.java).await() ?: listOf()


// delete
suspend inline fun <reified T> SQLConnection.asyncDeleteById(id: Any): Int =
    this.deleteById(id, T::class.java).await() ?: 0


suspend fun <T> SQLConnection.execSQL(
    time: Long = 10000L, unit: TimeUnit = TimeUnit.MILLISECONDS,
    handler: suspend (conn: SQLConnection) -> T
                                     ): T {
    beginTransaction().await()
    return try {
        val ret = withTimeout(unit.toMillis(time)) { handler.invoke(this@execSQL) }
        commitAndEndTransaction().await()
        ret
    } catch (e: RecordNotFound) {
        sysLogger.warn("execute SQL exception. record not found", e)
        commitAndEndTransaction().await()
        throw e
    } catch (e: TimeoutCancellationException) {
        sysLogger.error("execute SQL exception. timeout", e)
        rollbackAndEndTransaction().await()
        throw e
    } catch (e: Exception) {
        sysLogger.error("execute SQL exception", e)
        rollbackAndEndTransaction().await()
        throw e
    }
}

suspend fun <T : SQLConnection, R> T.safeUse(block: suspend (T) -> R): R {
    try {
        return block(this)
    } finally {
        withContext(NonCancellable) {
            commitAndClose().await()
        }
    }
}
{'fraction_non_alphanumeric': 0.13631363922061596, 'fraction_numerical': 0.002042740414833438, 'mean_word_length': 4.103849238171612, 'pattern_counts': {'":': 0, '<': 121, '<?xml version=': 0, '>': 131, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6893402', 'n_tokens_mistral': 4031, 'n_tokens_neox': 4108, 'n_words': 969}