Store post state as text so Go owns the allowed values and future states such as locked remain representable without a database enum migration.
This commit is contained in:
+36
-22
@@ -21,6 +21,14 @@ var (
|
||||
ErrPostNotVotable = errors.New("post not votable")
|
||||
)
|
||||
|
||||
type PostState string
|
||||
|
||||
const (
|
||||
PostStateVisible PostState = "visible"
|
||||
PostStateHidden PostState = "hidden"
|
||||
PostStateLocked PostState = "locked"
|
||||
)
|
||||
|
||||
// Post is either a root question (ParentID nil) or a reply to another post.
|
||||
type Post struct {
|
||||
ID string
|
||||
@@ -32,7 +40,7 @@ type Post struct {
|
||||
Body string
|
||||
City string
|
||||
PostDate string
|
||||
Hidden bool
|
||||
PostState PostState
|
||||
CreatedAt string
|
||||
UpdatedAt string
|
||||
Score int
|
||||
@@ -63,7 +71,7 @@ func (p *Post) Create(ctx context.Context) error {
|
||||
Body: p.Body,
|
||||
City: p.City,
|
||||
PostDate: p.PostDate,
|
||||
Hidden: boolInt32(p.Hidden),
|
||||
PostState: string(p.PostState),
|
||||
CreatedAt: p.CreatedAt,
|
||||
UpdatedAt: p.UpdatedAt,
|
||||
})
|
||||
@@ -101,6 +109,14 @@ func preparePost(p *Post) error {
|
||||
p.Body = strings.TrimSpace(p.Body)
|
||||
p.City = strings.TrimSpace(p.City)
|
||||
p.PostDate = strings.TrimSpace(p.PostDate)
|
||||
if p.PostState == "" {
|
||||
p.PostState = PostStateVisible
|
||||
}
|
||||
switch p.PostState {
|
||||
case PostStateVisible, PostStateHidden, PostStateLocked:
|
||||
default:
|
||||
return fmt.Errorf("%w: invalid post state", ErrInvalidPost)
|
||||
}
|
||||
if p.AuthorID == "" {
|
||||
return fmt.Errorf("%w: author is required", ErrInvalidPost)
|
||||
}
|
||||
@@ -120,7 +136,7 @@ func preparePost(p *Post) error {
|
||||
return fmt.Errorf("%w: parent is required", ErrInvalidPost)
|
||||
}
|
||||
p.ParentID = &parentID
|
||||
if p.Title != "" || p.City != "" || p.PostDate != "" || p.Hidden {
|
||||
if p.Title != "" || p.City != "" || p.PostDate != "" || p.PostState != PostStateVisible {
|
||||
return fmt.Errorf("%w: reply contains root-only fields", ErrInvalidPost)
|
||||
}
|
||||
}
|
||||
@@ -152,13 +168,6 @@ func parentIDFromNull(parentID sql.NullString) *string {
|
||||
return &id
|
||||
}
|
||||
|
||||
func boolInt32(value bool) int32 {
|
||||
if value {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func mapPostCreateError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
@@ -178,7 +187,7 @@ func postFromValues(
|
||||
id string,
|
||||
parentID sql.NullString,
|
||||
authorID, authorName, authorRole, title, body, city, postDate string,
|
||||
hidden int32,
|
||||
postState string,
|
||||
createdAt, updatedAt string,
|
||||
) Post {
|
||||
return Post{
|
||||
@@ -191,7 +200,7 @@ func postFromValues(
|
||||
Body: body,
|
||||
City: city,
|
||||
PostDate: postDate,
|
||||
Hidden: hidden != 0,
|
||||
PostState: PostState(postState),
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: updatedAt,
|
||||
db: db,
|
||||
@@ -215,7 +224,7 @@ func GetPost(ctx context.Context, db *sql.DB, id string) (*Post, error) {
|
||||
r.Body,
|
||||
r.City,
|
||||
r.PostDate,
|
||||
r.Hidden,
|
||||
r.PostState,
|
||||
r.CreatedAt,
|
||||
r.UpdatedAt,
|
||||
)
|
||||
@@ -241,7 +250,7 @@ func GetPostThread(ctx context.Context, db *sql.DB, rootID string) (*Post, error
|
||||
r.Body,
|
||||
r.City,
|
||||
r.PostDate,
|
||||
r.Hidden,
|
||||
r.PostState,
|
||||
r.CreatedAt,
|
||||
r.UpdatedAt,
|
||||
))
|
||||
@@ -292,9 +301,10 @@ func buildPostTree(posts []Post, rootID string) (*Post, error) {
|
||||
// ListRootPosts returns visible root posts for a post date.
|
||||
func ListRootPosts(ctx context.Context, db *sql.DB, postDate, viewerID string) ([]Post, error) {
|
||||
rows, err := sqlc.New(db).ListRootPosts(ctx, sqlc.ListRootPostsParams{
|
||||
ViewerID: viewerID,
|
||||
RowLimit: HuntListLimit,
|
||||
PostDate: postDate,
|
||||
ViewerID: viewerID,
|
||||
RowLimit: HuntListLimit,
|
||||
PostDate: postDate,
|
||||
HiddenState: string(PostStateHidden),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -312,7 +322,7 @@ func ListRootPosts(ctx context.Context, db *sql.DB, postDate, viewerID string) (
|
||||
r.Body,
|
||||
r.City,
|
||||
r.PostDate,
|
||||
r.Hidden,
|
||||
r.PostState,
|
||||
r.CreatedAt,
|
||||
r.UpdatedAt,
|
||||
)
|
||||
@@ -331,7 +341,10 @@ func SetPostVote(ctx context.Context, db *sql.DB, userID, postID string, value i
|
||||
}
|
||||
q := sqlc.New(db)
|
||||
if value == 0 {
|
||||
visible, err := q.PostIsVisibleRoot(ctx, postID)
|
||||
visible, err := q.PostIsVisibleRoot(ctx, sqlc.PostIsVisibleRootParams{
|
||||
ID: postID,
|
||||
HiddenState: string(PostStateHidden),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -344,9 +357,10 @@ func SetPostVote(ctx context.Context, db *sql.DB, userID, postID string, value i
|
||||
})
|
||||
}
|
||||
n, err := q.UpsertPostVoteOnVisibleRoot(ctx, sqlc.UpsertPostVoteOnVisibleRootParams{
|
||||
UserID: userID,
|
||||
PostID: postID,
|
||||
Value: int32(value),
|
||||
UserID: userID,
|
||||
PostID: postID,
|
||||
Value: int32(value),
|
||||
HiddenState: string(PostStateHidden),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user