Skip to content

Commit 8f3564a

Browse files
authored
feat: implement cast, right, left, replace expressions (#894)
* feat: implement cast, right, left, replace expressions
1 parent 12b931d commit 8f3564a

File tree

22 files changed

+886
-0
lines changed

22 files changed

+886
-0
lines changed

docs/en/jpql-with-kotlin-jdsl/expressions.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ Kotlin JDSL provides a series of functions to support built-in functions in JPA.
199199
* UPPER (upper)
200200
* LENGTH (length)
201201
* LOCATE (locate)
202+
* CAST (cast) - *Added in JPA 3.2*
203+
* LEFT (left) - *Added in JPA 3.2*
204+
* RIGHT (right) - *Added in JPA 3.2*
205+
* REPLACE (replace) - *Added in JPA 3.2*
202206

203207
```kotlin
204208
concat(path(Book::title), literal(":"), path(Book::imageUrl))
@@ -215,6 +219,25 @@ upper(path(Book::title))
215219
length(path(Book::title))
216220

217221
locate("Book", path(Book::title))
222+
223+
cast(path(Book::price)).asString()
224+
cast(path(Book::authorId)).asInt()
225+
cast(path(Book::authorId)).asLong()
226+
cast(path(Book::authorId)).asDouble()
227+
cast(path(Book::authorId)).asFloat()
228+
229+
left(path(Book::title), 3)
230+
left(path(Book::title), literal(3))
231+
232+
right(path(Book::title), 3)
233+
right(path(Book::title), literal(3))
234+
235+
replace(path(Book::title), "old", "new")
236+
replace(path(Book::title), stringLiteral("old"), "new")
237+
replace(path(Book::title), path(Book::name), "new")
238+
replace(path(Book::title), "old", stringLiteral("new"))
239+
replace(path(Book::title), "old", path(Book::name))
240+
replace(path(Book::title), literal("old"), literal("new"))
218241
```
219242

220243
### Arithmetic functions

docs/ko/jpql-with-kotlin-jdsl/expressions.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ Kotlin JDSL은 JPA에서 제공하는 여러 함수들을 지원하기 위한
197197
* UPPER (upper)
198198
* LENGTH (length)
199199
* LOCATE (locate)
200+
* CAST (cast) - *JPA 3.2에 추가됨*
201+
* LEFT (left) - *JPA 3.2에 추가됨*
202+
* RIGHT (right) - *JPA 3.2에 추가됨*
203+
* REPLACE (replace) - *JPA 3.2에 추가됨*
200204

201205
```kotlin
202206
concat(path(Book::title), literal(":"), path(Book::imageUrl))
@@ -213,6 +217,25 @@ upper(path(Book::title))
213217
length(path(Book::title))
214218

215219
locate("Book", path(Book::title))
220+
221+
cast(path(Book::price)).asString()
222+
cast(path(Book::authorId)).asInt()
223+
cast(path(Book::authorId)).asLong()
224+
cast(path(Book::authorId)).asDouble()
225+
cast(path(Book::authorId)).asFloat()
226+
227+
left(path(Book::title), 3)
228+
left(path(Book::title), literal(3))
229+
230+
right(path(Book::title), 3)
231+
right(path(Book::title), literal(3))
232+
233+
replace(path(Book::title), "old", "new")
234+
replace(path(Book::title), stringLiteral("old"), "new")
235+
replace(path(Book::title), path(Book::name), "new")
236+
replace(path(Book::title), "old", stringLiteral("new"))
237+
replace(path(Book::title), "old", path(Book::name))
238+
replace(path(Book::title), literal("old"), literal("new"))
216239
```
217240

218241
### Arithmetic functions

dsl/jpql/src/main/kotlin/com/linecorp/kotlinjdsl/dsl/jpql/Jpql.kt

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import com.linecorp.kotlinjdsl.dsl.jpql.delete.DeleteQueryWhereStep
55
import com.linecorp.kotlinjdsl.dsl.jpql.delete.impl.DeleteQueryDsl
66
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseThenFirstStep
77
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CaseValueWhenFirstStep
8+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStep
9+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStepToString
810
import com.linecorp.kotlinjdsl.dsl.jpql.expression.TrimFromStep
911
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseThenFirstStepDsl
1012
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.CaseValueWhenFirstStepDsl
13+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlCastStep
14+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.JpqlCastStepToString
1115
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimBothFromStepDsl
1216
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimFromStepDsl
1317
import com.linecorp.kotlinjdsl.dsl.jpql.expression.impl.TrimLeadingFromStepDsl
@@ -1737,6 +1741,102 @@ open class Jpql : JpqlDsl {
17371741
)
17381742
}
17391743

1744+
/**
1745+
* Creates a step to cast a string expression to another type.
1746+
*/
1747+
@SinceJdsl("3.6.0")
1748+
fun cast(value: Expressionable<String>): CastStep {
1749+
return JpqlCastStep(value.toExpression())
1750+
}
1751+
1752+
/**
1753+
* Creates a step to cast a scalar expression to a string.
1754+
*/
1755+
@SinceJdsl("3.6.0")
1756+
fun <T : Any> cast(value: Expressionable<T>): CastStepToString {
1757+
return JpqlCastStepToString(value.toExpression())
1758+
}
1759+
1760+
/**
1761+
* Creates an expression that returns the leftmost count characters from a string.
1762+
*/
1763+
@SinceJdsl("3.6.0")
1764+
fun left(value: Expressionable<String>, len: Expressionable<Int>): Expression<String> {
1765+
return Expressions.left(value.toExpression(), len.toExpression())
1766+
}
1767+
1768+
/**
1769+
* Creates an expression that returns the leftmost count characters from a string.
1770+
*/
1771+
@SinceJdsl("3.6.0")
1772+
fun left(value: Expressionable<String>, len: Int): Expression<String> {
1773+
return left(value.toExpression(), intLiteral(len))
1774+
}
1775+
1776+
/**
1777+
* Creates an expression that returns the rightmost count characters from a string.
1778+
*/
1779+
@SinceJdsl("3.6.0")
1780+
fun right(value: Expressionable<String>, len: Expressionable<Int>): Expression<String> {
1781+
return Expressions.right(value.toExpression(), len.toExpression())
1782+
}
1783+
1784+
/**
1785+
* Creates an expression that returns the rightmost count characters from a string.
1786+
*/
1787+
@SinceJdsl("3.6.0")
1788+
fun right(value: Expressionable<String>, len: Int): Expression<String> {
1789+
return right(value.toExpression(), intLiteral(len))
1790+
}
1791+
1792+
/**
1793+
* Creates an expression that replaces all occurrences of a search string with a replacement string.
1794+
*/
1795+
@SinceJdsl("3.6.0")
1796+
fun replace(
1797+
value: Expressionable<String>,
1798+
substring: Expressionable<String>,
1799+
replacement: Expressionable<String>,
1800+
): Expression<String> {
1801+
return Expressions.replace(value.toExpression(), substring.toExpression(), replacement.toExpression())
1802+
}
1803+
1804+
/**
1805+
* Creates an expression that replaces all occurrences of a search string with a replacement string.
1806+
*/
1807+
@SinceJdsl("3.6.0")
1808+
fun replace(
1809+
value: Expressionable<String>,
1810+
substring: String,
1811+
replacement: String,
1812+
): Expression<String> {
1813+
return replace(value.toExpression(), stringLiteral(substring), stringLiteral(replacement))
1814+
}
1815+
1816+
/**
1817+
* Creates an expression that replaces all occurrences of a search string with a replacement string.
1818+
*/
1819+
@SinceJdsl("3.6.0")
1820+
fun replace(
1821+
value: Expressionable<String>,
1822+
substring: Expressionable<String>,
1823+
replacement: String,
1824+
): Expression<String> {
1825+
return replace(value.toExpression(), substring, stringLiteral(replacement))
1826+
}
1827+
1828+
/**
1829+
* Creates an expression that replaces all occurrences of a search string with a replacement string.
1830+
*/
1831+
@SinceJdsl("3.6.0")
1832+
fun replace(
1833+
value: Expressionable<String>,
1834+
substring: String,
1835+
replacement: Expressionable<String>,
1836+
): Expression<String> {
1837+
return replace(value.toExpression(), substring, replacement)
1838+
}
1839+
17401840
/**
17411841
* Creates an expression that represents predefined database functions and user-defined database functions.
17421842
*/
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.linecorp.kotlinjdsl.dsl.jpql.expression
2+
3+
import com.linecorp.kotlinjdsl.SinceJdsl
4+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable
5+
6+
/**
7+
* A step to specify the target type for a cast from a string expression.
8+
* This corresponds to the BNF: CAST(string_expression AS {type})
9+
*/
10+
@SinceJdsl("3.6.0")
11+
interface CastStep {
12+
/**
13+
* Casts the expression to an INTEGER.
14+
*/
15+
@SinceJdsl("3.6.0")
16+
fun asInteger(): Expressionable<Int>
17+
18+
/**
19+
* Casts the expression to a LONG.
20+
*/
21+
@SinceJdsl("3.6.0")
22+
fun asLong(): Expressionable<Long>
23+
24+
/**
25+
* Casts the expression to a FLOAT.
26+
*/
27+
@SinceJdsl("3.6.0")
28+
fun asFloat(): Expressionable<Float>
29+
30+
/**
31+
* Casts the expression to a DOUBLE.
32+
*/
33+
@SinceJdsl("3.6.0")
34+
fun asDouble(): Expressionable<Double>
35+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.linecorp.kotlinjdsl.dsl.jpql.expression
2+
3+
import com.linecorp.kotlinjdsl.SinceJdsl
4+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable
5+
6+
/**
7+
* A step to cast a scalar expression to a STRING.
8+
* This corresponds to the BNF: CAST(scalar_expression AS STRING)
9+
*/
10+
@SinceJdsl("3.6.0")
11+
interface CastStepToString {
12+
/**
13+
* Casts the expression to a STRING.
14+
*/
15+
@SinceJdsl("3.6.0")
16+
fun asString(): Expressionable<String>
17+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl
2+
3+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStep
4+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression
5+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable
6+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast
7+
8+
@PublishedApi
9+
internal data class JpqlCastStep(
10+
private val expression: Expression<String>,
11+
) : CastStep {
12+
override fun asInteger(): Expressionable<Int> {
13+
return JpqlCast(expression, Int::class)
14+
}
15+
16+
override fun asLong(): Expressionable<Long> {
17+
return JpqlCast(expression, Long::class)
18+
}
19+
20+
override fun asFloat(): Expressionable<Float> {
21+
return JpqlCast(expression, Float::class)
22+
}
23+
24+
override fun asDouble(): Expressionable<Double> {
25+
return JpqlCast(expression, Double::class)
26+
}
27+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.linecorp.kotlinjdsl.dsl.jpql.expression.impl
2+
3+
import com.linecorp.kotlinjdsl.dsl.jpql.expression.CastStepToString
4+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expression
5+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.Expressionable
6+
import com.linecorp.kotlinjdsl.querymodel.jpql.expression.impl.JpqlCast
7+
8+
@PublishedApi
9+
internal data class JpqlCastStepToString<T : Any>(
10+
private val expression: Expression<T>,
11+
) : CastStepToString {
12+
override fun asString(): Expressionable<String> {
13+
return JpqlCast(expression, String::class)
14+
}
15+
}

0 commit comments

Comments
 (0)