fix: address code review findings
- Fix duplicate Telegram notifications: SyncArtistDiscography no longer wipes notifications_sent for the whole artist on every cache-miss re-sync; only markers for releases that disappear are pruned (FK-safe via INSERT OR REPLACE + rgid NOT IN (...)). - Cache empty MusicBrainz discographies via a new artist_settings.last_synced column (migration 009) so zero-release artists honor the TTL instead of being re-fetched every cycle. - Wire the Web UI server and Telegram notifier scheduler into main.run/NewApp. - Guard startPeriodicSync against overlapping syncs with a done-channel slot. - Add server.public_url config; NewServerWithConfig derives reachable links and no longer advertises the 0.0.0.0 bind address. - Web handlers: use scanner.ScanArtist per artist, drop always-false releaseIgnored lookup and dead endsWith, thread configured threshold. - Limit :memory: DB pool to one connection so migrations and queries share the same in-memory store.
This commit is contained in:
@@ -4,19 +4,27 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DBer is the minimal query interface satisfied by both *sql.DB and *sql.Tx,
|
||||
// so callers can run statements inside or outside a transaction.
|
||||
type DBer interface {
|
||||
Exec(query string, args ...interface{}) (sql.Result, error)
|
||||
}
|
||||
|
||||
// GetArtistSettings retrieves an artist_settings row by ID.
|
||||
// Returns sql.ErrNoRows if the artist is not found.
|
||||
func GetArtistSettings(db *DB, id string) (*ArtistSettings, error) {
|
||||
var (
|
||||
s ArtistSettings
|
||||
mbid sql.NullString
|
||||
s ArtistSettings
|
||||
mbid sql.NullString
|
||||
lastSynced sql.NullTime
|
||||
)
|
||||
err := db.Conn().QueryRow(
|
||||
"SELECT id, name, mbid, ignore_singles, ignore_compilations, monitored FROM artist_settings WHERE id = ?",
|
||||
"SELECT id, name, mbid, ignore_singles, ignore_compilations, monitored, last_synced FROM artist_settings WHERE id = ?",
|
||||
id,
|
||||
).Scan(&s.ID, &s.Name, &mbid, &s.IgnoreSingles, &s.IgnoreCompilations, &s.Monitored)
|
||||
).Scan(&s.ID, &s.Name, &mbid, &s.IgnoreSingles, &s.IgnoreCompilations, &s.Monitored, &lastSynced)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, ErrArtistNotFound
|
||||
@@ -24,9 +32,26 @@ func GetArtistSettings(db *DB, id string) (*ArtistSettings, error) {
|
||||
return nil, err
|
||||
}
|
||||
s.MBID = mbid.String
|
||||
if lastSynced.Valid {
|
||||
s.LastSynced = lastSynced.Time
|
||||
}
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
// TouchArtistSynced records that the artist was synced at the given time. It
|
||||
// is used by the MusicBrainz pipeline to mark a successful sync (even one that
|
||||
// found zero release groups) so the cache TTL is honoured.
|
||||
func TouchArtistSynced(db DBer, artistID string, syncedAt time.Time) error {
|
||||
_, err := db.Exec(
|
||||
"UPDATE artist_settings SET last_synced = ? WHERE id = ?",
|
||||
FormatCachedAt(syncedAt), artistID,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("touch artist synced: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SaveArtistSettings inserts or replaces an artist_settings row.
|
||||
func SaveArtistSettings(db *DB, settings *ArtistSettings) error {
|
||||
_, err := db.Conn().Exec(
|
||||
|
||||
Reference in New Issue
Block a user