CI / test (pull_request) Successful in 6m17s
Use named sqlc arguments, scope vote aggregation to selected roots, join viewer votes directly, and add the indexes and drift migration required by the resulting access paths.
124 lines
3.3 KiB
SQL
124 lines
3.3 KiB
SQL
-- name: CreatePost :exec
|
|
INSERT INTO posts (
|
|
id, parent_id, author_id, title, body, city, post_date, hidden, created_at, updated_at
|
|
)
|
|
VALUES (
|
|
sqlc.arg(id),
|
|
sqlc.arg(parent_id),
|
|
sqlc.arg(author_id),
|
|
sqlc.arg(title),
|
|
sqlc.arg(body),
|
|
sqlc.arg(city),
|
|
sqlc.arg(post_date),
|
|
sqlc.arg(hidden),
|
|
sqlc.arg(created_at),
|
|
sqlc.arg(updated_at)
|
|
);
|
|
|
|
-- name: GetPost :one
|
|
SELECT
|
|
p.id, p.parent_id, p.author_id, u.name AS author_name, u.role AS author_role,
|
|
p.title, p.body, p.city, p.post_date, p.hidden, p.created_at, p.updated_at
|
|
FROM posts p
|
|
JOIN users u ON u.id = p.author_id
|
|
WHERE p.id = sqlc.arg(id);
|
|
|
|
-- name: ListPostThread :many
|
|
WITH RECURSIVE thread AS (
|
|
SELECT p.*
|
|
FROM posts p
|
|
WHERE p.id = sqlc.arg(root_id) AND p.parent_id IS NULL
|
|
|
|
UNION ALL
|
|
|
|
SELECT child.*
|
|
FROM posts child
|
|
JOIN thread parent ON child.parent_id = parent.id
|
|
)
|
|
SELECT
|
|
thread.id, thread.parent_id, thread.author_id,
|
|
u.name AS author_name, u.role AS author_role,
|
|
thread.title, thread.body, thread.city, thread.post_date,
|
|
thread.hidden, thread.created_at, thread.updated_at
|
|
FROM thread
|
|
JOIN users u ON u.id = thread.author_id
|
|
ORDER BY thread.created_at, thread.id;
|
|
|
|
-- name: UpdatePost :execrows
|
|
UPDATE posts
|
|
SET
|
|
body = sqlc.arg(body),
|
|
updated_at = sqlc.arg(updated_at)
|
|
WHERE id = sqlc.arg(id);
|
|
|
|
-- name: ListRootPosts :many
|
|
WITH RECURSIVE roots AS (
|
|
SELECT p.*
|
|
FROM posts p
|
|
WHERE p.parent_id IS NULL
|
|
AND p.post_date = sqlc.arg(post_date)
|
|
AND p.hidden = 0
|
|
),
|
|
thread AS (
|
|
SELECT roots.id AS root_id, child.id AS post_id, child.author_id
|
|
FROM roots
|
|
JOIN posts child ON child.parent_id = roots.id
|
|
|
|
UNION ALL
|
|
|
|
SELECT thread.root_id, child.id, child.author_id
|
|
FROM thread
|
|
JOIN posts child ON child.parent_id = thread.post_id
|
|
),
|
|
answered AS (
|
|
SELECT DISTINCT thread.root_id
|
|
FROM thread
|
|
JOIN users u ON u.id = thread.author_id
|
|
WHERE u.role = 'admin'
|
|
),
|
|
scores AS (
|
|
SELECT votes.post_id, SUM(votes.value)::bigint AS score
|
|
FROM roots
|
|
JOIN post_votes votes ON votes.post_id = roots.id
|
|
GROUP BY votes.post_id
|
|
)
|
|
SELECT
|
|
roots.id, roots.parent_id, roots.author_id,
|
|
u.name AS author_name, u.role AS author_role,
|
|
roots.title, roots.body, roots.city, roots.post_date,
|
|
roots.hidden, roots.created_at, roots.updated_at,
|
|
COALESCE(scores.score, 0)::bigint AS score,
|
|
(answered.root_id IS NOT NULL)::bool AS answered,
|
|
COALESCE(viewer_vote.value, 0)::bigint AS user_vote
|
|
FROM roots
|
|
JOIN users u ON u.id = roots.author_id
|
|
LEFT JOIN scores ON scores.post_id = roots.id
|
|
LEFT JOIN answered ON answered.root_id = roots.id
|
|
LEFT JOIN post_votes viewer_vote
|
|
ON viewer_vote.user_id = sqlc.arg(viewer_id)
|
|
AND viewer_vote.post_id = roots.id
|
|
ORDER BY score DESC, roots.created_at, roots.id
|
|
LIMIT sqlc.arg(row_limit);
|
|
|
|
-- name: PostIsVisibleRoot :one
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM posts
|
|
WHERE id = sqlc.arg(id) AND parent_id IS NULL AND hidden = 0
|
|
)::bool;
|
|
|
|
-- name: DeletePostVote :exec
|
|
DELETE FROM post_votes
|
|
WHERE user_id = sqlc.arg(user_id)
|
|
AND post_id = sqlc.arg(post_id);
|
|
|
|
-- name: UpsertPostVoteOnVisibleRoot :execrows
|
|
INSERT INTO post_votes (user_id, post_id, value)
|
|
SELECT sqlc.arg(user_id), sqlc.arg(post_id), sqlc.arg(value)
|
|
FROM posts p
|
|
WHERE p.id = sqlc.arg(post_id)
|
|
AND p.parent_id IS NULL
|
|
AND p.hidden = 0
|
|
ON CONFLICT (user_id, post_id) DO UPDATE
|
|
SET value = excluded.value;
|