Skip to content
Snippets Groups Projects
Unverified Commit 424d1ada authored by chris-cwa's avatar chris-cwa Committed by GitHub
Browse files

Checkins Repository (EXPOSUREAPP-5421) (#2547)

* repo for checkins

* repo for checkins

* renamed param

* added more crud methods

* added fields from new specs version

* fixed ktlint issue

* fixed class hierarchy

* fixed UnnecessaryAbstractClass

* fixed nullable types

* renamed to Event* to TraceLocation* to be in sync with spec

* moved database one package level up

* use app scope for insert

* renamed const

* convert data between repo and database

* removed interface for data class, renaming, housekeeping

* entity is no parcel anymore

* + update method in checkin repo
parent 90ea9e56
No related branches found
No related tags found
No related merge requests found
Showing
with 292 additions and 23 deletions
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "244eed2a4665a1c60d0792de5945888b",
"entities": [
{
"tableName": "checkin",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `guid` TEXT NOT NULL, `version` INTEGER NOT NULL, `type` INTEGER NOT NULL, `description` TEXT NOT NULL, `address` TEXT NOT NULL, `traceLocationStart` TEXT, `traceLocationEnd` TEXT, `defaultCheckInLengthInMinutes` INTEGER, `signature` TEXT NOT NULL, `checkInStart` TEXT NOT NULL, `checkInEnd` TEXT, `targetCheckInEnd` TEXT, `createJournalEntry` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "guid",
"columnName": "guid",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "version",
"columnName": "version",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "type",
"columnName": "type",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "description",
"columnName": "description",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "address",
"columnName": "address",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "traceLocationStart",
"columnName": "traceLocationStart",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "traceLocationEnd",
"columnName": "traceLocationEnd",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "defaultCheckInLengthInMinutes",
"columnName": "defaultCheckInLengthInMinutes",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "signature",
"columnName": "signature",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "checkInStart",
"columnName": "checkInStart",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "checkInEnd",
"columnName": "checkInEnd",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "targetCheckInEnd",
"columnName": "targetCheckInEnd",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "createJournalEntry",
"columnName": "createJournalEntry",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"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, '244eed2a4665a1c60d0792de5945888b')"
]
}
}
\ No newline at end of file
package de.rki.coronawarnapp.eventregistration.checkins
import org.joda.time.Instant
@Suppress("LongParameterList")
class CheckIn(
val id: Long,
val guid: String,
val version: Int,
val type: Int,
val description: String,
val address: String,
val traceLocationStart: Instant?,
val traceLocationEnd: Instant?,
val defaultCheckInLengthInMinutes: Int?,
val signature: String,
val checkInStart: Instant,
val checkInEnd: Instant?,
val targetCheckInEnd: Instant?,
val createJournalEntry: Boolean
)
package de.rki.coronawarnapp.eventregistration.checkins
import de.rki.coronawarnapp.eventregistration.storage.TraceLocationDatabase
import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
import de.rki.coronawarnapp.util.coroutine.AppScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import javax.inject.Inject
class CheckInRepository @Inject constructor(
traceLocationDatabaseFactory: TraceLocationDatabase.Factory,
@AppScope private val appScope: CoroutineScope
) {
private val traceLocationDatabase: TraceLocationDatabase by lazy {
traceLocationDatabaseFactory.create()
}
private val checkInDao: CheckInDao by lazy {
traceLocationDatabase.eventCheckInDao()
}
val allCheckIns: Flow<List<CheckIn>> =
checkInDao
.allEntries()
.map { list -> list.map { it.toCheckIn() } }
fun addCheckIn(checkIn: CheckIn) {
appScope.launch {
checkInDao.insert(checkIn.toEntity())
}
}
fun updateCheckIn(checkIn: CheckIn) {
appScope.launch {
checkInDao.update(checkIn.toEntity())
}
}
}
private fun TraceLocationCheckInEntity.toCheckIn() = CheckIn(
id = id,
guid = guid,
version = version,
type = type,
description = description,
address = address,
traceLocationStart = traceLocationStart,
traceLocationEnd = traceLocationEnd,
defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
signature = signature,
checkInStart = checkInStart,
checkInEnd = checkInEnd,
targetCheckInEnd = targetCheckInEnd,
createJournalEntry = createJournalEntry
)
private fun CheckIn.toEntity() = TraceLocationCheckInEntity(
id = id,
guid = guid,
version = version,
type = type,
description = description,
address = address,
traceLocationStart = traceLocationStart,
traceLocationEnd = traceLocationEnd,
defaultCheckInLengthInMinutes = defaultCheckInLengthInMinutes,
signature = signature,
checkInStart = checkInStart,
checkInEnd = checkInEnd,
targetCheckInEnd = targetCheckInEnd,
createJournalEntry = createJournalEntry
)
package de.rki.coronawarnapp.eventregistration.checkins
import kotlinx.coroutines.flow.Flow
interface CheckInsRepository {
val allCheckIns: Flow<List<EventCheckIn>>
suspend fun addCheckIn(checkIn: EventCheckIn)
}
package de.rki.coronawarnapp.eventregistration.checkins
import org.joda.time.Instant
interface EventCheckIn {
val id: Long
val guid: String
val startTime: Instant
val endTime: Instant
}
package de.rki.coronawarnapp.eventregistration.checkins.download package de.rki.coronawarnapp.eventregistration.checkins.download
import de.rki.coronawarnapp.eventregistration.checkins.EventCheckIn import de.rki.coronawarnapp.eventregistration.checkins.CheckIn
interface CheckInsPackage { interface CheckInsPackage {
/** /**
* Hides the file reading * Hides the file reading
*/ */
suspend fun extractCheckIns(): List<EventCheckIn> suspend fun extractCheckIns(): List<CheckIn>
} }
package de.rki.coronawarnapp.eventregistration.storage
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import de.rki.coronawarnapp.eventregistration.storage.dao.CheckInDao
import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
import de.rki.coronawarnapp.util.database.CommonConverters
import de.rki.coronawarnapp.util.di.AppContext
import javax.inject.Inject
@Database(
entities = [
TraceLocationCheckInEntity::class
],
version = 1,
exportSchema = true
)
@TypeConverters(CommonConverters::class)
abstract class TraceLocationDatabase : RoomDatabase() {
abstract fun eventCheckInDao(): CheckInDao
class Factory @Inject constructor(@AppContext private val context: Context) {
fun create(databaseName: String = TRACE_LOCATIONS_DATABASE_NAME): TraceLocationDatabase = Room
.databaseBuilder(context, TraceLocationDatabase::class.java, databaseName)
.build()
}
}
private const val TRACE_LOCATIONS_DATABASE_NAME = "TraceLocations_db"
package de.rki.coronawarnapp.eventregistration.storage.dao
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import de.rki.coronawarnapp.eventregistration.storage.entity.TraceLocationCheckInEntity
import kotlinx.coroutines.flow.Flow
@Dao
interface CheckInDao {
@Query("SELECT * FROM checkin")
fun allEntries(): Flow<List<TraceLocationCheckInEntity>>
@Insert
suspend fun insert(entity: TraceLocationCheckInEntity): Long
@Update
suspend fun update(entity: TraceLocationCheckInEntity)
@Query("DELETE FROM checkin")
suspend fun deleteAll()
}
package de.rki.coronawarnapp.eventregistration.storage.entity
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import org.joda.time.Instant
@Entity(tableName = "checkin")
data class TraceLocationCheckInEntity(
@PrimaryKey(autoGenerate = true) @ColumnInfo(name = "id") val id: Long = 0L,
@ColumnInfo(name = "guid") val guid: String,
@ColumnInfo(name = "version") val version: Int,
@ColumnInfo(name = "type") val type: Int,
@ColumnInfo(name = "description") val description: String,
@ColumnInfo(name = "address") val address: String,
@ColumnInfo(name = "traceLocationStart") val traceLocationStart: Instant?,
@ColumnInfo(name = "traceLocationEnd") val traceLocationEnd: Instant?,
@ColumnInfo(name = "defaultCheckInLengthInMinutes") val defaultCheckInLengthInMinutes: Int?,
@ColumnInfo(name = "signature") val signature: String,
@ColumnInfo(name = "checkInStart") val checkInStart: Instant,
@ColumnInfo(name = "checkInEnd") val checkInEnd: Instant?,
@ColumnInfo(name = "targetCheckInEnd") val targetCheckInEnd: Instant?,
@ColumnInfo(name = "createJournalEntry") val createJournalEntry: Boolean
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment