From c7ff391ef988af0af72fa42036a5661d1f1e165c Mon Sep 17 00:00:00 2001 From: jamshid Date: Thu, 29 Aug 2019 13:39:50 +0430 Subject: [PATCH 1/2] #302 Bray rounds have changed to 10 ends of 3 arrows each --- .../de/dreier/mytargets/app/MigrationTest.kt | 70 ++++++++ .../mytargets/app/ApplicationInstance.kt | 6 +- .../dreier/mytargets/base/db/AppDatabase.kt | 6 +- .../mytargets/base/db/StandardRoundFactory.kt | 4 +- .../base/db/migrations/Migration27.kt | 149 ++++++++++++++++++ 5 files changed, 228 insertions(+), 7 deletions(-) create mode 100644 app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt diff --git a/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt b/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt index a83e6a299..6d603d229 100644 --- a/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt +++ b/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt @@ -309,4 +309,74 @@ class MigrationTest : InstrumentedTestBase() { assertThat(db.endDAO().loadEnds(rounds[0].id)).hasSize(6) assertThat(db.endDAO().loadEnds(rounds[1].id)).hasSize(6) } + + + private fun insertTrainingDataForVersion26(db: SupportSQLiteDatabase) { + db.execSQL("INSERT INTO `Training` (id,title,date,standardRoundId,bowId,arrowId,arrowNumbering,comment,archerSignatureId,witnessSignatureId,indoor,weather,windSpeed,windDirection,location,reachedPoints,totalPoints,shotCount) VALUES (1,'Training','2019-08-27',11,NULL,NULL,0,'',NULL,NULL,0,0,0,0,'',178,300,30);") + db.execSQL("INSERT INTO `StandardRound` (id,club,name) VALUES (11,4,'Bray I');") + db.execSQL("INSERT INTO `StandardRound` (id,club,name) VALUES (12,4,'Bray II');") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (1,0,1,0.0909451246261597,0.140448212623596,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (2,1,1,0.158708214759827,-0.0522582530975342,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (3,2,1,-0.130176305770874,0.0333890914916992,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (4,3,1,-0.00534975528717041,-0.170023441314697,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (5,4,1,0.155141711235046,0.0512322187423706,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (6,5,1,-0.0802456140518188,0.176134705543518,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (7,0,2,0.169407725334167,0.21182119846344,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (8,1,2,-0.0445809364318848,0.254644751548767,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (9,2,2,-0.287101149559021,0.101193308830261,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (10,3,2,-0.172973990440369,-0.155748844146729,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (11,4,2,0.183673501014709,-0.380573153495789,5,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (12,5,2,0.408361554145813,-0.0593955516815186,-2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (13,0,3,0.536754488945007,0.354566693305969,7,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (14,1,3,0.394095540046692,0.536567568778992,7,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (15,2,3,-0.226471185684204,0.679313063621521,8,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (16,3,3,-0.825638949871063,-0.14147424697876,9,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (17,4,3,-0.415494322776794,-0.605397462844849,8,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (18,5,3,0.793540835380554,-0.209278464317322,9,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (19,0,4,0.668714046478271,0.918412089347839,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (20,1,4,0.597384691238403,0.886294007301331,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (21,2,4,0.725777745246887,0.750685811042786,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (22,3,4,0.839905142784119,-0.887320160865784,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (23,4,4,0.458292126655579,-1.00508534908295,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (24,5,4,0.0445809364318848,-0.915869355201721,10,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (25,0,5,-0.0338814258575439,-0.0843760967254639,1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (26,1,5,-0.0267485380172729,-0.00943446159362793,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (27,2,5,-0.00178313255310059,0.0101931095123291,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (28,3,5,-0.0160490274429321,-0.0377378463745117,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (29,4,5,0.0124826431274414,-0.0389565229415894,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (30,5,5,0.0392313003540039,0.00840866565704346,0,NULL);") + + db.execSQL("INSERT INTO `RoundTemplate` (id,standardRoundId,`index`,shotsPerEnd,endCount,distance,targetId,targetScoringStyleIndex,targetDiameter) VALUES (13,11,0,6,5,'20.0 yd',0,0,'40.0 cm');") + db.execSQL("INSERT INTO `RoundTemplate` (id,standardRoundId,`index`,shotsPerEnd,endCount,distance,targetId,targetScoringStyleIndex,targetDiameter) VALUES (14,12,0,6,5,'25.0 yd',0,0,'60.0 cm');") + + db.execSQL("INSERT INTO `Round` (id,trainingId,`index`,shotsPerEnd,maxEndCount,distance,comment,targetId,targetScoringStyleIndex,targetDiameter,reachedPoints,totalPoints,shotCount) VALUES (1,1,0,6,5,'20.0 yd','',0,0,'40.0 cm',178,300,30);") + + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (1,0,1,1,'21:05:52.528','',54,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (2,1,1,1,'21:06:02.347','',45,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (3,2,1,1,'21:06:08.17','',18,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (4,3,1,1,'21:06:15.663','',1,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (5,4,1,1,'21:06:25.499','',60,60,6);") + } + + @Test + fun upgrade26to27() { + val db = testHelper.createDatabase(TEST_DB_NAME, 26) + insertTrainingDataForVersion26(db) + + val count = db.query("select * from StandardRound").count + assertThat(count).isEqualTo(2) + + db.close() + + testHelper.runMigrationsAndValidate( + TEST_DB_NAME, 27, + true, + Migration27 + ) + + val migratedDb = getMigratedRoomDatabase() + val ends = migratedDb.endDAO().loadEnds(1) + assertThat(ends.size).isEqualTo(10) + assertThat(migratedDb.endDAO().loadShots(15).get(1).x).isEqualTo(0.0124826431274414.toFloat()) + } } diff --git a/app/src/main/java/de/dreier/mytargets/app/ApplicationInstance.kt b/app/src/main/java/de/dreier/mytargets/app/ApplicationInstance.kt index 9cf92dca5..07ec6bb79 100644 --- a/app/src/main/java/de/dreier/mytargets/app/ApplicationInstance.kt +++ b/app/src/main/java/de/dreier/mytargets/app/ApplicationInstance.kt @@ -15,12 +15,12 @@ package de.dreier.mytargets.app -import androidx.room.Room import android.content.Context import android.content.SharedPreferences import android.content.res.Configuration -import androidx.multidex.MultiDex import android.util.Log +import androidx.multidex.MultiDex +import androidx.room.Room import androidx.room.RoomDatabase import com.crashlytics.android.Crashlytics import com.evernote.android.state.StateSaver @@ -127,7 +127,7 @@ class ApplicationInstance : SharedApplicationInstance() { Migration17, Migration18, Migration19, Migration20, Migration21, Migration22, Migration23, Migration24, Migration25, - Migration26 + Migration26, Migration27 ) .build() } diff --git a/app/src/main/java/de/dreier/mytargets/base/db/AppDatabase.kt b/app/src/main/java/de/dreier/mytargets/base/db/AppDatabase.kt index f5d35075d..5a79c0262 100644 --- a/app/src/main/java/de/dreier/mytargets/base/db/AppDatabase.kt +++ b/app/src/main/java/de/dreier/mytargets/base/db/AppDatabase.kt @@ -15,7 +15,9 @@ package de.dreier.mytargets.base.db -import androidx.room.* +import androidx.room.Database +import androidx.room.RoomDatabase +import androidx.room.TypeConverters import de.dreier.mytargets.base.db.dao.* import de.dreier.mytargets.base.db.typeconverters.* import de.dreier.mytargets.shared.models.db.* @@ -50,7 +52,7 @@ abstract class AppDatabase : RoomDatabase() { companion object { const val DATABASE_FILE_NAME = "database.db" const val DATABASE_IMPORT_FILE_NAME = "database" - const val VERSION = 26 + const val VERSION = 27 } abstract fun arrowDAO(): ArrowDAO diff --git a/app/src/main/java/de/dreier/mytargets/base/db/StandardRoundFactory.kt b/app/src/main/java/de/dreier/mytargets/base/db/StandardRoundFactory.kt index ebe600d7c..b200a6867 100644 --- a/app/src/main/java/de/dreier/mytargets/base/db/StandardRoundFactory.kt +++ b/app/src/main/java/de/dreier/mytargets/base/db/StandardRoundFactory.kt @@ -127,14 +127,14 @@ object StandardRoundFactory { build( ARCHERY_GB, R.string.bray_i, YARDS, CENTIMETER, - WAFull.ID, 0, 6, 20, 40, 5 + WAFull.ID, 0, 3, 20, 40, 10 ) ) rounds.add( build( ARCHERY_GB, R.string.bray_ii, YARDS, CENTIMETER, - WAFull.ID, 0, 6, 25, 60, 5 + WAFull.ID, 0, 3, 25, 60, 10 ) ) rounds.add( diff --git a/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt b/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt new file mode 100644 index 000000000..4ad07473f --- /dev/null +++ b/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2019 Florian Dreier + * + * This file is part of MyTargets. + * + * MyTargets is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * MyTargets is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +package de.dreier.mytargets.base.db.migrations + +import android.content.ContentValues +import android.database.sqlite.SQLiteDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import de.dreier.mytargets.shared.models.Dimension +import de.dreier.mytargets.shared.models.Score +import de.dreier.mytargets.shared.models.Target +import de.dreier.mytargets.shared.models.db.End +import de.dreier.mytargets.shared.models.db.Shot +import org.threeten.bp.LocalTime +import org.threeten.bp.format.DateTimeFormatter +import timber.log.Timber + +object Migration27 : Migration(26, 27) { + override fun migrate(database: SupportSQLiteDatabase) { + Timber.i("Migrating DB from version 26 to 27") + + database.execSQL( + "UPDATE RoundTemplate SET shotsPerEnd=3, endCount=10 " + + "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE name ='Bray I')" + ) + database.execSQL( + "UPDATE RoundTemplate SET shotsPerEnd=3, endCount=10 " + + "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE name ='Bray II')" + ) + database.execSQL( + "UPDATE Round SET shotsPerEnd=3, maxEndCount=10 " + + "WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name ='Bray I')" + ) + database.execSQL( + "UPDATE Round SET shotsPerEnd=3, maxEndCount=10 " + + "WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name ='Bray II')" + ) + + + database.query("SELECT `id`, `targetId`, `targetScoringStyleIndex`, `targetDiameter` FROM `Round` WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name in ('Bray I', 'Bray II'))") + .useEach { round -> + val roundId = round.getLong(0) + val diameter = Dimension.parse(round.getString(3)) + val target = Target(round.getLong(1), round.getInt(2), diameter) + + var index = 0 + val ends = mutableListOf() + database.query("SELECT * FROM `End` WHERE `roundId` = $roundId") + .useEach { end -> + val end = End( + id = end.getLong(0), + index = end.getInt(1), + roundId = end.getLong(2), + exact = end.getInt(3) == 1, + saveTime = LocalTime.parse(end.getString(4)), + comment = end.getString(5) + ) + + val cursor = database.query("SELECT `fileName` FROM `EndImage` WHERE `endId` = ${end.id}") + var fileName: String? = null + if (cursor.moveToFirst()) { + fileName = cursor.getString(0) + } + + ends.add(end.id) + + addEnd(database, target, end, fileName, index++) + addEnd(database, target, end, fileName, index++) + + deleteEndImage(database, end.id) // trigger? + deleteShots(database, end.id) + } + + deleteEnds(database, ends.joinToString()) + } + } + + fun addEnd(database: SupportSQLiteDatabase, target: Target, end: End, fileName: String?, index: Int) { + val shots = mutableListOf() + database.query("SELECT `id`, `index`, `scoringRing` FROM Shot WHERE endId = ${end.id} LIMIT 3") + .useEach { shotCursor -> + shots.add( + Shot( + id = shotCursor.getLong(0), + index = shotCursor.getInt(1), + scoringRing = shotCursor.getInt(2) + ) + ) + } + + val score = target.getReachedScore(shots) + + val endId = insertEnd(database, end, score, index) + if (fileName != null) { + insertEndImage(database, fileName, endId) + } + + var shotIndex = 0; + shots.forEach { + database.execSQL("UPDATE Shot SET endId = ?, `index` = ? WHERE id = ?", arrayOf(endId, shotIndex++, it.id)) + } + } + + + private fun insertEnd(database: SupportSQLiteDatabase, item: End, score: Score, index: Int): Long { + val values = ContentValues() + values.put("`index`", index) + values.put("roundId", item.roundId) + values.put("exact", if (item.exact) 1 else 0) + values.put("saveTime", item.saveTime?.format(DateTimeFormatter.ISO_LOCAL_TIME)) + values.put("comment", item.comment) + values.put("reachedPoints", score.reachedPoints) + values.put("totalPoints", score.totalPoints) + values.put("shotCount", score.shotCount) + return database.insert("END", SQLiteDatabase.CONFLICT_NONE, values) + } + + private fun insertEndImage(database: SupportSQLiteDatabase, fileName: String, endId: Long): Long { + val values = ContentValues() + values.put("fileName", fileName) + values.put("endId", endId) + return database.insert("ENDIMAGE", SQLiteDatabase.CONFLICT_NONE, values) + } + + private fun deleteEndImage(database: SupportSQLiteDatabase, endId: Long) { + database.delete("ENDIMAGE", "endId = ?", arrayOf(endId)) + } + + private fun deleteShots(database: SupportSQLiteDatabase, endId: Long) { + database.delete("SHOT", "endId = ?", arrayOf(endId)) + } + + private fun deleteEnds(database: SupportSQLiteDatabase, ids: String) { + database.execSQL("delete from end where id in (" + ids + ")") + } +} \ No newline at end of file From b7981623244a0bbe1ca6b11b9af87360469322a9 Mon Sep 17 00:00:00 2001 From: jamshid Date: Tue, 10 Sep 2019 16:57:00 +0430 Subject: [PATCH 2/2] uppercase SQL commands multiple EndImages for an End --- .../de/dreier/mytargets/app/MigrationTest.kt | 78 ++++++++++++++++--- .../base/db/migrations/Migration27.kt | 63 ++++++++------- 2 files changed, 100 insertions(+), 41 deletions(-) diff --git a/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt b/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt index 6d603d229..7c3318482 100644 --- a/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt +++ b/app/src/androidTest/java/de/dreier/mytargets/app/MigrationTest.kt @@ -312,9 +312,17 @@ class MigrationTest : InstrumentedTestBase() { private fun insertTrainingDataForVersion26(db: SupportSQLiteDatabase) { - db.execSQL("INSERT INTO `Training` (id,title,date,standardRoundId,bowId,arrowId,arrowNumbering,comment,archerSignatureId,witnessSignatureId,indoor,weather,windSpeed,windDirection,location,reachedPoints,totalPoints,shotCount) VALUES (1,'Training','2019-08-27',11,NULL,NULL,0,'',NULL,NULL,0,0,0,0,'',178,300,30);") + db.execSQL("INSERT INTO `RoundTemplate` (id,standardRoundId,`index`,shotsPerEnd,endCount,distance,targetId,targetScoringStyleIndex,targetDiameter) VALUES (13,11,0,6,5,'20.0 yd',0,0,'40.0 cm');") db.execSQL("INSERT INTO `StandardRound` (id,club,name) VALUES (11,4,'Bray I');") - db.execSQL("INSERT INTO `StandardRound` (id,club,name) VALUES (12,4,'Bray II');") + db.execSQL("INSERT INTO `Training` (id,title,date,standardRoundId,bowId,arrowId,arrowNumbering,comment,archerSignatureId,witnessSignatureId,indoor,weather,windSpeed,windDirection,location,reachedPoints,totalPoints,shotCount) VALUES (1,'Training','2019-08-27',11,NULL,NULL,0,'',NULL,NULL,0,0,0,0,'',178,300,30);") + db.execSQL("INSERT INTO `Round` (id,trainingId,`index`,shotsPerEnd,maxEndCount,distance,comment,targetId,targetScoringStyleIndex,targetDiameter,reachedPoints,totalPoints,shotCount) VALUES (1,1,0,6,5,'20.0 yd','',0,0,'40.0 cm',178,300,30);") + + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (1,0,1,1,'21:05:52.528','test',54,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (2,1,1,1,'21:06:02.347','',45,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (3,2,1,1,'21:06:08.17','',18,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (4,3,1,1,'21:06:15.663','',1,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (5,4,1,1,'21:06:25.499','',60,60,6);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (1,0,1,0.0909451246261597,0.140448212623596,2,NULL);") db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (2,1,1,0.158708214759827,-0.0522582530975342,2,NULL);") db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (3,2,1,-0.130176305770874,0.0333890914916992,2,NULL);") @@ -346,16 +354,48 @@ class MigrationTest : InstrumentedTestBase() { db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (29,4,5,0.0124826431274414,-0.0389565229415894,0,NULL);") db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (30,5,5,0.0392313003540039,0.00840866565704346,0,NULL);") - db.execSQL("INSERT INTO `RoundTemplate` (id,standardRoundId,`index`,shotsPerEnd,endCount,distance,targetId,targetScoringStyleIndex,targetDiameter) VALUES (13,11,0,6,5,'20.0 yd',0,0,'40.0 cm');") + db.execSQL("INSERT INTO `RoundTemplate` (id,standardRoundId,`index`,shotsPerEnd,endCount,distance,targetId,targetScoringStyleIndex,targetDiameter) VALUES (14,12,0,6,5,'25.0 yd',0,0,'60.0 cm');") + db.execSQL("INSERT INTO `StandardRound` (id,club,name) VALUES (12,4,'Bray II');") + db.execSQL("INSERT INTO `Training` (id,title,date,standardRoundId,bowId,arrowId,arrowNumbering,comment,archerSignatureId,witnessSignatureId,indoor,weather,windSpeed,windDirection,location,reachedPoints,totalPoints,shotCount) VALUES (2,'Training','2019-08-27',12,NULL,NULL,0,'',NULL,NULL,0,0,0,0,'',178,300,30);") + db.execSQL("INSERT INTO `Round` (id,trainingId,`index`,shotsPerEnd,maxEndCount,distance,comment,targetId,targetScoringStyleIndex,targetDiameter,reachedPoints,totalPoints,shotCount) VALUES (2,2,0,6,5,'20.0 yd','',0,0,'40.0 cm',178,300,30);") - db.execSQL("INSERT INTO `Round` (id,trainingId,`index`,shotsPerEnd,maxEndCount,distance,comment,targetId,targetScoringStyleIndex,targetDiameter,reachedPoints,totalPoints,shotCount) VALUES (1,1,0,6,5,'20.0 yd','',0,0,'40.0 cm',178,300,30);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (6,0,2,1,'21:05:52.528','test',54,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (7,1,2,1,'21:06:02.347','',45,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (8,2,2,1,'21:06:08.17','',18,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (9,3,2,1,'21:06:15.663','',1,60,6);") + db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (10,4,2,1,'21:06:25.499','',60,60,6);") - db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (1,0,1,1,'21:05:52.528','',54,60,6);") - db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (2,1,1,1,'21:06:02.347','',45,60,6);") - db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (3,2,1,1,'21:06:08.17','',18,60,6);") - db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (4,3,1,1,'21:06:15.663','',1,60,6);") - db.execSQL("INSERT INTO `End` (id,`index`,roundId,exact,saveTime,comment,reachedPoints,totalPoints,shotCount) VALUES (5,4,1,1,'21:06:25.499','',60,60,6);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (31,0,6,0.0909451246261597,0.140448212623596,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (32,1,6,0.158708214759827,-0.0522582530975342,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (33,2,6,-0.130176305770874,0.0333890914916992,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (34,3,6,-0.00534975528717041,-0.170023441314697,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (35,4,6,0.155141711235046,0.0512322187423706,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (36,5,6,-0.0802456140518188,0.176134705543518,2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (37,0,7,0.169407725334167,0.21182119846344,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (38,1,7,-0.0445809364318848,0.254644751548767,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (39,2,7,-0.287101149559021,0.101193308830261,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (40,3,7,-0.172973990440369,-0.155748844146729,3,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (41,4,7,0.183673501014709,-0.380573153495789,5,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (42,5,7,0.408361554145813,-0.0593955516815186,-2,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (43,0,8,0.536754488945007,0.354566693305969,7,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (44,1,8,0.394095540046692,0.536567568778992,7,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (45,2,8,-0.226471185684204,0.679313063621521,8,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (46,3,8,-0.825638949871063,-0.14147424697876,9,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (47,4,8,-0.415494322776794,-0.605397462844849,8,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (48,5,8,0.793540835380554,-0.209278464317322,9,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (49,0,9,0.668714046478271,0.918412089347839,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (50,1,9,0.597384691238403,0.886294007301331,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (51,2,9,0.725777745246887,0.750685811042786,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (52,3,9,0.839905142784119,-0.887320160865784,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (53,4,9,0.458292126655579,-1.00508534908295,-1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (54,5,9,0.0445809364318848,-0.915869355201721,10,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (55,0,10,-0.0338814258575439,-0.0843760967254639,1,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (56,1,10,-0.0267485380172729,-0.00943446159362793,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (57,2,10,-0.00178313255310059,0.0101931095123291,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (58,3,10,-0.0160490274429321,-0.0377378463745117,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (59,4,10,0.0124826431274414,-0.0389565229415894,0,NULL);") + db.execSQL("INSERT INTO `Shot` (id,`index`,endId,x,y,scoringRing,arrowNumber) VALUES (60,5,10,0.0392313003540039,0.00840866565704346,0,NULL);") } @Test @@ -363,7 +403,7 @@ class MigrationTest : InstrumentedTestBase() { val db = testHelper.createDatabase(TEST_DB_NAME, 26) insertTrainingDataForVersion26(db) - val count = db.query("select * from StandardRound").count + val count = db.query("SELECT * FROM StandardRound").count assertThat(count).isEqualTo(2) db.close() @@ -375,8 +415,22 @@ class MigrationTest : InstrumentedTestBase() { ) val migratedDb = getMigratedRoomDatabase() - val ends = migratedDb.endDAO().loadEnds(1) + + var ends = migratedDb.endDAO().loadEnds(1) + assertThat(ends.size).isEqualTo(10) + assertThat(ends.get(9).index).isEqualTo(9) + assertThat(ends.get(1).comment).isEqualTo("test") + + var shots = migratedDb.endDAO().loadShots(20) + assertThat(shots.size).isEqualTo(3) + assertThat(shots.get(1).x).isEqualTo(0.0124826431274414.toFloat()) + assertThat(shots.get(1).index).isEqualTo(1) + + ends = migratedDb.endDAO().loadEnds(2) assertThat(ends.size).isEqualTo(10) - assertThat(migratedDb.endDAO().loadShots(15).get(1).x).isEqualTo(0.0124826431274414.toFloat()) + + shots = migratedDb.endDAO().loadShots(22) + assertThat(shots.size).isEqualTo(3) + assertThat(shots.get(2).y).isEqualTo(0.176134705543518.toFloat()) } } diff --git a/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt b/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt index 4ad07473f..185bd8d0a 100644 --- a/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt +++ b/app/src/main/java/de/dreier/mytargets/base/db/migrations/Migration27.kt @@ -34,23 +34,27 @@ object Migration27 : Migration(26, 27) { database.execSQL( "UPDATE RoundTemplate SET shotsPerEnd=3, endCount=10 " + - "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE name ='Bray I')" + "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE id = 11)" // Bray I ) database.execSQL( "UPDATE RoundTemplate SET shotsPerEnd=3, endCount=10 " + - "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE name ='Bray II')" + "WHERE standardRoundId IN (SELECT id FROM StandardRound WHERE id = 12)" // Bray II ) database.execSQL( "UPDATE Round SET shotsPerEnd=3, maxEndCount=10 " + - "WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name ='Bray I')" + "WHERE trainingId IN (SELECT t.id FROM Training AS t JOIN StandardRound AS s WHERE s.id = 11)" // Bray I ) database.execSQL( "UPDATE Round SET shotsPerEnd=3, maxEndCount=10 " + - "WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name ='Bray II')" + "WHERE trainingId IN (SELECT t.id FROM Training AS t JOIN StandardRound AS s WHERE s.id = 12)" // Bray II ) + migrate(database, 11) // Bray I + migrate(database, 12) // Bray II + } - database.query("SELECT `id`, `targetId`, `targetScoringStyleIndex`, `targetDiameter` FROM `Round` WHERE trainingId IN (SELECT t.id FROM Training as t JOIN StandardRound as s WHERE s.name in ('Bray I', 'Bray II'))") + fun migrate(database: SupportSQLiteDatabase, standardRoundId: Int) { + database.query("SELECT r.id, `targetId`, `targetScoringStyleIndex`, `targetDiameter` FROM `Round` AS r JOIN `Training` AS t ON r.trainingId = t.id WHERE t.standardRoundId = ${standardRoundId}") .useEach { round -> val roundId = round.getLong(0) val diameter = Dimension.parse(round.getString(3)) @@ -58,9 +62,9 @@ object Migration27 : Migration(26, 27) { var index = 0 val ends = mutableListOf() - database.query("SELECT * FROM `End` WHERE `roundId` = $roundId") + database.query("SELECT `id`, `index`, `roundId`, `exact`, `saveTime`, `comment` FROM `End` WHERE `roundId` = $roundId") .useEach { end -> - val end = End( + val mEnd = End( id = end.getLong(0), index = end.getInt(1), roundId = end.getLong(2), @@ -69,28 +73,28 @@ object Migration27 : Migration(26, 27) { comment = end.getString(5) ) - val cursor = database.query("SELECT `fileName` FROM `EndImage` WHERE `endId` = ${end.id}") - var fileName: String? = null - if (cursor.moveToFirst()) { - fileName = cursor.getString(0) - } + val files = mutableListOf() + database.query("SELECT `fileName` FROM `EndImage` WHERE `endId` = ${mEnd.id}") + .useEach { image -> + files.add(image.getString(0)) + } - ends.add(end.id) + ends.add(mEnd.id) - addEnd(database, target, end, fileName, index++) - addEnd(database, target, end, fileName, index++) + addEnd(database, target, mEnd, files, index++) + addEnd(database, target, mEnd, files, index++) - deleteEndImage(database, end.id) // trigger? - deleteShots(database, end.id) + deleteEndImage(database, mEnd.id) + deleteShots(database, mEnd.id) } deleteEnds(database, ends.joinToString()) } } - fun addEnd(database: SupportSQLiteDatabase, target: Target, end: End, fileName: String?, index: Int) { + fun addEnd(database: SupportSQLiteDatabase, target: Target, end: End, files: List, index: Int) { val shots = mutableListOf() - database.query("SELECT `id`, `index`, `scoringRing` FROM Shot WHERE endId = ${end.id} LIMIT 3") + database.query("SELECT `id`, `index`, `scoringRing` FROM `Shot` WHERE `endId` = ${end.id} ORDER BY `id` LIMIT 3") .useEach { shotCursor -> shots.add( Shot( @@ -104,17 +108,18 @@ object Migration27 : Migration(26, 27) { val score = target.getReachedScore(shots) val endId = insertEnd(database, end, score, index) - if (fileName != null) { + + files.forEach { fileName -> insertEndImage(database, fileName, endId) } - var shotIndex = 0; - shots.forEach { - database.execSQL("UPDATE Shot SET endId = ?, `index` = ? WHERE id = ?", arrayOf(endId, shotIndex++, it.id)) + var shotIndex = 0 + shots.forEach { shot -> + database.execSQL("UPDATE `Shot` SET `endId` = $endId, `index` = $shotIndex WHERE `id` = ${shot.id}") + shotIndex++ } } - private fun insertEnd(database: SupportSQLiteDatabase, item: End, score: Score, index: Int): Long { val values = ContentValues() values.put("`index`", index) @@ -125,25 +130,25 @@ object Migration27 : Migration(26, 27) { values.put("reachedPoints", score.reachedPoints) values.put("totalPoints", score.totalPoints) values.put("shotCount", score.shotCount) - return database.insert("END", SQLiteDatabase.CONFLICT_NONE, values) + return database.insert("End", SQLiteDatabase.CONFLICT_NONE, values) } private fun insertEndImage(database: SupportSQLiteDatabase, fileName: String, endId: Long): Long { val values = ContentValues() values.put("fileName", fileName) values.put("endId", endId) - return database.insert("ENDIMAGE", SQLiteDatabase.CONFLICT_NONE, values) + return database.insert("EndImage", SQLiteDatabase.CONFLICT_NONE, values) } private fun deleteEndImage(database: SupportSQLiteDatabase, endId: Long) { - database.delete("ENDIMAGE", "endId = ?", arrayOf(endId)) + database.delete("EndImage", "endId = ?", arrayOf(endId)) } private fun deleteShots(database: SupportSQLiteDatabase, endId: Long) { - database.delete("SHOT", "endId = ?", arrayOf(endId)) + database.delete("Shot", "endId = ?", arrayOf(endId)) } private fun deleteEnds(database: SupportSQLiteDatabase, ids: String) { - database.execSQL("delete from end where id in (" + ids + ")") + database.execSQL("DELETE FROM `End` WHERE `id` IN ($ids)") } } \ No newline at end of file