override fun find()

in core/search/src/main/kotlin/io/klibs/core/search/ProjectSearchRepositoryJdbc.kt [81:192]


    override fun find(
        rawQuery: String?,
        platforms: List<PackagePlatform>,
        targetFilters: Map<TargetGroup, Set<String>>,
        ownerLogin: String?,
        sortBy: SearchSort,
        tags: List<String>,
        markers: List<String>,
        page: Int,
        limit: Int
    ): List<SearchProjectResult> {
        val isQueryPresent = rawQuery?.isBlank() == false
        val offset = limit * (page - 1)
        val orderBy = when {
            sortBy == SearchSort.RELEVANCY && isQueryPresent -> "weighted_rank DESC"
            sortBy == SearchSort.MOST_STARS -> "stars DESC"
            else -> "stars DESC"
        }

        val exactMatchQuery = rawQuery?.normalizeSearchQuery()
        val exactMatchWildcardQuery = rawQuery?.normalizeSearchQuery()?.addWildcardPostfix()
        val (wildcardQueryWithSpecialSymbols, wildcardQueryWithoutSpecialSymbols) = rawQuery?.let {
            createWildcardSubqueries(
                it
            )
        } ?: Pair("", "")

        val targetCondition = formTargetCondition(targetFilters)

        val sql = buildString {
            append("SELECT project_id, owner_type, owner_login, name, stars, license_name, latest_version")
            append(", latest_version_ts, array_to_string(platforms, ',') AS platforms, plain_description, tags, markers")

            // For debugging and testing purposes
            append(", targets_vector")

            if (isQueryPresent && sortBy == SearchSort.RELEVANCY) {
                append(
                    ", (ts_rank_cd(fts, :exactMatchQuery ::tsquery) * 0.7 + " +
                            "ts_rank_cd(fts, :wildcardQueryWithSpecialSymbols ::tsquery || wildcardQueryWithoutSpecialSymbols || :exactMatchWildcardQuery ::tsquery) * 0.3 + " +
                            "log(stars + 1) * 0.7) AS weighted_rank"
                )
            }
            appendLine(" FROM project_index")

            var prefix = "WHERE"

            if (isQueryPresent) {
                appendLine(", to_tsquery('english', :wildcardQueryWithoutSpecialSymbols) wildcardQueryWithoutSpecialSymbols")
                appendLine(
                    " WHERE (:wildcardQueryWithSpecialSymbols ::tsquery || wildcardQueryWithoutSpecialSymbols || :exactMatchWildcardQuery ::tsquery) @@ fts"
                )
                prefix = "AND"
            }

            if (platforms.isNotEmpty()) {
                val platformsQuery = platforms.distinct().joinToString(separator = " & ") { it.name }
                appendLine(" $prefix platforms_vector @@ '$platformsQuery'")

                prefix = "AND"
            }

            if (ownerLogin != null) {
                appendLine(" $prefix owner_login = :ownerLogin")

                prefix = "AND"
            }

            if (tags.isNotEmpty()) {
                appendLine(" $prefix tags @> ARRAY[:tags]::text[]")

                prefix = "AND"
            }

            if (markers.isNotEmpty()) {
                appendLine(" $prefix markers && :markers::varchar[]")
                prefix = "AND"
            }

            if (targetCondition != null) {
                appendLine(" $prefix targets_vector @@ $targetCondition")

                prefix = "AND"
            }

            if (targetFilters.containsKey(TargetGroup.JavaScript)) {
                appendLine(" $prefix platforms_vector @@ 'JS'")

                prefix = "AND"
            }

            if (targetFilters.containsKey(TargetGroup.Wasm)) {
                appendLine(" $prefix platforms_vector @@ 'WASM'")
            }

            appendLine(" ORDER BY $orderBy")
            appendLine(" LIMIT $limit")
            appendLine(" OFFSET $offset")
        }

        @Suppress("SqlSourceToSinkFlow")
        return jdbcClient.sql(sql)
            .param("exactMatchQuery", exactMatchQuery)
            .param("exactMatchWildcardQuery", exactMatchWildcardQuery)
            .param("wildcardQueryWithSpecialSymbols", wildcardQueryWithSpecialSymbols)
            .param("wildcardQueryWithoutSpecialSymbols", wildcardQueryWithoutSpecialSymbols)
            .param("ownerLogin", ownerLogin)
            .param("tags", tags.toTypedArray())
            .param("markers", markers.toTypedArray())
            .query(PROJECT_OVERVIEW_ROW_MAPPER)
            .list()
    }