diff --git a/.dir-locals.el b/.dir-locals.el index ae707415c299e421c768d7dbbc1daf462981fdb6..77cd0b4d233faf161a6877b12da140a35d5cf025 100644 --- a/.dir-locals.el +++ b/.dir-locals.el @@ -15,8 +15,6 @@ (check 1) (checkp 1) (cond-as-> 2) - (cond-let 0) - (conda 0) (context 2) (create-database-definition 1) (engine-case 0) diff --git a/src/metabase/driver.clj b/src/metabase/driver.clj index 2d6c28b12a09311f082ff078dfcbed2a3f14ec1b..4ba66233f79348e0ec51d492cc129274a414de68 100644 --- a/src/metabase/driver.clj +++ b/src/metabase/driver.clj @@ -484,10 +484,11 @@ "Save QueryExecution state and construct a completed (successful) query response" [query-execution query-result] ;; record our query execution and format response - (-> (u/assoc<> query-execution + (-> (assoc query-execution :status :completed :finished_at (u/new-sql-timestamp) - :running_time (- (System/currentTimeMillis) (:start_time_millis <>)) + :running_time (- (System/currentTimeMillis) + (:start_time_millis query-execution)) :result_rows (get query-result :row_count 0)) (dissoc :start_time_millis) (save-query-execution) diff --git a/src/metabase/driver/query_processor.clj b/src/metabase/driver/query_processor.clj index 88f0da8e916b7fa4e544ac8b7d553432efc12799..b0793866aa602f6e84c54524c964680fa9ec5a74 100644 --- a/src/metabase/driver/query_processor.clj +++ b/src/metabase/driver/query_processor.clj @@ -122,9 +122,7 @@ (let [report-tz (driver/report-timezone)] (when-not (empty? report-tz) report-tz)))}] - (->> (u/filter-nil-values settings) - (assoc query :settings) - qp)))) + (qp (assoc query :settings (m/filter-vals (complement nil?) settings)))))) (defn- pre-expand-macros diff --git a/src/metabase/models/metric.clj b/src/metabase/models/metric.clj index 8904b44313c1794139fe90700ea6de7bd0552521..97eeb71b90dd2b573f5b4e462a8ff42abdad5692 100644 --- a/src/metabase/models/metric.clj +++ b/src/metabase/models/metric.clj @@ -1,5 +1,6 @@ (ns metabase.models.metric (:require [korma.core :as k] + [medley.core :as m] [metabase.db :as db] [metabase.events :as events] (metabase.models [dependency :as dependency] @@ -30,17 +31,17 @@ (defn- diff-metrics [this metric1 metric2] (if-not metric1 ;; this is the first version of the metric - (u/update-values (select-keys metric2 [:name :description :definition]) (fn [v] {:after v})) + (m/map-vals (fn [v] {:after v}) (select-keys metric2 [:name :description :definition])) ;; do our diff logic (let [base-diff (revision/default-diff-map this (select-keys metric1 [:name :description :definition]) (select-keys metric2 [:name :description :definition]))] (cond-> (merge-with merge - (u/update-values (:after base-diff) (fn [v] {:after v})) - (u/update-values (:before base-diff) (fn [v] {:before v}))) - (or (get-in base-diff [:after :definition]) - (get-in base-diff [:before :definition])) (assoc :definition {:before (get-in metric1 [:definition]) - :after (get-in metric2 [:definition])}))))) + (m/map-vals (fn [v] {:after v}) (:after base-diff)) + (m/map-vals (fn [v] {:before v}) (:before base-diff))) + (or (get-in base-diff [:after :definition]) + (get-in base-diff [:before :definition])) (assoc :definition {:before (get-in metric1 [:definition]) + :after (get-in metric2 [:definition])}))))) (u/strict-extend (class Metric) revision/IRevisioned diff --git a/src/metabase/models/segment.clj b/src/metabase/models/segment.clj index e0f601811b9d60f465d628eae4f135cbbacad70b..9a9d4eeca7b176defdba34e95a750c4b814b02a9 100644 --- a/src/metabase/models/segment.clj +++ b/src/metabase/models/segment.clj @@ -1,5 +1,6 @@ (ns metabase.models.segment (:require [korma.core :as k] + [medley.core :as m] [metabase.db :as db] [metabase.events :as events] (metabase.models [hydrate :refer [hydrate]] @@ -29,14 +30,14 @@ (defn- diff-segments [this segment1 segment2] (if-not segment1 ;; this is the first version of the segment - (u/update-values (select-keys segment2 [:name :description :definition]) (fn [v] {:after v})) + (m/map-vals (fn [v] {:after v}) (select-keys segment2 [:name :description :definition])) ;; do our diff logic (let [base-diff (revision/default-diff-map this (select-keys segment1 [:name :description :definition]) (select-keys segment2 [:name :description :definition]))] (cond-> (merge-with merge - (u/update-values (:after base-diff) (fn [v] {:after v})) - (u/update-values (:before base-diff) (fn [v] {:before v}))) + (m/map-vals (fn [v] {:after v}) (:after base-diff)) + (m/map-vals (fn [v] {:before v}) (:before base-diff))) (or (get-in base-diff [:after :definition]) (get-in base-diff [:before :definition])) (assoc :definition {:before (get-in segment1 [:definition]) :after (get-in segment2 [:definition])}))))) diff --git a/src/metabase/util.clj b/src/metabase/util.clj index 97f9ecc50ac1aad0abba2a5498c402adc2ba26d2..7db4321ee1d9bb9df8441792a22e00952b08027e 100644 --- a/src/metabase/util.clj +++ b/src/metabase/util.clj @@ -114,10 +114,6 @@ (^String [date-format date] (time/unparse (->DateTimeFormatter date-format) (coerce/from-long (.getTime (->Timestamp date)))))) -(def ^{:arglists '([] [date])} date->yyyy-mm-dd - "Format DATE as a `YYYY-MM-DD` string." - (partial format-date "yyyy-MM-dd")) - (def ^{:arglists '([] [date])} date->iso-8601 "Format DATE a an ISO-8601 string." (partial format-date :date-time)) @@ -250,35 +246,6 @@ ;;; ## Etc -(defmacro assoc<> - "Like `assoc`, but associations happen sequentially; i.e. each successive binding can build - upon the result of the previous one using `<>`. - - (assoc<> {} - :a 100 - :b (+ 100 (:a <>)) ; -> {:a 100 :b 200}" - {:style/indent 1} - [object & kvs] - ;; wrap in a `fn` so this can be used in `->`/`->>` forms - `((fn [~'<>] - (let [~@(apply concat (for [[k v] (partition 2 kvs)] - ['<> `(assoc ~'<> ~k ~v)]))] - ~'<>)) - ~object)) - -(defn format-num - "format a number into a more human readable form." - [number] - {:pre [(number? number)]} - (let [decimal-type? #(or (float? %) (decimal? %))] - (cond - ;; looks like this is a decimal number, format with precision of 2 - (and (decimal-type? number) (not (zero? (mod number 1)))) (format "%,.2f" number) - ;; this is a decimal type number with no actual decimal value, so treat it as a whole number - (decimal-type? number) (format "%,d" (long number)) - ;; otherwise this is a whole number - :else (format "%,d" number)))) - (defprotocol ^:private IClobToStr (jdbc-clob->str ^String [this] "Convert a Postgres/H2/SQLServer JDBC Clob to a string.")) @@ -337,19 +304,6 @@ (if (pred? (first args)) [(first args) (next args)] [default args])) -;; provided courtesy of Jay Fields http://blog.jayfields.com/2011/08/clojure-apply-function-to-each-value-of.html -(defn update-values - "Update the values of a map by applying the given function. - Function expects the map value as an arg and optionally accepts additional args as passed." - [m f & args] - (reduce (fn [r [k v]] (assoc r k (apply f v args))) {} m)) - -(defn filter-nil-values - "Remove any keys from a MAP when the value is `nil`." - [m] - (into {} (for [[k v] m - :when (not (nil? v))] - {k v}))) (defn is-email? "Is STRING a valid email address?" @@ -477,13 +431,6 @@ ([color-symb x] ((ns-resolve 'colorize.core color-symb) (pprint-to-str x)))) -(defmacro cond-let - "Like `if-let` or `when-let`, but for `cond`." - [binding-form then-form & more] - `(if-let ~binding-form ~then-form - ~(when (seq more) - `(cond-let ~@more)))) - (defn filtered-stacktrace "Get the stack trace associated with E and return it as a vector with non-metabase frames filtered out." [^Throwable e] @@ -538,42 +485,6 @@ [& body] `(try ~@body (catch Throwable ~'_))) - -(defn wrap-try-catch! - "Re-intern FN-SYMB as a new fn that wraps the original with a `try-catch`. Intended for debugging. - - (defn z [] (throw (Exception. \"!\"))) - (z) ; -> exception - - (wrap-try-catch! 'z) - (z) ; -> nil; exception logged with log/error" - [fn-symb] - {:pre [(symbol? fn-symb) - (fn? @(resolve fn-symb))]} - (let [varr (resolve fn-symb) - {nmspc :ns, symb :name} (meta varr)] - (println (format "wrap-try-catch! %s/%s" nmspc symb)) - (intern nmspc symb (wrap-try-catch @varr fn-symb)))) - -(defn ns-wrap-try-catch! - "Re-intern all functions in NAMESPACE as ones that wrap the originals with a `try-catch`. - Defaults to the current namespace. You may optionally exclude a set of symbols using the kwarg `:exclude`. - - (ns-wrap-try-catch!) - (ns-wrap-try-catch! 'metabase.driver) - (ns-wrap-try-catch! 'metabase.driver :exclude 'query-complete) - - Intended for debugging." - {:arglists '([namespace? :exclude & excluded-symbs])} - [& args] - (let [[nmspc args] (optional #(try-apply the-ns [%]) args *ns*) - excluded (when (= (first args) :exclude) - (set (rest args)))] - (doseq [[symb varr] (ns-interns nmspc)] - (when (fn? @varr) - (when-not (contains? excluded symb) - (wrap-try-catch! (symbol (str (ns-name nmspc) \/ symb)))))))) - (defn deref-with-timeout "Call `deref` on a FUTURE and throw an exception if it takes more than TIMEOUT-MS." [futur timeout-ms] diff --git a/test/metabase/util_test.clj b/test/metabase/util_test.clj index f3b3b1d2d26fbe1d7863aa3815cf79c23433de52..f62b3a0e7d48977005c32bf0ee6e045438af8941 100644 --- a/test/metabase/util_test.clj +++ b/test/metabase/util_test.clj @@ -46,17 +46,6 @@ (expect #inst "2015-11-01" (date-trunc :month friday-the-13th)) (expect #inst "2015-10-01" (date-trunc :quarter friday-the-13th)) -;;; ## tests for ASSOC<> - -(expect - {:a 100 - :b 200 - :c 300} - (assoc<> {} - :a 100 - :b (+ 100 (:a <>)) - :c (+ 100 (:b <>)))) - ;;; ## tests for HOST-UP? (expect true @@ -71,36 +60,6 @@ (host-port-up? "nosuchhost" 8005)) -;; ## tests for `(format-num)` - -;; basic whole number case -(expect "1" (format-num 1)) -(expect "1" (format-num (float 1))) -(expect "1" (format-num (double 1))) -(expect "1" (format-num (bigdec 1))) -(expect "1" (format-num (long 1))) -;; make sure we correctly format down to 2 decimal places -;; note that we are expecting a round DOWN in this case -(expect "1.23" (format-num (float 1.23444))) -(expect "1.23" (format-num (double 1.23444))) -(expect "1.23" (format-num (bigdec 1.23444))) -;; test that we always force precision of 2 on decimal places -(expect "1.20" (format-num (float 1.2))) -(expect "1.20" (format-num (double 1.2))) -(expect "1.20" (format-num (bigdec 1.2))) -;; we can take big numbers and add in commas -(expect "1,234" (format-num 1234)) -(expect "1,234" (format-num (float 1234))) -(expect "1,234" (format-num (double 1234))) -(expect "1,234" (format-num (bigdec 1234))) -(expect "1,234" (format-num (long 1234))) -;; we can handle numbers with both commas and decimal places -;; note that we expect a basic round UP here -(expect "1,234.57" (format-num (float 1234.5678))) -(expect "1,234.57" (format-num (double 1234.5678))) -(expect "1,234.57" (format-num (bigdec 1234.5678))) - - ;;; ## tests for IS-URL? (expect true (is-url? "http://google.com"))