@@ -103,11 +103,17 @@ class DbRepository(
103103 progressCallback(0.07f , Res .string.info_syncing_playlists)
104104 val playlists = syncPlaylists().getOrThrow()
105105
106- syncLibrarySongs { localProgress, message ->
106+ val validAlbumIds = mutableSetOf<String >()
107+ val validSongIds = mutableSetOf<String >()
108+
109+ val libraryResult = syncLibrarySongs { localProgress, message ->
107110 val globalProgress = 0.10f + (localProgress * 0.65f )
108111 progressCallback(globalProgress, message)
109112 }.getOrThrow()
110113
114+ validAlbumIds.addAll(libraryResult.first)
115+ validSongIds.addAll(libraryResult.second)
116+
111117 val totalPlaylists = playlists.size
112118 if (totalPlaylists > 0 ) {
113119 val completedPlaylists = AtomicInt (0 )
@@ -116,7 +122,9 @@ class DbRepository(
116122 playlists.map { playlist ->
117123 async {
118124 concurrentRequestLimit.withPermit {
119- syncPlaylistSongs(playlist.playlistId).getOrThrow()
125+ val playlistSongIds = syncPlaylistSongs(playlist.playlistId).getOrThrow()
126+ validSongIds.addAll(playlistSongIds)
127+
120128 val done = completedPlaylists.incrementAndGet()
121129 val globalProgress = 0.75f + (0.25f * (done.toFloat() / totalPlaylists))
122130 progressCallback(globalProgress, Res .string.info_syncing_playlists)
@@ -126,12 +134,15 @@ class DbRepository(
126134 }
127135 }
128136
137+ albumDao.deleteObsoleteAlbums(validAlbumIds)
138+ songDao.deleteObsoleteSongs(validSongIds)
139+
129140 progressCallback(1.0f , Res .string.info_syncing_finished)
130141 }
131142
132143 suspend fun syncLibrarySongs (
133144 onProgress : (Float , StringResource ) -> Unit = { _, _ -> }
134- ): Result <Int > = runDbOp {
145+ ): Result <Pair < Set < String >, Set<String>> > = runDbOp {
135146 val pageSize = 500
136147 var offset = 0
137148 val allAlbumSummaries = mutableListOf<ApiAlbum >()
@@ -146,7 +157,7 @@ class DbRepository(
146157 offset + = pageSize
147158 }
148159
149- if (allAlbumSummaries.isEmpty()) return @runDbOp 0
160+ if (allAlbumSummaries.isEmpty()) return @runDbOp emptySet< String >() to emptySet()
150161
151162 val totalAlbums = allAlbumSummaries.size
152163 val completedAlbums = AtomicInt (0 )
@@ -230,16 +241,13 @@ class DbRepository(
230241 }
231242 }
232243
233- albumDao.deleteObsoleteAlbums(allValidAlbumIds)
234- songDao.deleteObsoleteSongs(allValidSongIds)
235-
236244 Logger .i(
237245 " DbRepository" ,
238246 " - Songs Synced: $totalAlbums albums, $finalSongsSynced songs"
239247 )
240248
241249 onProgress(1.0f , Res .string.info_syncing_saved)
242- finalSongsSynced
250+ allValidAlbumIds to allValidSongIds
243251 }
244252
245253 suspend fun syncPlaylists (): Result <List <PlaylistEntity >> = runDbOp {
@@ -258,7 +266,7 @@ class DbRepository(
258266 playlistEntities
259267 }
260268
261- suspend fun syncPlaylistSongs (playlistId : String ): Result <Int > = runDbOp {
269+ suspend fun syncPlaylistSongs (playlistId : String ): Result <Set < String > > = runDbOp {
262270 val playlist = try {
263271 sessionManager.api.getPlaylist(playlistId)
264272 } catch (e: Exception ) {
@@ -268,14 +276,13 @@ class DbRepository(
268276 " could not deserialize playlist $playlistId ; skipping it" ,
269277 e
270278 )
271- return @runDbOp 0
279+ return @runDbOp emptySet< String >()
272280 } else {
273281 throw e
274282 }
275283 }
276284 val songEntities = playlist.songs.map { it.toEntity() }
277-
278- playlistDao.deletePlaylistSongCrossRefs(playlistId)
285+ val songIds = songEntities.map { it.songId }.toSet()
279286
280287 if (songEntities.isNotEmpty()) {
281288 songEntities.chunked(dbChunkSize).forEach { chunk ->
@@ -286,13 +293,13 @@ class DbRepository(
286293 PlaylistSongCrossRef (playlistId = playlistId, songId = it.songId, position = index)
287294 }
288295
289- crossRefs.chunked(dbChunkSize).forEach { chunk ->
290- playlistDao.insertPlaylistSongCrossRefs(chunk)
291- }
296+ playlistDao.replacePlaylistSongs(playlistId, crossRefs)
297+ } else {
298+ playlistDao.deletePlaylistSongCrossRefs(playlistId)
292299 }
293300
294301 Logger .i(" DbRepository" , " - Playlist [$playlistId ] synced: ${songEntities.size} songs" )
295- songEntities.size
302+ songIds
296303 }
297304
298305 suspend fun syncGenres (): Result <Unit > = runDbOp {
0 commit comments