exclude cached data from DB in backup

This commit is contained in:
johan12345
2023-05-29 19:50:01 +02:00
committed by Johan von Forstner
parent d16d48bf8f
commit 81b4e77a66
8 changed files with 108 additions and 4 deletions

View File

@@ -26,6 +26,8 @@
android:allowBackup="true"
android:fullBackupContent="@xml/backup_rules"
android:dataExtractionRules="@xml/backup_rules_api31"
android:fullBackupOnly="true"
android:backupAgent=".storage.BackupAgent"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"

View File

@@ -0,0 +1,54 @@
package net.vonforst.evmap.storage
import android.app.backup.BackupAgent
import android.app.backup.BackupDataInput
import android.app.backup.BackupDataOutput
import android.app.backup.FullBackupDataOutput
import android.os.ParcelFileDescriptor
import kotlinx.coroutines.runBlocking
import java.time.Instant
private const val backupFileName = "evmap-backup.db"
class BackupAgent : BackupAgent() {
override fun onBackup(
oldState: ParcelFileDescriptor,
data: BackupDataOutput,
newState: ParcelFileDescriptor
) {
// unused on Android M+, we don't support backups on older versions
}
override fun onRestore(
data: BackupDataInput,
appVersionCode: Int,
newState: ParcelFileDescriptor
) {
// unused on Android M+, we don't support backups on older versions
}
override fun onFullBackup(data: FullBackupDataOutput) {
runBlocking {
// creates a backup of the app database to evmap-backup.db
AppDatabase.getInstance(applicationContext).createBackup(
applicationContext,
backupFileName
)
}
super.onFullBackup(data)
val backupDb = applicationContext.getDatabasePath(backupFileName)
if (backupDb.exists()) backupDb.delete()
}
override fun onRestoreFinished() {
super.onRestoreFinished()
// rename restored backup DB as evmap.db
val backupDb = applicationContext.getDatabasePath(backupFileName)
if (backupDb.exists()) {
backupDb.renameTo(applicationContext.getDatabasePath("evmap.db"))
}
// clear cache age
PreferenceDataSource(applicationContext).lastGeReferenceDataUpdate = Instant.EPOCH
PreferenceDataSource(applicationContext).lastOcmReferenceDataUpdate = Instant.EPOCH
}
}

View File

@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import androidx.lifecycle.map
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
@@ -18,6 +19,7 @@ import net.vonforst.evmap.api.openchargemap.OCMConnectionType
import net.vonforst.evmap.api.openchargemap.OCMCountry
import net.vonforst.evmap.api.openchargemap.OCMOperator
import net.vonforst.evmap.model.*
import net.vonforst.evmap.viewmodel.await
@Database(
entities = [
@@ -446,4 +448,30 @@ abstract class AppDatabase : RoomDatabase() {
}
}
}
/**
* Creates a backup of the database to evmap-backup.db.
*
* The backup excludes cached data which can easily be retrieved from the network on restore.
*/
suspend fun createBackup(context: Context, fileName: String) {
val db = getInstance(context.applicationContext)
val backupDb = initDb(
SpatiaRoom.databaseBuilder(
context.applicationContext,
AppDatabase::class.java,
fileName
)
)
backupDb.clearAllTables()
val favorites = db.favoritesDao().getAllFavoritesAsync()
backupDb.chargeLocationsDao().insert(*favorites.map { it.charger }.toTypedArray())
backupDb.favoritesDao().insert(*favorites.map { it.favorite }.toTypedArray())
backupDb.filterProfileDao().insert(*db.filterProfileDao().getAllProfiles().toTypedArray())
backupDb.filterValueDao().insert(*db.filterValueDao().getAllFilterValues().toTypedArray())
backupDb.recentAutocompletePlaceDao()
.insert(*db.recentAutocompletePlaceDao().getAllAsync().toTypedArray())
backupDb.close()
}
}

View File

@@ -19,7 +19,7 @@ data class FilterProfile(
@Dao
interface FilterProfileDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(profile: FilterProfile): Long
suspend fun insert(vararg profile: FilterProfile)
@Update
suspend fun update(vararg profiles: FilterProfile)
@@ -30,6 +30,9 @@ interface FilterProfileDao {
@Query("SELECT * FROM filterProfile WHERE dataSource = :dataSource AND id != $FILTERS_CUSTOM ORDER BY `order` ASC, `name` ASC")
fun getProfiles(dataSource: String): LiveData<List<FilterProfile>>
@Query("SELECT * FROM filterProfile")
suspend fun getAllProfiles(): List<FilterProfile>
@Query("SELECT * FROM filterProfile WHERE dataSource = :dataSource AND name = :name")
suspend fun getProfileByName(name: String, dataSource: String): FilterProfile?

View File

@@ -26,6 +26,15 @@ abstract class FilterValueDao {
dataSource: String
): List<SliderFilterValue>
@Query("SELECT * FROM booleanfiltervalue")
protected abstract suspend fun getAllBooleanFilterValuesAsync(): List<BooleanFilterValue>
@Query("SELECT * FROM multiplechoicefiltervalue")
protected abstract suspend fun getAllMultipleChoiceFilterValuesAsync(): List<MultipleChoiceFilterValue>
@Query("SELECT * FROM sliderfiltervalue")
protected abstract suspend fun getAllSliderFilterValuesAsync(): List<SliderFilterValue>
@Query("SELECT * FROM booleanfiltervalue WHERE profile = :profile AND dataSource = :dataSource")
protected abstract fun getBooleanFilterValues(
profile: Long,
@@ -105,6 +114,11 @@ abstract class FilterValueDao {
}
}
open suspend fun getAllFilterValues(): List<FilterValue> =
getAllBooleanFilterValuesAsync() +
getAllMultipleChoiceFilterValuesAsync() +
getAllSliderFilterValuesAsync()
@Transaction
open suspend fun insert(vararg values: FilterValue) {
values.forEach {

View File

@@ -80,4 +80,7 @@ abstract class RecentAutocompletePlaceDao {
dataSource: String,
limit: Int? = null
): List<RecentAutocompletePlace>
@Query("SELECT * FROM recentautocompleteplace")
abstract suspend fun getAllAsync(): List<RecentAutocompletePlace>
}

View File

@@ -8,5 +8,5 @@
path="encrypted_prefs.xml" />
<include
domain="database"
path="evmap.db" />
path="evmap-backup.db" />
</full-backup-content>

View File

@@ -9,7 +9,7 @@
path="encrypted_prefs.xml" />
<include
domain="database"
path="evmap.db" />
path="evmap-backup.db" />
</cloud-backup>
<device-transfer>
<include
@@ -20,6 +20,6 @@
path="encrypted_prefs.xml" />
<include
domain="database"
path="evmap.db" />
path="evmap-backup.db" />
</device-transfer>
</data-extraction-rules>