faster database update + song blocking
This commit is contained in:
parent
be212b0d81
commit
a9af877be2
7 changed files with 106 additions and 21 deletions
|
@ -35,6 +35,7 @@ class _AudioServiceWidgetState extends State<AudioServiceWidget>
|
|||
case AppLifecycleState.resumed:
|
||||
print('AppLifecycleState.resumed');
|
||||
AudioService.connect();
|
||||
if (AudioService.running)
|
||||
AudioService.customAction(APP_LIFECYCLE_RESUMED);
|
||||
break;
|
||||
case AppLifecycleState.paused:
|
||||
|
|
|
@ -44,6 +44,7 @@ class Songs extends Table {
|
|||
TextColumn get albumArtPath => text().nullable()();
|
||||
IntColumn get trackNumber => integer().nullable()();
|
||||
BoolColumn get blocked => boolean().withDefault(const Constant(false))();
|
||||
BoolColumn get present => boolean().withDefault(const Constant(true))();
|
||||
|
||||
@override
|
||||
Set<Column> get primaryKey => {path};
|
||||
|
@ -139,6 +140,29 @@ class MoorMusicDataSource extends _$MoorMusicDataSource
|
|||
.map((moorArtist) => ArtistModel.fromMoorArtist(moorArtist))
|
||||
.toList());
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> insertSongs(List<SongModel> songModels) async {
|
||||
|
||||
await update(songs).write(const SongsCompanion(present: Value(false)));
|
||||
|
||||
await batch((batch) {
|
||||
batch.insertAllOnConflictUpdate(
|
||||
songs,
|
||||
songModels
|
||||
.map((e) => e.toMoorInsert())
|
||||
.toList(),
|
||||
);
|
||||
});
|
||||
|
||||
await (delete(songs)..where((tbl) => tbl.present.equals(false))).go();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setSongBlocked(SongModel song, bool blocked) async {
|
||||
await (update(songs)..where((tbl) => tbl.path.equals(song.path)))
|
||||
.write(SongsCompanion(blocked: Value(blocked)));
|
||||
}
|
||||
}
|
||||
|
||||
LazyDatabase _openConnection() {
|
||||
|
|
|
@ -498,6 +498,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
final String albumArtPath;
|
||||
final int trackNumber;
|
||||
final bool blocked;
|
||||
final bool present;
|
||||
MoorSong(
|
||||
{@required this.title,
|
||||
@required this.albumTitle,
|
||||
|
@ -507,7 +508,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
this.duration,
|
||||
this.albumArtPath,
|
||||
this.trackNumber,
|
||||
@required this.blocked});
|
||||
@required this.blocked,
|
||||
@required this.present});
|
||||
factory MoorSong.fromData(Map<String, dynamic> data, GeneratedDatabase db,
|
||||
{String prefix}) {
|
||||
final effectivePrefix = prefix ?? '';
|
||||
|
@ -532,6 +534,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
.mapFromDatabaseResponse(data['${effectivePrefix}track_number']),
|
||||
blocked:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}blocked']),
|
||||
present:
|
||||
boolType.mapFromDatabaseResponse(data['${effectivePrefix}present']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -564,6 +568,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
if (!nullToAbsent || blocked != null) {
|
||||
map['blocked'] = Variable<bool>(blocked);
|
||||
}
|
||||
if (!nullToAbsent || present != null) {
|
||||
map['present'] = Variable<bool>(present);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -592,6 +599,9 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
blocked: blocked == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(blocked),
|
||||
present: present == null && nullToAbsent
|
||||
? const Value.absent()
|
||||
: Value(present),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -608,6 +618,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
albumArtPath: serializer.fromJson<String>(json['albumArtPath']),
|
||||
trackNumber: serializer.fromJson<int>(json['trackNumber']),
|
||||
blocked: serializer.fromJson<bool>(json['blocked']),
|
||||
present: serializer.fromJson<bool>(json['present']),
|
||||
);
|
||||
}
|
||||
@override
|
||||
|
@ -623,6 +634,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
'albumArtPath': serializer.toJson<String>(albumArtPath),
|
||||
'trackNumber': serializer.toJson<int>(trackNumber),
|
||||
'blocked': serializer.toJson<bool>(blocked),
|
||||
'present': serializer.toJson<bool>(present),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -635,7 +647,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
int duration,
|
||||
String albumArtPath,
|
||||
int trackNumber,
|
||||
bool blocked}) =>
|
||||
bool blocked,
|
||||
bool present}) =>
|
||||
MoorSong(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -646,6 +659,7 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
blocked: blocked ?? this.blocked,
|
||||
present: present ?? this.present,
|
||||
);
|
||||
@override
|
||||
String toString() {
|
||||
|
@ -658,7 +672,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
..write('duration: $duration, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('blocked: $blocked')
|
||||
..write('blocked: $blocked, ')
|
||||
..write('present: $present')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -678,8 +693,10 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
duration.hashCode,
|
||||
$mrjc(
|
||||
albumArtPath.hashCode,
|
||||
$mrjc(trackNumber.hashCode,
|
||||
blocked.hashCode)))))))));
|
||||
$mrjc(
|
||||
trackNumber.hashCode,
|
||||
$mrjc(blocked.hashCode,
|
||||
present.hashCode))))))))));
|
||||
@override
|
||||
bool operator ==(dynamic other) =>
|
||||
identical(this, other) ||
|
||||
|
@ -692,7 +709,8 @@ class MoorSong extends DataClass implements Insertable<MoorSong> {
|
|||
other.duration == this.duration &&
|
||||
other.albumArtPath == this.albumArtPath &&
|
||||
other.trackNumber == this.trackNumber &&
|
||||
other.blocked == this.blocked);
|
||||
other.blocked == this.blocked &&
|
||||
other.present == this.present);
|
||||
}
|
||||
|
||||
class SongsCompanion extends UpdateCompanion<MoorSong> {
|
||||
|
@ -705,6 +723,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
final Value<String> albumArtPath;
|
||||
final Value<int> trackNumber;
|
||||
final Value<bool> blocked;
|
||||
final Value<bool> present;
|
||||
const SongsCompanion({
|
||||
this.title = const Value.absent(),
|
||||
this.albumTitle = const Value.absent(),
|
||||
|
@ -715,6 +734,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.albumArtPath = const Value.absent(),
|
||||
this.trackNumber = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
});
|
||||
SongsCompanion.insert({
|
||||
@required String title,
|
||||
|
@ -726,6 +746,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
this.albumArtPath = const Value.absent(),
|
||||
this.trackNumber = const Value.absent(),
|
||||
this.blocked = const Value.absent(),
|
||||
this.present = const Value.absent(),
|
||||
}) : title = Value(title),
|
||||
albumTitle = Value(albumTitle),
|
||||
albumId = Value(albumId),
|
||||
|
@ -741,6 +762,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
Expression<String> albumArtPath,
|
||||
Expression<int> trackNumber,
|
||||
Expression<bool> blocked,
|
||||
Expression<bool> present,
|
||||
}) {
|
||||
return RawValuesInsertable({
|
||||
if (title != null) 'title': title,
|
||||
|
@ -752,6 +774,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (albumArtPath != null) 'album_art_path': albumArtPath,
|
||||
if (trackNumber != null) 'track_number': trackNumber,
|
||||
if (blocked != null) 'blocked': blocked,
|
||||
if (present != null) 'present': present,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -764,7 +787,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
Value<int> duration,
|
||||
Value<String> albumArtPath,
|
||||
Value<int> trackNumber,
|
||||
Value<bool> blocked}) {
|
||||
Value<bool> blocked,
|
||||
Value<bool> present}) {
|
||||
return SongsCompanion(
|
||||
title: title ?? this.title,
|
||||
albumTitle: albumTitle ?? this.albumTitle,
|
||||
|
@ -775,6 +799,7 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
albumArtPath: albumArtPath ?? this.albumArtPath,
|
||||
trackNumber: trackNumber ?? this.trackNumber,
|
||||
blocked: blocked ?? this.blocked,
|
||||
present: present ?? this.present,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -808,6 +833,9 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
if (blocked.present) {
|
||||
map['blocked'] = Variable<bool>(blocked.value);
|
||||
}
|
||||
if (present.present) {
|
||||
map['present'] = Variable<bool>(present.value);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -822,7 +850,8 @@ class SongsCompanion extends UpdateCompanion<MoorSong> {
|
|||
..write('duration: $duration, ')
|
||||
..write('albumArtPath: $albumArtPath, ')
|
||||
..write('trackNumber: $trackNumber, ')
|
||||
..write('blocked: $blocked')
|
||||
..write('blocked: $blocked, ')
|
||||
..write('present: $present')
|
||||
..write(')'))
|
||||
.toString();
|
||||
}
|
||||
|
@ -941,6 +970,15 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
defaultValue: const Constant(false));
|
||||
}
|
||||
|
||||
final VerificationMeta _presentMeta = const VerificationMeta('present');
|
||||
GeneratedBoolColumn _present;
|
||||
@override
|
||||
GeneratedBoolColumn get present => _present ??= _constructPresent();
|
||||
GeneratedBoolColumn _constructPresent() {
|
||||
return GeneratedBoolColumn('present', $tableName, false,
|
||||
defaultValue: const Constant(true));
|
||||
}
|
||||
|
||||
@override
|
||||
List<GeneratedColumn> get $columns => [
|
||||
title,
|
||||
|
@ -951,7 +989,8 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
duration,
|
||||
albumArtPath,
|
||||
trackNumber,
|
||||
blocked
|
||||
blocked,
|
||||
present
|
||||
];
|
||||
@override
|
||||
$SongsTable get asDslTable => this;
|
||||
|
@ -1016,6 +1055,10 @@ class $SongsTable extends Songs with TableInfo<$SongsTable, MoorSong> {
|
|||
context.handle(_blockedMeta,
|
||||
blocked.isAcceptableOrUnknown(data['blocked'], _blockedMeta));
|
||||
}
|
||||
if (data.containsKey('present')) {
|
||||
context.handle(_presentMeta,
|
||||
present.isAcceptableOrUnknown(data['present'], _presentMeta));
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ abstract class MusicDataSource {
|
|||
Future<List<SongModel>> getSongs();
|
||||
Future<List<SongModel>> getSongsFromAlbum(AlbumModel album);
|
||||
Future<void> insertSong(SongModel songModel);
|
||||
|
||||
Future<void> insertSongs(List<SongModel> songModels);
|
||||
Future<void> setSongBlocked(SongModel song, bool blocked);
|
||||
|
||||
Future<SongModel> getSongByPath(String path);
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ class QueueManager {
|
|||
List<MediaItem> mediaItems, int startIndex) {
|
||||
final List<int> indices = [];
|
||||
for (var i = 0; i < mediaItems.length; i++) {
|
||||
if (!(mediaItems[i].extras['blocked'] as bool)) {
|
||||
if (mediaItems[i].extras['blocked'] == 'false') {
|
||||
indices.add(i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,6 +126,19 @@ class SongModel extends Song {
|
|||
trackNumber: Value(trackNumber),
|
||||
);
|
||||
|
||||
SongsCompanion toMoorInsert() => SongsCompanion(
|
||||
albumTitle: Value(album),
|
||||
albumId: Value(albumId),
|
||||
artist: Value(artist),
|
||||
title: Value(title),
|
||||
path: Value(path),
|
||||
duration: Value(duration),
|
||||
albumArtPath: Value(albumArtPath),
|
||||
trackNumber: Value(trackNumber),
|
||||
// blocked: Value(blocked),
|
||||
present: const Value(true),
|
||||
);
|
||||
|
||||
MediaItem toMediaItem() => MediaItem(
|
||||
id: path,
|
||||
title: title,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:dartz/dartz.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
import '../../core/error/failures.dart';
|
||||
|
@ -21,6 +22,8 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
final LocalMusicFetcher localMusicFetcher;
|
||||
final MusicDataSource musicDataSource;
|
||||
|
||||
static final _log = Logger('MusicDataRepository');
|
||||
|
||||
@override
|
||||
Future<Either<Failure, List<Artist>>> getArtists() async {
|
||||
return musicDataSource.getArtists().then((List<ArtistModel> artists) =>
|
||||
|
@ -47,6 +50,8 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
|
||||
@override
|
||||
Future<void> updateDatabase() async {
|
||||
_log.info('updataDatabase called');
|
||||
|
||||
await musicDataSource.deleteAllArtists();
|
||||
final List<ArtistModel> artists = await localMusicFetcher.getArtists();
|
||||
|
||||
|
@ -63,21 +68,19 @@ class MusicDataRepositoryImpl implements MusicDataRepository {
|
|||
albumIdMap[album.id] = newAlbumId;
|
||||
}
|
||||
|
||||
await musicDataSource.deleteAllSongs();
|
||||
final List<SongModel> songs = await localMusicFetcher.getSongs();
|
||||
|
||||
final List<SongModel> songsToInsert = [];
|
||||
for (final SongModel song in songs) {
|
||||
final SongModel songToInsert =
|
||||
song.copyWith(albumId: albumIdMap[song.albumId]);
|
||||
|
||||
// TODO: fails if albumId is null
|
||||
await musicDataSource.insertSong(songToInsert);
|
||||
songsToInsert.add(song.copyWith(albumId: albumIdMap[song.albumId]));
|
||||
}
|
||||
await musicDataSource.insertSongs(songsToInsert);
|
||||
|
||||
_log.info('updataDatabase finished');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setSongBlocked(Song song, bool blocked) {
|
||||
// TODO: implement setSongBlocked
|
||||
throw UnimplementedError();
|
||||
Future<void> setSongBlocked(Song song, bool blocked) async {
|
||||
await musicDataSource.setSongBlocked(song as SongModel, blocked);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue