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.
367 lines
8.0 KiB
Go
367 lines
8.0 KiB
Go
// Code generated by sqlc. DO NOT EDIT.
|
|
// versions:
|
|
// sqlc v1.31.1
|
|
// source: posts.sql
|
|
|
|
package sqlc
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
const createPost = `-- name: CreatePost :exec
|
|
INSERT INTO posts (
|
|
id, parent_id, author_id, title, body, city, post_date, hidden, created_at, updated_at
|
|
)
|
|
VALUES (
|
|
$1,
|
|
$2,
|
|
$3,
|
|
$4,
|
|
$5,
|
|
$6,
|
|
$7,
|
|
$8,
|
|
$9,
|
|
$10
|
|
)
|
|
`
|
|
|
|
type CreatePostParams struct {
|
|
ID string
|
|
ParentID sql.NullString
|
|
AuthorID string
|
|
Title string
|
|
Body string
|
|
City string
|
|
PostDate string
|
|
Hidden int32
|
|
CreatedAt string
|
|
UpdatedAt string
|
|
}
|
|
|
|
func (q *Queries) CreatePost(ctx context.Context, arg CreatePostParams) error {
|
|
_, err := q.db.ExecContext(ctx, createPost,
|
|
arg.ID,
|
|
arg.ParentID,
|
|
arg.AuthorID,
|
|
arg.Title,
|
|
arg.Body,
|
|
arg.City,
|
|
arg.PostDate,
|
|
arg.Hidden,
|
|
arg.CreatedAt,
|
|
arg.UpdatedAt,
|
|
)
|
|
return err
|
|
}
|
|
|
|
const deletePostVote = `-- name: DeletePostVote :exec
|
|
DELETE FROM post_votes
|
|
WHERE user_id = $1
|
|
AND post_id = $2
|
|
`
|
|
|
|
type DeletePostVoteParams struct {
|
|
UserID string
|
|
PostID string
|
|
}
|
|
|
|
func (q *Queries) DeletePostVote(ctx context.Context, arg DeletePostVoteParams) error {
|
|
_, err := q.db.ExecContext(ctx, deletePostVote, arg.UserID, arg.PostID)
|
|
return err
|
|
}
|
|
|
|
const getPost = `-- 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 = $1
|
|
`
|
|
|
|
type GetPostRow struct {
|
|
ID string
|
|
ParentID sql.NullString
|
|
AuthorID string
|
|
AuthorName string
|
|
AuthorRole string
|
|
Title string
|
|
Body string
|
|
City string
|
|
PostDate string
|
|
Hidden int32
|
|
CreatedAt string
|
|
UpdatedAt string
|
|
}
|
|
|
|
func (q *Queries) GetPost(ctx context.Context, id string) (GetPostRow, error) {
|
|
row := q.db.QueryRowContext(ctx, getPost, id)
|
|
var i GetPostRow
|
|
err := row.Scan(
|
|
&i.ID,
|
|
&i.ParentID,
|
|
&i.AuthorID,
|
|
&i.AuthorName,
|
|
&i.AuthorRole,
|
|
&i.Title,
|
|
&i.Body,
|
|
&i.City,
|
|
&i.PostDate,
|
|
&i.Hidden,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
)
|
|
return i, err
|
|
}
|
|
|
|
const listPostThread = `-- name: ListPostThread :many
|
|
WITH RECURSIVE thread AS (
|
|
SELECT p.id, p.parent_id, p.author_id, p.title, p.body, p.city, p.post_date, p.hidden, p.created_at, p.updated_at
|
|
FROM posts p
|
|
WHERE p.id = $1 AND p.parent_id IS NULL
|
|
|
|
UNION ALL
|
|
|
|
SELECT child.id, child.parent_id, child.author_id, child.title, child.body, child.city, child.post_date, child.hidden, child.created_at, child.updated_at
|
|
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
|
|
`
|
|
|
|
type ListPostThreadRow struct {
|
|
ID string
|
|
ParentID sql.NullString
|
|
AuthorID string
|
|
AuthorName string
|
|
AuthorRole string
|
|
Title string
|
|
Body string
|
|
City string
|
|
PostDate string
|
|
Hidden int32
|
|
CreatedAt string
|
|
UpdatedAt string
|
|
}
|
|
|
|
func (q *Queries) ListPostThread(ctx context.Context, rootID string) ([]ListPostThreadRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, listPostThread, rootID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListPostThreadRow{}
|
|
for rows.Next() {
|
|
var i ListPostThreadRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ParentID,
|
|
&i.AuthorID,
|
|
&i.AuthorName,
|
|
&i.AuthorRole,
|
|
&i.Title,
|
|
&i.Body,
|
|
&i.City,
|
|
&i.PostDate,
|
|
&i.Hidden,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const listRootPosts = `-- name: ListRootPosts :many
|
|
WITH RECURSIVE roots AS (
|
|
SELECT p.id, p.parent_id, p.author_id, p.title, p.body, p.city, p.post_date, p.hidden, p.created_at, p.updated_at
|
|
FROM posts p
|
|
WHERE p.parent_id IS NULL
|
|
AND p.post_date = $3
|
|
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 = $1
|
|
AND viewer_vote.post_id = roots.id
|
|
ORDER BY score DESC, roots.created_at, roots.id
|
|
LIMIT $2
|
|
`
|
|
|
|
type ListRootPostsParams struct {
|
|
ViewerID string
|
|
RowLimit int32
|
|
PostDate string
|
|
}
|
|
|
|
type ListRootPostsRow struct {
|
|
ID string
|
|
ParentID sql.NullString
|
|
AuthorID string
|
|
AuthorName string
|
|
AuthorRole string
|
|
Title string
|
|
Body string
|
|
City string
|
|
PostDate string
|
|
Hidden int32
|
|
CreatedAt string
|
|
UpdatedAt string
|
|
Score int64
|
|
Answered bool
|
|
UserVote int64
|
|
}
|
|
|
|
func (q *Queries) ListRootPosts(ctx context.Context, arg ListRootPostsParams) ([]ListRootPostsRow, error) {
|
|
rows, err := q.db.QueryContext(ctx, listRootPosts, arg.ViewerID, arg.RowLimit, arg.PostDate)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
items := []ListRootPostsRow{}
|
|
for rows.Next() {
|
|
var i ListRootPostsRow
|
|
if err := rows.Scan(
|
|
&i.ID,
|
|
&i.ParentID,
|
|
&i.AuthorID,
|
|
&i.AuthorName,
|
|
&i.AuthorRole,
|
|
&i.Title,
|
|
&i.Body,
|
|
&i.City,
|
|
&i.PostDate,
|
|
&i.Hidden,
|
|
&i.CreatedAt,
|
|
&i.UpdatedAt,
|
|
&i.Score,
|
|
&i.Answered,
|
|
&i.UserVote,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
items = append(items, i)
|
|
}
|
|
if err := rows.Close(); err != nil {
|
|
return nil, err
|
|
}
|
|
if err := rows.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
return items, nil
|
|
}
|
|
|
|
const postIsVisibleRoot = `-- name: PostIsVisibleRoot :one
|
|
SELECT EXISTS(
|
|
SELECT 1
|
|
FROM posts
|
|
WHERE id = $1 AND parent_id IS NULL AND hidden = 0
|
|
)::bool
|
|
`
|
|
|
|
func (q *Queries) PostIsVisibleRoot(ctx context.Context, id string) (bool, error) {
|
|
row := q.db.QueryRowContext(ctx, postIsVisibleRoot, id)
|
|
var column_1 bool
|
|
err := row.Scan(&column_1)
|
|
return column_1, err
|
|
}
|
|
|
|
const updatePost = `-- name: UpdatePost :execrows
|
|
UPDATE posts
|
|
SET
|
|
body = $1,
|
|
updated_at = $2
|
|
WHERE id = $3
|
|
`
|
|
|
|
type UpdatePostParams struct {
|
|
Body string
|
|
UpdatedAt string
|
|
ID string
|
|
}
|
|
|
|
func (q *Queries) UpdatePost(ctx context.Context, arg UpdatePostParams) (int64, error) {
|
|
result, err := q.db.ExecContext(ctx, updatePost, arg.Body, arg.UpdatedAt, arg.ID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected()
|
|
}
|
|
|
|
const upsertPostVoteOnVisibleRoot = `-- name: UpsertPostVoteOnVisibleRoot :execrows
|
|
INSERT INTO post_votes (user_id, post_id, value)
|
|
SELECT $1, $2, $3
|
|
FROM posts p
|
|
WHERE p.id = $2
|
|
AND p.parent_id IS NULL
|
|
AND p.hidden = 0
|
|
ON CONFLICT (user_id, post_id) DO UPDATE
|
|
SET value = excluded.value
|
|
`
|
|
|
|
type UpsertPostVoteOnVisibleRootParams struct {
|
|
UserID string
|
|
PostID string
|
|
Value int32
|
|
}
|
|
|
|
func (q *Queries) UpsertPostVoteOnVisibleRoot(ctx context.Context, arg UpsertPostVoteOnVisibleRootParams) (int64, error) {
|
|
result, err := q.db.ExecContext(ctx, upsertPostVoteOnVisibleRoot, arg.UserID, arg.PostID, arg.Value)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
return result.RowsAffected()
|
|
}
|