PMDM 0489 · B3 · T4 ROOM: persistencia local

Simulador de Room con SQLite real

Cada botón llama a un método del DAO del tema y ejecuta su SQL sobre una base de datos SQLite que funciona en tu navegador. Observa la tabla, el SQL generado y la pantalla de AppDummy, que se actualiza cuando el Flow de Room vuelve a emitir.

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

AppDummyFlow: 1 emisión
observarTodos() · ORDER BY year DESC

Simplificació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.