/
json.clj
45 lines (37 loc) · 1.41 KB
/
json.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
(ns honey-ext.json
"Implements all the JSON operators available in postgres.
Docs here https://www.postgresql.org/docs/12/functions-json.html#FUNCTIONS-JSON-OP-TABLE."
(:require [clojure.string :as string]
[honey.sql :as sql]))
(defn- op->
[_ path]
(let [[sql-a & params] (sql/format-expr path)
fmt-sql (-> sql-a
(string/replace #"\(" "->")
(string/replace #", " "->")
(string/replace #"\)" ""))]
(-> [fmt-sql]
(into params))))
(sql/register-fn! :-> op->)
(sql/format {:select [:*]
:from [:honey]
:where [:-> :data "key"]})
;; => ["SELECT * FROM honey WHERE DATA->?" "key"]
(sql/format {:select [:*]
:from [:honey]
:where [:-> :data :?key]}
{:params {:key "key1"}})
;; => ["SELECT * FROM honey WHERE DATA->?" "key1"]
(sql/format {:select [:*]
:from [:honey]
:where [:-> :data :?key :?key2]}
{:params {:key "key1"
:key2 "key2"}})
;; => ["SELECT * FROM honey WHERE DATA->?->?" "key1" "key2"]
;; better syntax for path:
(sql/format {:select [:*]
:from [:honey]
:where [:-> :data :?path]}
{:params {:path ["key1" "key2"]}})
;; => ["SELECT * FROM honey WHERE DATA->?" ["key1" "key2"]] <<<-- wrong
;; => ["SELECT * FROM honey WHERE DATA->?->?" "key1" "key2"] <<<-- desired