Utility functions used by the Queries in metabase-lib. | (ns metabase.xrays.domain-entities.queries.util (:require #?@(:cljs ([metabase.xrays.domain-entities.converters :as converters])) [metabase.util.malli :as mu])) |
Schema for an Expression that's part of a query filter. | (def Expression :any) |
Malli schema for a map of expressions by name. | (def ExpressionMap [:map-of string? Expression]) |
Malli schema for a list of {:name :expression} maps. | (def ExpressionList [:vector [:map [:name string?] [:expression Expression]]]) |
(def ^:private ->expression-map
#?(:cljs (converters/incoming ExpressionMap)
:clj identity)) | |
(def ^:private expression-list->
#?(:cljs (converters/outgoing ExpressionList)
:clj identity)) | |
(mu/defn ^:export expressions-list :- ExpressionList
"Turns a map of expressions by name into a list of `{:name name :expression expression}` objects."
[expressions :- ExpressionMap]
(->> expressions
->expression-map
(mapv (fn [[name expr]] {:name name :expression expr}))
expression-list->)) | |
(defn- unique-name [names original-name index]
(let [indexed-name (str original-name " (" index ")")]
(if (names indexed-name)
(recur names original-name (inc index))
indexed-name))) | |
(mu/defn ^:export unique-expression-name :- string?
"Generates an expression name that's unique in the given map of expressions."
[expressions :- ExpressionMap
original-name :- string?]
(let [expression-names (-> expressions ->expression-map keys set)]
(if (not (expression-names original-name))
original-name
(let [re-duplicates (re-pattern (str "^" original-name " \\([0-9]+\\)$"))
duplicates (set (filter #(or (= % original-name)
(re-matches re-duplicates %))
expression-names))]
(unique-name duplicates original-name (count duplicates)))))) | |