Files
language/backend/internal/services/category_service.go
T

92 lines
2.4 KiB
Go

package services
import (
"context"
"errors"
"github.com/fish/language/backend/internal/models"
"github.com/fish/language/backend/internal/repository/queries"
)
// ErrCategoryNotEmpty is returned when deleting a category that still has words.
var ErrCategoryNotEmpty = errors.New("category has words")
// CategoryService handles business logic for categories.
type CategoryService struct {
q *queries.Queries
}
// NewCategoryService creates a new CategoryService.
func NewCategoryService(q *queries.Queries) *CategoryService {
return &CategoryService{q: q}
}
// List returns all categories ordered by sort_order.
func (s *CategoryService) List(ctx context.Context) ([]models.Category, error) {
rows, err := s.q.ListCategories(ctx)
if err != nil {
return nil, err
}
out := make([]models.Category, len(rows))
for i, r := range rows {
out[i] = toCategory(r)
}
return out, nil
}
// Get returns a single category by id.
func (s *CategoryService) Get(ctx context.Context, id int32) (models.Category, error) {
row, err := s.q.GetCategory(ctx, id)
if err != nil {
return models.Category{}, err
}
return toCategory(row), nil
}
// Create creates a new category.
func (s *CategoryService) Create(ctx context.Context, req models.CreateCategoryRequest) (models.Category, error) {
row, err := s.q.CreateCategory(ctx, queries.CreateCategoryParams{
Name: req.Name,
SortOrder: req.SortOrder,
})
if err != nil {
return models.Category{}, err
}
return toCategory(row), nil
}
// Update updates an existing category.
func (s *CategoryService) Update(ctx context.Context, id int32, req models.UpdateCategoryRequest) (models.Category, error) {
row, err := s.q.UpdateCategory(ctx, queries.UpdateCategoryParams{
ID: id,
Name: req.Name,
SortOrder: req.SortOrder,
})
if err != nil {
return models.Category{}, err
}
return toCategory(row), nil
}
// Delete removes a category by id. It refuses to delete a category that still has words.
func (s *CategoryService) Delete(ctx context.Context, id int32) error {
count, err := s.q.CountWords(ctx, queries.CountWordsParams{CategoryID: id})
if err != nil {
return err
}
if count > 0 {
return ErrCategoryNotEmpty
}
return s.q.DeleteCategory(ctx, id)
}
func toCategory(c queries.Category) models.Category {
return models.Category{
ID: c.ID,
Name: c.Name,
SortOrder: c.SortOrder,
CreatedAt: c.CreatedAt,
UpdatedAt: c.UpdatedAt,
}
}