2015-08-27 2 views
1

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

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

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

No Instance for (Functor SqlExpr) 

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

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

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

EDIT: добавлена ​​специальная функция, которую я хочу применить.

ответ

1

См here на пост, который добавляет функцию 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 
2

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

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

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

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

+0

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