api: implemented CountSubreddits API endpoint

This commit is contained in:
Tigor Hutasuhut 2024-08-15 15:07:17 +07:00
parent a17325bfed
commit c83387652b
5 changed files with 89 additions and 0 deletions

View file

@ -0,0 +1,50 @@
package api
import (
"context"
. "github.com/go-jet/jet/v2/sqlite"
. "github.com/tigorlazuardi/bluemage/go/gen/jet/table"
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
"github.com/tigorlazuardi/bluemage/go/pkg/telemetry"
)
type CountSubredditsRequest struct {
Search string
Disabled *bool
}
func (c CountSubredditsRequest) Statement() SelectStatement {
cond := Bool(true)
if c.Search != "" {
cond.AND(Subreddits.Name.LIKE(String("%" + c.Search + "%")))
}
if c.Disabled != nil {
disabled := *c.Disabled
if disabled {
cond.AND(Subreddits.Disabled.EQ(Int(1)))
} else {
cond.AND(Subreddits.Disabled.EQ(Int(0)))
}
}
return SELECT(COUNT(Subreddits.Name)).WHERE(cond)
}
func (api *API) CountSubreddits(ctx context.Context, request CountSubredditsRequest) (count int64, err error) {
ctx, span := tracer.Start(ctx, "CountSubreddits")
defer func() { telemetry.EndWithStatus(span, err) }()
stmt := request.Statement()
query, args := stmt.Sql()
err = api.DB.QueryRowContext(ctx, query, args...).Scan(&count)
if err != nil {
err = errs.Wrapw(err, "failed to count subreddits",
"request", request,
"query", stmt.DebugSql(),
)
return count, err
}
return count, err
}

View file

@ -2,6 +2,7 @@ package converts
import ( import (
"github.com/aarondl/opt/omit" "github.com/aarondl/opt/omit"
"github.com/tigorlazuardi/bluemage/go/api"
"github.com/tigorlazuardi/bluemage/go/gen/models" "github.com/tigorlazuardi/bluemage/go/gen/models"
subreddits "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1" subreddits "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"
) )
@ -25,9 +26,13 @@ import (
// goverter:extend StringToOmitString // goverter:extend StringToOmitString
// goverter:extend SubredditTypeToString // goverter:extend SubredditTypeToString
// goverter:extend SubredditTypeToOmitString // goverter:extend SubredditTypeToOmitString
// goverter:extend SubredditsDisabledFilterToPtrBool
type SubredditConverter interface { type SubredditConverter interface {
// goverter:ignore CreatedAt UpdatedAt CoverImageID // goverter:ignore CreatedAt UpdatedAt CoverImageID
CreateSubredditRequestToModelsSubredditSetter(*subreddits.CreateSubredditRequest) *models.SubredditSetter CreateSubredditRequestToModelsSubredditSetter(*subreddits.CreateSubredditRequest) *models.SubredditSetter
// goverter:useZeroValueOnPointerInconsistency
ProtoCountSubredditsRequestToAPICountSubredditsRequest(*subreddits.CountSubredditsRequest) api.CountSubredditsRequest
} }
func SubredditTypeToString(subType subreddits.SubredditType) string { func SubredditTypeToString(subType subreddits.SubredditType) string {
@ -43,3 +48,13 @@ func SubredditTypeToOmitString(subType subreddits.SubredditType) omit.Val[string
} }
return omit.From("r") return omit.From("r")
} }
func SubredditsDisabledFilterToPtrBool(filter subreddits.DisabledFilter) *bool {
switch filter {
case subreddits.DisabledFilter_DISABLED_FILTER_TRUE:
return boolPtr(true)
case subreddits.DisabledFilter_DISABLED_FILTER_FALSE:
return boolPtr(false)
}
return nil
}

View file

@ -78,3 +78,7 @@ func BoolToOmitInt8(b bool) omit.Val[int8] {
func Int8ToBool(i int8) bool { func Int8ToBool(i int8) bool {
return i > 0 return i > 0
} }
func boolPtr(b bool) *bool {
return &b
}

View file

@ -19,6 +19,20 @@ type SubredditHandler struct {
v1connect.UnimplementedSubredditsServiceHandler v1connect.UnimplementedSubredditsServiceHandler
} }
// Count the existing subreddits using given filter.
// Default values count all.
func (su *SubredditHandler) CountSubreddits(ctx context.Context, request *connect.Request[subreddits.CountSubredditsRequest]) (*connect.Response[subreddits.CountSubredditsResponse], error) {
countRequest := subredditConverter.ProtoCountSubredditsRequestToAPICountSubredditsRequest(request.Msg)
count, err := su.API.CountSubreddits(ctx, countRequest)
if err != nil {
return nil, errs.IntoConnectError(err)
}
resp := &subreddits.CountSubredditsResponse{
Count: count,
}
return connect.NewResponse(resp), nil
}
// CreateSubreddit creates a new subreddit // CreateSubreddit creates a new subreddit
// Returns the subreddit name. // Returns the subreddit name.
// //

View file

@ -2,6 +2,7 @@ syntax = "proto3";
package subreddits.v1; package subreddits.v1;
import "subreddits/v1/count.proto";
import "subreddits/v1/create.proto"; import "subreddits/v1/create.proto";
import "subreddits/v1/delete.proto"; import "subreddits/v1/delete.proto";
import "subreddits/v1/get.proto"; import "subreddits/v1/get.proto";
@ -50,4 +51,9 @@ service SubredditsService {
// Returns error with connect.CodeNotFound if subreddit does not exist. // Returns error with connect.CodeNotFound if subreddit does not exist.
// So this rpc endpoint also acts to check subreddit's existence. // So this rpc endpoint also acts to check subreddit's existence.
rpc ResolveSubredditName(ResolveSubredditNameRequest) returns (ResolveSubredditNameResponse); rpc ResolveSubredditName(ResolveSubredditNameRequest) returns (ResolveSubredditNameResponse);
// Count the existing subreddits using given filter.
//
// Default values count all.
rpc CountSubreddits(CountSubredditsRequest) returns (CountSubredditsResponse);
} }