Merge pull request #7506 from penpot/niwinz-staging-hotfix-6-comments-threads
Some checks failed
Commit Message Check / Check Commit Message (push) Has been cancelled

 Add minor comment threads queries optimization
This commit is contained in:
Alejandro Alonso
2025-10-15 12:04:42 +02:00
committed by GitHub
2 changed files with 52 additions and 53 deletions

View File

@@ -41,6 +41,7 @@
- Alternative ways of creating variants - Button Viewport [Taiga #11931](https://tree.taiga.io/project/penpot/us/11931) - Alternative ways of creating variants - Button Viewport [Taiga #11931](https://tree.taiga.io/project/penpot/us/11931)
- Reorder properties for a component [Taiga #10225](https://tree.taiga.io/project/penpot/us/10225) - Reorder properties for a component [Taiga #10225](https://tree.taiga.io/project/penpot/us/10225)
- File Data storage layout refactor [Github #7345](https://github.com/penpot/penpot/pull/7345) - File Data storage layout refactor [Github #7345](https://github.com/penpot/penpot/pull/7345)
- Make several queries optimization on comment threads [Github #7506](https://github.com/penpot/penpot/pull/7506)
### :bug: Bugs fixed ### :bug: Bugs fixed

View File

@@ -234,36 +234,39 @@
(files/check-comment-permissions! conn profile-id file-id share-id) (files/check-comment-permissions! conn profile-id file-id share-id)
(get-comment-threads conn profile-id file-id)))) (get-comment-threads conn profile-id file-id))))
(def ^:private sql:comment-threads (defn- get-comment-threads-sql
"SELECT DISTINCT ON (ct.id) [where]
ct.*, (str/ffmt
pf.fullname AS owner_fullname, "SELECT DISTINCT ON (ct.id)
pf.email AS owner_email, ct.*,
pf.photo_id AS owner_photo_id, pf.fullname AS owner_fullname,
p.team_id AS team_id, pf.email AS owner_email,
f.name AS file_name, pf.photo_id AS owner_photo_id,
f.project_id AS project_id, p.team_id AS team_id,
first_value(c.content) OVER w AS content, f.name AS file_name,
(SELECT count(1) f.project_id AS project_id,
FROM comment AS c first_value(c.content) OVER w AS content,
WHERE c.thread_id = ct.id) AS count_comments, (SELECT count(1)
(SELECT count(1) FROM comment AS c
FROM comment AS c WHERE c.thread_id = ct.id) AS count_comments,
WHERE c.thread_id = ct.id (SELECT count(1)
AND c.created_at >= coalesce(cts.modified_at, ct.created_at)) AS count_unread_comments FROM comment AS c
FROM comment_thread AS ct WHERE c.thread_id = ct.id
INNER JOIN comment AS c ON (c.thread_id = ct.id) AND c.created_at >= coalesce(cts.modified_at, ct.created_at)) AS count_unread_comments
INNER JOIN file AS f ON (f.id = ct.file_id) FROM comment_thread AS ct
INNER JOIN project AS p ON (p.id = f.project_id) INNER JOIN comment AS c ON (c.thread_id = ct.id)
LEFT JOIN comment_thread_status AS cts ON (cts.thread_id = ct.id AND cts.profile_id = ?) INNER JOIN file AS f ON (f.id = ct.file_id)
LEFT JOIN profile AS pf ON (ct.owner_id = pf.id) INNER JOIN project AS p ON (p.id = f.project_id)
WHERE f.deleted_at IS NULL LEFT JOIN comment_thread_status AS cts ON (cts.thread_id = ct.id AND cts.profile_id = ?)
AND p.deleted_at IS NULL LEFT JOIN profile AS pf ON (ct.owner_id = pf.id)
WINDOW w AS (PARTITION BY c.thread_id ORDER BY c.created_at ASC)") WHERE f.deleted_at IS NULL
AND p.deleted_at IS NULL
%1
WINDOW w AS (PARTITION BY c.thread_id ORDER BY c.created_at ASC)"
where))
(def ^:private sql:comment-threads-by-file-id (def ^:private sql:comment-threads-by-file-id
(str "WITH threads AS (" sql:comment-threads ")" (get-comment-threads-sql "AND ct.file_id = ?"))
"SELECT * FROM threads WHERE file_id = ?"))
(defn- get-comment-threads (defn- get-comment-threads
[conn profile-id file-id] [conn profile-id file-id]
@@ -273,34 +276,28 @@
;; --- COMMAND: Get Unread Comment Threads ;; --- COMMAND: Get Unread Comment Threads
(def ^:private sql:unread-all-comment-threads-by-team (def ^:private sql:unread-all-comment-threads-by-team
(str "WITH threads AS (" sql:comment-threads ")" (str "WITH threads AS ("
"SELECT * FROM threads WHERE count_unread_comments > 0 AND team_id = ?")) (get-comment-threads-sql "AND p.team_id = ?")
")"
"SELECT t.* FROM threads AS t
WHERE t.count_unread_comments > 0"))
;; The partial configuration will retrieve only comments created by the user and
;; threads that have a mention to the user.
(def ^:private sql:unread-partial-comment-threads-by-team (def ^:private sql:unread-partial-comment-threads-by-team
(str "WITH threads AS (" sql:comment-threads ")" (str "WITH threads AS ("
"SELECT * FROM threads (get-comment-threads-sql "AND p.team_id = ? AND (ct.owner_id = ? OR ? = ANY(ct.mentions))")
WHERE count_unread_comments > 0 ")"
AND team_id = ? "SELECT t.* FROM threads AS t
AND (owner_id = ? OR ? = ANY(mentions))")) WHERE t.count_unread_comments > 0"))
(defn- get-unread-comment-threads (defn- get-unread-comment-threads
[cfg profile-id team-id] [cfg profile-id team-id]
(let [profile (-> (db/get cfg :profile {:id profile-id}) (let [profile (-> (db/get cfg :profile {:id profile-id})
(profile/decode-row)) (profile/decode-row))
notify (or (-> profile :props :notifications :dashboard-comments) :all)] notify (or (-> profile :props :notifications :dashboard-comments) :all)
result (case notify
(case notify :all (db/exec! cfg [sql:unread-all-comment-threads-by-team profile-id team-id])
:all :partial (db/exec! cfg [sql:unread-partial-comment-threads-by-team profile-id team-id profile-id profile-id]))]
(->> (db/exec! cfg [sql:unread-all-comment-threads-by-team profile-id team-id]) (into [] xf-decode-row result)))
(into [] xf-decode-row))
:partial
(->> (db/exec! cfg [sql:unread-partial-comment-threads-by-team profile-id team-id profile-id profile-id])
(into [] xf-decode-row))
[])))
(def ^:private (def ^:private
schema:get-unread-comment-threads schema:get-unread-comment-threads
@@ -323,16 +320,17 @@
[:id ::sm/uuid] [:id ::sm/uuid]
[:share-id {:optional true} [:maybe ::sm/uuid]]]) [:share-id {:optional true} [:maybe ::sm/uuid]]])
(def ^:private sql:get-comment-thread
(get-comment-threads-sql "AND ct.file_id = ? AND ct.id = ?"))
(sv/defmethod ::get-comment-thread (sv/defmethod ::get-comment-thread
{::doc/added "1.15" {::doc/added "1.15"
::sm/params schema:get-comment-thread} ::sm/params schema:get-comment-thread}
[cfg {:keys [::rpc/profile-id file-id id share-id] :as params}] [cfg {:keys [::rpc/profile-id file-id id share-id] :as params}]
(db/run! cfg (fn [{:keys [::db/conn]}] (db/run! cfg (fn [{:keys [::db/conn]}]
(files/check-comment-permissions! conn profile-id file-id share-id) (files/check-comment-permissions! conn profile-id file-id share-id)
(let [sql (str "WITH threads AS (" sql:comment-threads ")" (some-> (db/exec-one! conn [sql:get-comment-thread profile-id file-id id])
"SELECT * FROM threads WHERE id = ? AND file_id = ?")] (decode-row)))))
(-> (db/exec-one! conn [sql profile-id id file-id])
(decode-row))))))
;; --- COMMAND: Retrieve Comments ;; --- COMMAND: Retrieve Comments