package bundb import ( "context" "database/sql" "errors" "fmt" "gitea.dwysokinski.me/twhelp/dcbot/internal/bundb/internal/model" "gitea.dwysokinski.me/twhelp/dcbot/internal/domain" "github.com/google/uuid" "github.com/uptrace/bun" ) type Group struct { db *bun.DB } func NewGroup(db *bun.DB) *Group { return &Group{db: db} } func (g *Group) Create(ctx context.Context, params domain.CreateGroupParams) (domain.Group, error) { group := model.Group{ ServerID: params.ServerID(), VersionCode: params.VersionCode(), ChannelGains: params.ChannelGains(), ChannelLosses: params.ChannelLosses(), ServerKey: params.ServerKey(), } if _, err := g.db.NewInsert(). Model(&group). Returning("*"). Exec(ctx); err != nil { return domain.Group{}, fmt.Errorf("something went wrong while inserting group into the db: %w", err) } return group.ToDomain(), nil } func (g *Group) UpdateByID(ctx context.Context, id string, params domain.UpdateGroupParams) (domain.Group, error) { if params.IsZero() { return domain.Group{}, domain.ErrNothingToUpdate } if _, err := uuid.Parse(id); err != nil { return domain.Group{}, domain.GroupNotFoundError{ID: id} } var group model.Group res, err := g.db.NewUpdate(). Model(&group). Returning("*"). Where("id = ?", id). Apply(updateGroupsParamsApplier{params}.apply). Exec(ctx) if err != nil && !errors.Is(err, sql.ErrNoRows) { return domain.Group{}, fmt.Errorf("couldn't update group (id=%s): %w", id, err) } if affected, _ := res.RowsAffected(); affected == 0 { return domain.Group{}, domain.GroupNotFoundError{ID: id} } return group.ToDomain(), nil } func (g *Group) List(ctx context.Context, params domain.ListGroupsParams) ([]domain.Group, error) { var groups []model.Group if err := g.db.NewSelect(). Model(&groups). Order("created_at ASC"). Apply(listGroupsParamsApplier{params}.apply). Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) { return nil, fmt.Errorf("couldn't select groups from the db: %w", err) } result := make([]domain.Group, 0, len(groups)) for _, version := range groups { result = append(result, version.ToDomain()) } return result, nil } type updateGroupsParamsApplier struct { params domain.UpdateGroupParams } func (u updateGroupsParamsApplier) apply(q *bun.UpdateQuery) *bun.UpdateQuery { if u.params.ChannelGains.Valid { q = q.Set("channel_gains = ?", u.params.ChannelGains.String) } if u.params.ChannelLosses.Valid { q = q.Set("channel_losses = ?", u.params.ChannelLosses.String) } if u.params.ServerKey.Valid { q = q.Set("server_key = ?", u.params.ServerKey.String) } if u.params.VersionCode.Valid { q = q.Set("version_code = ?", u.params.VersionCode.String) } return q } type listGroupsParamsApplier struct { params domain.ListGroupsParams } func (l listGroupsParamsApplier) apply(q *bun.SelectQuery) *bun.SelectQuery { if l.params.ServerIDs != nil { q = q.Where("server_id IN (?)", bun.In(l.params.ServerIDs)) } return q }