(ns metabase.models.search-index-metadata (:require [java-time.api :as t] [metabase.models.interface :as mi] [methodical.core :as methodical] [toucan2.core :as t2])) | |
(methodical/defmethod t2/table-name :model/SearchIndexMetadata [_model] :search_index_metadata) | |
(doto :model/SearchIndexMetadata (derive :metabase/model) (derive :hook/timestamped?)) | |
(t2/deftransforms :model/SearchIndexMetadata {:engine mi/transform-keyword :status (mi/transform-validator mi/transform-keyword (partial mi/assert-enum #{:pending :active :retired}))}) | |
The current 'pending' and 'active' indexes for the given co-ordinates, where they exist. | (defn indexes [engine version] (t2/select-fn->fn :status :index_name :model/SearchIndexMetadata :engine engine :version version :status [:in [:active :pending]])) |
Create a 'pending' entry, unless one already exists. Return whether it was created. | (defn create-pending! [engine version index-name] (boolean (when-not (t2/exists? :model/SearchIndexMetadata :engine engine :version version :status :pending) (try (t2/insert! :model/SearchIndexMetadata {:engine engine :version version :status :pending :index_name (name index-name)}) true (catch Exception _ ;; We assume that failure corresponds to a unique index conflict (a pending entry already exists) false))))) |
Delete the given pending index, as long as its still pending. | (defn delete-index! [engine version index-name] (t2/delete! :model/SearchIndexMetadata :engine engine :version version :index_name (name index-name))) |
If there is 'pending' index, make it 'active'. Return the name of the active index, regardless. | (defn active-pending! [engine version] (t2/with-transaction [_conn] (when (t2/exists? :model/SearchIndexMetadata :engine engine :version version :status :pending) (t2/delete! :model/SearchIndexMetadata :engine engine :version version :status :retired) (t2/update! :model/SearchIndexMetadata {:engine engine :version version :status :active} {:status :retired}) (t2/update! :model/SearchIndexMetadata {:engine engine :version version :status :pending} {:status :active})) (t2/select-one-fn :index_name :model/SearchIndexMetadata :engine engine :version version :status :active))) |
Remove metadata corresponding to obsolete Metabase versions. It is up to the relevant engine to delete the actual indexes themselves. | (defn delete-obsolete! [our-version] ;; If there are no recent versions, then there is nothing to delete. (when-let [most-recent (seq (map :version (t2/query {:select [:version] :from [(t2/table-name :model/SearchIndexMetadata)] :group-by [:version] ;; use pk as a tie-breaker :order-by [[[:max :updated_at] :desc] [[:max :id] :desc]] :limit 3})))] (t2/query-one {:delete-from [(t2/table-name :model/SearchIndexMetadata)] :where [:or [:not-in :version most-recent] ;; Drop those older than 1 day, unless we are using them, or they are the most recent. [:and [:not-in :version (filter some? [our-version (first most-recent)])] [:< :updated_at (t/minus (t/zoned-date-time) (t/days 1))]]]}))) |