diff --git a/app/schemas/com.karumi.jetpack.superheroes.common.SuperHeroesDatabase/1.json b/app/schemas/com.karumi.jetpack.superheroes.common.SuperHeroesDatabase/1.json new file mode 100644 index 0000000..8bd46b8 --- /dev/null +++ b/app/schemas/com.karumi.jetpack.superheroes.common.SuperHeroesDatabase/1.json @@ -0,0 +1,58 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "3298ad790ab4e90668532dfc9d342b54", + "entities": [ + { + "tableName": "superheroes", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `name` TEXT NOT NULL, `photo` TEXT, `isAvenger` INTEGER NOT NULL, `description` TEXT NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "photo", + "columnName": "photo", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "isAvenger", + "columnName": "isAvenger", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"3298ad790ab4e90668532dfc9d342b54\")" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt b/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt index 062e091..558920d 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/SuperHeroesApplication.kt @@ -1,10 +1,13 @@ package com.karumi.jetpack.superheroes import android.app.Application +import androidx.room.Room +import com.karumi.jetpack.superheroes.common.SuperHeroesDatabase import com.karumi.jetpack.superheroes.common.module import com.karumi.jetpack.superheroes.data.repository.LocalSuperHeroDataSource import com.karumi.jetpack.superheroes.data.repository.RemoteSuperHeroDataSource import com.karumi.jetpack.superheroes.data.repository.SuperHeroRepository +import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroDao import org.kodein.di.Kodein import org.kodein.di.KodeinAware import org.kodein.di.android.androidModule @@ -30,11 +33,23 @@ class SuperHeroesApplication : Application(), KodeinAware { } private fun appDependencies(): Kodein.Module = module { + bind() with singleton { + Room.databaseBuilder( + this@SuperHeroesApplication, + SuperHeroesDatabase::class.java, + "superheroes-db" + ).fallbackToDestructiveMigration() + .build() + } + bind() with provider { + val database: SuperHeroesDatabase = instance() + database.superHeroesDao() + } bind() with provider { SuperHeroRepository(instance(), instance()) } bind() with singleton { - LocalSuperHeroDataSource(instance()) + LocalSuperHeroDataSource(instance(), instance()) } bind() with provider { RemoteSuperHeroDataSource(instance()) diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/common/SuperHeroesDatabase.kt b/app/src/main/java/com/karumi/jetpack/superheroes/common/SuperHeroesDatabase.kt new file mode 100644 index 0000000..bb596dc --- /dev/null +++ b/app/src/main/java/com/karumi/jetpack/superheroes/common/SuperHeroesDatabase.kt @@ -0,0 +1,11 @@ +package com.karumi.jetpack.superheroes.common + +import androidx.room.Database +import androidx.room.RoomDatabase +import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroDao +import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroEntity + +@Database(entities = [SuperHeroEntity::class], version = 1) +abstract class SuperHeroesDatabase : RoomDatabase() { + abstract fun superHeroesDao(): SuperHeroDao +} \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/LocalSuperHeroDataSource.kt b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/LocalSuperHeroDataSource.kt index a7ec926..41239fa 100644 --- a/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/LocalSuperHeroDataSource.kt +++ b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/LocalSuperHeroDataSource.kt @@ -1,42 +1,36 @@ package com.karumi.jetpack.superheroes.data.repository +import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroDao +import com.karumi.jetpack.superheroes.data.repository.room.SuperHeroEntity import com.karumi.jetpack.superheroes.domain.model.SuperHero import java.util.concurrent.ExecutorService class LocalSuperHeroDataSource( + private val dao: SuperHeroDao, private val executor: ExecutorService ) { - companion object { - private const val BIT_TIME = 250L - } - - private val superHeroes: MutableMap = mutableMapOf() + fun getAllSuperHeroes(): List = + dao.getAll() + .map { it.toSuperHero() } - fun getAllSuperHeroes(): List { - waitABit() - return superHeroes.values.toList() - } - - fun get(id: String): SuperHero? { - waitABit() - return superHeroes[id] - } + fun get(id: String): SuperHero? = + dao.getById(id)?.toSuperHero() fun saveAll(all: List) = executor.execute { - waitABit() - superHeroes.clear() - superHeroes.putAll(all.associateBy { it.id }) + dao.deleteAll() + dao.insertAll(all.map { it.toEntity() }) } fun save(superHero: SuperHero): SuperHero { executor.execute { - waitABit() - superHeroes[superHero.id] = superHero + dao.insertAll(listOf(superHero.toEntity())) } return superHero } - private fun waitABit() { - Thread.sleep(BIT_TIME) - } + private fun SuperHeroEntity.toSuperHero(): SuperHero = + SuperHero(id, name, photo, isAvenger, description) + + private fun SuperHero.toEntity(): SuperHeroEntity = + SuperHeroEntity(id, name, photo, isAvenger, description) } \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroDao.kt b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroDao.kt new file mode 100644 index 0000000..efa3d9d --- /dev/null +++ b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroDao.kt @@ -0,0 +1,21 @@ +package com.karumi.jetpack.superheroes.data.repository.room + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query + +@Dao +interface SuperHeroDao { + @Query("SELECT * FROM superheroes ORDER BY id ASC") + fun getAll(): List + + @Query("SELECT * FROM superheroes WHERE id = :id") + fun getById(id: String): SuperHeroEntity? + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insertAll(superHeroes: List) + + @Query("DELETE FROM superheroes") + fun deleteAll() +} \ No newline at end of file diff --git a/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroEntity.kt b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroEntity.kt new file mode 100644 index 0000000..2d098e2 --- /dev/null +++ b/app/src/main/java/com/karumi/jetpack/superheroes/data/repository/room/SuperHeroEntity.kt @@ -0,0 +1,13 @@ +package com.karumi.jetpack.superheroes.data.repository.room + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "superheroes") +data class SuperHeroEntity( + @PrimaryKey val id: String, + val name: String, + val photo: String?, + val isAvenger: Boolean, + val description: String +) \ No newline at end of file