initial history database

This commit is contained in:
AdrianLxM 2021-02-27 23:50:51 +01:00
parent f8ca7592ae
commit 86d965a7f1
12 changed files with 284 additions and 1 deletions

View file

@ -17,4 +17,11 @@ android {
dependencies {
implementation project(':core')
implementation project(':omnipod-common')
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-rxjava2:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation 'com.github.guepardoapps:kulid:1.1.2.0'
}

View file

@ -0,0 +1,33 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.dagger
import android.content.Context
import dagger.Module
import dagger.Provides
import dagger.Reusable
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.DashHistoryDatabase
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordDao
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper.HistoryMapper
import javax.inject.Singleton
@Module
class OmnipodDashHistoryModule {
@Provides
@Singleton
internal fun provideDatabase(context: Context): DashHistoryDatabase = DashHistoryDatabase.build(context)
@Provides
@Singleton
internal fun provideHistoryRecordDao(dashHistoryDatabase: DashHistoryDatabase): HistoryRecordDao = dashHistoryDatabase.historyRecordDao()
@Provides
@Reusable // no state, let system decide when to reuse or create new.
internal fun provideHistoryMapper() = HistoryMapper()
@Provides
@Singleton
internal fun provideDashHistory(dao: HistoryRecordDao, historyMapper: HistoryMapper) =
DashHistory(dao, historyMapper)
}

View file

@ -16,7 +16,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOvervi
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activation.DashPodActivationWizardActivity
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.deactivation.DashPodDeactivationWizardActivity
@Module
@Module(includes = [OmnipodDashHistoryModule::class])
@Suppress("unused")
abstract class OmnipodDashModule {
// ACTIVITIES

View file

@ -0,0 +1,55 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history
import com.github.guepardoapps.kulid.ULID
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.HistoryRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordDao
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordEntity
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper.HistoryMapper
import io.reactivex.Completable
import io.reactivex.Single
import java.lang.System.currentTimeMillis
import javax.inject.Inject
class DashHistory @Inject constructor(
private val dao: HistoryRecordDao,
private val historyMapper: HistoryMapper
) {
fun markSuccess(id: String): Completable = dao.markResolved(id, ResolvedResult.SUCCESS, currentTimeMillis())
fun markFailure(id: String): Completable = dao.markResolved(id, ResolvedResult.FAILURE, currentTimeMillis())
fun createRecord(
commandType: OmnipodCommandType,
initialResult: InitialResult = InitialResult.UNCONFIRMED,
tempBasalRecord: TempBasalRecord? = null,
bolusRecord: BolusRecord? = null,
resolveResult: ResolvedResult? = null,
resolvedAt: Long? = null
): Single<String> {
val id = ULID.random()
return dao.save(
HistoryRecordEntity(
id = id,
createdAt = currentTimeMillis(),
commandType = commandType,
tempBasalRecord = tempBasalRecord,
bolusRecord = bolusRecord,
initialResult = initialResult,
resolvedResult = resolveResult,
resolvedAt = resolvedAt,
)
).toSingle { id }
}
fun getRecords(): Single<List<HistoryRecord>> =
dao.all().map { list -> list.map(historyMapper::entityToDomain) }
fun getRecordsAfter(time: Long): Single<List<HistoryRecordEntity>> = dao.allSince(time)
}

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
data class HistoryRecord(
val id: String, // ULID
val createdAt: Long,
val commandType: OmnipodCommandType,
val initialResult: InitialResult,
val record: Record?,
val resolvedResult: ResolvedResult?,
val resolvedAt: Long?
)

View file

@ -0,0 +1,11 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
sealed class Record
data class BolusRecord(val amout: Double, val bolusType: BolusType): Record()
data class TempBasalRecord(val duration: Long, val rate: Double): Record()
enum class BolusType {
DEFAULT, SMB
}

View file

@ -0,0 +1,9 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data
enum class InitialResult {
SUCCESS, FAILURE, UNCONFIRMED
}
enum class ResolvedResult {
SUCCESS, FAILURE
}

View file

@ -0,0 +1,34 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database
import androidx.room.TypeConverter
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
class Converters {
@TypeConverter
fun toBolusType(s: String) = enumValueOf<BolusType>(s)
@TypeConverter
fun fromBolusType(bolusType: BolusType) = bolusType.name
@TypeConverter
fun toInitialResult(s: String) = enumValueOf<InitialResult>(s)
@TypeConverter
fun fromInitialResult(initialResult: InitialResult) = initialResult.name
@TypeConverter
fun toResolvedResult(s: String) = enumValueOf<ResolvedResult>(s)
@TypeConverter
fun fromResolvedResult(resolvedResult: ResolvedResult) = resolvedResult.name
@TypeConverter
fun toOmnipodCommandType(s: String) = enumValueOf<OmnipodCommandType>(s)
@TypeConverter
fun fromOmnipodCommandType(omnipodCommandType: OmnipodCommandType) = omnipodCommandType.name
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database
import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
@Database(
entities = [HistoryRecordEntity::class],
exportSchema = false,
version = DashHistoryDatabase.VERSION
)
@TypeConverters(Converters::class)
abstract class DashHistoryDatabase : RoomDatabase() {
abstract fun historyRecordDao() : HistoryRecordDao
companion object {
const val VERSION = 1
@Synchronized
fun build(context: Context) =
Room.databaseBuilder(context.applicationContext, DashHistoryDatabase::class.java, "omnipod_dash_history_database.db")
.fallbackToDestructiveMigration()
.build()
}
}

View file

@ -0,0 +1,36 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
import io.reactivex.Completable
import io.reactivex.Single
@Dao
abstract class HistoryRecordDao {
@Query("SELECT * from historyrecords")
abstract fun all(): Single<List<HistoryRecordEntity>>
@Query("SELECT * from historyrecords")
abstract fun allBlocking(): List<HistoryRecordEntity>
@Query("SELECT * from historyrecords WHERE createdAt <= :since")
abstract fun allSince(since: Long): Single<List<HistoryRecordEntity>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun saveBlocking(historyRecordEntity: HistoryRecordEntity)
@Insert(onConflict = OnConflictStrategy.REPLACE)
abstract fun save(historyRecordEntity: HistoryRecordEntity): Completable
@Delete
abstract fun delete(historyRecordEntity: HistoryRecordEntity): Completable
@Query("UPDATE historyrecords SET resolvedResult = :resolvedResult, resolvedAt = :resolvedAt WHERE id = :id ")
abstract fun markResolved(id: String, resolvedResult: ResolvedResult, resolvedAt: Long): Completable
}

View file

@ -0,0 +1,22 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database
import androidx.room.Embedded
import androidx.room.Entity
import androidx.room.PrimaryKey
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
@Entity(tableName = "historyrecords")
data class HistoryRecordEntity(
@PrimaryKey val id: String, // ULID
val createdAt: Long,
val commandType: OmnipodCommandType,
val initialResult: InitialResult,
@Embedded(prefix = "tempBasalRecord_") val tempBasalRecord: TempBasalRecord?,
@Embedded(prefix = "bolusRecord_") val bolusRecord: BolusRecord?,
val resolvedResult: ResolvedResult?,
val resolvedAt: Long?)

View file

@ -0,0 +1,32 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.mapper
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.HistoryRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordEntity
class HistoryMapper {
fun domainToEntity(historyRecord: HistoryRecord): HistoryRecordEntity =
HistoryRecordEntity(
id = historyRecord.id,
createdAt = historyRecord.createdAt,
commandType = historyRecord.commandType,
initialResult = historyRecord.initialResult,
tempBasalRecord = historyRecord.record as? TempBasalRecord,
bolusRecord = historyRecord.record as? BolusRecord,
resolvedResult = historyRecord.resolvedResult,
resolvedAt = historyRecord.resolvedAt
)
fun entityToDomain(entity: HistoryRecordEntity): HistoryRecord =
HistoryRecord(id = entity.id,
createdAt = entity.createdAt,
initialResult = entity.initialResult,
commandType = entity.commandType,
record = entity.bolusRecord ?: entity.tempBasalRecord,
resolvedResult = entity.resolvedResult,
resolvedAt = entity.resolvedAt
)
}