chore: initial commit

This commit is contained in:
2026-07-22 17:50:33 +08:00
parent 82936a8987
commit ee9f50b859
107 changed files with 8346 additions and 0 deletions

View File

@@ -0,0 +1,491 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: post.sql
package db
import (
"context"
"time"
)
const countPosts = `-- name: CountPosts :one
SELECT COUNT(*)
FROM posts
`
func (q *Queries) CountPosts(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countPosts)
var count int64
err := row.Scan(&count)
return count, err
}
const countPublishedPosts = `-- name: CountPublishedPosts :one
SELECT COUNT(*)
FROM posts
WHERE status = 1
AND published_at < NOW()
`
func (q *Queries) CountPublishedPosts(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, countPublishedPosts)
var count int64
err := row.Scan(&count)
return count, err
}
const createPost = `-- name: CreatePost :one
INSERT INTO posts(title, cover_id, slug, content, summary, status, sort, published_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
RETURNING id
`
type CreatePostParams struct {
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug string `json:"slug"`
Content string `json:"content"`
Summary string `json:"summary"`
Status int16 `json:"status"`
Sort *int32 `json:"sort"`
PublishedAt time.Time `json:"published_at"`
}
func (q *Queries) CreatePost(ctx context.Context, arg CreatePostParams) (int32, error) {
row := q.db.QueryRow(ctx, createPost,
arg.Title,
arg.CoverID,
arg.Slug,
arg.Content,
arg.Summary,
arg.Status,
arg.Sort,
arg.PublishedAt,
)
var id int32
err := row.Scan(&id)
return id, err
}
const deletePost = `-- name: DeletePost :execrows
DELETE
FROM posts
WHERE id = $1
`
func (q *Queries) DeletePost(ctx context.Context, id int32) (int64, error) {
result, err := q.db.Exec(ctx, deletePost, id)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}
const getPostById = `-- name: GetPostById :one
SELECT p.id, p.title, p.cover_id, p.slug, p.content, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE p.id = $1
LIMIT 1
`
type GetPostByIdRow struct {
ID int32 `json:"id"`
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug string `json:"slug"`
Content string `json:"content"`
Summary string `json:"summary"`
Status int16 `json:"status"`
Sort *int32 `json:"sort"`
PublishedAt time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
Cover *string `json:"cover"`
CategoryName *string `json:"category_name"`
CategoryID *int32 `json:"category_id"`
}
func (q *Queries) GetPostById(ctx context.Context, id int32) (GetPostByIdRow, error) {
row := q.db.QueryRow(ctx, getPostById, id)
var i GetPostByIdRow
err := row.Scan(
&i.ID,
&i.Title,
&i.CoverID,
&i.Slug,
&i.Content,
&i.Summary,
&i.Status,
&i.Sort,
&i.PublishedAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Cover,
&i.CategoryName,
&i.CategoryID,
)
return i, err
}
const getPublicPostBySlug = `-- name: GetPublicPostBySlug :one
SELECT p.id, p.title, p.cover_id, p.slug, p.content, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
COALESCE(ps.view, 0) AS view
FROM posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
WHERE p.slug = $1
AND p.status = 1
AND p.published_at < NOW()
LIMIT 1
`
type GetPublicPostBySlugRow struct {
ID int32 `json:"id"`
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug string `json:"slug"`
Content string `json:"content"`
Summary string `json:"summary"`
Status int16 `json:"status"`
Sort *int32 `json:"sort"`
PublishedAt time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
Cover *string `json:"cover"`
View int32 `json:"view"`
}
// web -------------------------------------------------------
func (q *Queries) GetPublicPostBySlug(ctx context.Context, slug string) (GetPublicPostBySlugRow, error) {
row := q.db.QueryRow(ctx, getPublicPostBySlug, slug)
var i GetPublicPostBySlugRow
err := row.Scan(
&i.ID,
&i.Title,
&i.CoverID,
&i.Slug,
&i.Content,
&i.Summary,
&i.Status,
&i.Sort,
&i.PublishedAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Cover,
&i.View,
)
return i, err
}
const listArchives = `-- name: ListArchives :many
SELECT
p.id,
p.slug,
p.title,
p.published_at,
c."name" AS category_name
FROM
posts p
LEFT JOIN post_category pc ON p.id = pc.post_id
LEFT JOIN categories c ON c.id = pc.category_id
WHERE
p.status = 1
AND p.published_at < NOW()
ORDER BY
p.published_at DESC, p.id DESC
`
type ListArchivesRow struct {
ID int32 `json:"id"`
Slug string `json:"slug"`
Title string `json:"title"`
PublishedAt time.Time `json:"published_at"`
CategoryName *string `json:"category_name"`
}
func (q *Queries) ListArchives(ctx context.Context) ([]ListArchivesRow, error) {
rows, err := q.db.Query(ctx, listArchives)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListArchivesRow{}
for rows.Next() {
var i ListArchivesRow
if err := rows.Scan(
&i.ID,
&i.Slug,
&i.Title,
&i.PublishedAt,
&i.CategoryName,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listCategoryStats = `-- name: ListCategoryStats :many
SELECT
c.id,
c.name,
COUNT(p.id) AS post_count
FROM
categories c
LEFT JOIN post_category pc ON c.id = pc.category_id
LEFT JOIN posts p ON p.id = pc.post_id
AND p.status = 1
AND p.published_at < NOW()
GROUP BY
c.id,
c.name
`
type ListCategoryStatsRow struct {
ID int32 `json:"id"`
Name string `json:"name"`
PostCount int64 `json:"post_count"`
}
func (q *Queries) ListCategoryStats(ctx context.Context) ([]ListCategoryStatsRow, error) {
rows, err := q.db.Query(ctx, listCategoryStats)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListCategoryStatsRow{}
for rows.Next() {
var i ListCategoryStatsRow
if err := rows.Scan(&i.ID, &i.Name, &i.PostCount); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPosts = `-- name: ListPosts :many
WITH paginated_posts AS (
-- 第一步:先精准查出当前页需要的文章 ID
SELECT id,
title,
cover_id,
slug,
summary,
status,
sort,
published_at,
created_at,
updated_at
FROM posts
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.id, p.title, p.cover_id, p.slug, p.summary, p.status, p.sort, p.published_at, p.created_at, p.updated_at,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC
`
type ListPostsParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type ListPostsRow struct {
ID int32 `json:"id"`
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug string `json:"slug"`
Summary string `json:"summary"`
Status int16 `json:"status"`
Sort *int32 `json:"sort"`
PublishedAt time.Time `json:"published_at"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt *time.Time `json:"updated_at"`
Cover *string `json:"cover"`
CategoryName *string `json:"category_name"`
CategoryID *int32 `json:"category_id"`
View int32 `json:"view"`
}
// 第二步:用这极少量的记录去进行 JOIN
func (q *Queries) ListPosts(ctx context.Context, arg ListPostsParams) ([]ListPostsRow, error) {
rows, err := q.db.Query(ctx, listPosts, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListPostsRow{}
for rows.Next() {
var i ListPostsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.CoverID,
&i.Slug,
&i.Summary,
&i.Status,
&i.Sort,
&i.PublishedAt,
&i.CreatedAt,
&i.UpdatedAt,
&i.Cover,
&i.CategoryName,
&i.CategoryID,
&i.View,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPublishedPosts = `-- name: ListPublishedPosts :many
WITH paginated_posts AS (
-- 第一步:先精准查出当前页需要的文章 ID
SELECT id,
title,
cover_id,
slug,
summary,
sort,
published_at
FROM posts
WHERE status = 1
AND published_at < NOW()
ORDER BY sort DESC, published_at DESC, id DESC
LIMIT $1 OFFSET $2)
SELECT p.id, p.title, p.cover_id, p.slug, p.summary, p.sort, p.published_at,
f.file_path AS cover,
c.name AS category_name,
c.id AS category_id,
COALESCE(ps.view, 0) AS view
FROM paginated_posts p
LEFT JOIN files f ON f.id = p.cover_id
LEFT JOIN post_category pc ON pc.post_id = p.id
LEFT JOIN categories c ON c.id = pc.category_id
LEFT JOIN post_stats ps ON ps.post_id = p.id
ORDER BY p.sort DESC, p.published_at DESC, p.id DESC
`
type ListPublishedPostsParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
type ListPublishedPostsRow struct {
ID int32 `json:"id"`
Title string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug string `json:"slug"`
Summary string `json:"summary"`
Sort *int32 `json:"sort"`
PublishedAt time.Time `json:"published_at"`
Cover *string `json:"cover"`
CategoryName *string `json:"category_name"`
CategoryID *int32 `json:"category_id"`
View int32 `json:"view"`
}
func (q *Queries) ListPublishedPosts(ctx context.Context, arg ListPublishedPostsParams) ([]ListPublishedPostsRow, error) {
rows, err := q.db.Query(ctx, listPublishedPosts, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []ListPublishedPostsRow{}
for rows.Next() {
var i ListPublishedPostsRow
if err := rows.Scan(
&i.ID,
&i.Title,
&i.CoverID,
&i.Slug,
&i.Summary,
&i.Sort,
&i.PublishedAt,
&i.Cover,
&i.CategoryName,
&i.CategoryID,
&i.View,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updatePost = `-- name: UpdatePost :execrows
UPDATE posts
SET title = coalesce($1, title),
cover_id = coalesce($2, cover_id),
slug = coalesce($3, slug),
content = coalesce($4, content),
summary = coalesce($5, summary),
status = coalesce($6, status),
sort = coalesce($7, sort),
published_at = coalesce($8, published_at)
WHERE id = $9
`
type UpdatePostParams struct {
Title *string `json:"title"`
CoverID *int32 `json:"cover_id"`
Slug *string `json:"slug"`
Content *string `json:"content"`
Summary *string `json:"summary"`
Status *int16 `json:"status"`
Sort *int32 `json:"sort"`
PublishedAt *time.Time `json:"published_at"`
ID int32 `json:"id"`
}
func (q *Queries) UpdatePost(ctx context.Context, arg UpdatePostParams) (int64, error) {
result, err := q.db.Exec(ctx, updatePost,
arg.Title,
arg.CoverID,
arg.Slug,
arg.Content,
arg.Summary,
arg.Status,
arg.Sort,
arg.PublishedAt,
arg.ID,
)
if err != nil {
return 0, err
}
return result.RowsAffected(), nil
}