LibrosDao
@Query("UPDATE libros SET es_favorito = NOT es_favorito WHERE id = :id")
suspend fun toggleFavorito(id: String)
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertarIgnorando(libros: List<Libro>): List<Long>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertarReemplazando(libro: Libro)
@Upsert
suspend fun upsert(libro: Libro)
@Transaction
suspend fun upsertConservandoFavorito(libros: List<Libro>)
@Delete
suspend fun eliminar(libro: Libro)
Tabla libros
Elige una operación del DAO. «Festín de cuervos» (id 3) es favorito, como en el test de §9.
fila nuevavalor cambiadodato del usuario perdidocolumnas en amarillo: solo locales
SQL ejecutado
Pantalla de AppDummy
observarTodos() · ORDER BY year DESCSimplificación: aquí el Flow emite cuando una sentencia modifica filas. Room real reacciona a cualquier escritura sobre la tabla observada.
GeneroDao
Genero(generoId = 1, nombre = )
@Insert(onConflict = OnConflictStrategy.REPLACE) // versión anterior del tema
suspend fun insertarGenero(genero: Genero)
@Upsert // versión corregida
suspend fun insertarGenero(genero: Genero)
// onDelete = ForeignKey.CASCADE en libros_generos
DELETE FROM generos WHERE generoId = :id
Tablas
Las claves ajenas están activas (
PRAGMA foreign_keys = ON), como en Room.SQL ejecutado
observarGenerosConLibros()
Room ejecuta dos consultas dentro de una @Transaction y agrupa el resultado en GeneroConLibros.