(ns metabase.search.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))]]]}))) |