Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save svasquezm/401e88bbacd16263d83aacaa0d7c45b7 to your computer and use it in GitHub Desktop.
Save svasquezm/401e88bbacd16263d83aacaa0d7c45b7 to your computer and use it in GitHub Desktop.
Android Room 2.2.1 hierarchy implementation in Kotlin
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