diff --git a/exposed-core/api/exposed-core.api b/exposed-core/api/exposed-core.api index d97774ebfd..db8280d9b1 100644 --- a/exposed-core/api/exposed-core.api +++ b/exposed-core/api/exposed-core.api @@ -978,6 +978,9 @@ public abstract interface class org/jetbrains/exposed/sql/ISqlExpressionBuilder public abstract fun nthValue (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NthValue; public abstract fun ntile (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/Ntile; public abstract fun percentRank ()Lorg/jetbrains/exposed/sql/PercentRank; + public abstract fun plus (Ljava/lang/String;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; + public abstract fun plus (Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/Concat; + public abstract fun plus (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; public abstract fun plus (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Object;)Lorg/jetbrains/exposed/sql/PlusOp; public abstract fun plus (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/PlusOp; public abstract fun rank ()Lorg/jetbrains/exposed/sql/Rank; @@ -1087,6 +1090,9 @@ public final class org/jetbrains/exposed/sql/ISqlExpressionBuilder$DefaultImpls public static fun nthValue (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NthValue; public static fun ntile (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/Ntile; public static fun percentRank (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;)Lorg/jetbrains/exposed/sql/PercentRank; + public static fun plus (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Ljava/lang/String;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; + public static fun plus (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/Concat; + public static fun plus (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; public static fun plus (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Object;)Lorg/jetbrains/exposed/sql/PlusOp; public static fun plus (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/PlusOp; public static fun rank (Lorg/jetbrains/exposed/sql/ISqlExpressionBuilder;)Lorg/jetbrains/exposed/sql/Rank; @@ -2037,6 +2043,9 @@ public final class org/jetbrains/exposed/sql/SqlExpressionBuilder : org/jetbrain public fun nthValue (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/NthValue; public fun ntile (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;)Lorg/jetbrains/exposed/sql/Ntile; public fun percentRank ()Lorg/jetbrains/exposed/sql/PercentRank; + public fun plus (Ljava/lang/String;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; + public fun plus (Lorg/jetbrains/exposed/sql/Expression;Ljava/lang/String;)Lorg/jetbrains/exposed/sql/Concat; + public fun plus (Lorg/jetbrains/exposed/sql/Expression;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/Concat; public fun plus (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Ljava/lang/Object;)Lorg/jetbrains/exposed/sql/PlusOp; public fun plus (Lorg/jetbrains/exposed/sql/ExpressionWithColumnType;Lorg/jetbrains/exposed/sql/Expression;)Lorg/jetbrains/exposed/sql/PlusOp; public fun rank ()Lorg/jetbrains/exposed/sql/Rank; diff --git a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt index 98e663935d..d63540e45f 100644 --- a/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt +++ b/exposed-core/src/main/kotlin/org/jetbrains/exposed/sql/SQLExpressionBuilder.kt @@ -351,6 +351,30 @@ interface ISqlExpressionBuilder { /** Adds the [other] expression to this expression. */ infix operator fun ExpressionWithColumnType.plus(other: Expression): PlusOp = PlusOp(this, other, columnType) + /** + * Concatenate the value to the input expression. + * + * @param value The string value to be concatenated. + * @return The concatenated expression. + */ + infix operator fun Expression.plus(value: String): Concat = concat(this, stringLiteral(value)) + + /** + * Concatenate the value to the input expression. + * + * @param value The string value to be concatenated. + * @return The concatenated expression. + */ + infix operator fun Expression.plus(value: Expression): Concat = concat(this, value) + + /** + * Concatenate the value to the input expression. + * + * @param value The string value to be concatenated. + * @return The concatenated expression. + */ + infix operator fun String.plus(value: Expression): Concat = concat(stringLiteral(this), value) + /** Subtracts the [t] value from this expression. */ infix operator fun ExpressionWithColumnType.minus(t: T): MinusOp = MinusOp(this, wrap(t), columnType) diff --git a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/FunctionsTests.kt b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/FunctionsTests.kt index 0f1834cfbe..9fb7d652dd 100644 --- a/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/FunctionsTests.kt +++ b/exposed-tests/src/test/kotlin/org/jetbrains/exposed/sql/tests/shared/functions/FunctionsTests.kt @@ -5,6 +5,7 @@ import org.jetbrains.exposed.crypt.Encryptor import org.jetbrains.exposed.dao.id.IntIdTable import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.concat +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.tests.DatabaseTestsBase import org.jetbrains.exposed.sql.tests.TestDB import org.jetbrains.exposed.sql.tests.currentDialectTest @@ -597,6 +598,23 @@ class FunctionsTests : DatabaseTestsBase() { } } + @Test + fun testConcatUsingPlusOperator() { + withCitiesAndUsers { _, users, _ -> + val concatField = SqlExpressionBuilder.run { users.id + " - " + users.name } + val result = users.select(concatField).where { users.id eq "andrey" }.single() + assertEquals("andrey - Andrey", result[concatField]) + + val concatField2 = SqlExpressionBuilder.run { users.id + users.name } + val result2 = users.select(concatField2).where { users.id eq "andrey" }.single() + assertEquals("andreyAndrey", result2[concatField2]) + + val concatField3 = SqlExpressionBuilder.run { "Hi " plus users.name + "!" } + val result3 = users.select(concatField3).where { users.id eq "andrey" }.single() + assertEquals("Hi Andrey!", result3[concatField3]) + } + } + private val encryptors = arrayOf( "AES_256_PBE_GCM" to Algorithms.AES_256_PBE_GCM("passwd", "12345678"), "AES_256_PBE_CBC" to Algorithms.AES_256_PBE_CBC("passwd", "12345678"),