Skip to content

Commit d9c0d6b

Browse files
committed
PostgresSQL: array_position() for String and Enum (via casting)
1 parent fc31beb commit d9c0d6b

File tree

5 files changed

+115
-15
lines changed

5 files changed

+115
-15
lines changed

ktorm-core/src/test/kotlin/org/ktorm/BaseTest.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,19 @@ abstract class BaseTest {
111111
val phoneNumber = varchar("phone_number").bindTo { it.phoneNumber }
112112
}
113113

114+
enum class Mood {
115+
HAPPY,
116+
SAD
117+
}
118+
119+
object TableWithEnum : Table<Nothing>("t_enum") {
120+
val id = int("id").primaryKey()
121+
val current_mood = enum<Mood>("current_mood")
122+
}
123+
114124
val Database.departments get() = this.sequenceOf(Departments)
115125

116126
val Database.employees get() = this.sequenceOf(Employees)
117127

118128
val Database.customers get() = this.sequenceOf(Customers)
119-
}
129+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2018-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.ktorm.support.postgresql
18+
19+
import org.ktorm.dsl.cast
20+
import org.ktorm.expression.ArgumentExpression
21+
import org.ktorm.expression.FunctionExpression
22+
import org.ktorm.schema.ColumnDeclaring
23+
import org.ktorm.schema.IntSqlType
24+
import org.ktorm.schema.SqlType
25+
import org.ktorm.schema.TextSqlType
26+
27+
public fun <T : Enum<T>> arrayPosition(value: Array<T?>, column: ColumnDeclaring<T>): FunctionExpression<Int> =
28+
arrayPosition(value.map { it?.name }.toTypedArray(), column.cast(TextSqlType))
29+
30+
public inline fun <reified T : Enum<T>> arrayPosition(value: Collection<T?>, column: ColumnDeclaring<T>): FunctionExpression<Int> =
31+
arrayPosition(value.map { it?.name }.toTypedArray(), column.cast(TextSqlType))
32+
33+
public fun arrayPosition(value: TextArray, column: ColumnDeclaring<String>): FunctionExpression<Int> =
34+
arrayPosition(value, column, TextArraySqlType)
35+
36+
public fun <T : Any> arrayPosition(value: Array<T?>, column: ColumnDeclaring<T>, arraySqlType: SqlType<Array<T?>>): FunctionExpression<Int> =
37+
FunctionExpression(
38+
functionName = "array_position",
39+
arguments = listOf(ArgumentExpression(value, arraySqlType), column.asExpression()),
40+
sqlType = IntSqlType
41+
)

ktorm-support-postgresql/src/test/kotlin/org/ktorm/support/postgresql/BasePostgreSqlTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ abstract class BasePostgreSqlTest : BaseTest() {
1616
execSqlScript("drop-postgresql-data.sql")
1717
}
1818

19-
companion object : PostgreSQLContainer<Companion>("postgres:13-alpine") {
19+
companion object : PostgreSQLContainer<Companion>("postgres:14-alpine") {
2020
init {
2121
// Start the container when it's first used.
2222
start()
2323
// Stop the container when the process exits.
2424
Runtime.getRuntime().addShutdownHook(thread(start = false) { stop() })
2525
}
2626
}
27-
}
27+
}

ktorm-support-postgresql/src/test/kotlin/org/ktorm/support/postgresql/CommonTest.kt

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import org.ktorm.database.use
77
import org.ktorm.dsl.*
88
import org.ktorm.entity.*
99
import org.ktorm.schema.Table
10-
import org.ktorm.schema.enum
1110
import org.ktorm.schema.int
1211
import org.ktorm.schema.varchar
1312
import java.util.concurrent.ExecutionException
@@ -151,16 +150,6 @@ class CommonTest : BasePostgreSqlTest() {
151150

152151
}
153152

154-
enum class Mood {
155-
HAPPY,
156-
SAD
157-
}
158-
159-
object TableWithEnum : Table<Nothing>("t_enum") {
160-
val id = int("id").primaryKey()
161-
val current_mood = enum<Mood>("current_mood")
162-
}
163-
164153
@Test
165154
fun testEnum() {
166155
database.insert(TableWithEnum) {
@@ -220,4 +209,4 @@ class CommonTest : BasePostgreSqlTest() {
220209
assertEquals("test~~", e1.v)
221210
assert(e1.k.isNotEmpty())
222211
}
223-
}
212+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package org.ktorm.support.postgresql
2+
3+
import org.junit.Test
4+
import org.ktorm.dsl.*
5+
import kotlin.test.assertEquals
6+
7+
class FunctionsTest : BasePostgreSqlTest() {
8+
@Test
9+
fun testArrayPositionEnumCollection() {
10+
database.insert(TableWithEnum) {
11+
set(it.current_mood, Mood.SAD)
12+
}
13+
database.insert(TableWithEnum) {
14+
set(it.current_mood, Mood.HAPPY)
15+
}
16+
17+
val moodsSorted = database
18+
.from(TableWithEnum)
19+
.select()
20+
.orderBy(arrayPosition(listOf(Mood.SAD, Mood.HAPPY), TableWithEnum.current_mood).asc())
21+
.map { row ->
22+
row[TableWithEnum.current_mood]
23+
}
24+
25+
assertEquals(listOf(Mood.SAD, Mood.HAPPY, Mood.HAPPY), moodsSorted)
26+
}
27+
28+
@Test
29+
fun testArrayPositionEnumArray() {
30+
database.insert(TableWithEnum) {
31+
set(it.current_mood, Mood.SAD)
32+
}
33+
database.insert(TableWithEnum) {
34+
set(it.current_mood, Mood.HAPPY)
35+
}
36+
37+
val moodsSorted = database
38+
.from(TableWithEnum)
39+
.select()
40+
.orderBy(arrayPosition(arrayOf(Mood.SAD, Mood.HAPPY), TableWithEnum.current_mood).asc())
41+
.map { row ->
42+
row[TableWithEnum.current_mood]
43+
}
44+
45+
assertEquals(listOf(Mood.SAD, Mood.HAPPY, Mood.HAPPY), moodsSorted)
46+
}
47+
48+
@Test
49+
fun testArrayPositionText() {
50+
val namesSorted = database
51+
.from(Employees)
52+
.select()
53+
.orderBy(arrayPosition(arrayOf("tom", "vince", "marry"), Employees.name).asc())
54+
.map { row ->
55+
row[Employees.name]
56+
}
57+
58+
assertEquals(listOf("tom", "vince", "marry", "penny"), namesSorted)
59+
}
60+
}

0 commit comments

Comments
 (0)