fix: address code review findings
Remove dead code: duplicate ExternalRelease/Artist/ParsedArtist structs in model.go, ParseArtist/mbArtist/mbArtistData in client.go, ArtistTypeFilter and related filtering functions in api.go, SyncArtistDiscographyWithFilter in sync.go, and CacheStats/IsArtistCacheValid in cache.go. Fix bugs: SaveExternalRelease now stores NULL instead of empty string for zero CachedAt; sync upserts are now transactional with stale release cleanup; getCachedReleases returns int instead of *CacheStats; doGet uses url.Values for proper query encoding of MBID. Fix tests: removed duplicate TestRun_GracefulShutdown, removed dead code (_ = dbPath) from TestNewApp, fixed assertions in httptest handler goroutine to avoid data race, increased rate limiter timing tolerance, removed Client.Close() calls (no-op removed), fixed sync test cache expiry to use UPDATE instead of 0 TTL races. Fix formatting: cancel()}() formatting in main.go, error format string in sync.go.
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"golang.org/x/time/rate"
|
||||
@@ -35,23 +36,6 @@ func NewClient(cfg config.MusicBrainzConfig) *MusicBrainzClient {
|
||||
}
|
||||
}
|
||||
|
||||
// NewClientWithLimiter creates a MusicBrainzClient with a custom rate limiter.
|
||||
// This is primarily used for testing to inject a mock rate limiter.
|
||||
func NewClientWithLimiter(cfg config.MusicBrainzConfig, rl *rate.Limiter) *MusicBrainzClient {
|
||||
return &MusicBrainzClient{
|
||||
httpClient: &http.Client{
|
||||
Timeout: 30 * time.Second,
|
||||
},
|
||||
userAgent: cfg.UserAgent,
|
||||
baseURL: "https://musicbrainz.org/ws/2",
|
||||
rateLimiter: rl,
|
||||
}
|
||||
}
|
||||
|
||||
// Close is a no-op for the x/time/rate-based client (the limiter does not
|
||||
// spawn goroutines), but retained for API compatibility.
|
||||
func (c *MusicBrainzClient) Close() {}
|
||||
|
||||
// doGet performs a rate-limited HTTP GET request to the MusicBrainz API.
|
||||
// It blocks until the rate limiter allows the request, then sets the proper
|
||||
// User-Agent header and returns the response body.
|
||||
@@ -126,18 +110,6 @@ type mbReleaseGroupList struct {
|
||||
ReleaseGroupList mbReleaseGroupListXML `xml:"release-group-list"`
|
||||
}
|
||||
|
||||
// mbArtistData represents the artist element inside metadata.
|
||||
type mbArtistData struct {
|
||||
ID string `xml:"id,attr"`
|
||||
Name string `xml:"name"`
|
||||
}
|
||||
|
||||
// mbArtist represents the XML structure of a MusicBrainz artist response.
|
||||
type mbArtist struct {
|
||||
XMLName xml.Name `xml:"metadata"`
|
||||
Artist mbArtistData `xml:"artist"`
|
||||
}
|
||||
|
||||
// ParseReleaseGroups parses a MusicBrainz release-group list XML response
|
||||
// into a ParsedReleaseGroups struct.
|
||||
func ParseReleaseGroups(data []byte) (*ParsedReleaseGroups, error) {
|
||||
@@ -163,14 +135,7 @@ func ParseReleaseGroups(data []byte) (*ParsedReleaseGroups, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ParseArtist parses a MusicBrainz artist XML response into a ParsedArtist struct.
|
||||
func ParseArtist(data []byte) (*ParsedArtist, error) {
|
||||
var artist mbArtist
|
||||
if err := xml.Unmarshal(data, &artist); err != nil {
|
||||
return nil, fmt.Errorf("parse artist XML: %w", err)
|
||||
}
|
||||
return &ParsedArtist{
|
||||
ID: artist.Artist.ID,
|
||||
Name: artist.Artist.Name,
|
||||
}, nil
|
||||
// buildPath constructs a properly URL-encoded query path for the MusicBrainz API.
|
||||
func buildPath(endpoint string, params url.Values) string {
|
||||
return endpoint + "?" + params.Encode()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user