mirror of
https://github.com/ev-map/EVMap.git
synced 2026-04-20 14:18:20 -04:00
exclude cached data from DB in backup
This commit is contained in:
committed by
Johan von Forstner
parent
d16d48bf8f
commit
81b4e77a66
@@ -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"
|
||||
|
||||
54
app/src/main/java/net/vonforst/evmap/storage/BackupAgent.kt
Normal file
54
app/src/main/java/net/vonforst/evmap/storage/BackupAgent.kt
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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?
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -80,4 +80,7 @@ abstract class RecentAutocompletePlaceDao {
|
||||
dataSource: String,
|
||||
limit: Int? = null
|
||||
): List<RecentAutocompletePlace>
|
||||
|
||||
@Query("SELECT * FROM recentautocompleteplace")
|
||||
abstract suspend fun getAllAsync(): List<RecentAutocompletePlace>
|
||||
}
|
||||
@@ -8,5 +8,5 @@
|
||||
path="encrypted_prefs.xml" />
|
||||
<include
|
||||
domain="database"
|
||||
path="evmap.db" />
|
||||
path="evmap-backup.db" />
|
||||
</full-backup-content>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user