fix(library): include unindexed tracks in missing ReplayGain filter

This commit is contained in:
zarzet committed 2026-10-02 11:44:37 +07:00
1 parent 8758790d9f
commit c1892fcd69
2 files changed
+17 -25

No files matched your search

+6 -14
View File
@@ -7,10 +7,8 @@ String confirmedMissingLyricsSqlPredicate({
required String lyricsKnownExpr,
}) => '($lyricsKnownExpr) AND COALESCE($hasLyricsExpr, 0) = 0';
String confirmedMissingReplayGainSqlPredicate({
required String hasReplayGainExpr,
required String replayGainKnownExpr,
}) => '($replayGainKnownExpr) AND COALESCE($hasReplayGainExpr, 0) = 0';
String missingReplayGainSqlPredicate({required String hasReplayGainExpr}) =>
'COALESCE($hasReplayGainExpr, 0) = 0';
class _QueueOrderTerm {
final String column;
@@ -421,8 +419,6 @@ extension _LibraryDbQueueSql on LibraryDatabase {
hasLyricsExpr: 'h.has_lyrics',
lyricsKnownExpr: 'COALESCE(h.lyrics_metadata_scan_version, 0) >= 1',
hasReplayGainExpr: 'h.has_replaygain',
replayGainKnownExpr:
'COALESCE(h.replaygain_metadata_scan_version, 0) >= 1',
);
}
@@ -473,8 +469,6 @@ extension _LibraryDbQueueSql on LibraryDatabase {
lyricsKnownExpr:
'COALESCE(l.audio_metadata_scan_version, 0) >= ${LibraryDatabase.lyricsMetadataScanVersion}',
hasReplayGainExpr: 'l.has_replaygain',
replayGainKnownExpr:
'COALESCE(l.audio_metadata_scan_version, 0) >= ${LibraryDatabase.audioMetadataScanVersion}',
);
}
@@ -497,7 +491,6 @@ extension _LibraryDbQueueSql on LibraryDatabase {
required String hasLyricsExpr,
required String lyricsKnownExpr,
required String hasReplayGainExpr,
required String replayGainKnownExpr,
}) {
final quality = request.quality?.trim().toLowerCase();
if (quality != null && quality.isNotEmpty) {
@@ -593,12 +586,11 @@ extension _LibraryDbQueueSql on LibraryDatabase {
);
break;
case 'missing-replaygain':
// Only files whose tags were read since ReplayGain was indexed.
// Include legacy rows without indexed ReplayGain as candidates until
// a metadata refresh confirms their tags. Requiring a new scan version
// hides the entire older collection before it has been rescanned.
where.add(
confirmedMissingReplayGainSqlPredicate(
hasReplayGainExpr: hasReplayGainExpr,
replayGainKnownExpr: replayGainKnownExpr,
),
missingReplayGainSqlPredicate(hasReplayGainExpr: hasReplayGainExpr),
);
break;
}
+11 -11
View File
@@ -13,17 +13,13 @@ String _tableDefinition(String path, String table) {
void main() {
test(
'ReplayGain filter excludes unknown rows and follows tag add/remove in both databases',
'ReplayGain filter includes unindexed candidates and follows tag add/remove in both databases',
() async {
final historyPredicate = confirmedMissingReplayGainSqlPredicate(
final historyPredicate = missingReplayGainSqlPredicate(
hasReplayGainExpr: 'has_replaygain',
replayGainKnownExpr:
'COALESCE(replaygain_metadata_scan_version, 0) >= 1',
);
final localPredicate = confirmedMissingReplayGainSqlPredicate(
final localPredicate = missingReplayGainSqlPredicate(
hasReplayGainExpr: 'has_replaygain',
replayGainKnownExpr:
'COALESCE(audio_metadata_scan_version, 0) >= ${LibraryDatabase.audioMetadataScanVersion}',
);
// Use the production table definitions and filter predicates with real
// SQLite. This catches missing schema columns and NULL/default semantics.
@@ -40,18 +36,22 @@ for table, version, known, predicate in [
('library', 'audio_metadata_scan_version', data['scanVersion'], data['localPredicate']),
]:
for name, gain, scanned in [('unknown', 0, 0), ('legacy', 0, known - 1),
('tagged', 1, known), ('missing', 0, known)]:
('tagged', 1, known), ('missing', 0, known),
('legacy-tagged', 1, 0)]:
db.execute(f'INSERT INTO {table} (id, track_name, artist_name, album_name, file_path, '
+ ('downloaded_at, service' if table == 'history' else 'scanned_at, source_id')
+ f', has_replaygain, {version}) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)',
(name, 'Track', 'Artist', 'Album', '/'+name+'.flac', '2026-01-01', 'test', gain, scanned))
def matches():
return [row[0] for row in db.execute(f'SELECT id FROM {table} WHERE {predicate} ORDER BY id')]
assert matches() == ['missing'], (table, matches())
assert matches() == ['legacy', 'missing', 'unknown'], (table, matches())
db.execute(f"UPDATE {table} SET has_replaygain = 1 WHERE id = 'missing'")
assert matches() == [], (table, matches())
assert matches() == ['legacy', 'unknown'], (table, matches())
db.execute(f"UPDATE {table} SET has_replaygain = 0 WHERE id = 'tagged'")
assert matches() == ['tagged'], (table, matches())
assert matches() == ['legacy', 'tagged', 'unknown'], (table, matches())
# An entirely unindexed collection without ReplayGain must not look empty.
db.execute(f'UPDATE {table} SET has_replaygain = 0, {version} = 0')
assert len(matches()) == 5, (table, matches())
print('both databases passed')
''',
jsonEncode({