mirror of
https://github.com/gotson/komga.git
synced 2026-04-21 06:20:50 +02:00
reintroduce strip accents as custom collation does not work with LIKE
This commit is contained in:
parent
bac4e7c524
commit
293ac415fa
5 changed files with 72 additions and 20 deletions
|
|
@ -3,6 +3,7 @@ package org.gotson.komga.infrastructure.datasource
|
|||
import com.ibm.icu.text.Collator
|
||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||
import org.gotson.komga.infrastructure.unicode.Collators
|
||||
import org.gotson.komga.language.stripAccents
|
||||
import org.sqlite.Collation
|
||||
import org.sqlite.Function
|
||||
import org.sqlite.SQLiteConnection
|
||||
|
|
@ -13,6 +14,7 @@ private val log = KotlinLogging.logger {}
|
|||
|
||||
class SqliteUdfDataSource : SQLiteDataSource() {
|
||||
companion object {
|
||||
const val UDF_STRIP_ACCENTS = "UDF_STRIP_ACCENTS"
|
||||
const val COLLATION_UNICODE_1 = "COLLATION_UNICODE_1"
|
||||
const val COLLATION_UNICODE_3 = "COLLATION_UNICODE_3"
|
||||
}
|
||||
|
|
@ -26,6 +28,7 @@ class SqliteUdfDataSource : SQLiteDataSource() {
|
|||
|
||||
private fun addAllUdf(connection: SQLiteConnection) {
|
||||
createUdfRegexp(connection)
|
||||
createUdfStripAccents(connection)
|
||||
createUnicodeCollation(connection, COLLATION_UNICODE_3, Collators.collator3)
|
||||
createUnicodeCollation(connection, COLLATION_UNICODE_1, Collators.collator1)
|
||||
}
|
||||
|
|
@ -46,6 +49,21 @@ class SqliteUdfDataSource : SQLiteDataSource() {
|
|||
)
|
||||
}
|
||||
|
||||
private fun createUdfStripAccents(connection: SQLiteConnection) {
|
||||
log.debug { "Adding custom $UDF_STRIP_ACCENTS function" }
|
||||
Function.create(
|
||||
connection,
|
||||
UDF_STRIP_ACCENTS,
|
||||
object : Function() {
|
||||
override fun xFunc() =
|
||||
when (val text = value_text(0)) {
|
||||
null -> error("Argument must not be null")
|
||||
else -> result(text.stripAccents())
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
private fun createUnicodeCollation(
|
||||
connection: SQLiteConnection,
|
||||
collationName: String,
|
||||
|
|
|
|||
|
|
@ -146,7 +146,11 @@ class BookSearchHelper(
|
|||
DSL
|
||||
.select(Tables.BOOK_METADATA_TAG.BOOK_ID)
|
||||
.from(Tables.BOOK_METADATA_TAG)
|
||||
.where(Tables.BOOK_METADATA_TAG.TAG.unicode1().equal(tag))
|
||||
.where(
|
||||
Tables.BOOK_METADATA_TAG.TAG
|
||||
.unicode1()
|
||||
.equal(tag),
|
||||
)
|
||||
}
|
||||
val innerAny = {
|
||||
DSL
|
||||
|
|
@ -170,8 +174,21 @@ class BookSearchHelper(
|
|||
.select(Tables.BOOK_METADATA_AUTHOR.BOOK_ID)
|
||||
.from(Tables.BOOK_METADATA_AUTHOR)
|
||||
.where(DSL.noCondition())
|
||||
.apply { if (name != null) and(Tables.BOOK_METADATA_AUTHOR.NAME.unicode1().equal(name)) }
|
||||
.apply { if (role != null) and(Tables.BOOK_METADATA_AUTHOR.ROLE.unicode1().equal(role)) }
|
||||
.apply {
|
||||
if (name != null)
|
||||
and(
|
||||
Tables.BOOK_METADATA_AUTHOR.NAME
|
||||
.unicode1()
|
||||
.equal(name),
|
||||
)
|
||||
}.apply {
|
||||
if (role != null)
|
||||
and(
|
||||
Tables.BOOK_METADATA_AUTHOR.ROLE
|
||||
.unicode1()
|
||||
.equal(role),
|
||||
)
|
||||
}
|
||||
}
|
||||
when (searchCondition.operator) {
|
||||
is SearchOperator.Is -> {
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import org.gotson.komga.domain.model.SearchCondition
|
|||
import org.gotson.komga.domain.model.SearchContext
|
||||
import org.gotson.komga.domain.model.SearchOperator
|
||||
import org.gotson.komga.domain.model.SeriesMetadata
|
||||
import org.gotson.komga.infrastructure.datasource.SqliteUdfDataSource
|
||||
import org.gotson.komga.jooq.main.Tables
|
||||
import org.jooq.Condition
|
||||
import org.jooq.impl.DSL
|
||||
|
|
@ -101,12 +100,19 @@ class SeriesSearchHelper(
|
|||
DSL
|
||||
.select(Tables.SERIES_METADATA_TAG.SERIES_ID)
|
||||
.from(Tables.SERIES_METADATA_TAG)
|
||||
.where(Tables.SERIES_METADATA_TAG.TAG.unicode1().equal(tag))
|
||||
.union(
|
||||
.where(
|
||||
Tables.SERIES_METADATA_TAG.TAG
|
||||
.unicode1()
|
||||
.equal(tag),
|
||||
).union(
|
||||
DSL
|
||||
.select(Tables.BOOK_METADATA_AGGREGATION_TAG.SERIES_ID)
|
||||
.from(Tables.BOOK_METADATA_AGGREGATION_TAG)
|
||||
.where(Tables.BOOK_METADATA_AGGREGATION_TAG.TAG.unicode1().equal(tag)),
|
||||
.where(
|
||||
Tables.BOOK_METADATA_AGGREGATION_TAG.TAG
|
||||
.unicode1()
|
||||
.equal(tag),
|
||||
),
|
||||
)
|
||||
}
|
||||
val innerAny = {
|
||||
|
|
@ -141,17 +147,15 @@ class SeriesSearchHelper(
|
|||
if (name != null)
|
||||
and(
|
||||
Tables.BOOK_METADATA_AGGREGATION_AUTHOR.NAME
|
||||
.collate(
|
||||
SqliteUdfDataSource.COLLATION_UNICODE_3,
|
||||
).equalIgnoreCase(name),
|
||||
.unicode1()
|
||||
.equal(name),
|
||||
)
|
||||
}.apply {
|
||||
if (role != null)
|
||||
and(
|
||||
Tables.BOOK_METADATA_AGGREGATION_AUTHOR.ROLE
|
||||
.collate(
|
||||
SqliteUdfDataSource.COLLATION_UNICODE_3,
|
||||
).equalIgnoreCase(role),
|
||||
.unicode1()
|
||||
.equal(role),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -209,7 +213,11 @@ class SeriesSearchHelper(
|
|||
DSL
|
||||
.select(Tables.SERIES_METADATA_GENRE.SERIES_ID)
|
||||
.from(Tables.SERIES_METADATA_GENRE)
|
||||
.where(Tables.SERIES_METADATA_GENRE.GENRE.unicode1().equal(genre))
|
||||
.where(
|
||||
Tables.SERIES_METADATA_GENRE.GENRE
|
||||
.unicode1()
|
||||
.equal(genre),
|
||||
)
|
||||
}
|
||||
val innerAny = {
|
||||
DSL
|
||||
|
|
@ -236,7 +244,11 @@ class SeriesSearchHelper(
|
|||
DSL
|
||||
.select(Tables.SERIES_METADATA_SHARING.SERIES_ID)
|
||||
.from(Tables.SERIES_METADATA_SHARING)
|
||||
.where(Tables.SERIES_METADATA_SHARING.LABEL.unicode1().equal(label))
|
||||
.where(
|
||||
Tables.SERIES_METADATA_SHARING.LABEL
|
||||
.unicode1()
|
||||
.equal(label),
|
||||
)
|
||||
}
|
||||
val innerAny = {
|
||||
DSL
|
||||
|
|
|
|||
|
|
@ -17,10 +17,15 @@ import java.util.zip.GZIPOutputStream
|
|||
|
||||
fun Field<String>.noCase() = this.collate("NOCASE")
|
||||
|
||||
/**
|
||||
* Warning: SQLite doesn't use collations with LIKE
|
||||
*/
|
||||
fun Field<String>.unicode1() = this.collate(SqliteUdfDataSource.COLLATION_UNICODE_1)
|
||||
|
||||
fun Field<String>.unicode3() = this.collate(SqliteUdfDataSource.COLLATION_UNICODE_3)
|
||||
|
||||
fun Field<String>.udfStripAccents() = DSL.function(SqliteUdfDataSource.UDF_STRIP_ACCENTS, String::class.java, this)
|
||||
|
||||
fun Sort.toOrderBy(sorts: Map<String, Field<out Any>>): List<SortField<out Any>> =
|
||||
this.mapNotNull {
|
||||
it.toSortField(sorts)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ class ReferentialDao(
|
|||
.selectDistinct(a.NAME, a.ROLE)
|
||||
.from(a)
|
||||
.apply { filterOnLibraryIds?.let { leftJoin(b).on(a.BOOK_ID.eq(b.ID)) } }
|
||||
.where(a.NAME.unicode1().contains(search))
|
||||
.where(a.NAME.udfStripAccents().contains(search.stripAccents()))
|
||||
.apply { filterOnLibraryIds?.let { and(b.LIBRARY_ID.`in`(it)) } }
|
||||
.orderBy(a.NAME.unicode3())
|
||||
.fetchInto(a)
|
||||
|
|
@ -65,7 +65,7 @@ class ReferentialDao(
|
|||
.from(bmaa)
|
||||
.leftJoin(s)
|
||||
.on(bmaa.SERIES_ID.eq(s.ID))
|
||||
.where(bmaa.NAME.unicode1().contains(search))
|
||||
.where(bmaa.NAME.udfStripAccents().contains(search.stripAccents()))
|
||||
.and(s.LIBRARY_ID.eq(libraryId))
|
||||
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.orderBy(bmaa.NAME.unicode3())
|
||||
|
|
@ -83,7 +83,7 @@ class ReferentialDao(
|
|||
.leftJoin(cs)
|
||||
.on(bmaa.SERIES_ID.eq(cs.SERIES_ID))
|
||||
.apply { filterOnLibraryIds?.let { leftJoin(s).on(bmaa.SERIES_ID.eq(s.ID)) } }
|
||||
.where(bmaa.NAME.unicode1().contains(search))
|
||||
.where(bmaa.NAME.udfStripAccents().contains(search.stripAccents()))
|
||||
.and(cs.COLLECTION_ID.eq(collectionId))
|
||||
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.orderBy(bmaa.NAME.unicode3())
|
||||
|
|
@ -99,7 +99,7 @@ class ReferentialDao(
|
|||
.selectDistinct(bmaa.NAME, bmaa.ROLE)
|
||||
.from(bmaa)
|
||||
.apply { filterOnLibraryIds?.let { leftJoin(s).on(bmaa.SERIES_ID.eq(s.ID)) } }
|
||||
.where(bmaa.NAME.unicode1().contains(search))
|
||||
.where(bmaa.NAME.udfStripAccents().contains(search.stripAccents()))
|
||||
.and(bmaa.SERIES_ID.eq(seriesId))
|
||||
.apply { filterOnLibraryIds?.let { and(s.LIBRARY_ID.`in`(it)) } }
|
||||
.orderBy(bmaa.NAME.unicode3())
|
||||
|
|
@ -220,7 +220,7 @@ class ReferentialDao(
|
|||
.selectDistinct(a.NAME)
|
||||
.from(a)
|
||||
.apply { filterOnLibraryIds?.let { leftJoin(b).on(a.BOOK_ID.eq(b.ID)) } }
|
||||
.where(a.NAME.unicode1().contains(search))
|
||||
.where(a.NAME.udfStripAccents().contains(search.stripAccents()))
|
||||
.apply { filterOnLibraryIds?.let { and(b.LIBRARY_ID.`in`(it)) } }
|
||||
.orderBy(a.NAME.unicode3())
|
||||
.fetch(a.NAME)
|
||||
|
|
|
|||
Loading…
Reference in a new issue