@@ -3,12 +3,17 @@ package com.ljyh.mei.di
33import android.content.Context
44import androidx.room.Dao
55import androidx.room.Database
6+ import androidx.room.Delete
67import androidx.room.Insert
78import androidx.room.OnConflictStrategy
89import androidx.room.Query
910import androidx.room.Room
1011import androidx.room.RoomDatabase
1112import androidx.room.Transaction
13+ import com.ljyh.mei.data.model.room.AlbumArtistCrossRef
14+ import com.ljyh.mei.data.model.room.AlbumEntity
15+ import com.ljyh.mei.data.model.room.AlbumWithArtists
16+ import com.ljyh.mei.data.model.room.ArtistEntity
1217import com.ljyh.mei.data.model.room.CacheColor
1318import com.ljyh.mei.data.model.room.HistoryItem
1419import com.ljyh.mei.data.model.room.Like
@@ -73,7 +78,7 @@ interface PlaylistDao {
7378 suspend fun insertPlaylists (playlists : List <Playlist >)
7479
7580 @Query(" DELETE FROM playlist where id=:id" )
76- suspend fun deletePlaylistById (id : String )
81+ suspend fun deletePlaylistById (id : String )
7782}
7883
7984@Dao
@@ -129,9 +134,172 @@ interface HistoryDao {
129134 suspend fun deleteHistoryBySongId (songId : String )
130135}
131136
137+ @Dao
138+ interface AlbumsDao {
139+ @Transaction
140+ @Query(" SELECT * FROM albums WHERE albumId = :id" )
141+ suspend fun getAlbumWithArtists (id : Long ): AlbumWithArtists
142+
143+ @Transaction
144+ @Query(
145+ """
146+ SELECT * FROM albums
147+ INNER JOIN album_artist_cross_ref
148+ ON albums.albumId = album_artist_cross_ref.albumId
149+ WHERE album_artist_cross_ref.artistId = :artistId"""
150+ )
151+ suspend fun getAlbumsByArtist (artistId : Long ): List <AlbumEntity >
152+
153+
154+
155+
156+ @Transaction
157+ suspend fun insertAlbumWithArtists (
158+ album : AlbumEntity ,
159+ artists : List <ArtistEntity >
160+ ) {
161+ // 1. 插入 album
162+ insertAlbum(album)
163+
164+ // 2. 插入 artists(已存在的会被忽略)
165+ insertArtists(artists)
166+
167+ // 3. 建立关联
168+ val refs = artists.map {
169+ AlbumArtistCrossRef (
170+ albumId = album.albumId,
171+ artistId = it.artistId
172+ )
173+ }
174+ insertAlbumArtistRefs(refs)
175+ }
176+
177+ // --- 基础方法 ---
178+ @Insert(onConflict = OnConflictStrategy .REPLACE )
179+ suspend fun insertAlbum (album : AlbumEntity )
180+
181+ @Insert(onConflict = OnConflictStrategy .IGNORE )
182+ suspend fun insertArtists (artists : List <ArtistEntity >)
183+
184+ @Insert(onConflict = OnConflictStrategy .IGNORE )
185+ suspend fun insertAlbumArtistRefs (
186+ refs : List <AlbumArtistCrossRef >
187+ )
188+ @Query("""
189+ SELECT EXISTS(
190+ SELECT 1 FROM albums WHERE albumId = :albumId
191+ )
192+ """ )
193+ suspend fun existsAlbum (albumId : Long ): Boolean
194+
195+ /* *
196+ * 删除指定ID的专辑及其关联关系
197+ * 注意:这会删除专辑,但不会删除关联的艺术家(其他专辑可能还在使用)
198+ */
199+ @Transaction
200+ suspend fun deleteAlbumById (albumId : Long ) {
201+ // 1. 先删除关联关系
202+ deleteAlbumArtistRefsByAlbumId(albumId)
203+
204+ // 2. 再删除专辑
205+ deleteAlbum(albumId)
206+ }
207+
208+ /* *
209+ * 批量删除多个专辑及其关联关系
210+ */
211+ @Transaction
212+ suspend fun deleteAlbumsByIds (albumIds : List <Long >) {
213+ if (albumIds.isEmpty()) return
214+
215+ // 1. 删除关联关系
216+ deleteAlbumArtistRefsByAlbumIds(albumIds)
217+
218+ // 2. 删除专辑
219+ deleteAlbums(albumIds)
220+ }
221+
222+ /* *
223+ * 删除指定艺术家参与的所有专辑关联关系
224+ * 注意:这会移除该艺术家与专辑的关联,但不会删除专辑本身
225+ */
226+ suspend fun deleteArtistFromAllAlbums (artistId : Long ) {
227+ deleteAlbumArtistRefsByArtistId(artistId)
228+ }
229+
230+ /* *
231+ * 删除孤立的艺术家(没有被任何专辑引用的艺术家)
232+ * 用于清理不再使用的艺术家数据
233+ */
234+ @Transaction
235+ suspend fun deleteOrphanedArtists () {
236+ // 找到没有关联的艺术家
237+ val orphanedArtistIds = getOrphanedArtistIds()
238+ if (orphanedArtistIds.isNotEmpty()) {
239+ deleteArtistsByIds(orphanedArtistIds)
240+ }
241+ }
242+
243+
244+ @Delete
245+ suspend fun deleteAlbum (album : AlbumEntity )
246+
247+ @Query(" DELETE FROM albums WHERE albumId = :albumId" )
248+ suspend fun deleteAlbum (albumId : Long )
249+
250+ @Query(" DELETE FROM albums WHERE albumId IN (:albumIds)" )
251+ suspend fun deleteAlbums (albumIds : List <Long >)
252+
253+ @Delete
254+ suspend fun deleteArtist (artist : ArtistEntity )
255+
256+ @Query(" DELETE FROM artists WHERE artistId = :artistId" )
257+ suspend fun deleteArtist (artistId : Long )
258+
259+ @Query(" DELETE FROM artists WHERE artistId IN (:artistIds)" )
260+ suspend fun deleteArtistsByIds (artistIds : List <Long >)
261+
262+ @Delete
263+ suspend fun deleteAlbumArtistRef (ref : AlbumArtistCrossRef )
264+
265+ @Query(" DELETE FROM album_artist_cross_ref WHERE albumId = :albumId" )
266+ suspend fun deleteAlbumArtistRefsByAlbumId (albumId : Long )
267+
268+ @Query(" DELETE FROM album_artist_cross_ref WHERE albumId IN (:albumIds)" )
269+ suspend fun deleteAlbumArtistRefsByAlbumIds (albumIds : List <Long >)
270+
271+ @Query(" DELETE FROM album_artist_cross_ref WHERE artistId = :artistId" )
272+ suspend fun deleteAlbumArtistRefsByArtistId (artistId : Long )
273+
274+ // --- 查询辅助方法 ---
275+
276+ /* *
277+ * 查找孤立的艺术家ID(没有被任何专辑引用的艺术家)
278+ */
279+ @Query("""
280+ SELECT artistId FROM artists
281+ WHERE artistId NOT IN (
282+ SELECT DISTINCT artistId FROM album_artist_cross_ref
283+ )
284+ """ )
285+ suspend fun getOrphanedArtistIds (): List <Long >
286+
287+ /* *
288+ * 检查艺术家是否被任何专辑使用
289+ */
290+ @Query("""
291+ SELECT EXISTS(
292+ SELECT 1 FROM album_artist_cross_ref WHERE artistId = :artistId
293+ )
294+ """ )
295+ suspend fun isArtistUsed (artistId : Long ): Boolean
296+
297+ }
298+
299+
132300@Database(
133- entities = [CacheColor ::class , Song ::class , Like ::class , QQSong ::class , Playlist ::class , PlaybackHistory ::class ],
134- version = 7
301+ entities = [CacheColor ::class , Song ::class , Like ::class , QQSong ::class , Playlist ::class , PlaybackHistory ::class , AlbumEntity :: class , ArtistEntity :: class , AlbumArtistCrossRef :: class ],
302+ version = 8
135303)
136304abstract class AppDatabase : RoomDatabase () {
137305 abstract fun colorDao (): ColorDao
@@ -140,6 +308,7 @@ abstract class AppDatabase : RoomDatabase() {
140308 abstract fun qqSongDao (): QQSongDao
141309 abstract fun playlistDao (): PlaylistDao
142310 abstract fun historyDao (): HistoryDao
311+ abstract fun AlbumsDao (): AlbumsDao
143312
144313 companion object {
145314 @Volatile
0 commit comments