[英]Building WHEN clause with a clojure expression in hugsql
I have a database with a status
entity that I'd like to be able to fetch in many different ways. 我有一个带有
status
实体的数据库,我希望能够以许多不同的方式获取它。 As a result, I'd like to build the WHEN
clause of my query based on the content of a map. 结果,我想基于地图的内容构建查询的
WHEN
子句。
For instance, like this: 例如,像这样:
(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.
I'm struggling using hubsql's clojure expressions . 我正在努力使用hubsql的clojure表达式 。 I am doing the following:
我正在执行以下操作:
-- :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)))))))
~*/
However, here is how the request is prepared by hugsql: 但是,以下是hugsql如何准备请求:
=> (get-status-sqlvec {:message_id 2 :user_id 1})
["SELECT\n *\nFROM\n message_status\nWHERE ? = ?,? = ?" 2 2 1 1]
Whereas I want something like: 而我想要类似的东西:
=> (get-status-sqlvec {:message_id 2 :user_id 1})
["SELECT\n *\nFROM\n message_status\nWHERE message_id = 2, user_id = 1"]
I finally managed to get this working. 我终于设法使它工作了。 The above code had two issues.
上面的代码有两个问题。
First, we have 首先,我们有
(s/join ","
(for [[field value] params]
(str field " = " (keyword field)))
Since field
is a keyword, this actually generates this kind of string: :foo = :foo, :bar = :bar
. 由于
field
是关键字,因此实际上会生成这种字符串:foo = :foo, :bar = :bar
。 The keywords are then replaced by ?
然后将关键字替换为
?
by hugsql. 通过hugsql。 What we want instead is build this kind of string
foo = :foo, bar = :bar
, which we can do with this code: 我们想要的是构建这种字符串
foo = :foo, bar = :bar
,我们可以使用以下代码来完成:
(s/join ", "
(for [[field _] params]
(str (name field) " = " field))))))
The second problem is that the WHEN
clause is not even valid SQL. 第二个问题是
WHEN
子句甚至不是有效的SQL。 The above code ends up generating requests such as: 上面的代码最终生成如下请求:
SELECT * FROM message_status WHERE foo = 2, bar = 1
The commas in the WHERE
clause should be AND
, so the final (working) code is: 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.