/api/segment endpoints. | (ns metabase.api.segment (:require [compojure.core :refer [DELETE GET POST PUT]] [metabase.api.common :as api] [metabase.events :as events] [metabase.legacy-mbql.normalize :as mbql.normalize] [metabase.models.interface :as mi] [metabase.models.revision :as revision] [metabase.models.segment :refer [Segment]] [metabase.related :as related] [metabase.util :as u] [metabase.util.log :as log] [metabase.util.malli :as mu] [metabase.util.malli.schema :as ms] [toucan2.core :as t2])) |
/ | (api/defendpoint POST "Create a new `Segment`." [:as {{:keys [name description table_id definition], :as body} :body}] {name ms/NonBlankString table_id ms/PositiveInt definition ms/Map description [:maybe :string]} ;; TODO - why can't we set other properties like `show_in_getting_started` when we create the Segment? (api/create-check Segment body) (let [segment (api/check-500 (first (t2/insert-returning-instances! 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 Segment :id id)) (t2/hydrate :creator))) | |
/:id | (api/defendpoint GET "Fetch `Segment` with ID." [id] {id ms/PositiveInt} (hydrated-segment id)) |
/ | (api/defendpoint GET "Fetch *all* `Segments`." [] (as-> (t2/select 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 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! 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})))) |
/:id | (api/defendpoint PUT "Update a `Segment` with ID." [id :as {{:keys [name definition revision_message archived caveats description points_of_interest show_in_getting_started] :as body} :body}] {id ms/PositiveInt name [:maybe ms/NonBlankString] definition [:maybe :map] revision_message ms/NonBlankString archived [:maybe :boolean] caveats [:maybe :string] description [:maybe :string] points_of_interest [:maybe :string] show_in_getting_started [:maybe :boolean]} (write-check-and-update-segment! id body)) |
/:id | (api/defendpoint DELETE "Archive a Segment. (DEPRECATED -- Just pass updated value of `:archived` to the `PUT` endpoint instead.)" [id revision_message] {id ms/PositiveInt 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) |
/:id/revisions | (api/defendpoint GET "Fetch `Revisions` for `Segment` with ID." [id] {id ms/PositiveInt} (api/read-check Segment id) (revision/revisions+details Segment id)) |
/:id/revert | (api/defendpoint POST "Revert a `Segement` to a prior `Revision`." [id :as {{:keys [revision_id]} :body}] {id ms/PositiveInt revision_id ms/PositiveInt} (api/write-check Segment id) (revision/revert! {:entity Segment :id id :user-id api/*current-user-id* :revision-id revision_id})) |
/:id/related | (api/defendpoint GET "Return related entities." [id] {id ms/PositiveInt} (-> (t2/select-one Segment :id id) api/read-check related/related)) |
(api/define-routes) | |