Cleanup database mantenance option

This commit is contained in:
Milos Kozak 2022-10-20 11:37:27 +02:00
parent 91baf5e88a
commit 1438f6ecaf
32 changed files with 237 additions and 40 deletions

View file

@ -184,7 +184,7 @@ class MainApp : DaggerApplication() {
Thread.currentThread().uncaughtExceptionHandler?.uncaughtException(Thread.currentThread(), e)
return@setErrorHandler
}
aapsLogger.warn(LTag.CORE, "Undeliverable exception received, not sure what to do", e)
aapsLogger.warn(LTag.CORE, "Undeliverable exception received, not sure what to do", e.toString())
}
}

View file

@ -5,6 +5,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.text.toSpanned
import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.SingleFragmentActivity
@ -29,11 +30,13 @@ import info.nightscout.androidaps.plugins.general.overview.OverviewData
import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.DashHistoryDatabase
import info.nightscout.androidaps.plugins.pump.omnipod.eros.history.database.ErosHistoryDatabase
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.protection.ProtectionCheck.Protection.PREFERENCES
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import io.reactivex.rxjava3.core.Completable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign
@ -113,6 +116,25 @@ class MaintenanceFragment : DaggerFragment() {
})
}
}
binding.cleanupDb.setOnClickListener {
activity?.let { activity ->
var result = ""
OKDialog.showConfirmation(activity, rh.gs(R.string.maintenance), rh.gs(R.string.cleanup_db_confirm), Runnable {
disposable += Completable.fromAction { result = repository.cleanupDatabase(93, deleteTrackedChanges = true) }
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)
.subscribeBy(
onError = { aapsLogger.error("Error cleaning up databases", it) },
onComplete = {
if (result.isNotEmpty())
OKDialog.show(activity, rh.gs(R.string.result), HtmlHelper.fromHtml("<b>" + rh.gs(R.string.cleared_entries) + "</b>\n" + result).toSpanned())
aapsLogger.info(LTag.CORE, "Cleaned up databases with result: $result")
}
)
uel.log(Action.CLEANUP_DATABASES, Sources.Maintenance)
})
}
}
binding.navExport.setOnClickListener {
uel.log(Action.EXPORT_SETTINGS, Sources.Maintenance)
// start activity for checking permissions...

View file

@ -69,14 +69,14 @@ class MaintenancePlugin @Inject constructor(
val files = logDir.listFiles { _: File?, name: String ->
(name.startsWith("AndroidAPS") && name.endsWith(".zip"))
}
val autotunefiles = logDir.listFiles { _: File?, name: String ->
val autotuneFiles = logDir.listFiles { _: File?, name: String ->
(name.startsWith("autotune") && name.endsWith(".zip"))
}
val amount = sp.getInt(R.string.key_logshipper_amount, keep)
val keepIndex = amount - 1
if (autotunefiles != null && autotunefiles.isNotEmpty()) {
Arrays.sort(autotunefiles) { f1: File, f2: File -> f2.name.compareTo(f1.name) }
var delAutotuneFiles = listOf(*autotunefiles)
if (autotuneFiles != null && autotuneFiles.isNotEmpty()) {
Arrays.sort(autotuneFiles) { f1: File, f2: File -> f2.name.compareTo(f1.name) }
var delAutotuneFiles = listOf(*autotuneFiles)
if (keepIndex < delAutotuneFiles.size) {
delAutotuneFiles = delAutotuneFiles.subList(keepIndex, delAutotuneFiles.size)
for (file in delAutotuneFiles) {

View file

@ -37,6 +37,7 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.widget.updateWidget
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import kotlin.math.abs
@ -62,6 +63,7 @@ class KeepAliveWorker(
@Inject lateinit var fabricPrivacy: FabricPrivacy
@Inject lateinit var maintenancePlugin: MaintenancePlugin
@Inject lateinit var rh: ResourceHelper
@Inject lateinit var sp: SP
init {
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
@ -122,10 +124,22 @@ class KeepAliveWorker(
checkAPS()
maintenancePlugin.deleteLogs(30)
workerDbStatus()
databaseCleanup()
return Result.success()
}
// Perform history data cleanup every day
// Keep 6 months
private fun databaseCleanup() {
val lastRun = sp.getLong(R.string.key_last_cleanup_run, 0L)
if (lastRun < dateUtil.now() - T.days(1).msecs()) {
val result = repository.cleanupDatabase(6 * 31, deleteTrackedChanges = false)
aapsLogger.debug(LTag.CORE, "Cleanup result: $result")
sp.putLong(R.string.key_last_cleanup_run, dateUtil.now())
}
}
// When Worker DB grows too much, work operations become slow
// Library is cleaning DB every 7 days which may not be sufficient for NSClient full sync
private fun workerDbStatus() {

View file

@ -0,0 +1,7 @@
<vector android:height="48dp" android:viewportHeight="24"
android:viewportWidth="24" android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="?attr/colorControlNormal" android:pathData="M4.598,5.728a7.505,2.62 0,1 0,15.01 0a7.505,2.62 0,1 0,-15.01 0z"/>
<path android:fillColor="?attr/colorControlNormal" android:pathData="M19.051,7.533c-0.41,0.264 -0.91,0.493 -1.475,0.687c-1.517,0.521 -3.5,0.787 -5.473,0.787c-1.973,0 -3.957,-0.267 -5.473,-0.787C6.065,8.026 5.565,7.797 5.155,7.533C4.945,7.398 4.757,7.254 4.598,7.1v3.578c0.003,0.003 0.007,0.007 0.011,0.01c1.315,1.25 4.419,1.897 7.495,1.897c3.076,0 6.18,-0.647 7.495,-1.897c0.001,0 0.001,-0.001 0.002,-0.001V7.109C19.441,7.259 19.257,7.4 19.051,7.533z"/>
<path android:fillColor="?attr/colorControlNormal" android:pathData="M19.051,11.937c-0.41,0.264 -0.91,0.493 -1.475,0.687c-1.517,0.521 -3.5,0.787 -5.473,0.787c-1.973,0 -3.957,-0.267 -5.473,-0.787c-0.565,-0.194 -1.065,-0.423 -1.475,-0.687c-0.21,-0.135 -0.397,-0.28 -0.557,-0.433v3.578c0.003,0.003 0.007,0.007 0.011,0.01c1.315,1.25 4.419,1.897 7.495,1.897c3.076,0 6.18,-0.647 7.495,-1.897c0.001,0 0.001,-0.001 0.002,-0.001v-3.578C19.441,11.663 19.257,11.804 19.051,11.937z"/>
<path android:fillColor="?attr/colorControlNormal" android:pathData="M19.051,16.341c-0.41,0.264 -0.91,0.493 -1.475,0.687c-1.517,0.521 -3.5,0.787 -5.473,0.787c-1.973,0 -3.957,-0.267 -5.473,-0.787c-0.565,-0.194 -1.065,-0.423 -1.475,-0.687c-0.21,-0.135 -0.397,-0.28 -0.557,-0.433v3.578c0.003,0.003 0.007,0.007 0.011,0.01c1.315,1.25 4.419,1.897 7.495,1.897c3.076,0 6.18,-0.647 7.495,-1.897c0.001,0 0.001,-0.001 0.002,-0.001v-3.578C19.441,16.067 19.257,16.209 19.051,16.341z"/>
</vector>

View file

@ -211,6 +211,21 @@
app:layout_gravity="fill"
app:layout_row="0" />
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/cleanup_db"
style="@style/GrayButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_database_cleanup"
android:paddingStart="0dp"
android:paddingEnd="0dp"
android:text="@string/database_cleanup"
android:textSize="11sp"
app:layout_column="0"
app:layout_columnWeight="1"
app:layout_gravity="fill"
app:layout_row="1" />
<info.nightscout.androidaps.utils.ui.SingleClickButton
android:id="@+id/nav_resetdb"
style="@style/GrayButton"
@ -224,7 +239,7 @@
app:layout_column="1"
app:layout_columnWeight="1"
app:layout_gravity="fill"
app:layout_row="0" />
app:layout_row="1" />
</androidx.gridlayout.widget.GridLayout>

View file

@ -56,6 +56,7 @@
<string name="key_ns_profile_store_last_synced_timestamp" translatable="false">ns_profile_store_last_synced_timestamp</string>
<string name="key_local_profile_last_change" translatable="false">local_profile_last_change</string>
<string name="key_ns_sync_slow" translatable="false">ns_sync_slow</string>
<string name="key_last_cleanup_run" translatable="false">last_cleanup_run</string>
<string name="treatmentssafety_title">Treatments safety</string>
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
<string name="treatmentssafety_maxcarbs_title">Max allowed carbs [g]</string>
@ -1258,5 +1259,8 @@
<string name="error_asking_for_permissions">Error asking for permissions</string>
<string name="key_adjust_sensitivity" translatable="false">dynisf_adjust_sensitivity</string>
<string name="dynisf_adjust_sensitivity">Adjust sensitivity and BG</string>
<string name="database_cleanup">Database cleanup</string>
<string name="cleanup_db_confirm">Do you want to cleanup the database?\nIt will remove tracked changes and historic data older than 3 months.</string>
<string name="cleared_entries">Cleared entries</string>
</resources>

View file

@ -89,6 +89,7 @@ class Translator @Inject internal constructor(
Action.EXPORT_SETTINGS -> rh.gs(R.string.uel_export_settings)
Action.IMPORT_SETTINGS -> rh.gs(R.string.uel_import_settings)
Action.RESET_DATABASES -> rh.gs(R.string.uel_reset_databases)
Action.CLEANUP_DATABASES -> rh.gs(R.string.uel_cleanup_databases)
Action.EXPORT_DATABASES -> rh.gs(R.string.uel_export_databases)
Action.IMPORT_DATABASES -> rh.gs(R.string.uel_import_databases)
Action.OTP_EXPORT -> rh.gs(R.string.uel_otp_export)

View file

@ -462,6 +462,7 @@
<string name="uel_export_settings">EXPORT SETTINGS</string>
<string name="uel_import_settings">IMPORT SETTINGS</string>
<string name="uel_reset_databases">RESET DATABASES</string>
<string name="uel_cleanup_databases">CLEANUP DATABASES</string>
<string name="uel_export_databases">EXPORT DATABASES</string>
<string name="uel_import_databases">IMPORT DATABASES</string>
<string name="uel_otp_export">OTP EXPORT</string>

View file

@ -12,7 +12,9 @@ import io.reactivex.rxjava3.core.Observable
import io.reactivex.rxjava3.core.Single
import io.reactivex.rxjava3.schedulers.Schedulers
import io.reactivex.rxjava3.subjects.PublishSubject
import java.lang.StringBuilder
import java.util.concurrent.Callable
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.roundToInt
@ -46,7 +48,7 @@ import kotlin.math.roundToInt
* Executes a transaction and returns its result
* Runs on IO scheduler
*/
fun <T: Any> runTransactionForResult(transaction: Transaction<T>): Single<T> {
fun <T : Any> runTransactionForResult(transaction: Transaction<T>): Single<T> {
val changes = mutableListOf<DBEntry>()
return Single.fromCallable {
database.runInTransaction(Callable<T> {
@ -60,6 +62,57 @@ import kotlin.math.roundToInt
fun clearDatabases() = database.clearAllTables()
fun cleanupDatabase(keepDays: Long, deleteTrackedChanges: Boolean): String {
val than = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(keepDays)
val removed = mutableListOf<Pair<String, Int>>()
removed.add(Pair("GlucoseValue", database.glucoseValueDao.deleteOlderThan(than)))
removed.add(Pair("TherapyEvent", database.therapyEventDao.deleteOlderThan(than)))
removed.add(Pair("TemporaryBasal", database.temporaryBasalDao.deleteOlderThan(than)))
removed.add(Pair("ExtendedBolus", database.extendedBolusDao.deleteOlderThan(than)))
removed.add(Pair("Bolus", database.bolusDao.deleteOlderThan(than)))
removed.add(Pair("MultiWaveBolus", database.multiwaveBolusLinkDao.deleteOlderThan(than)))
//removed.add(Pair("TotalDailyDose", database.totalDailyDoseDao.deleteOlderThan(than)))
removed.add(Pair("Carbs", database.carbsDao.deleteOlderThan(than)))
removed.add(Pair("TemporaryTarget", database.temporaryTargetDao.deleteOlderThan(than)))
removed.add(Pair("ApsResultLink", database.apsResultLinkDao.deleteOlderThan(than)))
removed.add(Pair("BolusCalculatorResult", database.bolusCalculatorResultDao.deleteOlderThan(than)))
// keep at least one EPS
if (database.effectiveProfileSwitchDao.getEffectiveProfileSwitchDataFromTime(than + 1).blockingGet().isNotEmpty())
removed.add(Pair("EffectiveProfileSwitch", database.effectiveProfileSwitchDao.deleteOlderThan(than)))
removed.add(Pair("ProfileSwitch", database.profileSwitchDao.deleteOlderThan(than)))
removed.add(Pair("ApsResult", database.apsResultDao.deleteOlderThan(than)))
//database.versionChangeDao.deleteOlderThan(than)
removed.add(Pair("UserEntry", database.userEntryDao.deleteOlderThan(than)))
removed.add(Pair("PreferenceChange", database.preferenceChangeDao.deleteOlderThan(than)))
//database.foodDao.deleteOlderThan(than)
removed.add(Pair("DeviceStatus", database.deviceStatusDao.deleteOlderThan(than)))
removed.add(Pair("OfflineEvent", database.offlineEventDao.deleteOlderThan(than)))
if (deleteTrackedChanges) {
removed.add(Pair("GlucoseValue", database.glucoseValueDao.deleteTrackedChanges()))
removed.add(Pair("TherapyEvent", database.therapyEventDao.deleteTrackedChanges()))
removed.add(Pair("TemporaryBasal", database.temporaryBasalDao.deleteTrackedChanges()))
removed.add(Pair("Bolus", database.bolusDao.deleteTrackedChanges()))
removed.add(Pair("ExtendedBolus", database.extendedBolusDao.deleteTrackedChanges()))
removed.add(Pair("MultiWaveBolus", database.multiwaveBolusLinkDao.deleteTrackedChanges()))
//removed.add(Pair("TotalDailyDose", database.totalDailyDoseDao.deleteTrackedChanges()))
removed.add(Pair("Carbs", database.carbsDao.deleteTrackedChanges()))
removed.add(Pair("TemporaryTarget", database.temporaryTargetDao.deleteTrackedChanges()))
removed.add(Pair("ApsResultLink", database.apsResultLinkDao.deleteTrackedChanges()))
removed.add(Pair("BolusCalculatorResult", database.bolusCalculatorResultDao.deleteTrackedChanges()))
removed.add(Pair("EffectiveProfileSwitch", database.effectiveProfileSwitchDao.deleteTrackedChanges()))
removed.add(Pair("ProfileSwitch", database.profileSwitchDao.deleteTrackedChanges()))
removed.add(Pair("ApsResult", database.apsResultDao.deleteTrackedChanges()))
//database.foodDao.deleteHistory()
removed.add(Pair("OfflineEvent", database.offlineEventDao.deleteTrackedChanges()))
}
val ret = StringBuilder()
removed
.filter { it.second > 0 }
.map { ret.append(it.first + " " + it.second + "\n") }
return ret.toString()
}
fun clearCachedData(from: Long) {
database.totalDailyDoseDao.deleteNewerThan(from, InterfaceIDs.PumpType.CACHE)
}

View file

@ -15,6 +15,12 @@ internal interface APSResultDao : TraceableDao<APSResult> {
@Query("DELETE FROM $TABLE_APS_RESULTS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_APS_RESULTS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_APS_RESULTS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT * FROM $TABLE_APS_RESULTS WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset")
suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<APSResult>
}

View file

@ -6,7 +6,6 @@ import info.nightscout.androidaps.database.TABLE_APS_RESULTS
import info.nightscout.androidaps.database.TABLE_APS_RESULT_LINKS
import info.nightscout.androidaps.database.entities.APSResultLink
@Suppress("FunctionName")
@Dao
internal interface APSResultLinkDao : TraceableDao<APSResultLink> {
@ -16,6 +15,12 @@ internal interface APSResultLinkDao : TraceableDao<APSResultLink> {
@Query("DELETE FROM $TABLE_APS_RESULTS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_APS_RESULTS WHERE dateCreated < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_APS_RESULTS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT * FROM $TABLE_APS_RESULT_LINKS WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset")
suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<APSResultLink>
}

View file

@ -7,7 +7,6 @@ import info.nightscout.androidaps.database.entities.BolusCalculatorResult
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface BolusCalculatorResultDao : TraceableDao<BolusCalculatorResult> {
@ -18,6 +17,12 @@ internal interface BolusCalculatorResultDao : TraceableDao<BolusCalculatorResult
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_BOLUS_CALCULATOR_RESULTS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_BOLUS_CALCULATOR_RESULTS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.database.entities.Bolus
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface BolusDao : TraceableDao<Bolus> {
@ -18,6 +17,12 @@ internal interface BolusDao : TraceableDao<Bolus> {
@Query("DELETE FROM $TABLE_BOLUSES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_BOLUSES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_BOLUSES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_BOLUSES ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -2,13 +2,11 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_BOLUSES
import info.nightscout.androidaps.database.TABLE_CARBS
import info.nightscout.androidaps.database.entities.Carbs
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface CarbsDao : TraceableDao<Carbs> {
@ -18,6 +16,12 @@ internal interface CarbsDao : TraceableDao<Carbs> {
@Query("DELETE FROM $TABLE_CARBS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_CARBS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_CARBS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_CARBS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -4,8 +4,8 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import androidx.room.Update
import info.nightscout.androidaps.database.entities.DeviceStatus
import info.nightscout.androidaps.database.TABLE_DEVICE_STATUS
import info.nightscout.androidaps.database.entities.DeviceStatus
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@ -25,6 +25,9 @@ internal interface DeviceStatusDao {
@Query("DELETE FROM $TABLE_DEVICE_STATUS")
fun deleteAllEntries()
@Query("DELETE FROM $TABLE_DEVICE_STATUS WHERE timestamp < :than")
fun deleteOlderThan(than: Long): Int
@Query("SELECT id FROM $TABLE_DEVICE_STATUS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -7,7 +7,6 @@ import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface EffectiveProfileSwitchDao : TraceableDao<EffectiveProfileSwitch> {
@ -17,6 +16,12 @@ internal interface EffectiveProfileSwitchDao : TraceableDao<EffectiveProfileSwit
@Query("DELETE FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_EFFECTIVE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -2,15 +2,12 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_CARBS
import info.nightscout.androidaps.database.TABLE_EXTENDED_BOLUSES
import info.nightscout.androidaps.database.embedments.InterfaceIDs
import info.nightscout.androidaps.database.entities.Carbs
import info.nightscout.androidaps.database.entities.ExtendedBolus
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface ExtendedBolusDao : TraceableDao<ExtendedBolus> {
@ -20,6 +17,12 @@ internal interface ExtendedBolusDao : TraceableDao<ExtendedBolus> {
@Query("DELETE FROM $TABLE_EXTENDED_BOLUSES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_EXTENDED_BOLUSES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_EXTENDED_BOLUSES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_EXTENDED_BOLUSES ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -7,7 +7,6 @@ import info.nightscout.androidaps.database.entities.Food
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface FoodDao : TraceableDao<Food> {
@ -17,6 +16,12 @@ internal interface FoodDao : TraceableDao<Food> {
@Query("DELETE FROM $TABLE_FOODS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_FOODS WHERE dateCreated < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_FOODS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_FOODS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -16,6 +16,12 @@ internal interface GlucoseValueDao : TraceableDao<GlucoseValue> {
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_GLUCOSE_VALUES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT * FROM $TABLE_GLUCOSE_VALUES WHERE isValid = 1 AND referenceId IS NULL ORDER BY timestamp DESC limit 1")
fun getLast(): Maybe<GlucoseValue>

View file

@ -2,12 +2,9 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_GLUCOSE_VALUES
import info.nightscout.androidaps.database.TABLE_MULTIWAVE_BOLUS_LINKS
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.MultiwaveBolusLink
@Suppress("FunctionName")
@Dao
internal interface MultiwaveBolusLinkDao : TraceableDao<MultiwaveBolusLink> {
@ -17,6 +14,12 @@ internal interface MultiwaveBolusLinkDao : TraceableDao<MultiwaveBolusLink> {
@Query("DELETE FROM $TABLE_MULTIWAVE_BOLUS_LINKS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_MULTIWAVE_BOLUS_LINKS WHERE dateCreated < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_MULTIWAVE_BOLUS_LINKS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT * FROM $TABLE_MULTIWAVE_BOLUS_LINKS WHERE dateCreated > :since AND dateCreated <= :until LIMIT :limit OFFSET :offset")
suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<MultiwaveBolusLink>
}

View file

@ -2,14 +2,11 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_GLUCOSE_VALUES
import info.nightscout.androidaps.database.TABLE_OFFLINE_EVENTS
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.OfflineEvent
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface OfflineEventDao : TraceableDao<OfflineEvent> {
@ -19,6 +16,12 @@ internal interface OfflineEventDao : TraceableDao<OfflineEvent> {
@Query("DELETE FROM $TABLE_OFFLINE_EVENTS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_OFFLINE_EVENTS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_OFFLINE_EVENTS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_OFFLINE_EVENTS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -3,11 +3,8 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_GLUCOSE_VALUES
import info.nightscout.androidaps.database.TABLE_PREFERENCE_CHANGES
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.PreferenceChange
import io.reactivex.rxjava3.core.Single
@Dao
interface PreferenceChangeDao {
@ -15,6 +12,9 @@ interface PreferenceChangeDao {
@Insert
fun insert(preferenceChange: PreferenceChange)
@Query("DELETE FROM $TABLE_PREFERENCE_CHANGES WHERE timestamp < :than")
fun deleteOlderThan(than: Long): Int
@Query("SELECT * FROM $TABLE_PREFERENCE_CHANGES WHERE timestamp > :since AND timestamp <= :until LIMIT :limit OFFSET :offset")
suspend fun getNewEntriesSince(since: Long, until: Long, limit: Int, offset: Int): List<PreferenceChange>

View file

@ -9,7 +9,6 @@ import info.nightscout.androidaps.database.entities.ProfileSwitch
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface ProfileSwitchDao : ProfileSwitchDaoWorkaround {
@ -19,6 +18,12 @@ internal interface ProfileSwitchDao : ProfileSwitchDaoWorkaround {
@Query("DELETE FROM $TABLE_PROFILE_SWITCHES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_PROFILE_SWITCHES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_PROFILE_SWITCHES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_PROFILE_SWITCHES ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.database.entities.TemporaryBasal
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface TemporaryBasalDao : TraceableDao<TemporaryBasal> {
@ -18,6 +17,12 @@ internal interface TemporaryBasalDao : TraceableDao<TemporaryBasal> {
@Query("DELETE FROM $TABLE_TEMPORARY_BASALS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_TEMPORARY_BASALS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_TEMPORARY_BASALS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_TEMPORARY_BASALS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -2,14 +2,11 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_GLUCOSE_VALUES
import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.entities.TemporaryTarget
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface TemporaryTargetDao : TraceableDao<TemporaryTarget> {
@ -19,6 +16,12 @@ internal interface TemporaryTargetDao : TraceableDao<TemporaryTarget> {
@Query("DELETE FROM $TABLE_TEMPORARY_TARGETS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_TEMPORARY_TARGETS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_TEMPORARY_TARGETS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_TEMPORARY_TARGETS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -2,9 +2,7 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS
import info.nightscout.androidaps.database.TABLE_THERAPY_EVENTS
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.TherapyEvent
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@ -18,6 +16,12 @@ internal interface TherapyEventDao : TraceableDao<TherapyEvent> {
@Query("DELETE FROM $TABLE_THERAPY_EVENTS")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_THERAPY_EVENTS WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_THERAPY_EVENTS WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT id FROM $TABLE_THERAPY_EVENTS ORDER BY id DESC limit 1")
fun getLastId(): Maybe<Long>

View file

@ -8,7 +8,6 @@ import info.nightscout.androidaps.database.entities.TotalDailyDose
import io.reactivex.rxjava3.core.Maybe
import io.reactivex.rxjava3.core.Single
@Suppress("FunctionName")
@Dao
internal interface TotalDailyDoseDao : TraceableDao<TotalDailyDose> {
@ -18,6 +17,12 @@ internal interface TotalDailyDoseDao : TraceableDao<TotalDailyDose> {
@Query("DELETE FROM $TABLE_TOTAL_DAILY_DOSES")
override fun deleteAllEntries()
@Query("DELETE FROM $TABLE_TOTAL_DAILY_DOSES WHERE timestamp < :than")
override fun deleteOlderThan(than: Long): Int
@Query("DELETE FROM $TABLE_TOTAL_DAILY_DOSES WHERE referenceId IS NOT NULL")
override fun deleteTrackedChanges(): Int
@Query("SELECT * FROM $TABLE_TOTAL_DAILY_DOSES WHERE pumpId = :pumpId AND pumpType = :pumpType AND pumpSerial = :pumpSerial AND referenceId IS NULL")
fun findByPumpIds(pumpId: Long, pumpType: InterfaceIDs.PumpType, pumpSerial: String): TotalDailyDose?

View file

@ -11,7 +11,8 @@ internal interface TraceableDao<T : TraceableDBEntry> : TraceableDaoWorkaround<T
fun deleteAllEntries()
//fun getAllStartingFrom(id: Long): Single<List<T>>
fun deleteOlderThan(than: Long): Int
fun deleteTrackedChanges(): Int
@Insert
fun insert(entry: T): Long
@ -49,7 +50,7 @@ internal fun <T : TraceableDBEntry> TraceableDao<T>.updateExistingEntryImpl(entr
val lastModified = System.currentTimeMillis()
entry.dateCreated = lastModified
val current = findById(entry.id)
?: throw IllegalArgumentException("The entry with the specified ID does not exist.")
?: throw IllegalArgumentException("The entry with the specified ID does not exist.")
if (current.referenceId != null) throw IllegalArgumentException("The entry with the specified ID is historic and cannot be updated.")
entry.version = current.version + 1
update(entry)

View file

@ -14,6 +14,9 @@ interface UserEntryDao {
@Insert
fun insert(userEntry: UserEntry)
@Query("DELETE FROM $TABLE_USER_ENTRY WHERE timestamp < :than")
fun deleteOlderThan(than: Long): Int
@Query("SELECT * FROM $TABLE_USER_ENTRY ORDER BY id DESC")
fun getAll(): Single<List<UserEntry>>

View file

@ -3,11 +3,8 @@ package info.nightscout.androidaps.database.daos
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
import info.nightscout.androidaps.database.TABLE_TEMPORARY_TARGETS
import info.nightscout.androidaps.database.TABLE_VERSION_CHANGES
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.database.entities.VersionChange
import io.reactivex.rxjava3.core.Single
@Dao
interface VersionChangeDao {
@ -15,6 +12,9 @@ interface VersionChangeDao {
@Insert
fun insert(versionChange: VersionChange)
@Query("DELETE FROM $TABLE_VERSION_CHANGES WHERE timestamp < :than")
fun deleteOlderThan(than: Long): Int
@Query("SELECT * FROM $TABLE_VERSION_CHANGES ORDER BY id DESC LIMIT 1")
fun getMostRecentVersionChange(): VersionChange?

View file

@ -97,6 +97,7 @@ data class UserEntry(
EXPORT_SETTINGS (ColorGroup.Aaps),
IMPORT_SETTINGS (ColorGroup.Aaps),
RESET_DATABASES (ColorGroup.Aaps),
CLEANUP_DATABASES (ColorGroup.Aaps),
EXPORT_DATABASES (ColorGroup.Aaps),
IMPORT_DATABASES (ColorGroup.Aaps),
OTP_EXPORT (ColorGroup.Aaps),