api: implemented CountSubreddits API endpoint
This commit is contained in:
parent
a17325bfed
commit
c83387652b
50
go/api/subreddits_count.go
Normal file
50
go/api/subreddits_count.go
Normal 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
|
||||
}
|
|
@ -2,6 +2,7 @@ package converts
|
|||
|
||||
import (
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/tigorlazuardi/bluemage/go/api"
|
||||
"github.com/tigorlazuardi/bluemage/go/gen/models"
|
||||
subreddits "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"
|
||||
)
|
||||
|
@ -25,9 +26,13 @@ import (
|
|||
// goverter:extend StringToOmitString
|
||||
// goverter:extend SubredditTypeToString
|
||||
// goverter:extend SubredditTypeToOmitString
|
||||
// goverter:extend SubredditsDisabledFilterToPtrBool
|
||||
type SubredditConverter interface {
|
||||
// goverter:ignore CreatedAt UpdatedAt CoverImageID
|
||||
CreateSubredditRequestToModelsSubredditSetter(*subreddits.CreateSubredditRequest) *models.SubredditSetter
|
||||
|
||||
// goverter:useZeroValueOnPointerInconsistency
|
||||
ProtoCountSubredditsRequestToAPICountSubredditsRequest(*subreddits.CountSubredditsRequest) api.CountSubredditsRequest
|
||||
}
|
||||
|
||||
func SubredditTypeToString(subType subreddits.SubredditType) string {
|
||||
|
@ -43,3 +48,13 @@ func SubredditTypeToOmitString(subType subreddits.SubredditType) omit.Val[string
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
|
@ -78,3 +78,7 @@ func BoolToOmitInt8(b bool) omit.Val[int8] {
|
|||
func Int8ToBool(i int8) bool {
|
||||
return i > 0
|
||||
}
|
||||
|
||||
func boolPtr(b bool) *bool {
|
||||
return &b
|
||||
}
|
||||
|
|
|
@ -19,6 +19,20 @@ type SubredditHandler struct {
|
|||
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
|
||||
// Returns the subreddit name.
|
||||
//
|
||||
|
|
|
@ -2,6 +2,7 @@ syntax = "proto3";
|
|||
|
||||
package subreddits.v1;
|
||||
|
||||
import "subreddits/v1/count.proto";
|
||||
import "subreddits/v1/create.proto";
|
||||
import "subreddits/v1/delete.proto";
|
||||
import "subreddits/v1/get.proto";
|
||||
|
@ -50,4 +51,9 @@ service SubredditsService {
|
|||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
// So this rpc endpoint also acts to check subreddit's existence.
|
||||
rpc ResolveSubredditName(ResolveSubredditNameRequest) returns (ResolveSubredditNameResponse);
|
||||
|
||||
// Count the existing subreddits using given filter.
|
||||
//
|
||||
// Default values count all.
|
||||
rpc CountSubreddits(CountSubredditsRequest) returns (CountSubredditsResponse);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue