From cbece4ee1a3541db56080c533e89597915cc9664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Pich?= Date: Sun, 29 Oct 2023 22:28:41 +0100 Subject: [PATCH] Fix count all when using filtering vol. 2 --- .../wulkanowy/schools/dao/LoginEventDao.kt | 39 ++++++++++++++----- .../wulkanowy/schools/plugins/Routing.kt | 32 ++++++++------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/io/github/wulkanowy/schools/dao/LoginEventDao.kt b/src/main/kotlin/io/github/wulkanowy/schools/dao/LoginEventDao.kt index caa1202..7fe5240 100644 --- a/src/main/kotlin/io/github/wulkanowy/schools/dao/LoginEventDao.kt +++ b/src/main/kotlin/io/github/wulkanowy/schools/dao/LoginEventDao.kt @@ -11,6 +11,12 @@ import java.time.Instant class LoginEventDao { + private val uniqueColumns = listOf( + LoginEvents.schoolId, + LoginEvents.symbol, + LoginEvents.scraperBaseUrl, + ) + private fun resultRowToLoginEvent(row: ResultRow) = LoginEvent( schoolName = row[LoginEvents.schoolName], schoolShort = row[LoginEvents.schoolShort], @@ -29,23 +35,38 @@ class LoginEventDao { orderBy: Column<*>?, order: SortOrder?, ): List = dbQuery { - getQuery(text) - .let { - if (orderBy != null && order != null) { - it.orderBy(orderBy, order) - } else it - } + getQuery(text, orderBy, order) .limit(pageSize, page * pageSize) .map(::resultRowToLoginEvent) } - suspend fun getCount(text: String?) = dbQuery { - getQuery(text).count() + suspend fun getCount( + text: String?, + orderBy: Column<*>?, + order: SortOrder?, + ) = dbQuery { + val query = getQuery(text, orderBy, order).alias("getAll") + query.selectAll().count() } - private suspend fun getQuery(text: String?) = dbQuery { + private suspend fun getQuery( + text: String?, + orderBy: Column<*>?, + order: SortOrder?, + ) = dbQuery { + val currentOrderBy = listOfNotNull(orderBy).toSet() + val distinctColumns = currentOrderBy + (uniqueColumns - currentOrderBy) LoginEvents + .slice( + customDistinctOn(*distinctColumns.toTypedArray()), + *(LoginEvents.columns).toTypedArray() + ) .selectAll() + .let { query -> + if (order != null) { + query.orderBy(*distinctColumns.map { it to order }.toTypedArray()) + } else query + } .let { if (text.isNullOrBlank()) it else { it.orWhere { LoginEvents.schoolName like "%${text}%" } diff --git a/src/main/kotlin/io/github/wulkanowy/schools/plugins/Routing.kt b/src/main/kotlin/io/github/wulkanowy/schools/plugins/Routing.kt index 9a2467c..52c1100 100644 --- a/src/main/kotlin/io/github/wulkanowy/schools/plugins/Routing.kt +++ b/src/main/kotlin/io/github/wulkanowy/schools/plugins/Routing.kt @@ -42,26 +42,32 @@ fun Application.configureRouting() { } get("/log/list") { val params = call.request.queryParameters + val orderBy = when (params["sortBy"]) { + "id" -> LoginEvents.id + "schoolName" -> LoginEvents.schoolName + "schoolShort" -> LoginEvents.schoolShort + "schoolAddress" -> LoginEvents.schoolAddress + else -> null + } + val order = when (params["order"]) { + "asc" -> SortOrder.ASC + "desc" -> SortOrder.DESC + else -> null + } call.respond( ListResponse( rows = loginEventDao.allLoginEvents( page = params["page"]?.toLongOrNull() ?: 0, pageSize = params["pageSize"]?.toIntOrNull() ?: 10, text = params["text"], - orderBy = when (params["sortBy"]) { - "id" -> LoginEvents.id - "schoolName" -> LoginEvents.schoolName - "schoolShort" -> LoginEvents.schoolShort - "schoolAddress" -> LoginEvents.schoolAddress - else -> null - }, - order = when (params["order"]) { - "asc" -> SortOrder.ASC - "desc" -> SortOrder.DESC - else -> null - }, + orderBy = orderBy, + order = order, + ), + rowsCount = loginEventDao.getCount( + text = params["text"], + orderBy = orderBy, + order = order, ), - rowsCount = loginEventDao.getCount(text = params["text"]), ) ) }