Как применить функцию перед сравнением в запросе 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
Если это встроенная функция (или определяемая пользователем функция), возможно, вы можете сделать что-то подобное.