From f6adc6ad3a1212dbf11fca6376f3dbea50f35417 Mon Sep 17 00:00:00 2001 From: Stefan Niedermann Date: Wed, 7 Oct 2020 12:05:34 +0200 Subject: [PATCH] #831 Migrate from SQLiteOpenHelper to Room Safe old migration steps --- .../notes/persistence/NotesDatabase.java | 46 +++++++++++++++---- .../persistence/entity/LocalAccount.java | 10 ++-- .../migration/Migration_10_11.java | 15 +++++- .../migration/Migration_11_12.java | 15 +++++- .../migration/Migration_12_13.java | 15 +++++- .../migration/Migration_13_14.java | 21 +++++++-- .../migration/Migration_14_15.java | 21 +++++++-- .../migration/Migration_15_16.java | 30 +++++++----- .../migration/Migration_16_17.java | 14 ++++-- .../migration/Migration_17_18.java | 12 ++++- .../migration/Migration_18_19.java | 18 ++++++-- .../migration/Migration_19_20.java | 24 ++++++++++ .../persistence/migration/Migration_4_5.java | 14 ++++-- .../persistence/migration/Migration_5_6.java | 12 ++++- .../persistence/migration/Migration_6_7.java | 12 ++++- .../persistence/migration/Migration_7_8.java | 12 ++++- .../persistence/migration/Migration_8_9.java | 23 ++++++++-- .../persistence/migration/Migration_9_10.java | 17 +++++-- .../notes/shared/util/DatabaseIndexUtil.java | 9 ++-- 19 files changed, 266 insertions(+), 74 deletions(-) create mode 100644 app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java index 02f34afb..370c7e5d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java @@ -51,6 +51,22 @@ import it.niedermann.owncloud.notes.persistence.entity.LocalAccount; import it.niedermann.owncloud.notes.persistence.entity.Note; import it.niedermann.owncloud.notes.persistence.entity.NotesListWidgetData; import it.niedermann.owncloud.notes.persistence.entity.SingleNoteWidgetData; +import it.niedermann.owncloud.notes.persistence.migration.Migration_10_11; +import it.niedermann.owncloud.notes.persistence.migration.Migration_11_12; +import it.niedermann.owncloud.notes.persistence.migration.Migration_12_13; +import it.niedermann.owncloud.notes.persistence.migration.Migration_13_14; +import it.niedermann.owncloud.notes.persistence.migration.Migration_14_15; +import it.niedermann.owncloud.notes.persistence.migration.Migration_15_16; +import it.niedermann.owncloud.notes.persistence.migration.Migration_16_17; +import it.niedermann.owncloud.notes.persistence.migration.Migration_17_18; +import it.niedermann.owncloud.notes.persistence.migration.Migration_18_19; +import it.niedermann.owncloud.notes.persistence.migration.Migration_19_20; +import it.niedermann.owncloud.notes.persistence.migration.Migration_4_5; +import it.niedermann.owncloud.notes.persistence.migration.Migration_5_6; +import it.niedermann.owncloud.notes.persistence.migration.Migration_6_7; +import it.niedermann.owncloud.notes.persistence.migration.Migration_7_8; +import it.niedermann.owncloud.notes.persistence.migration.Migration_8_9; +import it.niedermann.owncloud.notes.persistence.migration.Migration_9_10; import it.niedermann.owncloud.notes.shared.model.ApiVersion; import it.niedermann.owncloud.notes.shared.model.Capabilities; import it.niedermann.owncloud.notes.shared.model.CategorySortingMethod; @@ -72,7 +88,7 @@ import static it.niedermann.owncloud.notes.widget.singlenote.SingleNoteWidget.up Category.class, SingleNoteWidgetData.class, NotesListWidgetData.class - }, version = 18 + }, version = 20 ) @TypeConverters({Converters.class}) public abstract class NotesDatabase extends RoomDatabase { @@ -88,8 +104,25 @@ public abstract class NotesDatabase extends RoomDatabase { context, NotesDatabase.class, NOTES_DB_NAME) - .addMigrations(OLD_STUFF) - .fallbackToDestructiveMigration() + .addMigrations( + new Migration_4_5(), + new Migration_5_6(), + new Migration_6_7(), + new Migration_7_8(), + new Migration_8_9(context, (supportSQLiteDatabase) -> { /* TODO */ }, () -> instance.notifyWidgets()), + new Migration_9_10(), + new Migration_10_11(context), + new Migration_11_12(context), + new Migration_12_13(context), + new Migration_13_14(context, () -> instance.notifyWidgets()), + new Migration_14_15(), + new Migration_15_16(context, () -> instance.notifyWidgets()), + new Migration_16_17(), + new Migration_17_18(), + new Migration_18_19(context), + new Migration_19_20() + ) +// .fallbackToDestructiveMigration() .addCallback(new RoomDatabase.Callback() { @Override public void onCreate(@NonNull SupportSQLiteDatabase db) { @@ -101,13 +134,6 @@ public abstract class NotesDatabase extends RoomDatabase { .build(); } - private static final Migration OLD_STUFF = new Migration(17, 18) { - @Override - public void migrate(SupportSQLiteDatabase database) { - - } - }; - public abstract LocalAccountDao getLocalAccountDao(); public abstract CategoryDao getCategoryDao(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/LocalAccount.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/LocalAccount.java index 45d0bb85..78ea1ede 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/LocalAccount.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/entity/LocalAccount.java @@ -25,11 +25,11 @@ import it.niedermann.owncloud.notes.shared.util.ColorUtil; @Entity( tableName = "ACCOUNTS", indices = { - @Index(name = "ACCOUNTS_ACCOUNT_NAME_idx", value = "ACCOUNT_NAME"), - @Index(name = "ACCOUNTS_ETAG_idx", value = "ETAG"), @Index(name = "ACCOUNTS_MODIFIED_idx", value = "MODIFIED"), @Index(name = "ACCOUNTS_URL_idx", value = "URL"), - @Index(name = "ACCOUNTS_USERNAME_idx", value = "USERNAME") + @Index(name = "ACCOUNTS_USERNAME_idx", value = "USERNAME"), + @Index(name = "ACCOUNTS_ACCOUNT_NAME_idx", value = "ACCOUNT_NAME"), + @Index(name = "ACCOUNTS_ETAG_idx", value = "ETAG") } ) public class LocalAccount { @@ -48,9 +48,9 @@ public class LocalAccount { private Calendar modified; @ColumnInfo(name = "API_VERSION") private String apiVersion; - @ColumnInfo(name = "COLOR") + @ColumnInfo(name = "COLOR", defaultValue = "000000") private String color; - @ColumnInfo(name = "TEXT_COLOR") + @ColumnInfo(name = "TEXT_COLOR", defaultValue = "0082C9") private String textColor; @ColumnInfo(name = "CAPABILITIES_ETAG") private String capabilitiesETag; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java index 4d45a3ce..5a739b7d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_10_11.java @@ -5,16 +5,27 @@ import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import java.util.Map; import it.niedermann.owncloud.notes.preferences.DarkModeSetting; -public class Migration_10_11 { +public class Migration_10_11 extends Migration { + @NonNull + private final Context context; + + public Migration_10_11(@NonNull Context context) { + super(10, 11); + this.context = context; + } + /** * Changes the boolean for light / dark mode to {@link DarkModeSetting} to also be able to represent system default value */ - public Migration_10_11(@NonNull Context context) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase database) { SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor editor = sharedPreferences.edit(); Map prefs = sharedPreferences.getAll(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java index b77eeb88..d37916e8 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_11_12.java @@ -4,15 +4,26 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import it.niedermann.owncloud.notes.persistence.CapabilitiesWorker; import it.niedermann.owncloud.notes.shared.model.ApiVersion; -public class Migration_11_12 { +public class Migration_11_12 extends Migration { + @NonNull + private final Context context; + + public Migration_11_12(@NonNull Context context) { + super(11, 12); + this.context = context; + } + /** * Adds columns to store the {@link ApiVersion} and the theme colors */ - public Migration_11_12(@NonNull SQLiteDatabase db, @NonNull Context context) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN API_VERSION TEXT"); db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN COLOR VARCHAR(6) NOT NULL DEFAULT '000000'"); db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN TEXT_COLOR VARCHAR(6) NOT NULL DEFAULT '0082C9'"); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java index 77954c3f..07c405b6 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_12_13.java @@ -4,15 +4,26 @@ import android.content.Context; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import androidx.work.WorkManager; import it.niedermann.owncloud.notes.shared.model.Capabilities; -public class Migration_12_13 { +public class Migration_12_13 extends Migration { + @NonNull + private final Context context; + + public Migration_12_13(@NonNull Context context) { + super(12, 13); + this.context = context; + } + /** * Adds a column to store the ETag of the server {@link Capabilities} */ - public Migration_12_13(@NonNull SQLiteDatabase db, @NonNull Context context) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE ACCOUNTS ADD COLUMN CAPABILITIES_ETAG TEXT"); WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("it.niedermann.owncloud.notes.persistence.SyncWorker"); WorkManager.getInstance(context.getApplicationContext()).cancelUniqueWork("SyncWorker"); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java index 66a2f643..85e02617 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_13_14.java @@ -3,25 +3,38 @@ package it.niedermann.owncloud.notes.persistence.migration; import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; -import android.database.sqlite.SQLiteDatabase; import android.util.Log; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; +import androidx.room.OnConflictStrategy; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import java.util.Map; import it.niedermann.owncloud.notes.preferences.DarkModeSetting; -public class Migration_13_14 { +public class Migration_13_14 extends Migration { private static final String TAG = Migration_13_14.class.getSimpleName(); + @NonNull + private final Context context; + @NonNull + private final Runnable notifyWidgets; + + public Migration_13_14(@NonNull Context context, @NonNull Runnable notifyWidgets) { + super(13, 14); + this.context = context; + this.notifyWidgets = notifyWidgets; + } /** * Move single note widget preferences to database * https://github.com/stefan-niedermann/nextcloud-notes/issues/754 */ - public Migration_13_14(@NonNull SQLiteDatabase db, @NonNull Context context, @NonNull Runnable notifyWidgets) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("CREATE TABLE WIDGET_SINGLE_NOTES ( " + "ID INTEGER PRIMARY KEY, " + "ACCOUNT_ID INTEGER, " + @@ -60,7 +73,7 @@ public class Migration_13_14 { migratedWidgetValues.put("ACCOUNT_ID", accountId); migratedWidgetValues.put("NOTE_ID", noteId); migratedWidgetValues.put("THEME_MODE", themeMode); - db.insert("WIDGET_SINGLE_NOTES", null, migratedWidgetValues); + db.insert("WIDGET_SINGLE_NOTES", OnConflictStrategy.REPLACE, migratedWidgetValues); } catch (Throwable t) { Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", noteId: " + noteId + ", themeMode: " + themeMode + "}"); t.printStackTrace(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java index e69c8ff1..6938e41c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_14_15.java @@ -5,16 +5,27 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.util.Log; +import androidx.annotation.NonNull; +import androidx.room.OnConflictStrategy; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + import java.util.Hashtable; import it.niedermann.owncloud.notes.shared.util.DatabaseIndexUtil; -public class Migration_14_15 { +public class Migration_14_15 extends Migration { + + public Migration_14_15() { + super(14, 15); + } + /** * Normalize database (move category from string field to own table) * https://github.com/stefan-niedermann/nextcloud-notes/issues/814 */ - public Migration_14_15(SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { // Rename a tmp_NOTES table. String tmpTableNotes = String.format("tmp_%s", "NOTES"); db.execSQL("ALTER TABLE NOTES RENAME TO " + tmpTableNotes); @@ -44,7 +55,7 @@ public class Migration_14_15 { // This is used to prevent too many searches in database Hashtable categoryTitleIdMap = new Hashtable<>(); int id = 1; - Cursor tmpNotesCursor = db.rawQuery("SELECT * FROM " + tmpTableNotes, null); + Cursor tmpNotesCursor = db.query("SELECT * FROM " + tmpTableNotes, null); while (tmpNotesCursor.moveToNext()) { String categoryTitle = tmpNotesCursor.getString(8); int accountId = tmpNotesCursor.getInt(2); @@ -59,7 +70,7 @@ public class Migration_14_15 { values.put("CATEGORY_ID", categoryId); values.put("CATEGORY_ACCOUNT_ID", accountId); values.put("CATEGORY_TITLE", categoryTitle); - db.insert("CATEGORIES", null, values); + db.insert("CATEGORIES", OnConflictStrategy.REPLACE, values); categoryTitleIdMap.put(categoryTitle, categoryId); } // Move the data in tmp_NOTES to NOTES @@ -75,7 +86,7 @@ public class Migration_14_15 { values.put("CATEGORY", categoryId); values.put("ETAG", tmpNotesCursor.getString(9)); values.put("EXCERPT", tmpNotesCursor.getString(10)); - db.insert("NOTES", null, values); + db.insert("NOTES", OnConflictStrategy.REPLACE, values); } tmpNotesCursor.close(); db.execSQL("DROP TABLE IF EXISTS " + tmpTableNotes); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java index 49056239..2732151f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_15_16.java @@ -4,25 +4,38 @@ import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; -import android.database.sqlite.SQLiteDatabase; import android.util.Log; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; +import androidx.room.OnConflictStrategy; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import java.util.Map; import it.niedermann.owncloud.notes.preferences.DarkModeSetting; -public class Migration_15_16 { +public class Migration_15_16 extends Migration { private static final String TAG = Migration_15_16.class.getSimpleName(); + @NonNull + private final Context context; + @NonNull + private final Runnable notifyWidgets; + + public Migration_15_16(@NonNull Context context, @NonNull Runnable notifyWidgets) { + super(15, 16); + this.context = context; + this.notifyWidgets = notifyWidgets; + } /** * Moves note list widget preferences from {@link SharedPreferences} to database * https://github.com/stefan-niedermann/nextcloud-notes/issues/832 */ - public Migration_15_16(SQLiteDatabase db, @NonNull Context context, @NonNull Runnable notifyWidgets) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("CREATE TABLE WIDGET_NOTE_LISTS ( " + "ID INTEGER PRIMARY KEY, " + "ACCOUNT_ID INTEGER, " + @@ -62,14 +75,7 @@ public class Migration_15_16 { if (mode == 2) { final String categoryTitle = sharedPreferences.getString(SP_CATEGORY_KEY + widgetId, null); - Cursor cursor = db.query( - "CATEGORIES", - new String[]{"CATEGORY_ID"}, - "CATEGORY_TITLE = ? AND CATEGORY_ACCOUNT_ID = ? ", - new String[]{categoryTitle, String.valueOf(accountId)}, - null, - null, - null); + Cursor cursor = db.query("SELECT CATEGORY_ID FROM CATEGORIES WHERE CATEGORY_TITLE = ? AND CATEGORY_ACCOUNT_ID = ?", new String[]{categoryTitle, String.valueOf(accountId)}); if (cursor.moveToNext()) { categoryId = cursor.getInt(0); } else { @@ -84,7 +90,7 @@ public class Migration_15_16 { migratedWidgetValues.put("CATEGORY_ID", categoryId); migratedWidgetValues.put("MODE", mode); migratedWidgetValues.put("THEME_MODE", themeMode); - db.insert("WIDGET_NOTE_LISTS", null, migratedWidgetValues); + db.insert("WIDGET_NOTE_LISTS", OnConflictStrategy.REPLACE, migratedWidgetValues); } catch (Throwable t) { Log.e(TAG, "Could not migrate widget {widgetId: " + widgetId + ", accountId: " + accountId + ", mode: " + mode + ", categoryId: " + categoryId + ", themeMode: " + themeMode + "}"); t.printStackTrace(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java index 547cb6c7..b61262eb 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_16_17.java @@ -1,15 +1,21 @@ package it.niedermann.owncloud.notes.persistence.migration; -import android.database.sqlite.SQLiteDatabase; - import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +public class Migration_16_17 extends Migration { + + public Migration_16_17() { + super(16, 17); + } -public class Migration_16_17 { /** * Adds a column to store the current scroll position per note * https://github.com/stefan-niedermann/nextcloud-notes/issues/227 */ - public Migration_16_17(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE NOTES ADD COLUMN SCROLL_Y INTEGER DEFAULT 0"); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_17_18.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_17_18.java index 6faa9016..1a7a96e7 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_17_18.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_17_18.java @@ -3,12 +3,20 @@ package it.niedermann.owncloud.notes.persistence.migration; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +public class Migration_17_18 extends Migration { + + public Migration_17_18() { + super(17, 18); + } -public class Migration_17_18 { /** * Add a new column to store the sorting method for a category note list */ - public Migration_17_18(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE CATEGORIES ADD COLUMN CATEGORY_SORTING_METHOD INTEGER DEFAULT 0"); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_18_19.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_18_19.java index a3205db0..343f9e81 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_18_19.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_18_19.java @@ -4,19 +4,29 @@ import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import com.bumptech.glide.Glide; -public class Migration_18_19 { +public class Migration_18_19 extends Migration { + private static final String TAG = Migration_18_19.class.getSimpleName(); + @NonNull + private final Context context; + + + public Migration_18_19(@NonNull Context context) { + super(18, 19); + this.context = context; + } /** * Clears the {@link Glide} disk cache to fix wrong avatars in a multi user setup * https://github.com/stefan-niedermann/nextcloud-deck/issues/531 - * - * @param context {@link Context} */ - public Migration_18_19(@NonNull Context context) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { new Thread(() -> { Log.i(TAG, "Clearing Glide disk cache"); Glide.get(context.getApplicationContext()).clearDiskCache(); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java new file mode 100644 index 00000000..0be47f22 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_19_20.java @@ -0,0 +1,24 @@ +package it.niedermann.owncloud.notes.persistence.migration; + +import android.database.sqlite.SQLiteOpenHelper; + +import androidx.annotation.NonNull; +import androidx.room.RoomDatabase; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +public class Migration_19_20 extends Migration { + + public Migration_19_20() { + super(19, 20); + } + + /** + * From {@link SQLiteOpenHelper} to {@link RoomDatabase} + * https://github.com/stefan-niedermann/nextcloud-deck/issues/531 + */ + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { + // Nothing to do...? + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java index aa807944..701320c9 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_4_5.java @@ -1,14 +1,20 @@ package it.niedermann.owncloud.notes.persistence.migration; -import android.database.sqlite.SQLiteDatabase; - import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +public class Migration_4_5 extends Migration { + + public Migration_4_5() { + super(4, 5); + } -public class Migration_4_5 { /** * Differentiate between local id and remote id */ - public Migration_4_5(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE NOTES ADD COLUMN REMOTEID INTEGER"); db.execSQL("UPDATE NOTES SET REMOTEID=ID WHERE (REMOTEID IS NULL OR REMOTEID=0) AND STATUS!=?", new String[]{"LOCAL_CREATED"}); db.execSQL("UPDATE NOTES SET REMOTEID=0, STATUS=? WHERE STATUS=?", new String[]{"LOCAL_EDITED", "LOCAL_CREATED"}); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java index 184a6033..e3fc1ffd 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_5_6.java @@ -3,12 +3,20 @@ package it.niedermann.owncloud.notes.persistence.migration; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; + +public class Migration_5_6 extends Migration { + + public Migration_5_6() { + super(5, 6); + } -public class Migration_5_6 { /** * Adds a column to support marking notes as favorite */ - public Migration_5_6(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE NOTES ADD COLUMN FAVORITE INTEGER DEFAULT 0"); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java index e7d0eadd..327841d9 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_6_7.java @@ -3,14 +3,22 @@ package it.niedermann.owncloud.notes.persistence.migration; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import it.niedermann.owncloud.notes.shared.util.DatabaseIndexUtil; -public class Migration_6_7 { +public class Migration_6_7 extends Migration { + + public Migration_6_7() { + super(6, 7); + } + /** * Adds columns for category support and ETags */ - public Migration_6_7(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { DatabaseIndexUtil.dropIndexes(db); db.execSQL("ALTER TABLE NOTES ADD COLUMN CATEGORY TEXT NOT NULL DEFAULT ''"); db.execSQL("ALTER TABLE NOTES ADD COLUMN ETAG TEXT"); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java index d1fd40c0..de0a1ded 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_7_8.java @@ -3,11 +3,19 @@ package it.niedermann.owncloud.notes.persistence.migration; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import it.niedermann.owncloud.notes.shared.util.DatabaseIndexUtil; -public class Migration_7_8 { - public Migration_7_8(@NonNull SQLiteDatabase db) { +public class Migration_7_8 extends Migration { + + public Migration_7_8() { + super(7, 8); + } + + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { final String table_temp = "NOTES_TEMP"; db.execSQL("CREATE TABLE " + table_temp + " ( " + "ID INTEGER PRIMARY KEY AUTOINCREMENT, " + diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java index 571adceb..33f6e830 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_8_9.java @@ -11,6 +11,9 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.core.util.Consumer; import androidx.preference.PreferenceManager; +import androidx.room.OnConflictStrategy; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import java.net.MalformedURLException; import java.net.URL; @@ -19,14 +22,26 @@ import it.niedermann.owncloud.notes.shared.util.DatabaseIndexUtil; import it.niedermann.owncloud.notes.widget.notelist.NoteListWidget; import it.niedermann.owncloud.notes.widget.singlenote.SingleNoteWidget; -public class Migration_8_9 { +public class Migration_8_9 extends Migration { private static final String TAG = Migration_8_9.class.getSimpleName(); + private final Context context; + private final Consumer recreateDatabase; + private final Runnable notifyWidgets; /** * Adds an account table for multi account usage in combination with SingleSignOn */ - public Migration_8_9(@NonNull SQLiteDatabase db, @NonNull Context context, @NonNull Consumer recreateDatabase, @NonNull Runnable notifyWidgets) { + public Migration_8_9(@NonNull Context context, @NonNull Consumer recreateDatabase, @NonNull Runnable notifyWidgets) { + super(8, 9); + this.context = context; + this.recreateDatabase = recreateDatabase; + this.notifyWidgets = notifyWidgets; + } + + + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { // Create accounts table db.execSQL("CREATE TABLE ACCOUNTS ( " + "ID INTEGER PRIMARY KEY AUTOINCREMENT, " + @@ -54,12 +69,12 @@ public class Migration_8_9 { migratedAccountValues.put("URL", url); migratedAccountValues.put("USERNAME", username); migratedAccountValues.put("ACCOUNT_NAME", accountName); - db.insert("ACCOUNTS", null, migratedAccountValues); + db.insert("ACCOUNTS", OnConflictStrategy.REPLACE, migratedAccountValues); // After successful insertion of migrated account, set accountId to 1 in each note ContentValues values = new ContentValues(); values.put("ACCOUNT_ID", 1); - db.update("NOTES", values, "ACCOUNT_ID = ?", new String[]{"NULL"}); + db.update("NOTES", OnConflictStrategy.REPLACE, values, "ACCOUNT_ID = ?", new String[]{"NULL"}); // Add FOREIGN_KEY constraint final String table_temp = "NOTES_TEMP"; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java index b17b8675..7cdab8c0 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/migration/Migration_9_10.java @@ -5,21 +5,30 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import androidx.annotation.NonNull; +import androidx.room.OnConflictStrategy; +import androidx.room.migration.Migration; +import androidx.sqlite.db.SupportSQLiteDatabase; import it.niedermann.owncloud.notes.shared.util.NoteUtil; -public class Migration_9_10 { +public class Migration_9_10 extends Migration { + + public Migration_9_10() { + super(9, 10); + } + /** * Adds a column to store excerpt instead of regenerating it each time * https://github.com/stefan-niedermann/nextcloud-notes/issues/528 */ - public Migration_9_10(@NonNull SQLiteDatabase db) { + @Override + public void migrate(@NonNull SupportSQLiteDatabase db) { db.execSQL("ALTER TABLE NOTES ADD COLUMN EXCERPT INTEGER NOT NULL DEFAULT ''"); - Cursor cursor = db.query("NOTES", new String[]{"ID", "CONTENT", "TITLE"}, null, null, null, null, null, null); + Cursor cursor = db.query("NOTES", new String[]{"ID", "CONTENT", "TITLE"}); while (cursor.moveToNext()) { ContentValues values = new ContentValues(); values.put("EXCERPT", NoteUtil.generateNoteExcerpt(cursor.getString(1), cursor.getString(2))); - db.update("NOTES", values, "ID" + " = ? ", new String[]{cursor.getString(0)}); + db.update("NOTES", OnConflictStrategy.REPLACE, values, "ID" + " = ? ", new String[]{cursor.getString(0)}); } cursor.close(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DatabaseIndexUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DatabaseIndexUtil.java index 59707b24..624aa02e 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DatabaseIndexUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/DatabaseIndexUtil.java @@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteDatabase; import android.util.Log; import androidx.annotation.NonNull; +import androidx.sqlite.db.SupportSQLiteDatabase; public class DatabaseIndexUtil { @@ -14,20 +15,20 @@ public class DatabaseIndexUtil { } - public static void createIndex(@NonNull SQLiteDatabase db, @NonNull String table, @NonNull String... columns) { + public static void createIndex(@NonNull SupportSQLiteDatabase db, @NonNull String table, @NonNull String... columns) { for (String column : columns) { createIndex(db, table, column); } } - public static void createIndex(@NonNull SQLiteDatabase db, @NonNull String table, @NonNull String column) { + public static void createIndex(@NonNull SupportSQLiteDatabase db, @NonNull String table, @NonNull String column) { String indexName = table + "_" + column + "_idx"; Log.v(TAG, "Creating database index: CREATE INDEX IF NOT EXISTS " + indexName + " ON " + table + "(" + column + ")"); db.execSQL("CREATE INDEX IF NOT EXISTS " + indexName + " ON " + table + "(" + column + ")"); } - public static void dropIndexes(@NonNull SQLiteDatabase db) { - try (Cursor c = db.query("sqlite_master", new String[]{"name", "sql"}, "type=?", new String[]{"index"}, null, null, null)) { + public static void dropIndexes(@NonNull SupportSQLiteDatabase db) { + try (Cursor c = db.query("SELECT name, sql FROM sqlite_master WHERE type = 'index'")) { while (c.moveToNext()) { // Skip automatic indexes which we can't drop manually if (c.getString(1) != null) {