(ns metabase.pulse.dashboard-subscription (:require [clojure.set :as set] [metabase.db.query :as mdb.query] [metabase.pulse.models.pulse :as models.pulse] [metabase.pulse.models.pulse-card :as pulse-card] [metabase.util :as u] [toucan2.core :as t2])) | |
Updates the pulses' names and collection IDs, and syncs the PulseCards TODO -- should this be done on | (defn update-dashboard-subscription-pulses!
[dashboard]
(let [dashboard-id (u/the-id dashboard)
affected (mdb.query/query
{:select-distinct [[:p.id :pulse-id] [:pc.card_id :card-id]]
:from [[:pulse :p]]
:join [[:pulse_card :pc] [:= :p.id :pc.pulse_id]]
:where [:= :p.dashboard_id dashboard-id]})]
(when-let [pulse-ids (seq (distinct (map :pulse-id affected)))]
(let [correct-card-ids (->> (mdb.query/query
{:select-distinct [:dc.card_id]
:from [[:report_dashboardcard :dc]]
:where [:and
[:= :dc.dashboard_id dashboard-id]
[:not= :dc.card_id nil]]})
(map :card_id)
set)
stale-card-ids (->> affected
(keep :card-id)
set)
cards-to-add (set/difference correct-card-ids stale-card-ids)
card-id->dashcard-id (when (seq cards-to-add)
(t2/select-fn->pk :card_id :model/DashboardCard :dashboard_id dashboard-id
:card_id [:in cards-to-add]))
positions-for (fn [pulse-id] (drop (pulse-card/next-position-for pulse-id)
(range)))
new-pulse-cards (for [pulse-id pulse-ids
[[card-id dashcard-id] position] (map vector
card-id->dashcard-id
(positions-for pulse-id))]
{:pulse_id pulse-id
:card_id card-id
:dashboard_card_id dashcard-id
:position position})]
(t2/with-transaction [_conn]
(binding [models.pulse/*allow-moving-dashboard-subscriptions* true]
(t2/update! :model/Pulse {:dashboard_id dashboard-id}
;; TODO we probably don't need this anymore
;; pulse.name is no longer used for generating title.
;; pulse.collection_id is a thing for the old "Pulse" feature, but it was removed
{:name (:name dashboard)
:collection_id (:collection_id dashboard)})
(pulse-card/bulk-create! new-pulse-cards))))))) |