/api/segment endpoints. | (ns metabase.segments.api (:require [metabase.api.common :as api] [metabase.api.macros :as api.macros] [metabase.events :as events] [metabase.legacy-mbql.normalize :as mbql.normalize] [metabase.models.interface :as mi] [metabase.util :as u] [metabase.util.log :as log] [metabase.util.malli :as mu] [metabase.util.malli.schema :as ms] [metabase.xrays.core :as xrays] [toucan2.core :as t2])) |
(api.macros/defendpoint :post "/" "Create a new `Segment`." [_route-params _query-params {:keys [name description table_id definition], :as body} :- [:map [:name ms/NonBlankString] [:table_id ms/PositiveInt] [:definition ms/Map] [:description {:optional true} [:maybe :string]]]] ;; TODO - why can't we set other properties like `show_in_getting_started` when we create the Segment? (api/create-check :model/Segment body) (let [segment (api/check-500 (first (t2/insert-returning-instances! :model/Segment :table_id table_id :creator_id api/*current-user-id* :name name :description description :definition definition)))] (events/publish-event! :event/segment-create {:object segment :user-id api/*current-user-id*}) (t2/hydrate segment :creator))) | |
(mu/defn- hydrated-segment [id :- ms/PositiveInt] (-> (api/read-check (t2/select-one :model/Segment :id id)) (t2/hydrate :creator))) | |
(api.macros/defendpoint :get "/:id" "Fetch `Segment` with ID." [{:keys [id]} :- [:map [:id ms/PositiveInt]]] (hydrated-segment id)) | |
(api.macros/defendpoint :get "/" "Fetch *all* `Segments`." [] (as-> (t2/select :model/Segment, :archived false, {:order-by [[:%lower.name :asc]]}) segments (filter mi/can-read? segments) (t2/hydrate segments :creator :definition_description))) | |
Check whether current user has write permissions, then update Segment with values in | (defn- write-check-and-update-segment! [id {:keys [revision_message], :as body}] (let [existing (api/write-check :model/Segment id) clean-body (u/select-keys-when body :present #{:description :caveats :points_of_interest} :non-nil #{:archived :definition :name :show_in_getting_started}) new-def (->> clean-body :definition (mbql.normalize/normalize-fragment [])) new-body (merge (dissoc clean-body :revision_message) (when new-def {:definition new-def})) changes (when-not (= new-body existing) new-body) archive? (:archived changes)] (when changes (t2/update! :model/Segment id changes)) (u/prog1 (hydrated-segment id) (events/publish-event! (if archive? :event/segment-delete :event/segment-update) {:object <> :user-id api/*current-user-id* :revision-message revision_message})))) |
(api.macros/defendpoint :put "/:id" "Update a `Segment` with ID." [{:keys [id]} :- [:map [:id ms/PositiveInt]] _query-params body :- [:map [:name {:optional true} [:maybe ms/NonBlankString]] [:definition {:optional true} [:maybe :map]] [:revision_message ms/NonBlankString] [:archived {:optional true} [:maybe :boolean]] [:caveats {:optional true} [:maybe :string]] [:description {:optional true} [:maybe :string]] [:points_of_interest {:optional true} [:maybe :string]] [:show_in_getting_started {:optional true} [:maybe :boolean]]]] (write-check-and-update-segment! id body)) | |
(api.macros/defendpoint :delete "/:id" "Archive a Segment. (DEPRECATED -- Just pass updated value of `:archived` to the `PUT` endpoint instead.)" [{:keys [id]} :- [:map [:id ms/PositiveInt]] {:keys [revision_message]} :- [:map [:revision_message ms/NonBlankString]]] (log/warn "DELETE /api/segment/:id is deprecated. Instead, change its `archived` value via PUT /api/segment/:id.") (write-check-and-update-segment! id {:archived true, :revision_message revision_message}) api/generic-204-no-content) | |
(api.macros/defendpoint :get "/:id/related" "Return related entities." [{:keys [id]} :- [:map [:id ms/PositiveInt]]] (-> (t2/select-one :model/Segment :id id) api/read-check xrays/related)) | |