Keep scs for cookies and session API while sessions DDL and queries live in the same sqlc stack as the rest of Postgres.
150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
|
|
"plumber/internal/pacific"
|
|
"plumber/internal/store/sqlc"
|
|
)
|
|
|
|
// RankedQuestion is a question row with score / vote annotations for lists.
|
|
type RankedQuestion struct {
|
|
ID string
|
|
AuthorID string
|
|
AuthorName string
|
|
Title string
|
|
Body string
|
|
City string
|
|
HuntDate string
|
|
Hidden bool
|
|
CreatedAt string
|
|
Score int
|
|
Answered bool
|
|
UserVote int
|
|
db *sql.DB
|
|
}
|
|
|
|
// NewQuestion returns a question bound to db (not yet inserted).
|
|
func NewQuestion(db *sql.DB) *RankedQuestion {
|
|
return &RankedQuestion{db: db}
|
|
}
|
|
|
|
// Create inserts the question. Sets ID, HuntDate, and CreatedAt when empty.
|
|
func (q *RankedQuestion) Create(ctx context.Context) error {
|
|
if q == nil || q.db == nil {
|
|
return fmt.Errorf("question: no database")
|
|
}
|
|
q.Title = strings.TrimSpace(q.Title)
|
|
q.Body = strings.TrimSpace(q.Body)
|
|
q.City = strings.TrimSpace(q.City)
|
|
if q.ID == "" {
|
|
q.ID = uuid.NewString()
|
|
}
|
|
if q.HuntDate == "" {
|
|
q.HuntDate = pacific.Today()
|
|
}
|
|
if q.CreatedAt == "" {
|
|
q.CreatedAt = time.Now().UTC().Format(time.RFC3339)
|
|
}
|
|
return sqlc.New(q.db).CreateQuestion(ctx, sqlc.CreateQuestionParams{
|
|
ID: q.ID,
|
|
AuthorID: q.AuthorID,
|
|
Title: q.Title,
|
|
Body: q.Body,
|
|
City: q.City,
|
|
HuntDate: q.HuntDate,
|
|
CreatedAt: q.CreatedAt,
|
|
})
|
|
}
|
|
|
|
// Hide marks the question hidden.
|
|
func (q *RankedQuestion) Hide(ctx context.Context) error {
|
|
if q == nil || q.db == nil {
|
|
return fmt.Errorf("question: no database")
|
|
}
|
|
if err := sqlc.New(q.db).HideQuestion(ctx, q.ID); err != nil {
|
|
return err
|
|
}
|
|
q.Hidden = true
|
|
return nil
|
|
}
|
|
|
|
func rankedFrom(
|
|
db *sql.DB,
|
|
id, authorID, authorName, title, body, city, huntDate, createdAt string,
|
|
hidden int32, score, answered, userVote int64,
|
|
) RankedQuestion {
|
|
return RankedQuestion{
|
|
ID: id,
|
|
AuthorID: authorID,
|
|
AuthorName: authorName,
|
|
Title: title,
|
|
Body: body,
|
|
City: city,
|
|
HuntDate: huntDate,
|
|
Hidden: hidden != 0,
|
|
CreatedAt: createdAt,
|
|
Score: int(score),
|
|
Answered: answered != 0,
|
|
UserVote: int(userVote),
|
|
db: db,
|
|
}
|
|
}
|
|
|
|
func ListHunt(ctx context.Context, db *sql.DB, huntDate, viewerID string) ([]RankedQuestion, error) {
|
|
rows, err := sqlc.New(db).ListHunt(ctx, sqlc.ListHuntParams{
|
|
ViewerID: viewerID,
|
|
HuntDate: huntDate,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out := make([]RankedQuestion, 0, len(rows))
|
|
for _, r := range rows {
|
|
out = append(out, rankedFrom(db, r.ID, r.AuthorID, r.AuthorName, r.Title, r.Body, r.City, r.HuntDate, r.CreatedAt, r.Hidden, r.Score, r.Answered, r.UserVote))
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func GetQuestion(ctx context.Context, db *sql.DB, id, viewerID string) (*RankedQuestion, error) {
|
|
r, err := sqlc.New(db).GetQuestion(ctx, sqlc.GetQuestionParams{
|
|
ViewerID: viewerID,
|
|
ID: id,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
q := rankedFrom(db, r.ID, r.AuthorID, r.AuthorName, r.Title, r.Body, r.City, r.HuntDate, r.CreatedAt, r.Hidden, r.Score, r.Answered, r.UserVote)
|
|
return &q, nil
|
|
}
|
|
|
|
func ListQuestionsByAuthor(ctx context.Context, db *sql.DB, authorID string) ([]RankedQuestion, error) {
|
|
rows, err := sqlc.New(db).ListQuestionsByAuthor(ctx, authorID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out := make([]RankedQuestion, 0, len(rows))
|
|
for _, r := range rows {
|
|
out = append(out, rankedFrom(db, r.ID, r.AuthorID, r.AuthorName, r.Title, r.Body, r.City, r.HuntDate, r.CreatedAt, r.Hidden, r.Score, r.Answered, r.UserVote))
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func ListQuestionsAnsweredBy(ctx context.Context, db *sql.DB, adminID string) ([]RankedQuestion, error) {
|
|
rows, err := sqlc.New(db).ListQuestionsAnsweredBy(ctx, adminID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
out := make([]RankedQuestion, 0, len(rows))
|
|
for _, r := range rows {
|
|
out = append(out, rankedFrom(db, r.ID, r.AuthorID, r.AuthorName, r.Title, r.Body, r.City, r.HuntDate, r.CreatedAt, r.Hidden, r.Score, r.Answered, r.UserVote))
|
|
}
|
|
return out, nil
|
|
}
|