profession: add pg_repository, add a new package errorutils

This commit is contained in:
Dawid Wysokiński 2021-02-27 11:33:16 +01:00
parent c3408ef7c8
commit f49dfc5c43
10 changed files with 198 additions and 2 deletions

View File

@ -40,6 +40,10 @@ type ProfessionInput struct {
Description *string `json:"description,omitempty" xml:"description" gqlgen:"description"`
}
func (input *ProfessionInput) IsEmpty() bool {
return input == nil && input.Name == nil && input.Description == nil
}
func (input *ProfessionInput) ToProfession() *Profession {
p := &Profession{}
if input.Name != nil {
@ -51,6 +55,19 @@ func (input *ProfessionInput) ToProfession() *Profession {
return p
}
func (input *ProfessionInput) ApplyUpdate(q *orm.Query) (*orm.Query, error) {
if !input.IsEmpty() {
if input.Name != nil {
q.Set("name = ?", *input.Name)
}
if input.Description != nil {
q.Set("description = ?", *input.Description)
}
}
return q, nil
}
type ProfessionFilter struct {
ID []int `gqlgen:"id" json:"id" xml:"id"`
IDNEQ []int `gqlgen:"idNEQ" json:"idNEQ" xml:"idNEQ"`
@ -74,6 +91,10 @@ type ProfessionFilter struct {
}
func (f *ProfessionFilter) WhereWithAlias(q *orm.Query, alias string) (*orm.Query, error) {
if f == nil {
return q, nil
}
if !isZero(f.ID) {
q = q.Where(sqlutils.BuildConditionArray(sqlutils.AddAliasToColumnName("id", alias)), pg.Array(f.ID))
}

View File

@ -79,6 +79,10 @@ type QualificationFilterOr struct {
}
func (f *QualificationFilterOr) WhereWithAlias(q *orm.Query, alias string) *orm.Query {
if f == nil {
return q
}
q = q.WhereGroup(func(q *orm.Query) (*orm.Query, error) {
if !isZero(f.NameMATCH) {
q = q.Where(sqlutils.BuildConditionMatch(sqlutils.AddAliasToColumnName("name", alias)), f.NameMATCH)
@ -134,6 +138,10 @@ type QualificationFilter struct {
}
func (f *QualificationFilter) WhereWithAlias(q *orm.Query, alias string) (*orm.Query, error) {
if f == nil {
return q, nil
}
if !isZero(f.ID) {
q = q.Where(sqlutils.BuildConditionArray(sqlutils.AddAliasToColumnName("id", alias)), pg.Array(f.ID))
}

View File

@ -124,6 +124,10 @@ type QuestionFilter struct {
}
func (f *QuestionFilter) WhereWithAlias(q *orm.Query, alias string) (*orm.Query, error) {
if f == nil {
return q, nil
}
if !isZero(f.ID) {
q = q.Where(sqlutils.BuildConditionArray(sqlutils.AddAliasToColumnName("id", alias)), pg.Array(f.ID))
}

View File

@ -122,6 +122,10 @@ type UserFilter struct {
}
func (f *UserFilter) WhereWithAlias(q *orm.Query, alias string) (*orm.Query, error) {
if f == nil {
return q, nil
}
if !isZero(f.ID) {
q = q.Where(sqlutils.BuildConditionArray(sqlutils.AddAliasToColumnName("id", alias)), pg.Array(f.ID))
}

View File

@ -0,0 +1,22 @@
package profession
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
)
type FetchConfig struct {
Filter *models.ProfessionFilter
Offset int
Limit int
Sort []string
Count bool
}
type Repository interface {
Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error)
Update(ctx context.Context, f *models.ProfessionFilter, input *models.ProfessionInput) ([]*models.Profession, error)
Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Profession, int, error)
}

View File

@ -0,0 +1,8 @@
package repository
const (
nameIsAlreadyTaken = "Istnieje już zawód o podanej nazwie."
failedToSaveModel = "Wystąpił błąd podczas zapisywania zawodu, prosimy spróbować później."
failedToDeleteModel = "Wystąpił błąd podczas usuwania zawodu, prosimy spróbować później."
failedToFetchModel = "Wystąpił błąd podczas pobierania zawodów, prosimy spróbować później."
)

View File

@ -0,0 +1,93 @@
package repository
import (
"context"
"strings"
errorutils "github.com/zdam-egzamin-zawodowy/backend/pkg/utils/error"
"github.com/go-pg/pg/v10"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
"github.com/zdam-egzamin-zawodowy/backend/internal/profession"
)
type pgRepository struct {
*pg.DB
}
type PGRepositoryConfig struct {
db *pg.DB
}
func NewPGRepository(cfg PGRepositoryConfig) profession.Repository {
return &pgRepository{
cfg.db,
}
}
func (repo *pgRepository) Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error) {
item := input.ToProfession()
if _, err := repo.
Model(item).
Context(ctx).
Returning("*").
Insert(); err != nil {
if strings.Contains(err.Error(), "name") {
return nil, errorutils.Wrap(err, nameIsAlreadyTaken)
}
return nil, errorutils.Wrap(err, failedToSaveModel)
}
return item, nil
}
func (repo *pgRepository) Update(ctx context.Context, f *models.ProfessionFilter, input *models.ProfessionInput) ([]*models.Profession, error) {
items := []*models.Profession{}
if _, err := repo.
Model(&items).
Context(ctx).
Returning("*").
Apply(input.ApplyUpdate).
Apply(f.Where).
Update(); err != nil {
if strings.Contains(err.Error(), "name") {
return nil, errorutils.Wrap(err, nameIsAlreadyTaken)
}
return nil, errorutils.Wrap(err, failedToSaveModel)
}
return items, nil
}
func (repo *pgRepository) Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error) {
items := []*models.Profession{}
if _, err := repo.
Model(&items).
Context(ctx).
Returning("*").
Apply(f.Where).
Delete(); err != nil {
return nil, errorutils.Wrap(err, failedToDeleteModel)
}
return items, nil
}
func (repo *pgRepository) Fetch(ctx context.Context, cfg *profession.FetchConfig) ([]*models.Profession, int, error) {
var err error
items := []*models.Profession{}
total := 0
query := repo.
Model(&items).
Context(ctx).
Limit(cfg.Limit).
Offset(cfg.Offset).
Apply(cfg.Filter.Where)
if cfg.Count {
total, err = query.SelectAndCount()
} else {
err = query.Select()
}
if err != nil && err != pg.ErrNoRows {
return nil, 0, errorutils.Wrap(err, failedToFetchModel)
}
return items, total, nil
}

View File

@ -0,0 +1,17 @@
package profession
import (
"context"
"github.com/zdam-egzamin-zawodowy/backend/internal/models"
)
type Usecase interface {
Store(ctx context.Context, input *models.ProfessionInput) (*models.Profession, error)
UpdateOne(ctx context.Context, id int, input *models.ProfessionInput) (*models.Profession, error)
UpdateMany(ctx context.Context, f *models.ProfessionFilter, input *models.ProfessionInput) ([]*models.Profession, error)
Delete(ctx context.Context, f *models.ProfessionFilter) ([]*models.Profession, error)
Fetch(ctx context.Context, cfg *FetchConfig) ([]*models.Profession, int, error)
GetByID(ctx context.Context, id int) (*models.Profession, error)
GetBySlug(ctx context.Context, slug string) (*models.Profession, error)
}

View File

@ -5,7 +5,7 @@ import (
)
const (
EnvMode = "MODE"
EnvKey = "MODE"
DevelopmentMode = "development"
ProductionMode = "production"
TestMode = "test"
@ -14,7 +14,7 @@ const (
var mode = DevelopmentMode
func init() {
Set(os.Getenv(EnvMode))
Set(os.Getenv(EnvKey))
}
func Set(value string) {

19
pkg/utils/error/error.go Normal file
View File

@ -0,0 +1,19 @@
package errorutils
import (
"fmt"
"github.com/pkg/errors"
"github.com/zdam-egzamin-zawodowy/backend/pkg/mode"
)
func Wrap(details error, message string) error {
return Wrapf(details, message)
}
func Wrapf(details error, message string, args ...interface{}) error {
if mode.Get() != mode.ProductionMode {
return errors.Wrapf(details, message, args...)
}
return fmt.Errorf(message)
}