39 lines · 1.7 KB
import { batch, first, stmt } from "./db";
import { VISIBLE_COMMENT } from "./issue-counters";

/**
 * Deletes an issue comment. The count update runs before the delete and only subtracts a visible comment: a hidden
 * one already left `comments_count` when it was hidden.
 */
export async function deleteIssueComment(comment: { id: string; issue_id: string }): Promise<void> {
  await batch([
    stmt("DELETE FROM reactions WHERE subject_type = 'comment' AND subject_id = ?", comment.id),
    stmt(
      `UPDATE issues SET comments_count = MAX(comments_count - ${VISIBLE_COMMENT}, 0) WHERE id = ?`,
      comment.id,
      comment.issue_id,
    ),
    stmt("DELETE FROM comments WHERE id = ?", comment.id),
  ]);
}

/** Deletes a discussion comment and its replies; only the visible ones come off `comments_count`. */
export async function deleteDiscussionComment(comment: { id: string; discussion_id: string }): Promise<void> {
  const removed = await first<{ count: number }>(
    "SELECT COUNT(*) AS count FROM discussion_comments WHERE (id = ?1 OR parent_id = ?1) AND hidden_at IS NULL",
    comment.id,
  );
  const subjects = "SELECT id FROM discussion_comments WHERE id = ?1 OR parent_id = ?1";
  await batch([
    stmt(`DELETE FROM reactions WHERE subject_type = 'discussion_comment' AND subject_id IN (${subjects})`, comment.id),
    stmt(`DELETE FROM discussion_votes WHERE subject_id IN (${subjects})`, comment.id),
    stmt("DELETE FROM discussion_comments WHERE id = ?", comment.id),
    stmt("UPDATE discussions SET answer_id = NULL WHERE answer_id = ?", comment.id),
    stmt(
      "UPDATE discussions SET comments_count = MAX(comments_count - ?, 0) WHERE id = ?",
      removed?.count ?? 0,
      comment.discussion_id,
    ),
  ]);
}