Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to apply groupConcat on expressions #486

Merged
merged 2 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/main/kotlin/org/jetbrains/exposed/sql/Function.kt
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ class CaseWhenElse<T, R:T> (val caseWhen: CaseWhen<T>, val elseResult: Expressio
}
}

class GroupConcat(val expr: Column<*>,
val separator: String?,
val distinct: Boolean,
vararg val orderBy: Pair<Expression<*>, SortOrder>): Function<String?>(VarCharColumnType()) {
class GroupConcat<T : String?>(
val expr: Expression<T>,
val separator: String?,
val distinct: Boolean,
vararg val orderBy: Pair<Expression<*>, SortOrder>
): Function<T>(VarCharColumnType()) {
override fun toSQL(queryBuilder: QueryBuilder): String
= currentDialect.functionProvider.groupConcat(this, queryBuilder)
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ fun<T:String?> Expression<T>.upperCase() : Function<T> = UpperCase(this)

@Deprecated("Use groupConcat function with SortOrder enum", ReplaceWith("groupConcat()"), level = DeprecationLevel.ERROR)
@JvmName("groupConcatDeprecated")
fun <T:Any?> Column<T>.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair<Expression<*>,Boolean>): GroupConcat =
fun <T : String?> Expression<T>.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair<Expression<*>,Boolean>): GroupConcat<T> =
GroupConcat(this, separator, distinct, *orderBy.map { it.first to if (it.second) SortOrder.ASC else SortOrder.DESC }.toTypedArray())

fun <T:Any?> Column<T>.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Pair<Expression<*>,SortOrder>): GroupConcat =
fun <T : String?> Expression<T>.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Pair<Expression<*>,SortOrder>): GroupConcat<T> =
GroupConcat(this, separator, distinct, orderBy)

fun <T:Any?> Column<T>.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Array<Pair<Expression<*>,SortOrder>> = emptyArray()): GroupConcat =
fun <T : String?> Expression<T>.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Array<Pair<Expression<*>,SortOrder>> = emptyArray()): GroupConcat<T> =
GroupConcat(this, separator, distinct, *orderBy)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ abstract class FunctionProvider {

open fun queryLimit(size: Int, offset: Int, alreadyOrdered: Boolean) = "LIMIT $size" + if (offset > 0) " OFFSET $offset" else ""

open fun groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder) = buildString {
open fun <T : String?> groupConcat(expr: GroupConcat<T>, queryBuilder: QueryBuilder) = buildString {
append("GROUP_CONCAT(")
if (expr.distinct)
append("DISTINCT ")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ internal object OracleFunctionProvider : FunctionProvider() {
override fun queryLimit(size: Int, offset: Int, alreadyOrdered: Boolean)
= (if (offset > 0) " OFFSET $offset ROWS" else "") + " FETCH FIRST $size ROWS ONLY"

override fun groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String = buildString {
override fun <T : String?> groupConcat(expr: GroupConcat<T>, queryBuilder: QueryBuilder): String = buildString {
if (expr.orderBy.size != 1)
TransactionManager.current().throwUnsupportedException("LISTAGG requires single order by clause")
append("LISTAGG(")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ internal object PostgreSQLFunctionProvider : FunctionProvider() {

private const val onConflictIgnore = "ON CONFLICT DO NOTHING"

override fun groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String {
override fun <T : String?> groupConcat(expr: GroupConcat<T>, queryBuilder: QueryBuilder): String {
val tr = TransactionManager.current()
return when {
expr.orderBy.isNotEmpty() -> tr.throwUnsupportedException("PostgreSQL doesn't support ORDER BY in STRING_AGG.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ internal object SQLServerFunctionProvider : FunctionProvider() {
return if (limit != null) def.replaceFirst("DELETE", "DELETE TOP($limit)") else def
}

override fun groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String {
override fun <T : String?> groupConcat(expr: GroupConcat<T>, queryBuilder: QueryBuilder): String {
val tr = TransactionManager.current()
return when {
expr.separator == null ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal object SQLiteFunctionProvider : FunctionProvider() {
return super.update(targets, columnsAndValues, limit, where, transaction)
}

override fun groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String {
override fun <T: String?> groupConcat(expr: GroupConcat<T>, queryBuilder: QueryBuilder): String {
val tr = TransactionManager.current()
return when {
expr.orderBy.isNotEmpty() -> tr.throwUnsupportedException("SQLite doesn't support ORDER BY in GROUP_CONCAT.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ class DMLTests : DatabaseTestsBase() {
@Test
fun testGroupConcat() {
withCitiesAndUsers(listOf(TestDB.SQLITE)) { cities, users, _ ->
fun GroupConcat.checkExcept(vararg dialects: KClass<out DatabaseDialect>, assert: (Map<String, String?>) ->Unit) {
fun <T : String?> GroupConcat<T>.checkExcept(vararg dialects: KClass<out DatabaseDialect>, assert: (Map<String, String?>) ->Unit) {
try {
val result = cities.leftJoin(users)
.slice(cities.name, this)
Expand Down