micrach/repositories/posts_repository.go

282 lines
5.3 KiB
Go
Raw Normal View History

2021-08-31 22:10:24 +03:00
package repositories
import (
"context"
Config "micrach/config"
2021-08-31 22:10:24 +03:00
Db "micrach/db"
"time"
2021-08-31 22:10:24 +03:00
"github.com/jackc/pgx/v4"
)
type PostsRepository struct{}
var Posts PostsRepository
func (r *PostsRepository) Get(limit, offset int) ([]Post, error) {
2021-08-31 22:51:10 +03:00
sql := `
SELECT id, title, text, created_at
FROM posts
WHERE
is_parent = true
2021-10-22 15:27:08 +03:00
AND is_deleted != true
2021-08-31 22:51:10 +03:00
ORDER BY updated_at DESC
2021-09-10 02:17:45 +03:00
OFFSET $1
LIMIT $2
2021-08-31 22:51:10 +03:00
`
2021-09-10 02:17:45 +03:00
rows, err := Db.Pool.Query(context.TODO(), sql, offset, limit)
2021-08-31 22:51:10 +03:00
if err != nil {
return nil, err
}
if rows.Err() != nil {
return nil, err
}
2021-09-01 23:00:37 +03:00
postsMap := make(map[int]Post)
var postIDs []int
2021-08-31 22:51:10 +03:00
for rows.Next() {
var post Post
err = rows.Scan(&post.ID, &post.Title, &post.Text, &post.CreatedAt)
if err != nil {
return nil, err
}
2021-09-01 23:00:37 +03:00
postsMap[post.ID] = post
postIDs = append(postIDs, post.ID)
}
filesMap, err := Files.GetByPostIDs(postIDs)
if err != nil {
return nil, err
}
var posts []Post
for _, postID := range postIDs {
post := postsMap[postID]
post.Files = filesMap[postID]
2021-08-31 22:51:10 +03:00
posts = append(posts, post)
}
return posts, nil
2021-08-31 22:10:24 +03:00
}
2022-04-05 21:17:08 +03:00
func (r *PostsRepository) GetThreadsCount() (int, error) {
2021-09-10 02:17:45 +03:00
sql := `
SELECT COUNT(*)
FROM posts
WHERE
is_parent = true
2021-10-22 15:27:08 +03:00
AND is_deleted != true
AND is_archived != true
2021-09-10 02:17:45 +03:00
`
row := Db.Pool.QueryRow(context.TODO(), sql)
var count int
err := row.Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
2021-08-31 22:10:24 +03:00
func (r *PostsRepository) Create(p Post) (int, error) {
2021-09-01 19:23:39 +03:00
sql := `
INSERT INTO posts (is_parent, parent_id, title, text, is_sage, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)
2021-09-01 19:23:39 +03:00
RETURNING id
`
2021-08-31 22:10:24 +03:00
var row pgx.Row
if p.IsParent {
2021-09-08 18:50:33 +03:00
row = Db.Pool.QueryRow(
context.TODO(), sql, p.IsParent, nil, p.Title, p.Text, p.IsSage, time.Now(),
2021-08-31 22:10:24 +03:00
)
} else {
2021-09-08 18:50:33 +03:00
row = Db.Pool.QueryRow(
context.TODO(), sql, p.IsParent, p.ParentID, p.Title, p.Text, p.IsSage, nil,
2021-08-31 22:10:24 +03:00
)
}
createdPost := new(Post)
2021-09-08 18:50:33 +03:00
err := row.Scan(&createdPost.ID)
2021-09-03 02:34:45 +03:00
if err != nil {
return 0, err
}
2021-08-31 22:10:24 +03:00
return createdPost.ID, nil
}
2021-09-05 00:36:55 +03:00
func (r *PostsRepository) GetThreadByPostID(ID int) ([]Post, error) {
sql := `
SELECT
id,
title,
text,
is_sage,
created_at,
2022-02-03 18:22:46 +03:00
is_parent,
parent_id
2021-09-05 00:36:55 +03:00
FROM posts
WHERE
2021-10-22 15:36:50 +03:00
(id = $1 AND is_parent = true AND is_deleted != true)
OR (parent_id = $1 AND is_deleted != true)
2021-09-05 00:36:55 +03:00
ORDER BY created_at ASC
`
2021-09-08 18:50:33 +03:00
rows, err := Db.Pool.Query(context.TODO(), sql, ID)
2021-09-05 00:36:55 +03:00
if err != nil {
return nil, err
}
if rows.Err() != nil {
return nil, err
}
postsMap := make(map[int]Post)
var postIDs []int
for rows.Next() {
var post Post
err = rows.Scan(
&post.ID,
&post.Title,
&post.Text,
&post.IsSage,
&post.CreatedAt,
&post.IsParent,
2022-02-03 18:22:46 +03:00
&post.ParentID,
2021-09-05 00:36:55 +03:00
)
if err != nil {
return nil, err
}
postsMap[post.ID] = post
postIDs = append(postIDs, post.ID)
}
filesMap, err := Files.GetByPostIDs(postIDs)
if err != nil {
return nil, err
}
var posts []Post
for _, postID := range postIDs {
post := postsMap[postID]
post.Files = filesMap[postID]
posts = append(posts, post)
}
return posts, nil
}
2021-09-05 13:50:22 +03:00
// Check if thread is archived
func (r *PostsRepository) GetIfThreadIsArchived(ID int) (bool, error) {
sql := `
SELECT is_archived
FROM posts
WHERE id = $1
LIMIT 1
`
row := Db.Pool.QueryRow(context.TODO(), sql, ID)
var isArchived bool
err := row.Scan(&isArchived)
if err != nil {
return false, err
}
return isArchived, nil
}
2021-09-10 19:16:53 +03:00
func (r *PostsRepository) CreateInTx(tx pgx.Tx, p Post) (int, error) {
sql := `
INSERT INTO posts (is_parent, parent_id, title, text, is_sage, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)
2021-09-10 19:16:53 +03:00
RETURNING id
`
var row pgx.Row
if p.IsParent {
row = tx.QueryRow(
context.TODO(), sql, p.IsParent, nil, p.Title, p.Text, p.IsSage, time.Now(),
2021-09-10 19:16:53 +03:00
)
} else {
row = tx.QueryRow(
context.TODO(), sql, p.IsParent, p.ParentID, p.Title, p.Text, p.IsSage, nil,
2021-09-10 19:16:53 +03:00
)
}
createdPost := new(Post)
err := row.Scan(&createdPost.ID)
if err != nil {
return 0, err
}
return createdPost.ID, nil
}
func (r *PostsRepository) GetOldestThreadUpdatedAt() (time.Time, error) {
sql := `
SELECT updated_at
FROM posts
WHERE
is_parent = true
AND is_deleted != true
AND is_archived != true
ORDER BY updated_at DESC
OFFSET $1 - 1
LIMIT 1
`
row := Db.Pool.QueryRow(context.TODO(), sql, Config.App.ThreadsMaxCount)
var updatedAt time.Time
err := row.Scan(&updatedAt)
if err != nil {
return time.Time{}, err
}
return updatedAt, nil
}
func (r *PostsRepository) ArchiveThreadsFrom(t time.Time) error {
sql := `
UPDATE posts
SET is_archived = true
2021-11-20 23:42:16 +03:00
WHERE
is_parent = true
AND is_archived != true
AND updated_at <= $1
`
_, err := Db.Pool.Exec(context.TODO(), sql, t)
return err
}
// Returns count of posts in thread by thread ID
func (r *PostsRepository) GetThreadPostsCount(id int) (int, error) {
sql := `
SELECT COUNT(*)
FROM posts
WHERE
(id = $1 AND is_parent = true AND is_deleted != true)
OR (parent_id = $1 AND is_deleted != true)
`
row := Db.Pool.QueryRow(context.TODO(), sql, id)
var count int
err := row.Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
// Updates threads updated at time by thread ID
func (r *PostsRepository) BumpThreadInTx(tx pgx.Tx, id int) error {
sql := `
UPDATE posts
SET updated_at = now()
WHERE id = $1
`
2022-02-03 19:28:22 +03:00
_, err := tx.Exec(context.TODO(), sql, id)
return err
}