mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 13:56:39 +02:00
✨ Move the dashboard grid thumbnails to backend cache
This commit is contained in:
parent
b91c42e186
commit
c876534c85
9 changed files with 167 additions and 82 deletions
|
@ -214,6 +214,9 @@
|
|||
|
||||
{:name "0068-mod-storage-object-table"
|
||||
:fn (mg/resource "app/migrations/sql/0068-mod-storage-object-table.sql")}
|
||||
|
||||
{:name "0069-add-file-thumbnail-table"
|
||||
:fn (mg/resource "app/migrations/sql/0069-add-file-thumbnail-table.sql")}
|
||||
])
|
||||
|
||||
|
||||
|
|
|
@ -8,3 +8,6 @@ CREATE TABLE file_frame_thumbnail (
|
|||
|
||||
PRIMARY KEY(file_id, frame_id)
|
||||
);
|
||||
|
||||
ALTER TABLE file_frame_thumbnail
|
||||
ALTER COLUMN data SET STORAGE external;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
CREATE TABLE file_thumbnail (
|
||||
file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE,
|
||||
revn bigint NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
deleted_at timestamptz NULL,
|
||||
data text NULL,
|
||||
props jsonb NULL,
|
||||
PRIMARY KEY(file_id, revn)
|
||||
);
|
||||
|
||||
ALTER TABLE file_thumbnail
|
||||
ALTER COLUMN data SET STORAGE external,
|
||||
ALTER COLUMN props SET STORAGE external;
|
16
backend/src/app/rpc/helpers.clj
Normal file
16
backend/src/app/rpc/helpers.clj
Normal file
|
@ -0,0 +1,16 @@
|
|||
;; 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) UXBOX Labs SL
|
||||
|
||||
(ns app.rpc.helpers
|
||||
"General purpose RPC helpers."
|
||||
(:require [app.common.data.macros :as dm]))
|
||||
|
||||
(defn http-cache
|
||||
[{:keys [max-age]}]
|
||||
(fn [_ response]
|
||||
(let [exp (if (integer? max-age) max-age (inst-ms max-age))
|
||||
val (dm/fmt "max-age=%" (int (/ exp 1000.0)))]
|
||||
(update response :headers assoc "cache-control" val))))
|
|
@ -487,14 +487,34 @@
|
|||
update set data = ?;")
|
||||
|
||||
(s/def ::data ::us/string)
|
||||
(s/def ::upsert-frame-thumbnail
|
||||
(s/def ::upsert-file-frame-thumbnail
|
||||
(s/keys :req-un [::profile-id ::file-id ::frame-id ::data]))
|
||||
|
||||
(sv/defmethod ::upsert-frame-thumbnail
|
||||
(sv/defmethod ::upsert-file-frame-thumbnail
|
||||
[{:keys [pool] :as cfg} {:keys [profile-id file-id frame-id data]}]
|
||||
(db/with-atomic [conn pool]
|
||||
(files/check-edition-permissions! conn profile-id file-id)
|
||||
(db/exec-one! conn [sql:upsert-frame-thumbnail file-id frame-id data data])
|
||||
nil))
|
||||
|
||||
;; --- Mutation: Upsert file thumbnail
|
||||
|
||||
(def sql:upsert-file-thumbnail
|
||||
"insert into file_thumbnail(file_id, revn, data, props)
|
||||
values (?, ?, ?, ?)
|
||||
on conflict(file_id, revn) do
|
||||
update set data = ?, updated_at=now();")
|
||||
|
||||
(s/def ::revn ::us/integer)
|
||||
(s/def ::props (s/map-of ::us/keyword any?))
|
||||
(s/def ::upsert-file-thumbnail
|
||||
(s/keys :req-un [::profile-id ::file-id ::revn ::data ::props]))
|
||||
|
||||
(sv/defmethod ::upsert-file-thumbnail
|
||||
[{:keys [pool] :as cfg} {:keys [profile-id file-id revn data props]}]
|
||||
(db/with-atomic [conn pool]
|
||||
(files/check-edition-permissions! conn profile-id file-id)
|
||||
(let [props (db/tjson (or props {}))]
|
||||
(db/exec-one! conn [sql:upsert-file-thumbnail
|
||||
file-id revn data props data])
|
||||
nil)))
|
||||
|
|
|
@ -7,11 +7,14 @@
|
|||
(ns app.rpc.queries.files
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.exceptions :as ex]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.pages.migrations :as pmg]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.db :as db]
|
||||
[app.db.sql :as sql]
|
||||
[app.rpc.helpers :as rpch]
|
||||
[app.rpc.permissions :as perms]
|
||||
[app.rpc.queries.projects :as projects]
|
||||
[app.rpc.queries.share-link :refer [retrieve-share-link]]
|
||||
|
@ -267,7 +270,9 @@
|
|||
[{:keys [pool] :as cfg} {:keys [profile-id file-id] :as props}]
|
||||
(check-read-permissions! pool profile-id file-id)
|
||||
(let [file (retrieve-file cfg file-id)]
|
||||
(get-thumbnail-data file props)))
|
||||
{:data (get-thumbnail-data file props)
|
||||
:file-id file-id
|
||||
:revn (:revn file)}))
|
||||
|
||||
(defn get-thumbnail-data
|
||||
[{:keys [data] :as file} props]
|
||||
|
@ -325,7 +330,6 @@
|
|||
|
||||
(update data :objects update-objects)))
|
||||
|
||||
|
||||
;; --- Query: Shared Library Files
|
||||
|
||||
(def ^:private sql:team-shared-files
|
||||
|
@ -424,22 +428,48 @@
|
|||
(teams/check-read-permissions! pool profile-id team-id)
|
||||
(db/exec! pool [sql:team-recent-files team-id]))
|
||||
|
||||
;; --- QUERY: get all file frame thumbnails
|
||||
|
||||
;; --- QUERY: get the thumbnail for an frame
|
||||
(s/def ::file-frame-thumbnails
|
||||
(s/keys :req-un [::profile-id ::file-id]
|
||||
:opt-un [::frame-id]))
|
||||
|
||||
(def ^:private sql:file-frame-thumbnail
|
||||
"select data
|
||||
from file_frame_thumbnail
|
||||
where file_id = ?
|
||||
and frame_id = ?")
|
||||
|
||||
(s/def ::file-frame-thumbnail
|
||||
(s/keys :req-un [::profile-id ::file-id ::frame-id]))
|
||||
|
||||
(sv/defmethod ::file-frame-thumbnail
|
||||
(sv/defmethod ::file-frame-thumbnails
|
||||
[{:keys [pool]} {:keys [profile-id file-id frame-id]}]
|
||||
(check-read-permissions! pool profile-id file-id)
|
||||
(db/exec-one! pool [sql:file-frame-thumbnail file-id frame-id]))
|
||||
(let [params (cond-> {:file-id file-id}
|
||||
frame-id (assoc :frame-id frame-id))
|
||||
rows (db/query pool :file-frame-thumbnail params)]
|
||||
(d/group-by :frame-id :data rows)))
|
||||
|
||||
;; --- QUERY: get file thumbnail
|
||||
|
||||
(s/def ::revn ::us/integer)
|
||||
|
||||
(s/def ::file-thumbnail
|
||||
(s/keys :req-un [::profile-id ::file-id]
|
||||
:opt-un [::revn]))
|
||||
|
||||
(sv/defmethod ::file-thumbnail
|
||||
[{:keys [pool]} {:keys [profile-id file-id revn]}]
|
||||
(check-read-permissions! pool profile-id file-id)
|
||||
(let [sql (sql/select :file-thumbnail
|
||||
(cond-> {:file-id file-id}
|
||||
revn (assoc :revn revn))
|
||||
{:limit 1
|
||||
:order-by [[:revn :desc]]})
|
||||
|
||||
row (db/exec-one! pool sql)]
|
||||
|
||||
(when-not row
|
||||
(ex/raise :type :not-found
|
||||
:code :file-thumbnail-not-found))
|
||||
|
||||
(with-meta {:data (:data row)
|
||||
:props (some-> (:props row) db/decode-transit-pgobject)
|
||||
:revn (:revn row)
|
||||
:file-id (:file-id row)}
|
||||
{:transform-response (rpch/http-cache {:max-age (* 1000 60 60)})})))
|
||||
|
||||
;; --- Helpers
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue