From 40c679e7dd6af2d2b5edc1231f1148769fbbf260 Mon Sep 17 00:00:00 2001 From: Julian Raufelder Date: Fri, 19 Mar 2021 17:49:15 +0100 Subject: [PATCH] Fix database update crash when Dao object changed --- .../java/org/cryptomator/data/db/Sql.java | 55 +++++++++++++++++++ .../org/cryptomator/data/db/Upgrade2To3.kt | 23 +++++--- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/data/src/main/java/org/cryptomator/data/db/Sql.java b/data/src/main/java/org/cryptomator/data/db/Sql.java index 5f703a0a..1fc488a4 100644 --- a/data/src/main/java/org/cryptomator/data/db/Sql.java +++ b/data/src/main/java/org/cryptomator/data/db/Sql.java @@ -1,6 +1,7 @@ package org.cryptomator.data.db; import android.content.ContentValues; +import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import org.greenrobot.greendao.database.Database; @@ -49,6 +50,10 @@ class Sql { return new SqlUpdateBuilder(tableName); } + public static SqlQueryBuilder query(String table) { + return new SqlQueryBuilder(table); + } + public static Criterion eq(final String value) { return (column, whereClause, whereArgs) -> { whereClause.append('"').append(column).append("\" = ?"); @@ -91,6 +96,56 @@ class Sql { void appendTo(String column, StringBuilder whereClause, List whereArgs); } + public static class SqlQueryBuilder { + + private final String tableName; + private final StringBuilder whereClause = new StringBuilder(); + private final List whereArgs = new ArrayList<>(); + + private List columns = new ArrayList<>(); + private String groupBy; + private String having; + private String limit; + + public SqlQueryBuilder(String tableName) { + this.tableName = tableName; + } + + public SqlQueryBuilder columns(List columns) { + this.columns = columns; + return this; + } + + public SqlQueryBuilder where(String column, Criterion criterion) { + if (whereClause.length() > 0) { + whereClause.append(" AND "); + } + criterion.appendTo(column, whereClause, whereArgs); + return this; + } + + public SqlQueryBuilder groupBy(String groupBy) { + this.groupBy = groupBy; + return this; + } + + public SqlQueryBuilder having(String having) { + this.having = having; + return this; + } + + public SqlQueryBuilder limit(String limit) { + this.limit = limit; + return this; + } + + public Cursor executeOn(Database wrapped) { + SQLiteDatabase db = unwrap(wrapped); + return db.query(tableName, columns.toArray(new String[columns.size()]), whereClause.toString(), whereArgs.toArray(new String[whereArgs.size()]), groupBy, having, limit); + } + + } + public static class SqlUpdateBuilder { private final String tableName; diff --git a/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt b/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt index 465b5cd6..183f7333 100644 --- a/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt +++ b/data/src/main/java/org/cryptomator/data/db/Upgrade2To3.kt @@ -2,10 +2,8 @@ package org.cryptomator.data.db import android.content.Context import android.content.SharedPreferences -import org.cryptomator.data.db.entities.CloudEntityDao import org.cryptomator.util.crypto.CredentialCryptor import org.greenrobot.greendao.database.Database -import org.greenrobot.greendao.internal.DaoConfig import javax.inject.Inject import javax.inject.Singleton @@ -13,16 +11,23 @@ import javax.inject.Singleton internal class Upgrade2To3 @Inject constructor(private val context: Context) : DatabaseUpgrade(2, 3) { override fun internalApplyTo(db: Database, origin: Int) { - val clouds = CloudEntityDao(DaoConfig(db, CloudEntityDao::class.java)).loadAll() db.beginTransaction() try { - clouds.filter { cloud -> cloud.type == "DROPBOX" || cloud.type == "ONEDRIVE" } // - .map { - Sql.update("CLOUD_ENTITY") // - .where("TYPE", Sql.eq(it.type)) // - .set("ACCESS_TOKEN", Sql.toString(encrypt(if (it.type == "DROPBOX") it.accessToken else onedriveToken()))) // - .executeOn(db) + Sql.query("CLOUD_ENTITY") + .columns(listOf("ACCESS_TOKEN")) + .where("TYPE", Sql.eq("DROPBOX")) + .executeOn(db).use { + if(it.moveToFirst()) { + Sql.update("CLOUD_ENTITY") + .set("ACCESS_TOKEN", Sql.toString(encrypt(it.getString(it.getColumnIndex("ACCESS_TOKEN"))))) + .where("TYPE", Sql.eq("DROPBOX")); + } } + + Sql.update("CLOUD_ENTITY") + .set("ACCESS_TOKEN", Sql.toString(encrypt(onedriveToken()))) + .where("TYPE", Sql.eq("ONEDRIVE")); + db.setTransactionSuccessful() } finally { db.endTransaction()