Skip to content

Commit

Permalink
PG insert jackson support
Browse files Browse the repository at this point in the history
  • Loading branch information
Aitem committed Oct 16, 2023
1 parent 1d733a6 commit 9e10746
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 14 deletions.
6 changes: 4 additions & 2 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
cheshire/cheshire {:mvn/version "5.11.0"}}
:deps {org.clojure/clojure {:mvn/version "1.11.1"}
cheshire/cheshire {:mvn/version "5.11.0"}
com.fasterxml.jackson.core/jackson-core {:mvn/version "2.15.2"}
com.fasterxml.jackson.core/jackson-databind {:mvn/version "2.15.2"}}

:aliases
{:dev
Expand Down
1 change: 1 addition & 0 deletions src/dsql/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
(meta node)))))

(defn dispatch-sql [opts x]
(prn "->>> " x)
(or
(get-type x)
(when-let [resolver (:resolve-type opts)]
Expand Down
59 changes: 48 additions & 11 deletions src/dsql/pg.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
(:require [dsql.core :as ql]
[cheshire.core]
[clojure.string :as str])
(:import [com.fasterxml.jackson.databind.node ObjectNode ArrayNode TextNode IntNode BooleanNode]
[com.fasterxml.jackson.databind JsonNode ObjectMapper])
(:refer-clojure :exclude [format]))

(def keywords
Expand Down Expand Up @@ -100,6 +102,9 @@
;; [ FETCH { FIRST | NEXT } [ число ] { ROW | ROWS } ONLY ]
;; [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF имя_таблицы [, ...] ] [ NOWAIT | SKIP LOCKED ] [...] ]


(defonce ^ObjectMapper object-mapper (ObjectMapper.))

(defn acc-identity [acc & _]
acc)

Expand Down Expand Up @@ -402,6 +407,20 @@
(conj acc (ql/string-litteral (cheshire.core/generate-string (second v))))
(conj acc (ql/string-litteral (cheshire.core/generate-string v)))))

(defn to-json-string [^JsonNode json]
(.writeValueAsString object-mapper json))

(defn jackson-param [acc v] (conj acc ["?" (to-json-string v)]))
(defn jackson-param-as-text [acc ^JsonNode v] (conj acc ["?" (.asText v)]))

(defmethod ql/to-sql ObjectNode [acc opts v] (jackson-param acc v))
(defmethod ql/to-sql ArrayNode [acc opts v] (jackson-param acc v))
(defmethod ql/to-sql TextNode [acc opts v] (jackson-param-as-text acc v))
(defmethod ql/to-sql IntNode [acc opts v] (jackson-param-as-text acc v))
(defmethod ql/to-sql BooleanNode [acc opts v] (jackson-param-as-text acc v))



(defmethod ql/to-sql
:pg/obj
[acc opts obj]
Expand Down Expand Up @@ -659,14 +678,14 @@
(defn resolve-type [x]
(if-let [m (meta x)]
(cond
(:pg/op m) :pg/op
(:pg/fn m) :pg/fn
(:pg/obj m) :pg/obj
(:jsonb/obj m) :jsonb/obj
(:jsonb/array m) :jsonb/array
(:pg/jsonb m) :pg/jsonb
(:pg/kfn m) :pg/kfn
(:pg/select m) :pg/select
(:pg/op m) :pg/op
(:pg/fn m) :pg/fn
(:pg/obj m) :pg/obj
(:jsonb/obj m) :jsonb/obj
(:jsonb/array m) :jsonb/array
(:pg/jsonb m) :pg/jsonb
(:pg/kfn m) :pg/kfn
(:pg/select m) :pg/select
(:pg/sub-select m) :pg/sub-select
:else nil)))

Expand Down Expand Up @@ -1379,10 +1398,23 @@
ret (-> (conj "RETURNING")
(ql/to-sql opts ret))))))


(defn jackson-get-keys [^ObjectNode object]
(let [it (.fieldNames object)]
(loop [keys []]
(if (.hasNext it)
(recur (conj keys (.next it)))
keys))))

(defn get-by-key [^ObjectNode node ^String key]
(.get node key))

(defmethod ql/to-sql
:pg/insert
[acc opts {tbl :into vls :value ret :returning on-conflict :on-conflict}]
(let [cols (->> (keys vls) (sort))]
[acc opts {tbl :into vls :value jackson :jackson-value ret :returning on-conflict :on-conflict}]
(let [cols (if jackson
(jackson-get-keys jackson)
(->> (keys vls) (sort)))]
(-> acc
(conj "INSERT INTO")
(conj (name tbl))
Expand All @@ -1391,7 +1423,12 @@
(conj ")")
(conj "VALUES")
(conj "(")
(ql/reduce-separated2 "," (fn [acc c] (ql/to-sql acc opts (get vls c))) cols)
(ql/reduce-separated2
","
(if jackson
(fn [acc c] (ql/to-sql acc opts (get-by-key jackson c)))
(fn [acc c] (ql/to-sql acc opts (get vls c))))
cols)
(conj ")")
(cond->
on-conflict (-> (conj "ON CONFLICT")
Expand Down
33 changes: 32 additions & 1 deletion test/dsql/pg_test.clj
Original file line number Diff line number Diff line change
@@ -1,14 +1,45 @@
(ns dsql.pg-test
(:require [dsql.pg :as sut]
[clojure.test :refer [deftest is testing]]
[dsql.core :as ql]))
[cheshire.core])
(:import [com.fasterxml.jackson.databind JsonNode ObjectMapper]))

(defmacro format= [q patt]
`(let [res# (sut/format ~q)]
(is (= ~patt res#))
res#))


(defonce ^ObjectMapper object-mapper (ObjectMapper.))
;; Only for tests purproses
(defn to-jackson [o] (.readTree object-mapper (cheshire.core/generate-string o)) )

(deftest test-dsql-pgi



(testing "jackson"
(def r
{:id "fd209869-1f1c-42eb-b0bf-b5942370452c"
:meta_partition 123
:birthDate "1991-11-08"
:name [{:given "Ibragim"}]
:deceasedBoolean false
:extension {:foo "bar"}} )
(format=
{:ql/type :pg/insert
:into :patient
:jackson-value (to-jackson r)
:returning :*}
["INSERT INTO patient ( \"id\", \"meta_partition\", \"birthDate\", \"name\", \"deceasedBoolean\", \"extension\" ) VALUES ( ? , ? , ? , ? , ? , ? ) RETURNING *"
"fd209869-1f1c-42eb-b0bf-b5942370452c"
"123"
"1991-11-08"
"[{\"given\":\"Ibragim\"}]"
"false"
"{\"foo\":\"bar\"}"])
)

(testing "select"
(format=
{:ql/type :pg/projection
Expand Down

0 comments on commit 9e10746

Please sign in to comment.