From 86d965a7f135e1bd8458605dc2538f52cc8e0574 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Sat, 27 Feb 2021 23:50:51 +0100 Subject: [PATCH] initial history database --- omnipod-dash/build.gradle | 7 +++ .../dash/dagger/OmnipodDashHistoryModule.kt | 33 +++++++++++ .../omnipod/dash/dagger/OmnipodDashModule.kt | 2 +- .../pump/omnipod/dash/history/DashHistory.kt | 55 +++++++++++++++++++ .../dash/history/data/HistoryRecord.kt | 13 +++++ .../pump/omnipod/dash/history/data/Record.kt | 11 ++++ .../omnipod/dash/history/data/ResultStates.kt | 9 +++ .../dash/history/database/Converters.kt | 34 ++++++++++++ .../history/database/DashHistoryDatabase.kt | 31 +++++++++++ .../dash/history/database/HistoryRecordDao.kt | 36 ++++++++++++ .../history/database/HistoryRecordEntity.kt | 22 ++++++++ .../dash/history/mapper/HistoryMapper.kt | 32 +++++++++++ 12 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt diff --git a/omnipod-dash/build.gradle b/omnipod-dash/build.gradle index ea8c60af66..45c11a93bf 100644 --- a/omnipod-dash/build.gradle +++ b/omnipod-dash/build.gradle @@ -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' + } \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt new file mode 100644 index 0000000000..172dd497b0 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt @@ -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) + +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashModule.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashModule.kt index a67a8dd570..98780b10d9 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashModule.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashModule.kt @@ -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 diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt new file mode 100644 index 0000000000..98319550ed --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt @@ -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 { + 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> = + dao.all().map { list -> list.map(historyMapper::entityToDomain) } + + fun getRecordsAfter(time: Long): Single> = dao.allSince(time) + +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt new file mode 100644 index 0000000000..5229248a7e --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt @@ -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? +) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt new file mode 100644 index 0000000000..6344c9fcd7 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt @@ -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 +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt new file mode 100644 index 0000000000..53dc608e60 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt @@ -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 +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt new file mode 100644 index 0000000000..b37d71bf3f --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/Converters.kt @@ -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(s) + + @TypeConverter + fun fromBolusType(bolusType: BolusType) = bolusType.name + + @TypeConverter + fun toInitialResult(s: String) = enumValueOf(s) + + @TypeConverter + fun fromInitialResult(initialResult: InitialResult) = initialResult.name + + @TypeConverter + fun toResolvedResult(s: String) = enumValueOf(s) + + @TypeConverter + fun fromResolvedResult(resolvedResult: ResolvedResult) = resolvedResult.name + + @TypeConverter + fun toOmnipodCommandType(s: String) = enumValueOf(s) + + @TypeConverter + fun fromOmnipodCommandType(omnipodCommandType: OmnipodCommandType) = omnipodCommandType.name +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt new file mode 100644 index 0000000000..259447afb0 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/DashHistoryDatabase.kt @@ -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() + + } + +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt new file mode 100644 index 0000000000..e5c425dd24 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt @@ -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> + + @Query("SELECT * from historyrecords") + abstract fun allBlocking(): List + + @Query("SELECT * from historyrecords WHERE createdAt <= :since") + abstract fun allSince(since: Long): Single> + + @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 + +} \ No newline at end of file diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt new file mode 100644 index 0000000000..6539009117 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordEntity.kt @@ -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?) + diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt new file mode 100644 index 0000000000..6ceeb6920c --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/mapper/HistoryMapper.kt @@ -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 + ) + +} \ No newline at end of file