JetBrains Exposed (DSL Api): проблема при использовании .regexp (), где условие - PullRequest
2 голосов
/ 31 мая 2019

Я создаю небольшой API, используя Javalin & Exposed ORM.Я пытаюсь использовать регулярное выражение, где условие, но исключение - бросить, потому что SQL-запрос, выполненный из-за моего кода, кажется неполным (шаблон отсутствует).

fun getUsersByFilter(filter: String): List<User> {
    val regex = StringBuilder("/")
            .append(filter.toLowerCase())
            .append("/i")
            .toString()


    /**
     * The .regexp(someString) method take a string as argument (a pattern)
     */
    val users = transaction {
        User.find{ Users.pseudo.regexp(regex)  }.toList()
    }

    return users
}
  Position : 141. Statement(s): SELECT users.id, users.pseudo, users.email, users."password", users.admin, users.created_at, users.updated_at FROM users WHERE users.pseudo REGEXP ?
org.jetbrains.exposed.exceptions.ExposedSQLException: org.postgresql.util.PSQLException: ERREUR: erreur de syntaxe sur ou près de « REGEXP »
  Position : 141
SQL: [SELECT users.id, users.pseudo, users.email, users."password", users.admin, users.created_at, users.updated_at FROM users WHERE users.pseudo REGEXP ?]

Может кто-то помочьмне, пожалуйста?

Ответы [ 2 ]

1 голос
/ 10 июня 2019

Хорошо, я понял. Аргумент regex был правильно передан в запрос (вопросительный знак в сообщении об исключении был просто там, чтобы указать на параметр ...) даже при использовании StringBuilder. Ошибка пришла из PostgreSQL, потому что функция «REGEXP» просто не существует в PostgreSQL ...

Я наконец-то использую этот код:

    fun getUsersByFilter(filter: String): List<User> {
        val regex = "%${filter.toLowerCase()}%"

        val users = transaction {
            User.find{ Users.pseudo.lowerCase().like(regex) }.toList()
        }

        return users
    }
0 голосов
/ 07 июня 2019

Из вашего кода это выглядит так, как будто вы пытаетесь создать регулярное выражение из пользовательского ввода, объединяя /, шаблон и /i разделитель + флаг без учета регистра.

Это неправильнопотому что:

  • В Kotlin (и Java) шаблоны регулярных выражений задаются с помощью строковых литералов, а не regex литералов, как это обычно бывает в JavaScript, PHP, Perl, поэтому вы делаетене нужно добавлять / на обоих концах
  • Нечувствительность к регистру устанавливается с использованием либо конкретных опций (RegexOptions.IGNORE_CASE), либо, проще, с использованием встроенных модификаторов, таких как (?i).Добавьте его в начале, и все регулярные выражения будут нечувствительны к регистру.
  • Однако пользовательская часть, которая должна совпадать буквально, выдает исключение, если она содержит специальные метасимволы регулярных выражений.Вам нужно «процитировать» его, и в Kotlin у вас есть Regex.fromLiteral метод для этого.

Итак, я предлагаю использовать

val regex = "(?i)" + Regex.fromLiteral(filter)
...