fix(store): Reorder validiert Vollständigkeit und RowsAffected
This commit is contained in:
parent
b463aeeae1
commit
1c11aa9877
1 changed files with 33 additions and 2 deletions
|
|
@ -3,12 +3,17 @@ package store
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// ErrReorderMismatch wird von Reorder zurückgegeben, wenn die übergebene
|
||||
// ID-Liste nicht mit den tatsächlichen Items der Playlist übereinstimmt.
|
||||
var ErrReorderMismatch = errors.New("reorder: item list does not match playlist")
|
||||
|
||||
// ------------------------------------------------------------------
|
||||
// Domain types
|
||||
// ------------------------------------------------------------------
|
||||
|
|
@ -531,20 +536,46 @@ func (s *PlaylistStore) ScreenSlugByItemID(ctx context.Context, itemID string) (
|
|||
}
|
||||
|
||||
// Reorder sets order_index for each item ID in the given slice order.
|
||||
// Returns ErrReorderMismatch if the number of provided IDs does not match
|
||||
// the number of items in the playlist, or if any ID does not belong to it.
|
||||
func (s *PlaylistStore) Reorder(ctx context.Context, playlistID string, itemIDs []string) error {
|
||||
seen := make(map[string]struct{}, len(itemIDs))
|
||||
for _, id := range itemIDs {
|
||||
if _, dup := seen[id]; dup {
|
||||
return fmt.Errorf("%w: duplicate id %s", ErrReorderMismatch, id)
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
}
|
||||
|
||||
tx, err := s.pool.Begin(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback(ctx) //nolint:errcheck
|
||||
|
||||
var count int
|
||||
if err := tx.QueryRow(ctx,
|
||||
`select count(*) from playlist_items where playlist_id=$1`, playlistID,
|
||||
).Scan(&count); err != nil {
|
||||
return err
|
||||
}
|
||||
if count != len(itemIDs) {
|
||||
return fmt.Errorf("%w: got %d ids, playlist has %d items",
|
||||
ErrReorderMismatch, len(itemIDs), count)
|
||||
}
|
||||
|
||||
for i, id := range itemIDs {
|
||||
if _, err := tx.Exec(ctx,
|
||||
tag, err := tx.Exec(ctx,
|
||||
`update playlist_items set order_index=$1 where id=$2 and playlist_id=$3`,
|
||||
i, id, playlistID,
|
||||
); err != nil {
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if tag.RowsAffected() != 1 {
|
||||
return fmt.Errorf("%w: id %s not found in playlist %s",
|
||||
ErrReorderMismatch, id, playlistID)
|
||||
}
|
||||
}
|
||||
return tx.Commit(ctx)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue