(ns metabase.lib.metadata.composed-provider (:require #?(:clj [pretty.core :as pretty]) [clojure.core.protocols] [clojure.datafy :as datafy] [clojure.set :as set] [medley.core :as m] [metabase.lib.metadata.protocols :as metadata.protocols])) | |
(defn- cached-providers [providers] (filter metadata.protocols/cached-metadata-provider? providers)) | |
(defn- invocation-tracker-providers [providers]
(filter #(satisfies? metadata.protocols/InvocationTracker %)
providers)) | |
(defn- metadatas-for-f [f providers metadata-type ids]
(loop [[provider & more-providers] providers, unfetched-ids (set ids), fetched []]
(cond
(empty? unfetched-ids)
fetched
(not provider)
fetched
:else
(let [newly-fetched (f provider metadata-type unfetched-ids)
newly-fetched-ids (into #{} (map :id) newly-fetched)
unfetched-ids (set/difference unfetched-ids newly-fetched-ids)]
(recur more-providers
unfetched-ids
(into fetched newly-fetched)))))) | |
(defn- metadatas [providers metadata-type ids] (metadatas-for-f metadata.protocols/metadatas providers metadata-type ids)) | |
(defn- cached-metadatas [providers metadata-type ids]
(metadatas-for-f metadata.protocols/cached-metadatas
(cached-providers providers)
metadata-type
ids)) | |
(defn- store-metadata! [metadata-providers metadata]
(when-first [provider (cached-providers metadata-providers)]
(metadata.protocols/store-metadata! provider metadata))) | |
(defn- tables [metadata-providers] (m/distinct-by :id (mapcat metadata.protocols/tables metadata-providers))) | |
(defn- metadatas-for-table [metadata-type table-id metadata-providers]
(into []
(comp
(mapcat (fn [provider]
(metadata.protocols/metadatas-for-table provider metadata-type table-id)))
(m/distinct-by :id))
metadata-providers)) | |
(defn- metadatas-for-card [metadata-type card-id metadata-providers]
(into []
(comp
(mapcat (fn [provider]
(metadata.protocols/metadatas-for-card provider metadata-type card-id)))
(m/distinct-by :id))
metadata-providers)) | |
(defn- setting [metadata-providers setting-key]
(some (fn [provider]
(metadata.protocols/setting provider setting-key))
metadata-providers)) | |
(deftype ComposedMetadataProvider [metadata-providers]
metadata.protocols/MetadataProvider
(database [_this]
(some metadata.protocols/database metadata-providers))
(metadatas [_this metadata-type ids]
(metadatas metadata-providers metadata-type ids))
(tables [_this]
(tables metadata-providers))
(metadatas-for-table [_this metadata-type table-id]
(metadatas-for-table metadata-type table-id metadata-providers))
(metadatas-for-card [_this metadata-type card-id]
(metadatas-for-card metadata-type card-id metadata-providers))
(setting [_this setting-key]
(setting metadata-providers setting-key))
metadata.protocols/CachedMetadataProvider
(cached-metadatas [_this metadata-type metadata-ids]
(cached-metadatas metadata-providers metadata-type metadata-ids))
(store-metadata! [_this metadata]
(store-metadata! metadata-providers metadata))
metadata.protocols/InvocationTracker
(invoked-ids [_this metadata-type]
(when-first [provider (invocation-tracker-providers metadata-providers)]
(metadata.protocols/invoked-ids provider metadata-type)))
#?(:clj Object :cljs IEquiv)
(#?(:clj equals :cljs -equiv) [_this another]
(and (instance? ComposedMetadataProvider another)
(= metadata-providers
(.-metadata-providers ^ComposedMetadataProvider another))))
clojure.core.protocols/Datafiable
(datafy [_this]
(cons `composed-metadata-provider (map datafy/datafy metadata-providers)))
#?@(:clj
[pretty/PrettyPrintable
(pretty [_this]
(list* `composed-metadata-provider metadata-providers))])) | |
A metadata provider composed of several different | (defn composed-metadata-provider [& metadata-providers] (->ComposedMetadataProvider metadata-providers)) |