简体   繁体   English

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

[英]How to apply a function before comparison in an esqueleto query

For a query simple as that 对于这样简单的查询

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

I want to apply a function before the comparison of the field value with "x". 我想在将字段值与“ x”进行比较之前应用一个函数。 The reason is that the cell code has trailing spaces in the database and nothing easier than trimming them away, eg with strip from Data.Text . 其原因是,小区代码后在数据库中,没有什么比用修剪他们离开,如容易空格Data.Text However, my initial approach of using fmap (twice) resulted in 但是,我最初使用fmap (两次)导致

No Instance for (Functor SqlExpr)

I know that there are functions provides by Esqueleto, like just , that accomplish similar things specifically (I couldn't find the implementation of just , though). 我知道Esqueleto提供的功能(例如just )可以专门完成类似的功能(尽管我找不到just的实现)。

Is there a way to apply any function on the packed value? 有没有办法在打包值上应用任何功能?

While writing: in my specific case, I just might want to use like . 在写作时:在我的特定情况下,我可能只想使用like

EDIT: Added the specific function I want to apply. 编辑:添加了我要应用的特定功能。

What kind of function to you want to apply? 您要应用哪种功能?

Here is how someone added the ability to call the chr() function in a query: 这是某人在查询中添加了调用chr()函数的功能的方式:

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

If it is a built-in function (or a user-definable function), perhaps you can do something similar. 如果它是内置函数(或用户可定义的函数),则您可以执行类似的操作。

See here for a post that adds the postgresql function trim : 请参阅此处以添加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)

(If you're not using postgres, you may need to consult the documentation from your database to find if it supports something similar.) (如果您不使用postgres,则可能需要查阅数据库中的文档以查找其是否支持类似的东西。)

unsafeSqlFunction can be used to import any function your database supports, but it is unsafe because you have the responsibility to make sure the type signature is actually what your database expects. unsafeSqlFunction可以用于导入数据库支持的任何功能,但这是不安全的,因为您有责任确保类型签名实际上是数据库期望的。 The name will be copied literally to your SQL. 该名称将原样复制到您的SQL。

unsafeSqlBinOp is similar, but it defines a binary operation: unsafeSqlBinOp "FROM" "a" "b" is translated into the SQL "a" FROM "b" . unsafeSqlBinOp类似,但是它定义了一个二进制操作: unsafeSqlBinOp "FROM" "a" "b"被转换为SQL "a" FROM "b"

With this, you should be able to do: 这样,您应该可以执行以下操作:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM