2022-10-23 06:20:48 +00:00
|
|
|
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"
|
2022-10-29 06:13:02 +00:00
|
|
|
"github.com/jackc/pgerrcode"
|
2022-10-23 06:20:48 +00:00
|
|
|
"github.com/uptrace/bun"
|
|
|
|
"github.com/uptrace/bun/driver/pgdriver"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Monitor struct {
|
|
|
|
db *bun.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewMonitor(db *bun.DB) *Monitor {
|
|
|
|
return &Monitor{db: db}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Monitor) Create(ctx context.Context, params domain.CreateMonitorParams) (domain.Monitor, error) {
|
|
|
|
groupID, err := uuid.Parse(params.GroupID())
|
|
|
|
if err != nil {
|
|
|
|
return domain.Monitor{}, domain.GroupDoesNotExistError{
|
|
|
|
ID: params.GroupID(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
monitor := model.Monitor{
|
|
|
|
GroupID: groupID,
|
|
|
|
TribeID: params.TribeID(),
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err = m.db.NewInsert().
|
|
|
|
Model(&monitor).
|
|
|
|
Returning("*").
|
|
|
|
Exec(ctx); err != nil {
|
|
|
|
|
|
|
|
return domain.Monitor{}, fmt.Errorf(
|
|
|
|
"something went wrong while inserting monitor into the db: %w",
|
|
|
|
mapCreateMonitorError(err, params),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return monitor.ToDomain(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Monitor) List(ctx context.Context, groupID string) ([]domain.Monitor, error) {
|
|
|
|
if _, err := uuid.Parse(groupID); err != nil {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var monitors []model.Monitor
|
|
|
|
|
|
|
|
if err := m.db.NewSelect().
|
|
|
|
Model(&monitors).
|
|
|
|
Order("created_at ASC").
|
|
|
|
Where("group_id = ?", groupID).
|
|
|
|
Scan(ctx); err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return nil, fmt.Errorf("couldn't select monitors from the db: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
result := make([]domain.Monitor, 0, len(monitors))
|
|
|
|
for _, monitor := range monitors {
|
|
|
|
result = append(result, monitor.ToDomain())
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2022-10-23 07:44:20 +00:00
|
|
|
func (m *Monitor) Get(ctx context.Context, id string) (domain.Monitor, error) {
|
|
|
|
if _, err := uuid.Parse(id); err != nil {
|
|
|
|
return domain.Monitor{}, domain.MonitorNotFoundError{ID: id}
|
|
|
|
}
|
|
|
|
|
|
|
|
var monitor model.Monitor
|
|
|
|
|
|
|
|
err := m.db.NewSelect().
|
|
|
|
Model(&monitor).
|
|
|
|
Where("id = ?", id).
|
|
|
|
Scan(ctx)
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return domain.Monitor{}, domain.MonitorNotFoundError{ID: id}
|
|
|
|
}
|
|
|
|
return domain.Monitor{}, fmt.Errorf("couldn't select monitor from the db (id=%s): %w", id, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return monitor.ToDomain(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (m *Monitor) Delete(ctx context.Context, id string) error {
|
|
|
|
if _, err := uuid.Parse(id); err != nil {
|
|
|
|
return domain.MonitorNotFoundError{ID: id}
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := m.db.NewDelete().
|
|
|
|
Model(&model.Monitor{}).
|
|
|
|
Returning("NULL").
|
|
|
|
Where("id = ?", id).
|
|
|
|
Exec(ctx)
|
|
|
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
|
|
|
return fmt.Errorf("couldn't delete monitor (id=%s): %w", id, err)
|
|
|
|
}
|
|
|
|
if affected, _ := res.RowsAffected(); affected == 0 {
|
|
|
|
return domain.MonitorNotFoundError{ID: id}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-23 06:20:48 +00:00
|
|
|
func mapCreateMonitorError(err error, params domain.CreateMonitorParams) error {
|
|
|
|
var pgError pgdriver.Error
|
|
|
|
if !errors.As(err, &pgError) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
code := pgError.Field('C')
|
|
|
|
constraint := pgError.Field('n')
|
|
|
|
switch {
|
2022-10-29 06:13:02 +00:00
|
|
|
case code == pgerrcode.ForeignKeyViolation && constraint == "monitors_group_id_fkey":
|
2022-10-23 06:20:48 +00:00
|
|
|
return domain.GroupDoesNotExistError{
|
|
|
|
ID: params.GroupID(),
|
|
|
|
}
|
2022-10-29 06:13:02 +00:00
|
|
|
case code == pgerrcode.UniqueViolation && constraint == "monitors_group_id_tribe_id_key":
|
2022-10-23 06:20:48 +00:00
|
|
|
return domain.MonitorAlreadyExistsError{
|
|
|
|
TribeID: params.TribeID(),
|
|
|
|
GroupID: params.GroupID(),
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|