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:
@@ -25,10 +25,21 @@ func New(dbPath string) (*DB, error) {
|
||||
// EVERY connection in the pool. A one-off "PRAGMA foreign_keys=ON" executed
|
||||
// on the pooled *sql.DB only applies to the first connection and is lost on
|
||||
// connections opened later by the pool, silently disabling the safety net.
|
||||
// A plain ":memory:" database is private to the connection that opened it,
|
||||
// so a pool of N connections would give N separate empty databases and
|
||||
// migrations would appear missing on some. Limiting the pool to a single
|
||||
// connection keeps one in-memory database per New() call, which is correct
|
||||
// for both tests (isolated) and the single-process production service.
|
||||
conn, err := sql.Open("sqlite3", dbPath+"?_foreign_keys=on")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open database: %w", err)
|
||||
}
|
||||
if dbPath == ":memory:" {
|
||||
conn.SetMaxOpenConns(1)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("open database: %w", err)
|
||||
}
|
||||
|
||||
// Enable WAL mode for better concurrent read performance.
|
||||
if _, err := conn.Exec("PRAGMA journal_mode=WAL"); err != nil {
|
||||
@@ -135,6 +146,10 @@ func (db *DB) migrate() error {
|
||||
name: "008_add_mbid_to_artist_settings",
|
||||
sql: `ALTER TABLE artist_settings ADD COLUMN mbid TEXT;`,
|
||||
},
|
||||
{
|
||||
name: "009_add_last_synced_to_artist_settings",
|
||||
sql: `ALTER TABLE artist_settings ADD COLUMN last_synced DATETIME;`,
|
||||
},
|
||||
}
|
||||
|
||||
for _, m := range migrations {
|
||||
@@ -181,12 +196,13 @@ func (db *DB) isMigrationApplied(name string) (bool, error) {
|
||||
|
||||
// ArtistSettings represents a row in the artist_settings table.
|
||||
type ArtistSettings struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
MBID string `json:"mbid"`
|
||||
IgnoreSingles bool `json:"ignore_singles"`
|
||||
IgnoreCompilations bool `json:"ignore_compilations"`
|
||||
Monitored bool `json:"monitored"`
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
MBID string `json:"mbid"`
|
||||
IgnoreSingles bool `json:"ignore_singles"`
|
||||
IgnoreCompilations bool `json:"ignore_compilations"`
|
||||
Monitored bool `json:"monitored"`
|
||||
LastSynced time.Time `json:"last_synced"`
|
||||
}
|
||||
|
||||
// LocalAlbum represents a row in the local_albums table.
|
||||
|
||||
Reference in New Issue
Block a user