feat(#17): Room-Entities & LocalDateConverter
- Add CategoryEntity, LocationEntity, SettingsEntity, ItemEntity - ItemEntity: FK to Category+Location with CASCADE, indices on FK columns - LocalDateConverter: LocalDate? <-> String? (ISO-8601) via @TypeConverter - Add LocalDateConverterTest: 4 unit tests (null/non-null round-trip)
This commit is contained in:
parent
74bf5ef060
commit
645a110297
6 changed files with 146 additions and 0 deletions
|
|
@ -0,0 +1,13 @@
|
|||
package de.krisenvorrat.app.data.db
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import java.time.LocalDate
|
||||
|
||||
internal class LocalDateConverter {
|
||||
|
||||
@TypeConverter
|
||||
fun fromLocalDate(date: LocalDate?): String? = date?.toString()
|
||||
|
||||
@TypeConverter
|
||||
fun toLocalDate(value: String?): LocalDate? = value?.let { LocalDate.parse(it) }
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package de.krisenvorrat.app.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "categories")
|
||||
internal data class CategoryEntity(
|
||||
@PrimaryKey(autoGenerate = true) val id: Int = 0,
|
||||
@ColumnInfo(name = "name") val name: String
|
||||
)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package de.krisenvorrat.app.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import java.time.LocalDate
|
||||
|
||||
@Entity(
|
||||
tableName = "items",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = CategoryEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["category_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = LocationEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["location_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
)
|
||||
],
|
||||
indices = [Index("category_id"), Index("location_id")]
|
||||
)
|
||||
internal data class ItemEntity(
|
||||
@PrimaryKey val id: String,
|
||||
@ColumnInfo(name = "name") val name: String,
|
||||
@ColumnInfo(name = "category_id") val categoryId: Int,
|
||||
@ColumnInfo(name = "quantity") val quantity: Double,
|
||||
@ColumnInfo(name = "unit") val unit: String,
|
||||
@ColumnInfo(name = "unit_price") val unitPrice: Double,
|
||||
@ColumnInfo(name = "kcal_per_100g") val kcalPer100g: Int?,
|
||||
@ColumnInfo(name = "expiry_date") val expiryDate: LocalDate?,
|
||||
@ColumnInfo(name = "location_id") val locationId: Int,
|
||||
@ColumnInfo(name = "min_stock") val minStock: Double,
|
||||
@ColumnInfo(name = "notes") val notes: String,
|
||||
@ColumnInfo(name = "last_updated") val lastUpdated: Long
|
||||
)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package de.krisenvorrat.app.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "locations")
|
||||
internal data class LocationEntity(
|
||||
@PrimaryKey(autoGenerate = true) val id: Int = 0,
|
||||
@ColumnInfo(name = "name") val name: String
|
||||
)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package de.krisenvorrat.app.data.db.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
@Entity(tableName = "settings")
|
||||
internal data class SettingsEntity(
|
||||
@PrimaryKey val key: String,
|
||||
@ColumnInfo(name = "value") val value: String
|
||||
)
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package de.krisenvorrat.app.data.db
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import java.time.LocalDate
|
||||
|
||||
class LocalDateConverterTest {
|
||||
|
||||
private val converter = LocalDateConverter()
|
||||
|
||||
@Test
|
||||
fun test_fromLocalDate_withDate_returnsIsoString() {
|
||||
// Given
|
||||
val date = LocalDate.of(2025, 12, 31)
|
||||
|
||||
// When
|
||||
val result = converter.fromLocalDate(date)
|
||||
|
||||
// Then
|
||||
assertEquals("2025-12-31", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_fromLocalDate_withNull_returnsNull() {
|
||||
// Given
|
||||
val date: LocalDate? = null
|
||||
|
||||
// When
|
||||
val result = converter.fromLocalDate(date)
|
||||
|
||||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_toLocalDate_withIsoString_returnsDate() {
|
||||
// Given
|
||||
val isoString = "2025-12-31"
|
||||
|
||||
// When
|
||||
val result = converter.toLocalDate(isoString)
|
||||
|
||||
// Then
|
||||
assertEquals(LocalDate.of(2025, 12, 31), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun test_toLocalDate_withNull_returnsNull() {
|
||||
// Given
|
||||
val isoString: String? = null
|
||||
|
||||
// When
|
||||
val result = converter.toLocalDate(isoString)
|
||||
|
||||
// Then
|
||||
assertNull(result)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue