繁体   English   中英

在hugsql中使用Clojure表达式构建WHEN子句

[英]Building WHEN clause with a clojure expression in hugsql

我有一个带有status实体的数据库,我希望能够以许多不同的方式获取它。 结果,我想基于地图的内容构建查询的WHEN子句。

例如,像这样:

(get-status *db* {:message_id 2 :user_id 1 :status "sent"})
;; or
(get-status *db* {:message_id 2})
;; or
(get-status *db* {:user_id 1})
;; etc.

我正在努力使用hubsql的clojure表达式 我正在执行以下操作:

-- :name get-status
-- :doc fetch the status of a specific message
-- :command :query
-- :return :many
/* :require [clojure.string :as s] */
SELECT
    *
FROM
    message_status
/*~
(let [params (filter (comp some? val) params)]
  (when (not (empty? params))
    (str "WHERE "
      (s/join ","
              (for [[field value] params]
                (str field " = " (keyword field)))))))
~*/

但是,以下是hugsql如何准备请求:

=> (get-status-sqlvec {:message_id 2 :user_id 1})
["SELECT\n    *\nFROM\n    message_status\nWHERE ? = ?,? = ?" 2 2 1 1]

而我想要类似的东西:

=> (get-status-sqlvec {:message_id 2 :user_id 1})
["SELECT\n    *\nFROM\n    message_status\nWHERE message_id = 2, user_id = 1"]

我终于设法使它工作了。 上面的代码有两个问题。

首先,我们有

(s/join ","
  (for [[field value] params]
    (str field " = " (keyword field)))

由于field是关键字,因此实际上会生成这种字符串:foo = :foo, :bar = :bar 然后将关键字替换为? 通过hugsql。 我们想要的是构建这种字符串foo = :foo, bar = :bar ,我们可以使用以下代码来完成:

(s/join ", "
  (for [[field _] params]
    (str (name field) " = " field))))))

第二个问题是WHEN子句甚至不是有效的SQL。 上面的代码最终生成如下请求:

SELECT * FROM message_status WHERE foo = 2, bar = 1

WHERE子句中的逗号应为AND ,因此最终的(有效的)代码为:

-- :name get-status
-- :doc fetch the status of a specific message
-- :command :query
-- :return :many
/* :require [clojure.string :as s] */
SELECT
    *
FROM
    message_status
/*~
(let [params (filter (comp some? val) params)]
  (when (not (empty? params))
    (str "WHERE "
      (s/join " AND "
              (for [[field _] params]
                (str (name field) " = " field))))))
~*/

暂无
暂无

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

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