88 lines
1.9 KiB
Go
88 lines
1.9 KiB
Go
|
package crud
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
|
||
|
"github.com/uptrace/bun"
|
||
|
"github.com/uptrace/bun/driver/pgdriver"
|
||
|
)
|
||
|
|
||
|
var ErrRecordAlreadyExists = errors.New("record already exists")
|
||
|
|
||
|
type Service[T any] struct {
|
||
|
db *bun.DB
|
||
|
}
|
||
|
|
||
|
func NewService[T any](db *bun.DB) *Service[T] {
|
||
|
return &Service[T]{
|
||
|
db: db,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Service[T]) Insert(ctx context.Context, model *T) error {
|
||
|
if _, err := s.db.NewInsert().Model(model).Returning("*").Exec(ctx); err != nil {
|
||
|
pqErr := pgdriver.Error{}
|
||
|
if errors.As(err, &pqErr) {
|
||
|
if pqErr.Field('C') == "23505" {
|
||
|
return ErrRecordAlreadyExists
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (s *Service[T]) UpdatePk(ctx context.Context, model *T, columns []string) error {
|
||
|
if _, err := s.db.NewUpdate().Model(model).WherePK(columns...).Column(columns...).Exec(ctx); err != nil {
|
||
|
pqErr := pgdriver.Error{}
|
||
|
if errors.As(err, &pqErr) {
|
||
|
if pqErr.Field('C') == "23505" {
|
||
|
return ErrRecordAlreadyExists
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
//nolint:revive
|
||
|
func (s *Service[T]) Update(ctx context.Context, model *T, columns []string, query string, args ...any) error {
|
||
|
if _, err := s.db.NewUpdate().Model(model).Where(query, args...).Column(columns...).Exec(ctx); err != nil {
|
||
|
pqErr := pgdriver.Error{}
|
||
|
if errors.As(err, &pqErr) {
|
||
|
if pqErr.Field('C') == "23505" {
|
||
|
return ErrRecordAlreadyExists
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (s *Service[T]) FindOne(ctx context.Context, query string, args ...any) (*T, error) {
|
||
|
m := new(T)
|
||
|
|
||
|
return m, s.db.NewSelect().Model(m).Where(query, args...).Scan(ctx, m)
|
||
|
}
|
||
|
|
||
|
//nolint:revive
|
||
|
func (s *Service[T]) Find(ctx context.Context, query string, args ...any) ([]T, int, error) {
|
||
|
m := make([]T, 0)
|
||
|
c, err := s.db.NewSelect().Model(m).Where(query, args...).ScanAndCount(ctx, &m)
|
||
|
|
||
|
return m, c, err
|
||
|
}
|
||
|
|
||
|
func (s *Service[T]) Delete(ctx context.Context, query string, args ...any) error {
|
||
|
_, err := s.db.NewDelete().Model((*T)(nil)).Where(query, args...).Exec(ctx)
|
||
|
|
||
|
return err
|
||
|
}
|