Add unified post storage (#3)
Adds one post creation path for roots and replies, recursive thread loading, body-only updates, root listings, and root-only voting across PostgreSQL and the in-memory store. Co-authored-by: codegirl-007 <s.raide@gmail.com>
This commit was merged in pull request #3.
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
-- name: CreatePost :exec
|
||||
INSERT INTO posts (
|
||||
id, parent_id, author_id, title, body, city, post_date, post_state, 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(post_state),
|
||||
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.post_state, 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.post_state, 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.post_state <> sqlc.arg(hidden_state)
|
||||
),
|
||||
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.post_state, 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 post_state <> sqlc.arg(hidden_state)
|
||||
)::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.post_state <> sqlc.arg(hidden_state)
|
||||
ON CONFLICT (user_id, post_id) DO UPDATE
|
||||
SET value = excluded.value;
|
||||
Reference in New Issue
Block a user