diff options
author | Álvaro Brey <alvaro.brey@nextcloud.com> | 2022-11-04 15:37:04 +0300 |
---|---|---|
committer | Álvaro Brey <alvaro.brey@nextcloud.com> | 2022-11-11 01:24:50 +0300 |
commit | 365694f3745e155a577f1784db46762564083e37 (patch) | |
tree | 3a7778164c8b83796fa583aef06f41eb8ffb8e60 | |
parent | fe8fa3455eab96ac2fe0c787d1e71d57db464af7 (diff) |
Clean up creation, injection and migrations for room database
Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
-rw-r--r-- | app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt | 48 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt | 105 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigration.kt | 61 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigrationHelper.java (renamed from app/src/main/java/com/nextcloud/client/database/LegacyMigrationHelper.java) | 13 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/database/migrations/RoomMigration.kt | 102 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/di/AppComponent.java | 4 | ||||
-rw-r--r-- | app/src/main/java/com/nextcloud/client/di/AppModule.java | 11 |
7 files changed, 220 insertions, 124 deletions
diff --git a/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt b/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt new file mode 100644 index 0000000000..8a24049f7f --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/DatabaseModule.kt @@ -0,0 +1,48 @@ +/* + * Nextcloud Android client application + * + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This program 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package com.nextcloud.client.database + +import android.content.Context +import androidx.room.Room +import com.nextcloud.client.core.Clock +import com.nextcloud.client.database.migrations.RoomMigration +import com.nextcloud.client.database.migrations.addLegacyMigrations +import com.owncloud.android.db.ProviderMeta +import dagger.Module +import dagger.Provides +import javax.inject.Singleton + +@Module +class DatabaseModule { + + @Provides + @Singleton + @Suppress("Detekt.SpreadOperator") // forced by Room API + fun database(context: Context, clock: Clock): NextcloudDatabase { + return Room + .databaseBuilder(context, NextcloudDatabase::class.java, ProviderMeta.DB_NAME) + .addLegacyMigrations(context, clock) + .addMigrations(RoomMigration()) + .build() + } +} diff --git a/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt index d1c4e8d61c..7069aabe3b 100644 --- a/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt +++ b/app/src/main/java/com/nextcloud/client/database/NextcloudDatabase.kt @@ -22,12 +22,8 @@ package com.nextcloud.client.database -import android.content.Context import androidx.room.Database import androidx.room.RoomDatabase -import androidx.room.migration.Migration -import androidx.sqlite.db.SupportSQLiteDatabase -import com.nextcloud.client.core.Clock import com.nextcloud.client.database.entity.ArbitraryDataEntity import com.nextcloud.client.database.entity.CapabilityEntity import com.nextcloud.client.database.entity.ExternalLinkEntity @@ -54,106 +50,9 @@ import com.owncloud.android.db.ProviderMeta version = ProviderMeta.DB_VERSION, exportSchema = true ) +@Suppress("Detekt.UnnecessaryAbstractClass") // needed by Room abstract class NextcloudDatabase : RoomDatabase() { - - // migrations from before Room was introduced - private class LegacyMigration( - private val from: Int, - private val to: Int, - private val context: Context, - private val clock: Clock - ) : - Migration(from, to) { - override fun migrate(database: SupportSQLiteDatabase) { - LegacyMigrationHelper(context, clock) - .onUpgrade(database, from, to) - } - } - companion object { - private const val FIRST_ROOM_DB_VERSION = 65 - - @JvmField - val roomMigration = object : Migration(FIRST_ROOM_DB_VERSION - 1, FIRST_ROOM_DB_VERSION) { - override fun migrate(database: SupportSQLiteDatabase) { - // migrate LONG, STRING to INTEGER, TEXT - migrateFilesystemTable(database) - migrateUploadsTable(database) - } - - private fun migrateFilesystemTable(database: SupportSQLiteDatabase) { - val table = "filesystem" - val newTable = "${table}_new" - // create table with fixed types - database.execSQL( - "CREATE TABLE $newTable (" + - "_id INTEGER PRIMARY KEY," + - "local_path TEXT," + - "is_folder INTEGER," + - "found_at INTEGER," + - "upload_triggered INTEGER," + - "syncedfolder_id TEXT," + - "crc32 TEXT," + - "modified_at INTEGER " + - ")" - ) - // copy data - val columns = - "_id, local_path, is_folder, found_at, upload_triggered, syncedfolder_id, crc32, modified_at" - database.execSQL( - "INSERT INTO $newTable ($columns) " + - "SELECT $columns FROM $table" - ) - // replace table - database.execSQL("DROP TABLE $table") - database.execSQL("ALTER TABLE $newTable RENAME TO $table") - } - - private fun migrateUploadsTable(database: SupportSQLiteDatabase) { - val table = "list_of_uploads" - val newTable = "${table}_new" - // create table with fixed types - database.execSQL( - "CREATE TABLE $newTable (" + - "_id INTEGER PRIMARY KEY," + - "local_path TEXT, " + - "remote_path TEXT, " + - "account_name TEXT, " + - "file_size INTEGER, " + - "status INTEGER, " + - "local_behaviour INTEGER, " + - "upload_time INTEGER, " + - "name_collision_policy INTEGER, " + - "is_create_remote_folder INTEGER, " + - "upload_end_timestamp INTEGER, " + - "last_result INTEGER, " + - "is_while_charging_only INTEGER, " + - "is_wifi_only INTEGER, " + - "created_by INTEGER, " + - "folder_unlock_token TEXT " + - ")" - ) - - // copy data - val columns = - "_id, local_path, remote_path, account_name, file_size, status, local_behaviour, upload_time," + - " name_collision_policy, is_create_remote_folder, upload_end_timestamp, last_result," + - " is_while_charging_only, is_wifi_only, created_by, folder_unlock_token" - database.execSQL( - "INSERT INTO $newTable ($columns) " + - "SELECT $columns FROM $table" - ) - // replace table - database.execSQL("DROP TABLE $table") - database.execSQL("ALTER TABLE $newTable RENAME TO $table") - } - } - - @JvmStatic - fun getLegacyMigrations(context: Context, clock: Clock): Array<Migration> { - // no way to get old and new version inside the migration so we need to replicate it for every version bump - return (1 until FIRST_ROOM_DB_VERSION - 1) - .map { from -> LegacyMigration(from, from + 1, context, clock) }.toTypedArray() - } + const val FIRST_ROOM_DB_VERSION = 65 } } diff --git a/app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigration.kt b/app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigration.kt new file mode 100644 index 0000000000..a5491f097c --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigration.kt @@ -0,0 +1,61 @@ +/* + * Nextcloud Android client application + * + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This program 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package com.nextcloud.client.database.migrations + +import android.content.Context +import androidx.room.RoomDatabase +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import com.nextcloud.client.core.Clock +import com.nextcloud.client.database.NextcloudDatabase + +/** + * Migrations for DB versions before Room was introduced + */ +class LegacyMigration( + private val from: Int, + private val to: Int, + private val context: Context, + private val clock: Clock +) : Migration(from, to) { + + override fun migrate(database: SupportSQLiteDatabase) { + LegacyMigrationHelper(context, clock) + .onUpgrade(database, from, to) + } +} + +/** + * Adds a legacy migration for all versions before Room was introduced + * + * This is needed because the [Migration] does not know which versions it's dealing with + */ +fun RoomDatabase.Builder<NextcloudDatabase>.addLegacyMigrations( + context: Context, + clock: Clock +): RoomDatabase.Builder<NextcloudDatabase> { + (1 until NextcloudDatabase.FIRST_ROOM_DB_VERSION - 1) + .map { from -> LegacyMigration(from, from + 1, context, clock) } + .forEach { migration -> this.addMigrations(migration) } + return this +} diff --git a/app/src/main/java/com/nextcloud/client/database/LegacyMigrationHelper.java b/app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigrationHelper.java index 557220dd41..f0872630b2 100644 --- a/app/src/main/java/com/nextcloud/client/database/LegacyMigrationHelper.java +++ b/app/src/main/java/com/nextcloud/client/database/migrations/LegacyMigrationHelper.java @@ -1,14 +1,9 @@ /* * Nextcloud Android client application * - * @author Bartek Przybylski - * @author David A. Velasco - * @author masensio - * @author Álvaro Brey Vilas - * Copyright (C) 2011 Bartek Przybylski - * Copyright (C) 2016 ownCloud Inc. - * Copyright (C) 2022 Álvaro Brey Vilas - * Copyright (C) 2022 Nextcloud GmbH + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -25,7 +20,7 @@ * */ -package com.nextcloud.client.database; +package com.nextcloud.client.database.migrations; import android.accounts.Account; import android.accounts.AccountManager; diff --git a/app/src/main/java/com/nextcloud/client/database/migrations/RoomMigration.kt b/app/src/main/java/com/nextcloud/client/database/migrations/RoomMigration.kt new file mode 100644 index 0000000000..d7da9af63d --- /dev/null +++ b/app/src/main/java/com/nextcloud/client/database/migrations/RoomMigration.kt @@ -0,0 +1,102 @@ +/* + * Nextcloud Android client application + * + * @author Álvaro Brey + * Copyright (C) 2022 Álvaro Brey + * Copyright (C) 2022 Nextcloud GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This program 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 AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +package com.nextcloud.client.database.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase +import com.nextcloud.client.database.NextcloudDatabase + +class RoomMigration : Migration(NextcloudDatabase.FIRST_ROOM_DB_VERSION - 1, NextcloudDatabase.FIRST_ROOM_DB_VERSION) { + override fun migrate(database: SupportSQLiteDatabase) { + // migrate LONG, STRING to INTEGER, TEXT + migrateFilesystemTable(database) + migrateUploadsTable(database) + } + + private fun migrateFilesystemTable(database: SupportSQLiteDatabase) { + val table = "filesystem" + val newTable = "${table}_new" + // create table with fixed types + database.execSQL( + "CREATE TABLE $newTable (" + + "_id INTEGER PRIMARY KEY," + + "local_path TEXT," + + "is_folder INTEGER," + + "found_at INTEGER," + + "upload_triggered INTEGER," + + "syncedfolder_id TEXT," + + "crc32 TEXT," + + "modified_at INTEGER " + + ")" + ) + // copy data + val columns = + "_id, local_path, is_folder, found_at, upload_triggered, syncedfolder_id, crc32, modified_at" + database.execSQL( + "INSERT INTO $newTable ($columns) " + + "SELECT $columns FROM $table" + ) + // replace table + database.execSQL("DROP TABLE $table") + database.execSQL("ALTER TABLE $newTable RENAME TO $table") + } + + private fun migrateUploadsTable(database: SupportSQLiteDatabase) { + val table = "list_of_uploads" + val newTable = "${table}_new" + // create table with fixed types + database.execSQL( + "CREATE TABLE $newTable (" + + "_id INTEGER PRIMARY KEY," + + "local_path TEXT, " + + "remote_path TEXT, " + + "account_name TEXT, " + + "file_size INTEGER, " + + "status INTEGER, " + + "local_behaviour INTEGER, " + + "upload_time INTEGER, " + + "name_collision_policy INTEGER, " + + "is_create_remote_folder INTEGER, " + + "upload_end_timestamp INTEGER, " + + "last_result INTEGER, " + + "is_while_charging_only INTEGER, " + + "is_wifi_only INTEGER, " + + "created_by INTEGER, " + + "folder_unlock_token TEXT " + + ")" + ) + + // copy data + val columns = + "_id, local_path, remote_path, account_name, file_size, status, local_behaviour, upload_time," + + " name_collision_policy, is_create_remote_folder, upload_end_timestamp, last_result," + + " is_while_charging_only, is_wifi_only, created_by, folder_unlock_token" + database.execSQL( + "INSERT INTO $newTable ($columns) " + + "SELECT $columns FROM $table" + ) + // replace table + database.execSQL("DROP TABLE $table") + database.execSQL("ALTER TABLE $newTable RENAME TO $table") + } +} diff --git a/app/src/main/java/com/nextcloud/client/di/AppComponent.java b/app/src/main/java/com/nextcloud/client/di/AppComponent.java index 2484d4c9de..46dcb2c417 100644 --- a/app/src/main/java/com/nextcloud/client/di/AppComponent.java +++ b/app/src/main/java/com/nextcloud/client/di/AppComponent.java @@ -23,6 +23,7 @@ package com.nextcloud.client.di; import android.app.Application; import com.nextcloud.client.appinfo.AppInfoModule; +import com.nextcloud.client.database.DatabaseModule; import com.nextcloud.client.device.DeviceModule; import com.nextcloud.client.integrations.IntegrationsModule; import com.nextcloud.client.jobs.JobsModule; @@ -51,7 +52,8 @@ import dagger.android.support.AndroidSupportInjectionModule; ViewModelModule.class, JobsModule.class, IntegrationsModule.class, - ThemeModule.class + ThemeModule.class, + DatabaseModule.class }) @Singleton public interface AppComponent { diff --git a/app/src/main/java/com/nextcloud/client/di/AppModule.java b/app/src/main/java/com/nextcloud/client/di/AppModule.java index 32caa8414d..f71e71ddf5 100644 --- a/app/src/main/java/com/nextcloud/client/di/AppModule.java +++ b/app/src/main/java/com/nextcloud/client/di/AppModule.java @@ -95,17 +95,6 @@ class AppModule { } @Provides - @Singleton - NextcloudDatabase database(Context context, Clock clock) { - // TODO move somewhere else to not pollute this file - return Room - .databaseBuilder(context, NextcloudDatabase.class, ProviderMeta.DB_NAME) - .addMigrations(NextcloudDatabase.getLegacyMigrations(context, clock)) - .addMigrations(NextcloudDatabase.roomMigration) - .build(); - } - - @Provides PackageManager packageManager(Application application) { return application.getPackageManager(); } |