Skip to content
This repository has been archived by the owner on Apr 26, 2020. It is now read-only.

Restore problem #389

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

package de.dreier.mytargets.base.db.migrations

import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.room.migration.Migration
import android.database.Cursor
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import de.dreier.mytargets.shared.models.Dimension
import de.dreier.mytargets.shared.models.Target
import de.dreier.mytargets.shared.models.db.Shot
Expand All @@ -28,55 +28,59 @@ object Migration26 : Migration(25, 26) {
override fun migrate(database: SupportSQLiteDatabase) {
Timber.i("Migrating DB from version 25 to 26")

database.execSQL("ALTER TABLE `Training` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Training` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Training` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")
try {
database.execSQL("ALTER TABLE `Training` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Training` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Training` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")

database.execSQL("ALTER TABLE `Round` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Round` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Round` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Round` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Round` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `Round` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")

database.execSQL("ALTER TABLE `End` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `End` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `End` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `End` ADD COLUMN `reachedPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `End` ADD COLUMN `totalPoints` INTEGER DEFAULT 0;")
database.execSQL("ALTER TABLE `End` ADD COLUMN `shotCount` INTEGER DEFAULT 0;")

recreateTablesWithNonNull(database)
recreateTablesWithNonNull(database)

createScoreTriggers(database)
createScoreTriggers(database)

createIndices(database)
createIndices(database)

database.query("SELECT `id`, `targetId`, `targetScoringStyleIndex`, `targetDiameter` FROM `Round`")
.useEach { round ->
val diameter = Dimension.parse(round.getString(3))
val target = Target(round.getLong(1), round.getInt(2), diameter)
val roundId = round.getLong(0)
database.query("SELECT `id`, `targetId`, `targetScoringStyleIndex`, `targetDiameter` FROM `Round`")
.useEach { round ->
val diameter = Dimension.parse(round.getString(3))
val target = Target(round.getLong(1), round.getInt(2), diameter)
val roundId = round.getLong(0)

database.query("SELECT `id` FROM `End` WHERE `roundId` = $roundId")
.useEach { end ->
val endId = end.getLong(0)
database.query("SELECT `id` FROM `End` WHERE `roundId` = $roundId")
.useEach { end ->
val endId = end.getLong(0)

val shots = mutableListOf<Shot>()
database.query("SELECT `index`, `scoringRing` FROM `Shot` WHERE `endId` = $endId ORDER BY `index`")
.useEach { shotCursor ->
shots.add(
Shot(
index = shotCursor.getInt(0),
scoringRing = shotCursor.getInt(1)
val shots = mutableListOf<Shot>()
database.query("SELECT `index`, `scoringRing` FROM `Shot` WHERE `endId` = $endId ORDER BY `index`")
.useEach { shotCursor ->
shots.add(
Shot(
index = shotCursor.getInt(0),
scoringRing = shotCursor.getInt(1)
)
)
)
}

val score = target.getReachedScore(shots)
database.execSQL(
"UPDATE `End` SET " +
"`reachedPoints` = ${score.reachedPoints}, " +
"`totalPoints` = ${score.totalPoints}, " +
"`shotCount` = ${score.shotCount} " +
"WHERE `id` = $endId"
)
}
}
}

val score = target.getReachedScore(shots)
database.execSQL(
"UPDATE `End` SET " +
"`reachedPoints` = ${score.reachedPoints}, " +
"`totalPoints` = ${score.totalPoints}, " +
"`shotCount` = ${score.shotCount} " +
"WHERE `id` = $endId"
)
}
}
} catch (e: Exception) {
Timber.i(e, "DB has changed because of restoring a backup")
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching generic exceptions without properly handling them is basically always a bad idea. I also don't understand yet how this would solve the restore problems.

Basically when you import a backup into the app the database contained in the backup is stored in the internal data of the app. Then the app restarts. If a database is detected that is currently being imported the previous database is replaced by the temporary copy (imported db). When the imported database is on an older version schema it has to be migrated to the newest schema (which happens automatically). Skipping the migration (as you did here) in case an error occurs just fixes the symptom of the app crashing, but not the underlying problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the version of backup DB is 25 and it tries to migrate to 26. but, Training table has already all columns!

}
}

private fun createScoreTriggers(database: SupportSQLiteDatabase) {
Expand Down