Some small join-related helper functions which are used from a few different namespaces. | (ns metabase.lib.join.util (:require [metabase.lib.dispatch :as lib.dispatch] [metabase.lib.metadata :as lib.metadata] [metabase.lib.options :as lib.options] [metabase.lib.schema :as lib.schema] [metabase.lib.schema.common :as lib.schema.common] [metabase.lib.schema.join :as lib.schema.join] [metabase.lib.schema.metadata :as lib.schema.metadata] [metabase.lib.util :as lib.util] [metabase.util.malli :as mu])) |
A Join that may not yet have an | (def JoinWithOptionalAlias
[:merge
[:ref ::lib.schema.join/join]
[:map
[:alias {:optional true} [:ref ::lib.schema.join/alias]]]]) |
A join that may not yet have an | (def PartialJoin
[:merge
JoinWithOptionalAlias
[:map
[:conditions {:optional true} [:ref ::lib.schema.join/conditions]]]]) |
A field in a join, either | (def Field [:or [:ref ::lib.schema.metadata/column] [:ref :mbql.clause/field]]) |
A field or a partial join. | (def FieldOrPartialJoin [:or Field PartialJoin]) |
(mu/defn current-join-alias :- [:maybe ::lib.schema.common/non-blank-string]
"Get the current join alias associated with something, if it has one."
[field-or-join :- [:maybe FieldOrPartialJoin]]
(case (lib.dispatch/dispatch-value field-or-join)
:dispatch-type/nil nil
:field (:join-alias (lib.options/options field-or-join))
:metadata/column (:metabase.lib.join/join-alias field-or-join)
:mbql/join (:alias field-or-join))) | |
(mu/defn joined-field-desired-alias :- ::lib.schema.common/non-blank-string
"Desired alias for a Field that comes from a join, e.g.
MyJoin__my_field
You should pass the results thru a unique name function e.g. one returned
by [[metabase.lib.util/unique-name-generator]]."
[join-alias :- ::lib.schema.common/non-blank-string
field-name :- ::lib.schema.common/non-blank-string]
(lib.util/format "%s__%s" join-alias field-name)) | |
(mu/defn format-implicit-join-name :- ::lib.schema.common/non-blank-string
"Name for an implicit join against `table-name` via an FK field, e.g.
CATEGORIES__via__CATEGORY_ID
You should make sure this gets ran thru a unique-name fn e.g. one returned
by [[metabase.lib.util/unique-name-generator]]."
[table-name :- ::lib.schema.common/non-blank-string
source-field-id-name :- ::lib.schema.common/non-blank-string]
(lib.util/format "%s__via__%s" table-name source-field-id-name)) | |
(defn- implicit-join-name [query {:keys [fk-field-id table-id], :as _field-metadata}]
(when (and fk-field-id table-id)
(when-let [table (lib.metadata/table-or-card query table-id)]
(let [table-name (:name table)
source-field-id-name (:name (lib.metadata/field query fk-field-id))]
(format-implicit-join-name table-name source-field-id-name))))) | |
(mu/defn desired-alias :- ::lib.schema.common/non-blank-string
"Desired alias for a Field e.g.
my_field
OR
MyJoin__my_field
You should pass the results thru a unique name function."
[query :- ::lib.schema/query
field-metadata :- ::lib.schema.metadata/column]
(if-let [join-alias (or (current-join-alias field-metadata)
(implicit-join-name query field-metadata))]
(joined-field-desired-alias join-alias (:name field-metadata))
(:name field-metadata))) | |