Skip to content

Commit

Permalink
Optimize
Browse files Browse the repository at this point in the history
  • Loading branch information
Aitem committed Nov 2, 2023
1 parent 09ca3bb commit da1f153
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 25 deletions.
71 changes: 55 additions & 16 deletions src/dsql/core.clj
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
(ns dsql.core
(:require [clojure.string :as str])
(:import [java.util Iterator])
(:refer-clojure :exclude [format]))

(defn reduce-separated [sep acc f coll]
(defn fast-join [^String sep ^Iterable coll]
(let [^Iterator iter (.iterator coll)
builder (StringBuilder.)]
(loop []
(when (.hasNext iter)
(let [s (.next iter)]
(.append builder (.toString s))
(when (.hasNext iter)
(.append builder sep)))
(recur)))
(.toString builder)))

(defmacro build-string [& strs]
(let [w (gensym)]
`(let [~w (StringBuilder.)]
~@(map (fn [arg] `(.append ~w ~arg)) strs)
(.toString ~w))))

(defn reduce-separated-old [sep acc f coll]
(if (empty? coll)
acc
(loop [[x & xs] coll
Expand All @@ -12,6 +31,19 @@
acc'
(recur xs (conj acc' sep)))))))

(defn reduce-separated [sep acc f ^Iterable coll]
(if coll
(let [^Iterator iter (.iterator coll)]
(loop [acc acc]
(if (.hasNext iter)
(let [x (.next iter)
acc' (f acc x)]
(if (.hasNext iter)
(recur (conj acc' sep))
acc'))
acc)))
acc))

(defn reduce-separated2 [acc sep f coll]
(reduce-separated sep acc f coll))

Expand Down Expand Up @@ -40,11 +72,13 @@
(and (sequential? x) (first x))
(type x)))

(defn escape-string [s]
(str/replace s #"'" "''"))
(defn escape-string [^String s]
(when s
(.replace s "'" "''")))


(defn string-litteral [s]
(str "'" (escape-string (if (keyword? s) (name s) s)) "'"))
(build-string "'" (escape-string (if (keyword? s) (name s) s)) "'"))

(defn default-type [node tp]
(if (and (not (get-type node)) (map? node))
Expand Down Expand Up @@ -88,7 +122,7 @@
(name node)
(if (or (not (safe-identifier? norm-name))
(contains? keywords (keyword norm-name)))
(str "\"" (name node) "\"")
(build-string "\"" (name node) "\"")
(name node)))))

(defn parens [acc body-cb]
Expand All @@ -100,7 +134,7 @@
(let [norm-name (str/upper-case (name node))]
(if (or (not (safe-identifier? norm-name))
(contains? keywords (keyword norm-name)))
(str "\"" (name node) "\"")
(build-string "\"" (name node) "\"")
(name node))))

(defmethod to-sql
Expand All @@ -123,15 +157,20 @@
[acc _ _]
(conj acc "NULL"))


(defn format [opts node]
(let [sql-vec (to-sql [] opts node)]
(let [^Iterable sql-vec (to-sql [] opts node)
^Iterator iter (.iterator sql-vec)
builder (StringBuilder.)]
(assert (sequential? sql-vec) (pr-str sql-vec))
(loop [[x & xs] sql-vec
sql-str []
params []]
(let [[sql-str params] (if (vector? x)
[(conj sql-str (first x)) (conj params (second x))]
[(conj sql-str x) params])]
(if (empty? xs)
(into [(str/join " " sql-str)] params)
(recur xs sql-str params))))))
(loop [params []]
(when (.hasNext iter)
(let [x (.next iter)
params (if (vector? x) (conj params (nth x 1)) params)]
(.append builder (if (vector? x) (nth x 0) x))
(if (.hasNext iter)
(do
(.append builder " ")
(recur params))
(into [(.toString builder)] params)
))))))
30 changes: 21 additions & 9 deletions src/dsql/pg.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
[jsonista.core :as json]
[clojure.string :as str])
(:import [com.fasterxml.jackson.databind.node ObjectNode ArrayNode TextNode IntNode BooleanNode]
[com.fasterxml.jackson.databind JsonNode ObjectMapper])
[com.fasterxml.jackson.databind JsonNode ObjectMapper]
[java.util Iterator])
(:refer-clojure :exclude [format]))

(def keywords
Expand Down Expand Up @@ -389,7 +390,7 @@
(conj ")")
(conj (name k))
(conj "(")
(conj (str/join " , " (map name ks)))
(conj (ql/fast-join " , " (map name ks)))
(conj ")"))
(-> acc
(ql/to-sql opts sub-node)
Expand Down Expand Up @@ -493,7 +494,7 @@
(if (number? x)
x
(assert false (pr-str x)))))))
(str/join ",")))
(ql/fast-join ",")))


(defn- to-array-value [arr]
Expand Down Expand Up @@ -744,6 +745,7 @@
(defn format [node]
(ql/format {:resolve-type #'resolve-type :keywords keywords} (ql/default-type node :pg/select)))


(def keys-for-update
[[:set :pg/set]
[:from :pg/from]
Expand All @@ -756,7 +758,7 @@
(assert (:update data) "Key :update is required!")
(let [acc (conj acc "UPDATE")
acc (conj acc (if (map? (:update data))
(str/join " " (reverse (map name (first (:update data)))))
(ql/fast-join " " (reverse (map name (first (:update data)))))
(name (:update data))))]
(->> keys-for-update
(ql/reduce-acc
Expand Down Expand Up @@ -1117,7 +1119,7 @@
(fn [acc column val]
(cond
(vector? val)
(conj acc [(str "\"" (name column) "\"") (str/join " " (map name val))])
(conj acc [(str "\"" (name column) "\"") (ql/fast-join " " (map name val))])

(map? val)
(->> [(str "\"" (name column) "\"")
Expand All @@ -1141,7 +1143,7 @@
(fn [acc opt val]
(conj acc (str (name opt) " '" (name val) "'")))
[])
(str/join ", ")))
(ql/fast-join ", ")))

(defmethod ql/to-sql
:pg/create-table
Expand Down Expand Up @@ -1221,7 +1223,7 @@
(identifier opts tbl)
(cond-> (map? proj)
(-> (conj "(")
(conj (->> (keys proj) (sort) (mapv #(str "\"" (name %) "\"")) (str/join ", ")))
(conj (->> (keys proj) (sort) (mapv #(str "\"" (name %) "\"")) (ql/fast-join ", ")))
(conj ")")))
(ql/to-sql opts (assoc sel :ql/type :pg/sub-select))
(cond->
Expand Down Expand Up @@ -1377,8 +1379,18 @@
(ql/to-sql opts b)))


(defn concat-columns [cols]
(->> cols (mapv #(str "\"" (name %) "\"")) (str/join ", ")))
(defn concat-columns [^Iterable coll]
(let [^String sep ", "
^Iterator iter (.iterator coll)
builder (StringBuilder.)]
(loop []
(when (.hasNext iter)
(let [s (.next iter)]
(.append builder "\"") (.append builder (name s)) (.append builder "\"")
(when (.hasNext iter)
(.append builder sep)))
(recur)))
(.toString builder)))


(defmethod ql/to-sql
Expand Down

0 comments on commit da1f153

Please sign in to comment.