没有自定义转换器的jOOQ查询表达式类型安全性

问题描述 投票:1回答:2

我正在尝试使用Kotlin的扩展功能以类型安全的方式通过PostgreSQL的全文本搜索来扩展jOOQ。>

我的问题是DSL.function无法“知道”我的自定义类/类型TsQuery和TsVector并引发异常。 Function类本身没有公共构造函数。

org.jooq.exception.SQLDialectNotSupportedException:方言DEFAULT中不支持类型类jooq.fulltext.TsVector。>

class TsQuery

class TsVector

fun Field<String>.toTsVector(searchConfig: String): Field<TsVector> {
    return DSL.function(
        "to_tsvector",
        TsVector::class.java,
        DSL.inline(searchConfig),
        DSL.coalesce(this, "")
    )!!
}

fun String.toTsQuery(searchConfig: String): Field<TsQuery> {
    return DSL.function(
        "to_tsquery",
        TsQuery::class.java,
        DSL.inline(searchConfig),
        DSL.value(this)
    )!!
}

fun Field<TsVector>.tsMatches(query: Field<TsQuery>): Condition {
    return DSL.condition(
        "{0} @@ {1}",
        this,
        query
    )!!
}

fun Field<TsVector>.tsRank(query: Field<TsQuery>): Field<Double> {
    return DSL.function(
        "ts_rank",
        Double::class.java,
        this,
        query
    )!!
}

如果我将TsQuery和TsVector替换为String,则可以使用,但是我松了打字。我只想将它们用于查询构建,而无需解析这些类型或将它们转换为Kotlin。

我正在尝试使用Kotlin的扩展功能以类型安全的方式通过PostgreSQL的全文搜索扩展jOOQ。我的问题是DSL.function无法“知道”我的自定义类/类型TsQuery和...

postgresql generics kotlin jooq
2个回答
1
投票

即使没有创建自定义转换器,也可以直接创建DefaultDataType对象。

fun Field<String>.toTsVector(searchConfig: String): Field<TsVector> {

    return DSL.function(
        "to_tsvector",
        DefaultDataType(
            SQLDialect.POSTGRES,
            TsVector::class.java,
            "ts_vector"
        ),
        DSL.inline(searchConfig),
        DSL.coalesce(this, "")
    )!!
}

fun String.toTsQuery(searchConfig: String): Field<TsQuery> {
    return DSL.function(
        "to_tsquery",
        DefaultDataType(
            SQLDialect.POSTGRES,
            TsQuery::class.java,
            "ts_vector"
        ),
        DSL.inline(searchConfig),
        DSL.value(this)
    )!!
}

fun Field<TsVector>.tsMatches(query: Field<TsQuery>): Condition {
    return DSL.condition(
        "{0} @@ {1}",
        this,
        query
    )!!
}

fun Field<TsVector>.tsRank(query: Field<TsQuery>): Field<Double> {
    return DSL.function(
        "ts_rank",
        Double::class.java,
        this,
        query
    )!!
}

0
投票

虽然您可以使用内部类(例如DefaultDataTypeas in your own answer)来使它正常工作,但您不应该这样做,因为您的解决方案可能会在将来的次要版本甚至补丁程序版本中中断。

© www.soinside.com 2019 - 2024. All rights reserved.