diff --git a/readropsdb/build.gradle b/readropsdb/build.gradle index 6e95a8ef..ad797caa 100644 --- a/readropsdb/build.gradle +++ b/readropsdb/build.gradle @@ -24,6 +24,10 @@ android { consumerProguardFiles 'consumer-rules.pro' } + sourceSets { + androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) + } + buildTypes { release { minifyEnabled true @@ -46,13 +50,16 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.appcompat:appcompat:1.1.0' + testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test:runner:1.2.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' - api 'androidx.room:room-runtime:2.2.4' - kapt 'androidx.room:room-compiler:2.2.4' - implementation 'androidx.room:room-rxjava2:2.2.4' + api 'androidx.room:room-runtime:2.2.5' + kapt 'androidx.room:room-compiler:2.2.5' + implementation 'androidx.room:room-rxjava2:2.2.5' + androidTestImplementation "androidx.room:room-testing:2.2.5" api 'androidx.paging:paging-runtime:2.1.1' api 'androidx.paging:paging-common:2.1.1' diff --git a/readropsdb/schemas/com.readrops.readropsdb.Database/1.json b/readropsdb/schemas/com.readrops.readropsdb.Database/1.json new file mode 100644 index 00000000..eb20faa6 --- /dev/null +++ b/readropsdb/schemas/com.readrops.readropsdb.Database/1.json @@ -0,0 +1,418 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "e06be6f0942ff2ab40259adf80793de2", + "entities": [ + { + "tableName": "Feed", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `description` TEXT, `url` TEXT, `siteUrl` TEXT, `lastUpdated` TEXT, `text_color` INTEGER NOT NULL, `background_color` INTEGER NOT NULL, `icon_url` TEXT, `etag` TEXT, `last_modified` TEXT, `folder_id` INTEGER, `remoteId` TEXT, `account_id` INTEGER NOT NULL, FOREIGN KEY(`folder_id`) REFERENCES `Folder`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`account_id`) REFERENCES `Account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "siteUrl", + "columnName": "siteUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdated", + "columnName": "lastUpdated", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backgroundColor", + "columnName": "background_color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "iconUrl", + "columnName": "icon_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "etag", + "columnName": "etag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastModified", + "columnName": "last_modified", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountId", + "columnName": "account_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Feed_folder_id", + "unique": false, + "columnNames": [ + "folder_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Feed_folder_id` ON `${TABLE_NAME}` (`folder_id`)" + }, + { + "name": "index_Feed_account_id", + "unique": false, + "columnNames": [ + "account_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Feed_account_id` ON `${TABLE_NAME}` (`account_id`)" + } + ], + "foreignKeys": [ + { + "table": "Folder", + "onDelete": "SET NULL", + "onUpdate": "NO ACTION", + "columns": [ + "folder_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "Account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Item", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `read_changed` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cleanDescription", + "columnName": "clean_description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "imageLink", + "columnName": "image_link", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pubDate", + "columnName": "pub_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "feedId", + "columnName": "feed_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "guid", + "columnName": "guid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "readTime", + "columnName": "read_time", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readChanged", + "columnName": "read_changed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readItLater", + "columnName": "read_it_later", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Item_feed_id", + "unique": false, + "columnNames": [ + "feed_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Item_feed_id` ON `${TABLE_NAME}` (`feed_id`)" + }, + { + "name": "index_Item_guid", + "unique": false, + "columnNames": [ + "guid" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Item_guid` ON `${TABLE_NAME}` (`guid`)" + } + ], + "foreignKeys": [ + { + "table": "Feed", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "feed_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Folder", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `remoteId` TEXT, `account_id` INTEGER NOT NULL, FOREIGN KEY(`account_id`) REFERENCES `Account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountId", + "columnName": "account_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Folder_account_id", + "unique": false, + "columnNames": [ + "account_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Folder_account_id` ON `${TABLE_NAME}` (`account_id`)" + } + ], + "foreignKeys": [ + { + "table": "Account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Account", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT, `account_name` TEXT, `displayed_name` TEXT, `account_type` INTEGER, `last_modified` INTEGER NOT NULL, `current_account` INTEGER NOT NULL, `token` TEXT, `writeToken` TEXT)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountName", + "columnName": "account_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayedName", + "columnName": "displayed_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastModified", + "columnName": "last_modified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currentAccount", + "columnName": "current_account", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "writeToken", + "columnName": "writeToken", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "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, 'e06be6f0942ff2ab40259adf80793de2')" + ] + } +} \ No newline at end of file diff --git a/readropsdb/schemas/com.readrops.readropsdb.Database/2.json b/readropsdb/schemas/com.readrops.readropsdb.Database/2.json new file mode 100644 index 00000000..ad240f05 --- /dev/null +++ b/readropsdb/schemas/com.readrops.readropsdb.Database/2.json @@ -0,0 +1,431 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "09ffedb5d59c0709ed6662d9f068c91f", + "entities": [ + { + "tableName": "Feed", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `description` TEXT, `url` TEXT, `siteUrl` TEXT, `lastUpdated` TEXT, `text_color` INTEGER NOT NULL, `background_color` INTEGER NOT NULL, `icon_url` TEXT, `etag` TEXT, `last_modified` TEXT, `folder_id` INTEGER, `remoteId` TEXT, `account_id` INTEGER NOT NULL, `notification_enabled` INTEGER NOT NULL DEFAULT 1, FOREIGN KEY(`folder_id`) REFERENCES `Folder`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`account_id`) REFERENCES `Account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "siteUrl", + "columnName": "siteUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdated", + "columnName": "lastUpdated", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "textColor", + "columnName": "text_color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "backgroundColor", + "columnName": "background_color", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "iconUrl", + "columnName": "icon_url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "etag", + "columnName": "etag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastModified", + "columnName": "last_modified", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "folderId", + "columnName": "folder_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountId", + "columnName": "account_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationEnabled", + "columnName": "notification_enabled", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Feed_folder_id", + "unique": false, + "columnNames": [ + "folder_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Feed_folder_id` ON `${TABLE_NAME}` (`folder_id`)" + }, + { + "name": "index_Feed_account_id", + "unique": false, + "columnNames": [ + "account_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Feed_account_id` ON `${TABLE_NAME}` (`account_id`)" + } + ], + "foreignKeys": [ + { + "table": "Folder", + "onDelete": "SET NULL", + "onUpdate": "NO ACTION", + "columns": [ + "folder_id" + ], + "referencedColumns": [ + "id" + ] + }, + { + "table": "Account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Item", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `description` TEXT, `clean_description` TEXT, `link` TEXT, `image_link` TEXT, `author` TEXT, `pub_date` INTEGER, `content` TEXT, `feed_id` INTEGER NOT NULL, `guid` TEXT, `read_time` REAL NOT NULL, `read` INTEGER NOT NULL, `read_changed` INTEGER NOT NULL, `read_it_later` INTEGER NOT NULL, `remoteId` TEXT, FOREIGN KEY(`feed_id`) REFERENCES `Feed`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "cleanDescription", + "columnName": "clean_description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "imageLink", + "columnName": "image_link", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pubDate", + "columnName": "pub_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "feedId", + "columnName": "feed_id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "guid", + "columnName": "guid", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "readTime", + "columnName": "read_time", + "affinity": "REAL", + "notNull": true + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readChanged", + "columnName": "read_changed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "readItLater", + "columnName": "read_it_later", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Item_feed_id", + "unique": false, + "columnNames": [ + "feed_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Item_feed_id` ON `${TABLE_NAME}` (`feed_id`)" + }, + { + "name": "index_Item_guid", + "unique": false, + "columnNames": [ + "guid" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Item_guid` ON `${TABLE_NAME}` (`guid`)" + } + ], + "foreignKeys": [ + { + "table": "Feed", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "feed_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Folder", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `remoteId` TEXT, `account_id` INTEGER NOT NULL, FOREIGN KEY(`account_id`) REFERENCES `Account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "remoteId", + "columnName": "remoteId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountId", + "columnName": "account_id", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_Folder_account_id", + "unique": false, + "columnNames": [ + "account_id" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Folder_account_id` ON `${TABLE_NAME}` (`account_id`)" + } + ], + "foreignKeys": [ + { + "table": "Account", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account_id" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "Account", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `url` TEXT, `account_name` TEXT, `displayed_name` TEXT, `account_type` INTEGER, `last_modified` INTEGER NOT NULL, `current_account` INTEGER NOT NULL, `token` TEXT, `writeToken` TEXT, `notifications_enabled` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountName", + "columnName": "account_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "displayedName", + "columnName": "displayed_name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "lastModified", + "columnName": "last_modified", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "currentAccount", + "columnName": "current_account", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "writeToken", + "columnName": "writeToken", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "notificationsEnabled", + "columnName": "notifications_enabled", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "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, '09ffedb5d59c0709ed6662d9f068c91f')" + ] + } +} \ No newline at end of file diff --git a/readropsdb/src/androidTest/java/com/readrops/readropsdb/DatabaseMigrationsTests.kt b/readropsdb/src/androidTest/java/com/readrops/readropsdb/DatabaseMigrationsTests.kt new file mode 100644 index 00000000..af720558 --- /dev/null +++ b/readropsdb/src/androidTest/java/com/readrops/readropsdb/DatabaseMigrationsTests.kt @@ -0,0 +1,33 @@ +package com.readrops.readropsdb + +import androidx.room.testing.MigrationTestHelper +import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.readrops.readropsdb.entities.Feed +import com.readrops.readropsdb.entities.account.Account +import com.readrops.readropsdb.entities.account.AccountType +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import java.io.IOException + +@RunWith(AndroidJUnit4::class) +class DatabaseMigrationsTests { + + private val testDb = "migration-test" + + @get:Rule + val helper = MigrationTestHelper( + InstrumentationRegistry.getInstrumentation(), + "com.readrops.readropsdb.Database/", + FrameworkSQLiteOpenHelperFactory() + ) + + @Test + @Throws(IOException::class) + fun migrate1To2() { + helper.createDatabase(testDb, 1).close() + helper.runMigrationsAndValidate(testDb, 2, true, Database.MIGRATION_1_2).close() + } +} \ No newline at end of file diff --git a/readropsdb/src/androidTest/java/com/readrops/readropsdb/ExampleInstrumentedTest.java b/readropsdb/src/androidTest/java/com/readrops/readropsdb/ExampleInstrumentedTest.java deleted file mode 100644 index 91a14295..00000000 --- a/readropsdb/src/androidTest/java/com/readrops/readropsdb/ExampleInstrumentedTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.readrops.readropsdb; - -import android.content.Context; - -import androidx.test.platform.app.InstrumentationRegistry; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); - - assertEquals("com.readrops.readropsdb.test", appContext.getPackageName()); - } -} diff --git a/readropsdb/src/main/java/com/readrops/readropsdb/Database.java b/readropsdb/src/main/java/com/readrops/readropsdb/Database.java index 98f3659a..30a63098 100644 --- a/readropsdb/src/main/java/com/readrops/readropsdb/Database.java +++ b/readropsdb/src/main/java/com/readrops/readropsdb/Database.java @@ -2,9 +2,12 @@ package com.readrops.readropsdb; import android.content.Context; +import androidx.annotation.NonNull; import androidx.room.Room; import androidx.room.RoomDatabase; import androidx.room.TypeConverters; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import com.readrops.readropsdb.dao.AccountDao; import com.readrops.readropsdb.dao.FeedDao; @@ -33,8 +36,18 @@ public abstract class Database extends RoomDatabase { public static Database getInstance(Context context) { if (database == null) database = Room.databaseBuilder(context, Database.class, "readrops-db") + .addMigrations(MIGRATION_1_2) .build(); return database; } + + public static final Migration MIGRATION_1_2 = new Migration(1, 2) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { + database.execSQL("Alter Table Account Add Column notifications_enabled INTEGER Not Null Default 0"); + + database.execSQL("Alter Table Feed Add Column notification_enabled INTEGER Not Null Default 1"); + } + }; } \ No newline at end of file