subreddits: implemented create subreddit rpc endpoint
This commit is contained in:
parent
114a6d5116
commit
82f9fb903f
38
go/api/subreddits_create.go
Normal file
38
go/api/subreddits_create.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/aarondl/opt/omit"
|
||||
"github.com/mattn/go-sqlite3"
|
||||
"github.com/tigorlazuardi/bluemage/go/gen/models"
|
||||
"github.com/tigorlazuardi/bluemage/go/pkg/errs"
|
||||
)
|
||||
|
||||
func (api *API) SubredditCreate(ctx context.Context, subreddit *models.Subreddit) (err error) {
|
||||
// TODO: add check to Reddit API to see if subreddit exists.
|
||||
|
||||
api.lockf(func() {
|
||||
_, err = models.Subreddits.Insert(ctx, api.DB, &models.SubredditSetter{
|
||||
Name: omit.From(subreddit.Name),
|
||||
DisableScheduler: omit.From(subreddit.DisableScheduler),
|
||||
Type: omit.From(subreddit.Type),
|
||||
Schedule: omit.From(subreddit.Schedule),
|
||||
Countback: omit.From(subreddit.Countback),
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
if sqlite3err := new(sqlite3.Error); errors.As(err, &sqlite3err) {
|
||||
if sqlite3err.Code == sqlite3.ErrConstraint {
|
||||
return errs.
|
||||
Wrapw(err, "subreddit already exists", "input", subreddit).
|
||||
Code(connect.CodeAlreadyExists)
|
||||
}
|
||||
}
|
||||
return errs.Wrap(err, "failed to insert subreddit")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package converter
|
||||
package converts
|
||||
|
||||
import (
|
||||
"github.com/aarondl/opt/omit"
|
||||
|
|
21
go/converts/subreddit.go
Normal file
21
go/converts/subreddit.go
Normal file
|
@ -0,0 +1,21 @@
|
|||
package converts
|
||||
|
||||
import (
|
||||
"github.com/tigorlazuardi/bluemage/go/gen/models"
|
||||
subreddits "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"
|
||||
)
|
||||
|
||||
// goverter:converter
|
||||
// goverter:extend BoolToInt8 SubredditTypeToString Int8ToBool PtrBoolToOmitInt8
|
||||
// goverter:extend PtrStringToOmitString PtrFloat64ToOmitFloat64 PtrInt32ToOmitInt32
|
||||
type SubredditConverter interface {
|
||||
// goverter:ignore CreatedAt UpdatedAt R CoverImageID
|
||||
CreateSubredditRequestToModelsSubreddit(*subreddits.CreateSubredditRequest) *models.Subreddit
|
||||
}
|
||||
|
||||
func SubredditTypeToString(subType subreddits.SubredditType) string {
|
||||
if subType == subreddits.SubredditType_SUBREDDIT_TYPE_USER {
|
||||
return "user"
|
||||
}
|
||||
return "r"
|
||||
}
|
|
@ -19,16 +19,16 @@ type DeviceHandler struct {
|
|||
v1connect.UnimplementedDeviceServiceHandler
|
||||
}
|
||||
|
||||
var convert converter.DeviceConverterImpl
|
||||
var deviceConvert converter.DeviceConverterImpl
|
||||
|
||||
// CreateDevice implements v1connect.DeviceServiceHandler.
|
||||
func (d *DeviceHandler) CreateDevice(ctx context.Context, request *connect.Request[device.CreateDeviceRequest]) (*connect.Response[device.CreateDeviceResponse], error) {
|
||||
dev := convert.CreateDeviceRequestToModelsDevice(request.Msg)
|
||||
dev := deviceConvert.CreateDeviceRequestToModelsDevice(request.Msg)
|
||||
dev, err := d.API.DevicesCreate(ctx, dev)
|
||||
if err != nil {
|
||||
return nil, errs.IntoConnectError(err)
|
||||
}
|
||||
devResp := convert.ModelsDeviceToCreateDeviceResponse(dev)
|
||||
devResp := deviceConvert.ModelsDeviceToCreateDeviceResponse(dev)
|
||||
return connect.NewResponse(devResp), nil
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ func (d *DeviceHandler) GetDevice(ctx context.Context, request *connect.Request[
|
|||
return nil, errs.IntoConnectError(err)
|
||||
}
|
||||
|
||||
devResp := convert.ModelsDeviceToGetDeviceResponse(dev)
|
||||
devResp := deviceConvert.ModelsDeviceToGetDeviceResponse(dev)
|
||||
return connect.NewResponse(devResp), nil
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ func (d *DeviceHandler) ListDevices(ctx context.Context, request *connect.Reques
|
|||
// Only fields that are set in the request will be updated.
|
||||
func (de *DeviceHandler) UpdateDevice(ctx context.Context, request *connect.Request[device.UpdateDeviceRequest]) (*connect.Response[device.UpdateDeviceResponse], error) {
|
||||
slug := request.Msg.Slug
|
||||
set := convert.DeviceSetterProtoToModelsDeviceSetter(request.Msg.Set)
|
||||
set := deviceConvert.DeviceSetterProtoToModelsDeviceSetter(request.Msg.Set)
|
||||
err := de.API.DevicesUpdate(ctx, slug, set)
|
||||
if err != nil {
|
||||
return nil, errs.IntoConnectError(err)
|
||||
|
|
66
go/server/subreddit_handlers.go
Normal file
66
go/server/subreddit_handlers.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"connectrpc.com/connect"
|
||||
"github.com/tigorlazuardi/bluemage/go/api"
|
||||
subreddits "github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1"
|
||||
"github.com/tigorlazuardi/bluemage/go/gen/proto/subreddits/v1/v1connect"
|
||||
)
|
||||
|
||||
type SubredditHandler struct {
|
||||
API *api.API
|
||||
|
||||
v1connect.UnimplementedSubredditsServiceHandler
|
||||
}
|
||||
|
||||
// CreateSubreddit creates a new subreddit
|
||||
// Returns the subreddit name.
|
||||
//
|
||||
// Returns the following error codes:
|
||||
// - connect.CodeAlreadyExists if subreddit with the same name already exists.
|
||||
// - connect.CodeInvalidArgument if validation failed, e.g. Invalid schedule cron format.
|
||||
// - connect.CodeNotFound if the subreddit does not exist.
|
||||
func (su *SubredditHandler) CreateSubreddit(ctx context.Context, request *connect.Request[subreddits.CreateSubredditRequest]) (*connect.Response[subreddits.CreateSubredditResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
// GetSubreddit returns a subreddit by its name.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
func (su *SubredditHandler) GetSubreddit(_ context.Context, _ *connect.Request[subreddits.GetSubredditRequest]) (*connect.Response[subreddits.GetSubredditResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
// ListSubreddits returns a list of subreddits.
|
||||
func (su *SubredditHandler) ListSubreddits(_ context.Context, _ *connect.Request[subreddits.ListSubredditsRequest]) (*connect.Response[subreddits.ListSubredditsResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
// UpdateSubreddit updates a subreddit.
|
||||
//
|
||||
// Only the fields that are set in the request will be updated.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
func (su *SubredditHandler) UpdateSubreddit(_ context.Context, _ *connect.Request[subreddits.UpdateSubredditRequest]) (*connect.Response[subreddits.UpdateSubredditResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
// DeleteSubreddit deletes a subreddit.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
func (su *SubredditHandler) DeleteSubreddit(_ context.Context, _ *connect.Request[subreddits.DeleteSubredditRequest]) (*connect.Response[subreddits.DeleteSubredditResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
||||
|
||||
// ResolveSubredditName resolves the given subreddit name.
|
||||
//
|
||||
// The returned resolved_name is the name that is actually
|
||||
// used in Reddit.
|
||||
//
|
||||
// Returns error with connect.CodeNotFound if subreddit does not exist.
|
||||
// So this rpc endpoint also acts to check subreddit's existence.
|
||||
func (su *SubredditHandler) ResolveSubredditName(_ context.Context, _ *connect.Request[subreddits.ResolveSubredditNameRequest]) (*connect.Response[subreddits.ResolveSubredditNameResponse], error) {
|
||||
panic("not implemented") // TODO: Implement
|
||||
}
|
|
@ -18,7 +18,7 @@ message CreateSubredditRequest {
|
|||
// schedule is cron job spec to set schedule on when
|
||||
// the runner for this subreddit runs.
|
||||
string schedule = 4 [(buf.validate.field).string.min_len = 1];
|
||||
uint32 countback = 5 [(buf.validate.field).uint32.gt = 0];
|
||||
int64 countback = 5 [(buf.validate.field).int64.gt = 0];
|
||||
}
|
||||
|
||||
enum SubredditType {
|
||||
|
|
Loading…
Reference in a new issue