start work on nrql dialect #510
This commit is contained in:
parent
872cb1d006
commit
2c6b89751d
2 changed files with 81 additions and 25 deletions
|
|
@ -67,7 +67,9 @@
|
||||||
:order-by :limit :offset :fetch :for :lock :values
|
:order-by :limit :offset :fetch :for :lock :values
|
||||||
:on-conflict :on-constraint :do-nothing :do-update-set :on-duplicate-key-update
|
:on-conflict :on-constraint :do-nothing :do-update-set :on-duplicate-key-update
|
||||||
:returning
|
:returning
|
||||||
:with-data])
|
:with-data
|
||||||
|
;; NRQL extensions:
|
||||||
|
:since :until :compare-with :timeseries])
|
||||||
|
|
||||||
(defn add-clause-before
|
(defn add-clause-before
|
||||||
"Low-level helper just to insert a new clause.
|
"Low-level helper just to insert a new clause.
|
||||||
|
|
@ -108,7 +110,10 @@
|
||||||
:mysql {:quote #(strop \` % \`)
|
:mysql {:quote #(strop \` % \`)
|
||||||
:clause-order-fn
|
:clause-order-fn
|
||||||
#(add-clause-before % :set :where)}
|
#(add-clause-before % :set :where)}
|
||||||
:oracle {:quote #(strop \" % \") :as false}})))
|
:oracle {:quote #(strop \" % \") :as false}
|
||||||
|
:nrql {:quote #(strop \` % \`)
|
||||||
|
:col-fn #(if (keyword? %) (subs (str %) 1) (str %))
|
||||||
|
:parts-fn vector}})))
|
||||||
|
|
||||||
; should become defonce
|
; should become defonce
|
||||||
(def ^:private default-dialect (atom (:ansi @dialects)))
|
(def ^:private default-dialect (atom (:ansi @dialects)))
|
||||||
|
|
@ -225,6 +230,17 @@
|
||||||
(defn- ensure-sequential [xs]
|
(defn- ensure-sequential [xs]
|
||||||
(if (sequential? xs) xs [xs]))
|
(if (sequential? xs) xs [xs]))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(format {:select [:mulog/timestamp :mulog/event-name]
|
||||||
|
:from :Log
|
||||||
|
:where [:= :mulog/data.account "foo-account-id"]
|
||||||
|
:since [2 :days :ago]
|
||||||
|
:limit 2000}
|
||||||
|
{:dialect :nrql})
|
||||||
|
;; ["SELECT `mulog/timestamp`, `mulog/event-name` FROM Log
|
||||||
|
;; WHERE `mulog/data.account` = 'foo-account-id' LIMIT 2000 SINCE 2 DAYS AGO"]
|
||||||
|
)
|
||||||
|
|
||||||
(defn format-entity
|
(defn format-entity
|
||||||
"Given a simple SQL entity (a keyword or symbol -- or string),
|
"Given a simple SQL entity (a keyword or symbol -- or string),
|
||||||
return the equivalent SQL fragment (as a string -- no parameters).
|
return the equivalent SQL fragment (as a string -- no parameters).
|
||||||
|
|
@ -235,9 +251,10 @@
|
||||||
;; #497 quoted alias support (should behave like string)
|
;; #497 quoted alias support (should behave like string)
|
||||||
(subs (name e) 1)
|
(subs (name e) 1)
|
||||||
e)
|
e)
|
||||||
col-fn (if (or *quoted* (string? e))
|
col-fn (or (:col-fn *dialect*)
|
||||||
|
(if (or *quoted* (string? e))
|
||||||
(if *quoted-snake* name-_ name)
|
(if *quoted-snake* name-_ name)
|
||||||
name-_)
|
name-_))
|
||||||
col-e (col-fn e)
|
col-e (col-fn e)
|
||||||
dialect-q (:quote *dialect* identity)
|
dialect-q (:quote *dialect* identity)
|
||||||
quote-fn (cond (or *quoted* (string? e))
|
quote-fn (cond (or *quoted* (string? e))
|
||||||
|
|
@ -251,12 +268,14 @@
|
||||||
(dialect-q part)))
|
(dialect-q part)))
|
||||||
:else
|
:else
|
||||||
identity)
|
identity)
|
||||||
parts (if-let [n (when-not (or drop-ns (string? e))
|
parts-fn (or (:parts-fn *dialect*)
|
||||||
|
#(if-let [n (when-not (or drop-ns (string? e))
|
||||||
(namespace-_ e))]
|
(namespace-_ e))]
|
||||||
[n col-e]
|
[n %]
|
||||||
(if aliased
|
(if aliased
|
||||||
[col-e]
|
[%]
|
||||||
(str/split col-e #"\.")))
|
(str/split % #"\."))))
|
||||||
|
parts (parts-fn col-e)
|
||||||
entity (str/join "." (map #(cond-> % (not= "*" %) (quote-fn)) parts))
|
entity (str/join "." (map #(cond-> % (not= "*" %) (quote-fn)) parts))
|
||||||
suspicious #";"]
|
suspicious #";"]
|
||||||
(when-not *allow-suspicious-entities*
|
(when-not *allow-suspicious-entities*
|
||||||
|
|
@ -1287,6 +1306,16 @@
|
||||||
(let [tables (destructure-drop-columns params)]
|
(let [tables (destructure-drop-columns params)]
|
||||||
[(str/join ", " (mapv #(str (sql-kw k) " " %) tables))]))
|
[(str/join ", " (mapv #(str (sql-kw k) " " %) tables))]))
|
||||||
|
|
||||||
|
(defn- format-interval
|
||||||
|
[k [n & units]]
|
||||||
|
(if (seq units)
|
||||||
|
(let [[sql & params] (format-expr n)]
|
||||||
|
(into [(str (sql-kw k) " " sql " "
|
||||||
|
(str/join " " (map sql-kw units)))]
|
||||||
|
params))
|
||||||
|
(binding [*inline* true]
|
||||||
|
(let [[sql & params] (format-expr n)]
|
||||||
|
(into [(str (sql-kw k) " " sql)] params)))))
|
||||||
(defn- check-where
|
(defn- check-where
|
||||||
"Given a formatter function, performs a pre-flight check that there is
|
"Given a formatter function, performs a pre-flight check that there is
|
||||||
a non-empty where clause if at least basic checking is enabled."
|
a non-empty where clause if at least basic checking is enabled."
|
||||||
|
|
@ -1414,7 +1443,12 @@
|
||||||
;; MySQL-specific but might as well be always enabled:
|
;; MySQL-specific but might as well be always enabled:
|
||||||
:on-duplicate-key-update #'format-do-update-set
|
:on-duplicate-key-update #'format-do-update-set
|
||||||
:returning #'format-selects
|
:returning #'format-selects
|
||||||
:with-data #'format-with-data}))
|
:with-data #'format-with-data
|
||||||
|
;; NRQL extensions:
|
||||||
|
:since #'format-interval
|
||||||
|
:until #'format-interval
|
||||||
|
:compare-with #'format-interval
|
||||||
|
:timeseries #'format-interval}))
|
||||||
|
|
||||||
(assert (= (set @base-clause-order)
|
(assert (= (set @base-clause-order)
|
||||||
(set @current-clause-order)
|
(set @current-clause-order)
|
||||||
|
|
@ -1707,14 +1741,7 @@
|
||||||
(fn [_ [x]]
|
(fn [_ [x]]
|
||||||
(binding [*inline* true]
|
(binding [*inline* true]
|
||||||
(format-expr x)))
|
(format-expr x)))
|
||||||
:interval
|
:interval format-interval
|
||||||
(fn [_ [n units]]
|
|
||||||
(if units
|
|
||||||
(let [[sql & params] (format-expr n)]
|
|
||||||
(into [(str "INTERVAL " sql " " (sql-kw units))] params))
|
|
||||||
(binding [*inline* true]
|
|
||||||
(let [[sql & params] (format-expr n)]
|
|
||||||
(into [(str "INTERVAL " sql)] params)))))
|
|
||||||
:join
|
:join
|
||||||
(fn [_ [e & js]]
|
(fn [_ [e & js]]
|
||||||
(let [[sqls params] (reduce-sql (cons (format-expr e)
|
(let [[sqls params] (reduce-sql (cons (format-expr e)
|
||||||
|
|
@ -1932,12 +1959,14 @@
|
||||||
([data opts]
|
([data opts]
|
||||||
(let [cache (:cache opts)
|
(let [cache (:cache opts)
|
||||||
dialect? (contains? opts :dialect)
|
dialect? (contains? opts :dialect)
|
||||||
dialect (when dialect? (get @dialects (check-dialect (:dialect opts))))
|
dialect (if dialect?
|
||||||
|
(get @dialects (check-dialect (:dialect opts)))
|
||||||
|
@default-dialect)
|
||||||
numbered (if (contains? opts :numbered)
|
numbered (if (contains? opts :numbered)
|
||||||
(:numbered opts)
|
(:numbered opts)
|
||||||
@default-numbered)
|
@default-numbered)
|
||||||
formatter (if (map? data) #'format-dsl #'format-expr)]
|
formatter (if (map? data) #'format-dsl #'format-expr)]
|
||||||
(binding [*dialect* (if dialect? dialect @default-dialect)
|
(binding [*dialect* dialect
|
||||||
*caching* cache
|
*caching* cache
|
||||||
*checking* (if (contains? opts :checking)
|
*checking* (if (contains? opts :checking)
|
||||||
(:checking opts)
|
(:checking opts)
|
||||||
|
|
@ -1947,13 +1976,18 @@
|
||||||
(f @base-clause-order)
|
(f @base-clause-order)
|
||||||
@current-clause-order)
|
@current-clause-order)
|
||||||
@current-clause-order)
|
@current-clause-order)
|
||||||
*inline* (if (contains? opts :inline)
|
*inline* (cond (contains? opts :inline)
|
||||||
(:inline opts)
|
(:inline opts)
|
||||||
|
(= :nrql (:dialect dialect))
|
||||||
|
true
|
||||||
|
:else
|
||||||
@default-inline)
|
@default-inline)
|
||||||
*numbered* (when numbered
|
*numbered* (when numbered
|
||||||
(atom []))
|
(atom []))
|
||||||
*quoted* (cond (contains? opts :quoted)
|
*quoted* (cond (contains? opts :quoted)
|
||||||
(:quoted opts)
|
(:quoted opts)
|
||||||
|
(= :nrql (:dialect dialect))
|
||||||
|
nil
|
||||||
dialect?
|
dialect?
|
||||||
true
|
true
|
||||||
:else
|
:else
|
||||||
|
|
|
||||||
|
|
@ -1018,6 +1018,28 @@
|
||||||
[& args]
|
[& args]
|
||||||
(c/into [:within-group] args))
|
(c/into [:within-group] args))
|
||||||
|
|
||||||
|
;; nrql-specific helpers:
|
||||||
|
|
||||||
|
(defn since
|
||||||
|
"(since 2 :days :ago)"
|
||||||
|
[& args]
|
||||||
|
(generic :since args))
|
||||||
|
|
||||||
|
(defn until
|
||||||
|
"(until 1 :month :ago)"
|
||||||
|
[& args]
|
||||||
|
(generic :until args))
|
||||||
|
|
||||||
|
(defn compare-with
|
||||||
|
"(compare-with 1 :week :ago)"
|
||||||
|
[& args]
|
||||||
|
(generic :compare-with args))
|
||||||
|
|
||||||
|
(defn timeseries
|
||||||
|
"(timeseries 1 :week :ago)"
|
||||||
|
[& args]
|
||||||
|
(generic :timeseries args))
|
||||||
|
|
||||||
;; this helper is intended to ease the migration from nilenso:
|
;; this helper is intended to ease the migration from nilenso:
|
||||||
(defn upsert
|
(defn upsert
|
||||||
"Provided purely to ease migration from nilenso/honeysql-postgres
|
"Provided purely to ease migration from nilenso/honeysql-postgres
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue