如何在 esqueleto 查询中进行比较之前应用函数

How to apply a function before comparison in an esqueleto query

对于这么简单的查询

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

我想在字段值与 "x" 比较之前应用一个函数。原因是单元格代码在数据库中有尾随空格,没有什么比删除它们更容易的了,例如strip 来自 Data.Text。但是,我最初使用 fmap(两次)的方法导致

No Instance for (Functor SqlExpr)

我知道 Esqueleto 提供了一些功能,例如 just,它们专门完成类似的事情(不过我找不到 just 的实现)。

有没有办法对打包值应用任何函数?

写作时:在我的具体情况下,我可能只想使用 like

编辑:添加了我要应用的特定功能。

您想申请什么样的功能?

以下是某人如何在查询中添加调用 chr() 函数的功能:

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

如果是内置函数(或用户自定义函数),也许你可以做类似的事情。

here for a post that adds the postgresql function 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