Как применить функцию перед сравнением в запросе esqueleto

Для простого запроса

runDb . select . from $ \cell -> do
  where_ $ cell ^. CellCode ==. val "x"
  return cell

Я хочу применить функцию перед сравнением значения поля с "x". Причина в том, что в коде ячейки есть конечные пробелы в базе данных, и нет ничего проще, чем обрезать их, например, с помощью Data.Text, Тем не менее, мой первоначальный подход использования fmap (дважды) привело к

No Instance for (Functor SqlExpr)

Я знаю, что есть функции, предоставляемые Esqueleto, как just, которые выполняют подобные вещи специально (я не мог найти реализацию just, хоть).

Есть ли способ применить какую-либо функцию к упакованному значению?

При написании: в моем конкретном случае, я просто хотел бы использовать like,

РЕДАКТИРОВАТЬ: Добавлена ​​конкретная функция, которую я хочу применить.

2 ответа

Решение

Смотрите здесь для сообщения, которое добавляет функцию postgresql trim:

import Database.Esqueleto.Internal.Sql

trim :: (IsString s) => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s)
trim pattern target =
    unsafeSqlFunction "trim" (unsafeSqlBinOp "FROM" pattern target)

(Если вы не используете postgres, вам может понадобиться обратиться к документации из вашей базы данных, чтобы узнать, поддерживает ли она что-то подобное.)

unsafeSqlFunction может использоваться для импорта любой функции, поддерживаемой вашей базой данных, но это небезопасно, поскольку вы несете ответственность за то, чтобы убедиться, что сигнатура типа действительно соответствует вашей базе данных. Имя будет скопировано буквально в ваш SQL.

unsafeSqlBinOp аналогично, но определяет двоичную операцию: unsafeSqlBinOp "FROM" "a" "b" переводится в SQL "a" FROM "b",

С этим вы должны быть в состоянии сделать:

runDb . select . from $ \cell -> do
    where_ $ trim " " (cell ^. CellCode) ==. val "x"
    return cell

Какую функцию вы хотите применить?

Вот как кто-то добавил возможность вызывать chr() функция в запросе:

https://github.com/krisajenkins/esqueleto/commit/fa1d1c888770e297fef52d76b6cb68342a6c0376

Если это встроенная функция (или определяемая пользователем функция), возможно, вы можете сделать что-то подобное.

Другие вопросы по тегам