From 2d4d8fa9e32970b11183c573892ab3116ac117d5 Mon Sep 17 00:00:00 2001 From: Edvinas Date: Tue, 5 Feb 2019 22:15:35 +0200 Subject: [PATCH 1/2] Allow to apply groupConcat on expressions --- src/main/kotlin/org/jetbrains/exposed/sql/Function.kt | 10 ++++++---- .../org/jetbrains/exposed/sql/SQLExpressionBuilder.kt | 6 +++--- .../org/jetbrains/exposed/sql/vendors/Default.kt | 2 +- .../org/jetbrains/exposed/sql/vendors/OracleDialect.kt | 2 +- .../org/jetbrains/exposed/sql/vendors/PostgreSQL.kt | 2 +- .../jetbrains/exposed/sql/vendors/SQLServerDialect.kt | 2 +- .../org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt | 2 +- .../org/jetbrains/exposed/sql/tests/shared/DMLTests.kt | 2 +- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt b/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt index 6f141cbdfc..008e8ea64d 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/Function.kt @@ -120,10 +120,12 @@ class CaseWhenElse (val caseWhen: CaseWhen, val elseResult: Expressio } } -class GroupConcat(val expr: Column<*>, - val separator: String?, - val distinct: Boolean, - vararg val orderBy: Pair, SortOrder>): Function(VarCharColumnType()) { +class GroupConcat( + val expr: Expression, + val separator: String?, + val distinct: Boolean, + vararg val orderBy: Pair, SortOrder> +): Function(VarCharColumnType()) { override fun toSQL(queryBuilder: QueryBuilder): String = currentDialect.functionProvider.groupConcat(this, queryBuilder) } diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 78acea85d4..93d461ad61 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -44,13 +44,13 @@ fun Expression.upperCase() : Function = UpperCase(this) @Deprecated("Use groupConcat function with SortOrder enum", ReplaceWith("groupConcat()"), level = DeprecationLevel.ERROR) @JvmName("groupConcatDeprecated") -fun Column.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair,Boolean>): GroupConcat = +fun Column.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair,Boolean>): GroupConcat = GroupConcat(this, separator, distinct, *orderBy.map { it.first to if (it.second) SortOrder.ASC else SortOrder.DESC }.toTypedArray()) -fun Column.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Pair,SortOrder>): GroupConcat = +fun Expression.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Pair,SortOrder>): GroupConcat = GroupConcat(this, separator, distinct, orderBy) -fun Column.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Array,SortOrder>> = emptyArray()): GroupConcat = +fun Expression.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Array,SortOrder>> = emptyArray()): GroupConcat = GroupConcat(this, separator, distinct, *orderBy) diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt index d0de919efc..36f721f0b6 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/Default.kt @@ -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 groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder) = buildString { append("GROUP_CONCAT(") if (expr.distinct) append("DISTINCT ") diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt index 07f275f596..f1b5c5f852 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/OracleDialect.kt @@ -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 groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String = buildString { if (expr.orderBy.size != 1) TransactionManager.current().throwUnsupportedException("LISTAGG requires single order by clause") append("LISTAGG(") diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt index 2da087ea19..7c34e8e97a 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/PostgreSQL.kt @@ -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 groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String { val tr = TransactionManager.current() return when { expr.orderBy.isNotEmpty() -> tr.throwUnsupportedException("PostgreSQL doesn't support ORDER BY in STRING_AGG.") diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt index f5ad085fbf..b9b0129cd0 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLServerDialect.kt @@ -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 groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String { val tr = TransactionManager.current() return when { expr.separator == null -> diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt index 1064cd5c6c..2d71e98d8a 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/vendors/SQLiteDialect.kt @@ -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 groupConcat(expr: GroupConcat, queryBuilder: QueryBuilder): String { val tr = TransactionManager.current() return when { expr.orderBy.isNotEmpty() -> tr.throwUnsupportedException("SQLite doesn't support ORDER BY in GROUP_CONCAT.") diff --git a/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DMLTests.kt b/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DMLTests.kt index 79993d3248..7415aa296b 100644 --- a/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DMLTests.kt +++ b/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/DMLTests.kt @@ -612,7 +612,7 @@ class DMLTests : DatabaseTestsBase() { @Test fun testGroupConcat() { withCitiesAndUsers(listOf(TestDB.SQLITE)) { cities, users, _ -> - fun GroupConcat.checkExcept(vararg dialects: KClass, assert: (Map) ->Unit) { + fun GroupConcat.checkExcept(vararg dialects: KClass, assert: (Map) ->Unit) { try { val result = cities.leftJoin(users) .slice(cities.name, this) From f2746f4f51c43d9b255fc093d89a9f524199d787 Mon Sep 17 00:00:00 2001 From: Edvinas Date: Tue, 5 Feb 2019 22:26:27 +0200 Subject: [PATCH 2/2] Migrate deprecated function to Expression as well --- .../kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 93d461ad61..37b84d49c4 100644 --- a/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -44,7 +44,7 @@ fun Expression.upperCase() : Function = UpperCase(this) @Deprecated("Use groupConcat function with SortOrder enum", ReplaceWith("groupConcat()"), level = DeprecationLevel.ERROR) @JvmName("groupConcatDeprecated") -fun Column.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair,Boolean>): GroupConcat = +fun Expression.groupConcat(separator: String?, distinct: Boolean = false, vararg orderBy: Pair,Boolean>): GroupConcat = GroupConcat(this, separator, distinct, *orderBy.map { it.first to if (it.second) SortOrder.ASC else SortOrder.DESC }.toTypedArray()) fun Expression.groupConcat(separator: String? = null, distinct: Boolean = false, orderBy: Pair,SortOrder>): GroupConcat =