(ns metabase.lib.common (:require [metabase.lib.dispatch :as lib.dispatch] [metabase.lib.hierarchy :as lib.hierarchy] [metabase.lib.ident :as lib.ident] [metabase.lib.options :as lib.options] [metabase.lib.ref :as lib.ref] [metabase.lib.schema.common :as schema.common] [metabase.util :as u] [metabase.util.malli :as mu]) #?(:cljs (:require-macros [metabase.lib.common]))) | |
(comment lib.options/keep-me
mu/keep-me) | |
(mu/defn external-op :- [:maybe ::schema.common/external-op]
"Convert the internal operator `clause` to the external format."
[[operator options :as clause]]
(when clause
{:lib/type :lib/external-op
:operator (cond-> operator
(keyword? operator) name)
:options options
:args (subvec clause 2)})) | |
Ensures that clause arguments are properly unwrapped | (defmulti ->op-arg
{:arglists '([x])}
lib.dispatch/dispatch-value
:hierarchy lib.hierarchy/hierarchy) |
(defmethod ->op-arg :default
[x]
(if (and (vector? x)
(keyword? (first x)))
;; MBQL clause
(mapv ->op-arg x)
;; Something else - just return it
x)) | |
(defmethod ->op-arg :dispatch-type/sequential [xs] (mapv ->op-arg xs)) | |
(defmethod ->op-arg :dispatch-type/regex [regex] (u/regex->str regex)) | |
(defmethod ->op-arg :metadata/column [field-metadata] (lib.ref/ref field-metadata)) | |
(defmethod ->op-arg :metadata/metric [metric-def] (lib.ref/ref metric-def)) | |
(defmethod ->op-arg :metadata/segment [segment-def] (lib.ref/ref segment-def)) | |
(defmethod ->op-arg :lib/external-op
[{:keys [operator options args] :or {options {}}}]
(->op-arg (lib.options/ensure-uuid (into [(keyword operator) options]
(map ->op-arg)
args)))) | |
Given an MBQL clause, ensure that it has an | (defn ensure-ident [clause] (lib.options/update-options clause update :ident #(or % (lib.ident/random-ident)))) |
Given two clauses, preserve the | (defn preserve-ident-of
[replacement original]
(if-let [ident (lib.options/ident original)]
(lib.options/update-options replacement assoc :ident ident)
replacement)) |
Impl for [[defop]]. | (defn defop-create
[op-name args]
(into [op-name {:lib/uuid (str (random-uuid))}]
(map ->op-arg)
args)) |
Defines a clause creating function with given args. Calling the clause without query and stage produces a fn that can be resolved later. | #?(:clj
(defmacro defop
[op-name & argvecs]
{:pre [(symbol? op-name)
(every? vector? argvecs) (every? #(every? symbol? %) argvecs)
(every? #(not-any? #{'query 'stage-number} %) argvecs)]}
`(mu/defn ~op-name :- ~(keyword "mbql.clause" (name op-name))
~(format "Create a standalone clause of type `%s`." (name op-name))
~@(for [argvec argvecs
:let [arglist-expr (if (contains? (set argvec) '&)
(cons `list* (remove #{'&} argvec))
argvec)]]
`([~@argvec]
(defop-create ~(keyword op-name) ~arglist-expr)))))) |