mirror of
https://github.com/penpot/penpot.git
synced 2025-01-06 14:50:20 -05:00
114 lines
3.3 KiB
Clojure
114 lines
3.3 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
;; This is an example on how it can be executed:
|
|
;; clojure -Scp $(cat classpath) -M dev/script-fix-sobjects.clj
|
|
|
|
(require
|
|
'[app.common.logging :as l]
|
|
'[app.common.data :as d]
|
|
'[app.common.pprint]
|
|
'[app.db :as db]
|
|
'[app.storage :as sto]
|
|
'[app.storage.impl :as impl]
|
|
'[app.util.time :as dt]
|
|
'[integrant.core :as ig])
|
|
|
|
;; --- HELPERS
|
|
|
|
(l/info :hint "initializing script" :args *command-line-args*)
|
|
|
|
(def noop? (some #(= % "noop") *command-line-args*))
|
|
(def chunk-size 10)
|
|
|
|
(def sql:retrieve-sobjects-chunk
|
|
"SELECT * FROM storage_object
|
|
WHERE created_at < ? AND deleted_at is NULL
|
|
ORDER BY created_at desc LIMIT ?")
|
|
|
|
(defn get-chunk
|
|
[conn cursor]
|
|
(let [rows (db/exec! conn [sql:retrieve-sobjects-chunk cursor chunk-size])]
|
|
[(some->> rows peek :created-at) (seq rows)]))
|
|
|
|
(defn get-candidates
|
|
[conn]
|
|
(->> (d/iteration (partial get-chunk conn)
|
|
:vf second
|
|
:kf first
|
|
:initk (dt/now))
|
|
(sequence cat)))
|
|
|
|
(def modules
|
|
[:app.db/pool
|
|
:app.storage/storage
|
|
[:app.main/default :app.worker/executor]
|
|
[:app.main/assets :app.storage.s3/backend]
|
|
[:app.main/assets :app.storage.fs/backend]])
|
|
|
|
(def system
|
|
(let [config (select-keys app.main/system-config modules)
|
|
config (-> config
|
|
(assoc :app.migrations/all {})
|
|
(assoc :app.metrics/metrics nil))]
|
|
(ig/load-namespaces config)
|
|
(-> config ig/prep ig/init)))
|
|
|
|
(defn update-fn
|
|
[{:keys [conn] :as storage} {:keys [id backend] :as row}]
|
|
(cond
|
|
(= backend "s3")
|
|
(do
|
|
(l/info :hint "rename storage object backend"
|
|
:id id
|
|
:from-backend backend
|
|
:to-backend :assets-s3)
|
|
(assoc row :backend "assets-s3"))
|
|
|
|
(= backend "assets-s3")
|
|
(do
|
|
(l/info :hint "ignoring storage object" :id id :backend backend)
|
|
nil)
|
|
|
|
(or (= backend "fs")
|
|
(= backend "assets-fs"))
|
|
(let [sobj (sto/row->storage-object row)
|
|
path (-> (sto/get-object-path storage sobj) deref)]
|
|
(l/info :hint "change storage object backend"
|
|
:id id
|
|
:from-backend backend
|
|
:to-backend :assets-s3)
|
|
(when-not noop?
|
|
(-> (impl/resolve-backend storage :assets-s3)
|
|
(impl/put-object sobj (sto/content path))
|
|
(deref)))
|
|
(assoc row :backend "assets-s3"))
|
|
|
|
:else
|
|
(throw (IllegalArgumentException. "unexpected backend found"))))
|
|
|
|
(try
|
|
(db/with-atomic [conn (:app.db/pool system)]
|
|
(let [storage (:app.storage/storage system)
|
|
storage (assoc storage :conn conn)]
|
|
(loop [items (get-candidates conn)]
|
|
(when-let [item (first items)]
|
|
(when-let [{:keys [id] :as row} (update-fn storage item)]
|
|
(db/update! conn :storage-object (dissoc row :id) {:id (:id item)}))
|
|
(recur (rest items))))
|
|
(when noop?
|
|
(throw (ex-info "explicit rollback" {})))))
|
|
|
|
(catch Throwable cause
|
|
(cond
|
|
(= "explicit rollback" (ex-message cause))
|
|
(l/warn :hint "transaction aborted")
|
|
|
|
:else
|
|
(l/error :hint "unexpected exception" :cause cause))))
|
|
|
|
(ig/halt! system)
|
|
(System/exit 0)
|