diff --git a/src/main/kotlin/no/nav/k9/los/db/util/InClauseHjelper.kt b/src/main/kotlin/no/nav/k9/los/db/util/InClauseHjelper.kt index 8474b7ce5..633852d37 100644 --- a/src/main/kotlin/no/nav/k9/los/db/util/InClauseHjelper.kt +++ b/src/main/kotlin/no/nav/k9/los/db/util/InClauseHjelper.kt @@ -2,6 +2,8 @@ package no.nav.k9.los.db.util object InClauseHjelper { + val STØRRELSER = listOf(2, 4, 8, 16, 32, 64).sorted() + fun tilParameternavnMedCast(input: Collection, prefix: String, castTilType: String): String { return tilParameternavnListe(input, "cast(:" + prefix, " as $castTilType)").joinToString(",") } @@ -11,12 +13,35 @@ object InClauseHjelper { } fun parameternavnTilVerdierMap(input: Collection, prefix: String): Map { - return tilParameternavnListe(input, prefix).zip(input).associateBy({ it.first }, { it.second }) + return tilParameternavnListe(input, prefix).zip(rundOppStørrelse(input)).associateBy({ it.first }, { it.second }) } private fun tilParameternavnListe(input: Collection, prefix: String, postfix: String = ""): List { check(input.isNotEmpty()) - return IntRange(1, input.size).map { "$prefix$it$postfix" } + return IntRange(1, rundOppStørrelse(input.size)).map { "$prefix$it$postfix" } + } + + private fun rundOppStørrelse(input : Collection) : List { + if (input.isEmpty()){ + return emptyList() + } + val resultat = ArrayList(input) + val sisteElement = input.last() + val rundetStørrelse = rundOppStørrelse(input.size) + while (resultat.size < rundetStørrelse){ + resultat.add(sisteElement) + } + return resultat; + } + private fun rundOppStørrelse(antall: Int):Int { + for (s in STØRRELSER) { + if (antall <= s){ + return s; + } + } + val største = STØRRELSER.last() + //multiplum av største + return største * ((antall + største -1) / største) } } \ No newline at end of file diff --git a/src/test/kotlin/no/nav/k9/los/db/util/InClauseHjelperTest.kt b/src/test/kotlin/no/nav/k9/los/db/util/InClauseHjelperTest.kt index 0b22cde4b..c75c23859 100644 --- a/src/test/kotlin/no/nav/k9/los/db/util/InClauseHjelperTest.kt +++ b/src/test/kotlin/no/nav/k9/los/db/util/InClauseHjelperTest.kt @@ -18,4 +18,52 @@ class InClauseHjelperTest { assertThat(InClauseHjelper.tilParameternavnMedCast(verdier, "v", castTilType = "mintype")).isEqualTo("cast(:v1 as mintype),cast(:v2 as mintype)") assertThat(InClauseHjelper.parameternavnTilVerdierMap(verdier, "v")).isEqualTo(mapOf("v1" to "foo", "v2" to "bar")) } + + @Test + fun skal_begrense_antall_ulike_prepared_statements() { + // ønsker helst å kunne si ' in(:listenavn) ' for å kunne gjenbruke prepared statement på tvers av alle listelengder, men er ikke støttet i kotliquery + // begrenser variasjonen i listelengder ved å sende et av elementene flere ganger, og slik kunne gjenbruke prepared statements noe + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 1).map { it }, "x")).isEqualTo(":x1,:x2") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 2).map { it }, "x")).isEqualTo(":x1,:x2") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 3).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 4).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 5).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4,:x5,:x6,:x7,:x8") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 6).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4,:x5,:x6,:x7,:x8") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 7).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4,:x5,:x6,:x7,:x8") + assertThat(InClauseHjelper.tilParameternavn(IntRange(1, 8).map { it }, "x")).isEqualTo(":x1,:x2,:x3,:x4,:x5,:x6,:x7,:x8") + + + assertThat(InClauseHjelper.parameternavnTilVerdierMap(listOf("en"), "x")).isEqualTo(mapOf( + "x1" to "en", + "x2" to "en" + )) + assertThat(InClauseHjelper.parameternavnTilVerdierMap(listOf("en", "to", "tre").map { it }, "x")).isEqualTo( + mapOf( + "x1" to "en", + "x2" to "to", + "x3" to "tre", + "x4" to "tre", //gjentas + ) + ) + assertThat(InClauseHjelper.parameternavnTilVerdierMap(listOf("en", "to", "tre", "fire").map { it }, "x")).isEqualTo( + mapOf( + "x1" to "en", + "x2" to "to", + "x3" to "tre", + "x4" to "fire", + ) + ) + assertThat(InClauseHjelper.parameternavnTilVerdierMap(listOf("en", "to", "tre", "fire", "fem").map { it }, "x")).isEqualTo( + mapOf( + "x1" to "en", + "x2" to "to", + "x3" to "tre", + "x4" to "fire", + "x5" to "fem", + "x6" to "fem", //gjentas + "x7" to "fem", + "x8" to "fem", + ) + ) + } } \ No newline at end of file