Created
November 6, 2019 17:04
-
-
Save svasquezm/401e88bbacd16263d83aacaa0d7c45b7 to your computer and use it in GitHub Desktop.
Android Room 2.2.1 hierarchy implementation in Kotlin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.frogmi.feature.information.domain.models | |
import android.content.Context | |
import androidx.room.* | |
/** | |
* Entities | |
*/ | |
@Entity(tableName = "infos") | |
data class Info( | |
@PrimaryKey val id: String | |
) | |
// Parent data | |
@Entity(tableName = "datas", | |
foreignKeys = [ | |
ForeignKey(entity = Info::class, parentColumns = ["id"], childColumns = ["infoId"]) | |
]) | |
class Data( | |
@PrimaryKey val id: Int, | |
var name: String, | |
@Embedded(prefix = "data1_") val data1: Data1? = null, | |
@Embedded(prefix = "data2_") val data2: Data2? = null, | |
var infoId: String = "" | |
) | |
// Parent Data builder | |
class DataBuilder(id: Int, name: String, d: IData) { | |
internal val data = when (d) { | |
is Data1 -> Data(id = id, name = name, data1 = d) | |
is Data2 -> Data(id = id, name = name, data2 = d) | |
else -> throw Exception("") | |
} | |
var infoId: String = "" | |
set(_infoId){ | |
field = _infoId | |
data.infoId = _infoId | |
} | |
} | |
interface IData | |
data class Data1( | |
val field1: String | |
): IData | |
data class Data2( | |
val field1: String, | |
val field2: String | |
): IData | |
/** | |
* Relation class | |
*/ | |
data class InfoWithData( | |
@Embedded val info: Info, | |
@Relation(parentColumn = "id", entityColumn = "infoId", entity = Data::class) | |
val data: List<Data> | |
) | |
@Dao | |
abstract class InfoDAO { | |
@Query("SELECT * FROM infos WHERE id = :id") | |
abstract fun loadInfo(id: String): InfoWithData | |
fun insertInfo(info: Info, data: List<DataBuilder>){ | |
data.forEach { it.infoId = info.id } | |
_insertInfo(info) | |
_insertData(data.map { it.data }) | |
} | |
@Insert(onConflict = OnConflictStrategy.REPLACE) | |
abstract fun _insertInfo(info: Info) | |
@Insert(onConflict = OnConflictStrategy.REPLACE) | |
abstract fun _insertData(data: List<Data>) | |
} | |
// Usage | |
private lateinit var dao: InfoDAO | |
private lateinit var db: DummyDataBase | |
fun use(){ | |
val context = InstrumentationRegistry.getInstrumentation().context | |
db = Room.inMemoryDatabaseBuilder( | |
context, | |
DummyDataBase::class.java | |
).allowMainThreadQueries().build() | |
dao = db.dao() | |
val info = Info("information_01") | |
val dataSubtype1 = Data1("field value 1") | |
val dataSubtype2 = Data2("field value 1", "field value 2") | |
val data1 = DataBuilder(0, "Data nombre 1", dataSubtype1) | |
val data2 = DataBuilder(1, "Data nombre 2", dataSubtype2) | |
dao.insertInfo(info, listOf(data1, data2)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment