I'm trying to figure out how to add a group_concat...
# komapper
d
I'm trying to figure out how to add a group_concat function... I know I must have the types wrong though... how do I do this @Toshihiro Nakamura?
Copy code
inline fun <reified T : Any> groupConcat(vararg columns: ColumnExpression<T, String>) : ColumnExpression<T, String> {
        val operands = columns.map { Operand.Column(it) }
        return columnExpression(T::class, String::class, { this as T }, "group_concat", operands.toList()) {
            append("GROUP_CONCAT(")
            operands.dropLast(1).forEach { visit(it); append(", ") }
            visit(operands.last())
            append(")")
        }
    }
There seems to be two variants of the columnExpression function, and I don't really understand the first arguments too much...
t
Try the following code:
Copy code
fun <T: Any> groupConcat(vararg columns: ColumnExpression<T, String>) : ColumnExpression<T, String> {
    if (columns.isEmpty()) error("empty columns")
    val operands = columns.map { Operand.Column(it) }
    return columnExpression(columns.first(), "group_concat", operands.toList()) {
        append("GROUP_CONCAT(")
        operands.dropLast(1).forEach { visit(it); append(", ") }
        visit(operands.last())
        append(")")
    }
}
d
I get this:|
Copy code
Type mismatch.
Required:
ColumnExpression<TypeVariable(T), String>
Found:
PropertyMetamodel<SomeEntity, SomeId, Int>
when I try to use it in my select statement...
It seems that this works:
Copy code
fun <E: Any, I: Any> groupConcat(vararg columns: ColumnExpression<E, I>) : ColumnExpression<E, I> {
        if (columns.isEmpty()) error("empty columns")
        val operands = columns.map { Operand.Column(it) }
        return columnExpression(columns.first(), "group_concat", operands.toList()) {
            append("GROUP_CONCAT(")
            operands.dropLast(1).forEach { visit(it); append(", ") }
            visit(operands.last())
            append(")")
        }
    }
But that seems to mean that only columns with the same interior exterior types can be provided...
t
OK. This code should work:
Copy code
fun groupConcat(vararg columns: ColumnExpression<*, *>) : ColumnExpression<String, String> {
    if (columns.isEmpty()) error("empty columns")
    val operands = columns.map { Operand.Column(it) }
    return columnExpression(String::class, String::class, {it}, "group_concat", operands.toList()) {
        append("GROUP_CONCAT(")
        operands.dropLast(1).forEach { visit(it); append(", ") }
        visit(operands.last())
        append(")")
    }
}
d
Yup, that worked, thanks! This could be a nice inclusion for the next version... It would also be amazing if you could add kdocs for those functions to explain what those params are and how to use them... they're not internal, since they're in the official docs, and it's not really clear just by looking at them.