From d76b5dd086704238cbb59cb7b9675361e7420055 Mon Sep 17 00:00:00 2001 From: Erik Johansson Date: Mon, 14 May 2018 23:23:32 +0200 Subject: [PATCH] Rename lbw to lbm in database version 3 --- .../3.json | 8 +- .../openscale/DatabaseMigrationTest.java | 74 ++++++++++++++++++- .../openscale/core/database/AppDatabase.java | 43 ++++++++--- .../core/datatypes/ScaleMeasurement.java | 2 +- 4 files changed, 109 insertions(+), 18 deletions(-) diff --git a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/3.json b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/3.json index b238f019..603b6aa7 100644 --- a/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/3.json +++ b/android_app/app/schemas/com.health.openscale.core.database.AppDatabase/3.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 3, - "identityHash": "d64c7b69a0b7a1a0f93dd154a24b20f2", + "identityHash": "83d2f44ffc34383c4f1103f001329440", "entities": [ { "tableName": "scaleMeasurements", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userId` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `datetime` INTEGER, `weight` REAL NOT NULL, `fat` REAL NOT NULL, `water` REAL NOT NULL, `muscle` REAL NOT NULL, `visceralFat` REAL NOT NULL, `lbw` REAL NOT NULL, `waist` REAL NOT NULL, `hip` REAL NOT NULL, `bone` REAL NOT NULL, `chest` REAL NOT NULL, `thigh` REAL NOT NULL, `biceps` REAL NOT NULL, `neck` REAL NOT NULL, `caliper1` REAL NOT NULL, `caliper2` REAL NOT NULL, `caliper3` REAL NOT NULL, `comment` TEXT, FOREIGN KEY(`userId`) REFERENCES `scaleUsers`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userId` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `datetime` INTEGER, `weight` REAL NOT NULL, `fat` REAL NOT NULL, `water` REAL NOT NULL, `muscle` REAL NOT NULL, `visceralFat` REAL NOT NULL, `lbm` REAL NOT NULL, `waist` REAL NOT NULL, `hip` REAL NOT NULL, `bone` REAL NOT NULL, `chest` REAL NOT NULL, `thigh` REAL NOT NULL, `biceps` REAL NOT NULL, `neck` REAL NOT NULL, `caliper1` REAL NOT NULL, `caliper2` REAL NOT NULL, `caliper3` REAL NOT NULL, `comment` TEXT, FOREIGN KEY(`userId`) REFERENCES `scaleUsers`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", "fields": [ { "fieldPath": "id", @@ -64,7 +64,7 @@ }, { "fieldPath": "lbm", - "columnName": "lbw", + "columnName": "lbm", "affinity": "REAL", "notNull": true }, @@ -237,7 +237,7 @@ ], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"d64c7b69a0b7a1a0f93dd154a24b20f2\")" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"83d2f44ffc34383c4f1103f001329440\")" ] } } \ No newline at end of file diff --git a/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java index 001de449..63cfc655 100644 --- a/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java +++ b/android_app/app/src/androidTest/java/com/health/openscale/DatabaseMigrationTest.java @@ -72,7 +72,7 @@ public class DatabaseMigrationTest { measurement.put("enabled", j); measurement.put("comment", "a string"); for (String type : new String[]{"weight", "fat", "water", "muscle", "lbw", "waist", "hip", "bone"}) { - measurement.put(type, i * j); + measurement.put(type, i * j + type.hashCode()); } assertNotSame(-1, db.insert("scaleMeasurements", SQLiteDatabase.CONFLICT_ABORT, measurement)); @@ -97,7 +97,77 @@ public class DatabaseMigrationTest { assertEquals(j, cursor.getInt(cursor.getColumnIndex("enabled"))); assertEquals("a string", cursor.getString(cursor.getColumnIndex("comment"))); for (String type : new String[]{"weight", "fat", "water", "muscle", "lbw", "waist", "hip", "bone"}) { - assertEquals((float) i * j, cursor.getFloat(cursor.getColumnIndex(type))); + assertEquals((float) i * j + type.hashCode(), + cursor.getFloat(cursor.getColumnIndex(type))); + } + + cursor.moveToNext(); + } + } + + assertTrue(cursor.isAfterLast()); + } + + @Test + public void migrate2To3() throws Exception { + SupportSQLiteDatabase db = helper.createDatabase(TEST_DB, 2); + + ContentValues users = new ContentValues(); + for (int i = 1; i < 4; ++i) { + users.put("id", i); + users.put("username", String.format("test%d", i)); + users.put("bodyHeight", i * 50); + users.put("scaleUnit", 0); + users.put("gender", 0); + users.put("initialWeight", i * 25); + users.put("goalWeight", i * 20); + assertNotSame(-1, db.insert("scaleUsers", SQLiteDatabase.CONFLICT_ABORT, users)); + } + + ContentValues measurement = new ContentValues(); + for (int i = 2; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + measurement.put("userId", i); + measurement.put("enabled", j); + measurement.put("comment", "a string"); + for (String type : new String[]{"weight", "fat", "water", "muscle", "lbw", "waist", "hip", "bone"}) { + measurement.put(type, i * j + type.hashCode()); + } + + assertNotSame(-1, db.insert("scaleMeasurements", SQLiteDatabase.CONFLICT_ABORT, measurement)); + } + } + + // Prepare for the next version. + db.close(); + + // Re-open the database with version 3 and provide MIGRATION_2_3 as the migration process. + db = helper.runMigrationsAndValidate(TEST_DB, 3, true, AppDatabase.MIGRATION_2_3); + + // MigrationTestHelper automatically verifies the schema changes. + + Cursor cursor = db.query("SELECT * FROM scaleMeasurements ORDER BY id, userId"); + assertEquals(2 * 2, cursor.getCount()); + + cursor.moveToFirst(); + for (int i = 2; i < 4; ++i) { + for (int j = 0; j < 2; ++j) { + assertEquals(i, cursor.getInt(cursor.getColumnIndex("userId"))); + assertEquals(j, cursor.getInt(cursor.getColumnIndex("enabled"))); + assertEquals("a string", cursor.getString(cursor.getColumnIndex("comment"))); + for (String type : new String[]{"weight", "fat", "water", "muscle", "lbm", "waist", "hip", "bone"}) { + float value = i * j; + if (type.equals("lbm")) { + value += "lbw".hashCode(); + } + else { + value += type.hashCode(); + } + assertEquals(value, cursor.getFloat(cursor.getColumnIndex(type))); + } + for (String type : new String[]{"visceralFat", "chest", "thigh", "biceps", "neck", + "caliper1", "caliper2", "caliper3"}) { + assertEquals(0.0f, cursor.getFloat(cursor.getColumnIndex(type))); } cursor.moveToNext(); diff --git a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java index 814dfc90..873feb4a 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java +++ b/android_app/app/src/main/java/com/health/openscale/core/database/AppDatabase.java @@ -32,9 +32,6 @@ public abstract class AppDatabase extends RoomDatabase { public abstract ScaleMeasurementDAO measurementDAO(); public abstract ScaleUserDAO userDAO(); - // For the next database version: - // - rename lbw column to lbm - public static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { @@ -81,14 +78,38 @@ public abstract class AppDatabase extends RoomDatabase { public void migrate(SupportSQLiteDatabase database) { database.beginTransaction(); try { - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN visceralFat REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN chest REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN thigh REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN biceps REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN neck REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN caliper1 REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN caliper2 REAL NOT NULL DEFAULT 0"); - database.execSQL("ALTER TABLE scaleMeasurements ADD COLUMN caliper3 REAL NOT NULL DEFAULT 0"); + // Drop old index + database.execSQL("DROP INDEX index_scaleMeasurements_userId_datetime"); + + // Rename old table + database.execSQL("ALTER TABLE scaleMeasurements RENAME TO scaleMeasurementsOld"); + + // Create new table with foreign key + database.execSQL("CREATE TABLE scaleMeasurements" + + " (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + + " userId INTEGER NOT NULL, enabled INTEGER NOT NULL," + + " datetime INTEGER, weight REAL NOT NULL, fat REAL NOT NULL," + + " water REAL NOT NULL, muscle REAL NOT NULL, visceralFat REAL NOT NULL," + + " lbm REAL NOT NULL, waist REAL NOT NULL, hip REAL NOT NULL," + + " bone REAL NOT NULL, chest REAL NOT NULL, thigh REAL NOT NULL," + + " biceps REAL NOT NULL, neck REAL NOT NULL, caliper1 REAL NOT NULL," + + " caliper2 REAL NOT NULL, caliper3 REAL NOT NULL, comment TEXT," + + " FOREIGN KEY(userId) REFERENCES scaleUsers(id)" + + " ON UPDATE NO ACTION ON DELETE CASCADE)"); + + // Create new index on datetime + userId + database.execSQL("CREATE UNIQUE INDEX index_scaleMeasurements_userId_datetime" + + " ON scaleMeasurements (userId, datetime)"); + + // Copy data from the old table + database.execSQL("INSERT INTO scaleMeasurements" + + " SELECT id, userId, enabled, datetime, weight, fat, water, muscle," + + " 0 AS visceralFat, lbw AS lbm, waist, hip, bone, 0 AS chest," + + " 0 as thigh, 0 as biceps, 0 as neck, 0 as caliper1," + + " 0 as caliper2, 0 as caliper3, comment FROM scaleMeasurementsOld"); + + // Delete old table + database.execSQL("DROP TABLE scaleMeasurementsOld"); database.setTransactionSuccessful(); } diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java index b3622818..e9ff843a 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleMeasurement.java @@ -65,7 +65,7 @@ public class ScaleMeasurement implements Cloneable { @ColumnInfo(name = "visceralFat") private float visceralFat; @CsvColumn(mustBeSupplied = false) - @ColumnInfo(name = "lbw") + @ColumnInfo(name = "lbm") private float lbm; @CsvColumn(mustBeSupplied = false) @ColumnInfo(name = "waist")