diff --git a/go/api/subreddits_delete.go b/go/api/subreddits_delete.go new file mode 100644 index 0000000..aef48a1 --- /dev/null +++ b/go/api/subreddits_delete.go @@ -0,0 +1,22 @@ +package api + +import ( + "context" + + "github.com/tigorlazuardi/bluemage/go/pkg/telemetry" +) + +type SubredditDeleteRequest struct { + Name string + DeleteImages bool +} + +func (api *API) SubredditDelete(ctx context.Context, request SubredditDeleteRequest) (numberOfImagesToDelete int, err error) { + ctx, span := tracer.Start(ctx, "SubredditDelete") + defer func() { telemetry.EndWithStatus(span, err) }() + + if request.DeleteImages { + } + + return numberOfImagesToDelete, nil +} diff --git a/go/api/subreddits_exist.go b/go/api/subreddits_exist.go new file mode 100644 index 0000000..fdde5f7 --- /dev/null +++ b/go/api/subreddits_exist.go @@ -0,0 +1,31 @@ +package api + +import ( + "context" + + "github.com/tigorlazuardi/bluemage/go/pkg/errs" + "github.com/tigorlazuardi/bluemage/go/pkg/telemetry" + + . "github.com/go-jet/jet/v2/sqlite" + . "github.com/tigorlazuardi/bluemage/go/gen/jet/table" +) + +func (api *API) SubredditExists(ctx context.Context, name string) (exist bool, err error) { + ctx, span := tracer.Start(ctx, "SubredditExists") + defer func() { telemetry.EndWithStatus(span, err) }() + + var count int64 + stmt := SELECT(COUNT(Subreddits.Name)).WHERE(Subreddits.Name.EQ(String(name))) + query, args := stmt.Sql() + + err = api.DB.QueryRowContext(ctx, query, args...).Scan(&count) + if err != nil { + err = errs. + Wrapw(err, "failed to check subreddit existence", + "name", name, + "query", stmt.DebugSql(), + ) + return exist, err + } + return count > 0, err +} diff --git a/go/converts/subreddit.go b/go/converts/subreddit.go index ffe67c3..9b8aba6 100644 --- a/go/converts/subreddit.go +++ b/go/converts/subreddit.go @@ -57,6 +57,9 @@ type SubredditConverter interface { // goverter:useZeroValueOnPointerInconsistency ProtoResolveSubredditNameRequestToAPISubredditResolveName(*subreddits.ResolveSubredditNameRequest) api.SubredditResolveNameRequest + + // goverter:useZeroValueOnPointerInconsistency + ProtoDeleteSubredditRequestToAPISubredditDeleteRequest(*subreddits.DeleteSubredditRequest) api.SubredditDeleteRequest } func SubredditTypeToString(subType subreddits.SubredditType) string { diff --git a/go/server/subreddit_handlers.go b/go/server/subreddit_handlers.go index 5913544..c86b579 100644 --- a/go/server/subreddit_handlers.go +++ b/go/server/subreddit_handlers.go @@ -2,6 +2,7 @@ package server import ( "context" + "errors" "connectrpc.com/connect" "github.com/tigorlazuardi/bluemage/go/api" @@ -19,6 +20,21 @@ type SubredditHandler struct { v1connect.UnimplementedSubredditsServiceHandler } +// SubredditExists checks if the subreddits already handled in database. +// THIS ENDPOINT DOES NOT CALL REDDIT API, ONLY DATABASE. +// +// Use ResolveSubredditName to check if subreddit actually exists in Reddit. +func (su *SubredditHandler) SubredditExists(ctx context.Context, request *connect.Request[subreddits.SubredditExistsRequest]) (*connect.Response[subreddits.SubredditExistsResponse], error) { + exist, err := su.API.SubredditExists(ctx, request.Msg.Name) + if err != nil { + return nil, errs.IntoConnectError(err) + } + resp := &subreddits.SubredditExistsResponse{ + Exist: exist, + } + return connect.NewResponse(resp), nil +} + // 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) { @@ -94,8 +110,19 @@ func (su *SubredditHandler) ListSubreddits(ctx context.Context, request *connect // // Returns error with connect.CodeNotFound if subreddit does not exist. func (su *SubredditHandler) UpdateSubreddit(ctx context.Context, request *connect.Request[subreddits.UpdateSubredditRequest]) (*connect.Response[subreddits.UpdateSubredditResponse], error) { + exist, err := su.API.SubredditExists(ctx, request.Msg.Name) + if err != nil { + return nil, errs.IntoConnectError(err) + } + if !exist { + err := errs. + Failf("subreddit '%s' is not registered", request.Msg.Name). + Details("request", request.Msg). + Code(connect.CodeNotFound) + return nil, errs.IntoConnectError(err) + } set := subredditConverter.ProtoSubredditSetterToBobSubredditSetter(request.Msg.Set) - err := su.API.UpdateSubreddit(ctx, request.Msg.Name, set) + err = su.API.UpdateSubreddit(ctx, request.Msg.Name, set) if err != nil { return nil, errs.IntoConnectError(err) } @@ -109,7 +136,18 @@ func (su *SubredditHandler) UpdateSubreddit(ctx context.Context, request *connec // // Returns error with connect.CodeNotFound if subreddit does not exist. func (su *SubredditHandler) DeleteSubreddit(ctx context.Context, request *connect.Request[subreddits.DeleteSubredditRequest]) (*connect.Response[subreddits.DeleteSubredditResponse], error) { - panic("not implemented") // TODO: Implement + exist, err := su.API.SubredditExists(ctx, request.Msg.Name) + if err != nil { + return nil, errs.IntoConnectError(err) + } + if !exist { + err := errs. + Failf("subreddit '%s' is not registered", request.Msg.Name). + Code(connect.CodeNotFound) + return nil, errs.IntoConnectError(err) + } + + return nil, connect.NewError(connect.CodeUnimplemented, errors.New("deleting subreddit is still unimplemented")) } // ResolveSubredditName resolves the given subreddit name. diff --git a/schemas/proto/subreddits/v1/delete.proto b/schemas/proto/subreddits/v1/delete.proto index 4ec2593..7f76423 100644 --- a/schemas/proto/subreddits/v1/delete.proto +++ b/schemas/proto/subreddits/v1/delete.proto @@ -18,8 +18,8 @@ message DeleteSubredditRequest { message DeleteSubredditResponse { // name of the subreddit that was deleted. string name = 1; - // number of images that were deleted. + // number of images that were about to be deleted. // // always 0 if delete_images is false. - uint32 deleted_images = 2; + int64 images_to_delete = 2; }