Fix database update crash when Dao object changed

This commit is contained in:
Julian Raufelder 2021-03-19 17:49:15 +01:00
parent 91a93d675a
commit 40c679e7dd
No known key found for this signature in database
GPG Key ID: 17EE71F6634E381D
2 changed files with 69 additions and 9 deletions

View File

@ -1,6 +1,7 @@
package org.cryptomator.data.db; package org.cryptomator.data.db;
import android.content.ContentValues; import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import org.greenrobot.greendao.database.Database; import org.greenrobot.greendao.database.Database;
@ -49,6 +50,10 @@ class Sql {
return new SqlUpdateBuilder(tableName); return new SqlUpdateBuilder(tableName);
} }
public static SqlQueryBuilder query(String table) {
return new SqlQueryBuilder(table);
}
public static Criterion eq(final String value) { public static Criterion eq(final String value) {
return (column, whereClause, whereArgs) -> { return (column, whereClause, whereArgs) -> {
whereClause.append('"').append(column).append("\" = ?"); whereClause.append('"').append(column).append("\" = ?");
@ -91,6 +96,56 @@ class Sql {
void appendTo(String column, StringBuilder whereClause, List<String> whereArgs); void appendTo(String column, StringBuilder whereClause, List<String> whereArgs);
} }
public static class SqlQueryBuilder {
private final String tableName;
private final StringBuilder whereClause = new StringBuilder();
private final List<String> whereArgs = new ArrayList<>();
private List<String> columns = new ArrayList<>();
private String groupBy;
private String having;
private String limit;
public SqlQueryBuilder(String tableName) {
this.tableName = tableName;
}
public SqlQueryBuilder columns(List<String> 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 { public static class SqlUpdateBuilder {
private final String tableName; private final String tableName;

View File

@ -2,10 +2,8 @@ package org.cryptomator.data.db
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import org.cryptomator.data.db.entities.CloudEntityDao
import org.cryptomator.util.crypto.CredentialCryptor import org.cryptomator.util.crypto.CredentialCryptor
import org.greenrobot.greendao.database.Database import org.greenrobot.greendao.database.Database
import org.greenrobot.greendao.internal.DaoConfig
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -13,16 +11,23 @@ import javax.inject.Singleton
internal class Upgrade2To3 @Inject constructor(private val context: Context) : DatabaseUpgrade(2, 3) { internal class Upgrade2To3 @Inject constructor(private val context: Context) : DatabaseUpgrade(2, 3) {
override fun internalApplyTo(db: Database, origin: Int) { override fun internalApplyTo(db: Database, origin: Int) {
val clouds = CloudEntityDao(DaoConfig(db, CloudEntityDao::class.java)).loadAll()
db.beginTransaction() db.beginTransaction()
try { try {
clouds.filter { cloud -> cloud.type == "DROPBOX" || cloud.type == "ONEDRIVE" } // Sql.query("CLOUD_ENTITY")
.map { .columns(listOf("ACCESS_TOKEN"))
Sql.update("CLOUD_ENTITY") // .where("TYPE", Sql.eq("DROPBOX"))
.where("TYPE", Sql.eq(it.type)) // .executeOn(db).use {
.set("ACCESS_TOKEN", Sql.toString(encrypt(if (it.type == "DROPBOX") it.accessToken else onedriveToken()))) // if(it.moveToFirst()) {
.executeOn(db) 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() db.setTransactionSuccessful()
} finally { } finally {
db.endTransaction() db.endTransaction()