Merge pull request #3519 from k9mail/add_folder_extra_values
Allow backend code to store additional per-account and per-folder data
This commit is contained in:
commit
b35074315c
8 changed files with 194 additions and 2 deletions
|
@ -234,6 +234,36 @@ class K9BackendFolder(
|
|||
}
|
||||
}
|
||||
|
||||
override fun getFolderExtraString(name: String): String? {
|
||||
return database.getStringOrNull(
|
||||
table = "folder_extra_values",
|
||||
column = "value_string"
|
||||
)
|
||||
}
|
||||
|
||||
override fun setFolderExtraString(name: String, value: String) {
|
||||
database.setString(
|
||||
table = "folder_extra_values",
|
||||
column = "value_string",
|
||||
value = value
|
||||
)
|
||||
}
|
||||
|
||||
override fun getFolderExtraNumber(name: String): Long? {
|
||||
return database.getLongOrNull(
|
||||
table = "folder_extra_values",
|
||||
column = "value_integer"
|
||||
)
|
||||
}
|
||||
|
||||
override fun setFolderExtraNumber(name: String, value: Long) {
|
||||
database.setLong(
|
||||
table = "folder_extra_values",
|
||||
column = "value_integer",
|
||||
value = value
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun LockableDatabase.getString(
|
||||
table: String = "folders",
|
||||
|
@ -253,6 +283,24 @@ class K9BackendFolder(
|
|||
}
|
||||
}
|
||||
|
||||
private fun LockableDatabase.getStringOrNull(
|
||||
table: String = "folders",
|
||||
column: String,
|
||||
selection: String = "id = ?",
|
||||
vararg selectionArgs: String = arrayOf(databaseId)
|
||||
): String? {
|
||||
return execute(false) { db ->
|
||||
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
||||
cursor.use {
|
||||
if (it.moveToFirst()) {
|
||||
it.getStringOrNull(0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LockableDatabase.setString(
|
||||
table: String = "folders",
|
||||
column: String,
|
||||
|
@ -281,6 +329,24 @@ class K9BackendFolder(
|
|||
}
|
||||
}
|
||||
|
||||
private fun LockableDatabase.getLongOrNull(
|
||||
table: String = "folders",
|
||||
column: String,
|
||||
selection: String = "id = ?",
|
||||
vararg selectionArgs: String = arrayOf(databaseId)
|
||||
): Long? {
|
||||
return execute(false) { db ->
|
||||
val cursor = db.query(table, arrayOf(column), selection, selectionArgs, null, null, null)
|
||||
cursor.use {
|
||||
if (it.moveToFirst()) {
|
||||
it.getLongOrNull(0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun LockableDatabase.setLong(
|
||||
table: String = "folders",
|
||||
column: String,
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.fsck.k9.mailstore
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.Cursor
|
||||
import androidx.core.database.getStringOrNull
|
||||
import com.fsck.k9.Account
|
||||
import com.fsck.k9.Preferences
|
||||
import com.fsck.k9.backend.api.BackendFolder
|
||||
|
@ -8,9 +11,68 @@ import com.fsck.k9.backend.api.BackendStorage
|
|||
class K9BackendStorage(
|
||||
private val preferences: Preferences,
|
||||
private val account: Account,
|
||||
private val localStore: LocalStore) : BackendStorage {
|
||||
private val localStore: LocalStore
|
||||
) : BackendStorage {
|
||||
private val database = localStore.database
|
||||
|
||||
|
||||
override fun getFolder(folderServerId: String): BackendFolder {
|
||||
return K9BackendFolder(preferences, account, localStore, folderServerId)
|
||||
}
|
||||
|
||||
override fun getExtraString(name: String): String? {
|
||||
return database.execute(false) { db ->
|
||||
val cursor = db.query(
|
||||
"account_extra_values",
|
||||
arrayOf("value_string"),
|
||||
"name = ?",
|
||||
arrayOf(name),
|
||||
null, null, null)
|
||||
cursor.use {
|
||||
if (it.moveToFirst()) {
|
||||
it.getStringOrNull(0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setExtraString(name: String, value: String) {
|
||||
database.execute(false) { db ->
|
||||
val contentValues = ContentValues().apply {
|
||||
put("value_string", value)
|
||||
}
|
||||
db.update("account_extra_values", contentValues, "name = ?", arrayOf(name))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getExtraNumber(name: String): Long? {
|
||||
return database.execute(false) { db ->
|
||||
val cursor = db.query(
|
||||
"account_extra_values",
|
||||
arrayOf("value_integer"),
|
||||
"name = ?",
|
||||
arrayOf(name),
|
||||
null, null, null)
|
||||
cursor.use {
|
||||
if (it.moveToFirst()) {
|
||||
it.getLongOrNull(0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun setExtraNumber(name: String, value: Long) {
|
||||
database.execute(false) { db ->
|
||||
val contentValues = ContentValues().apply {
|
||||
put("value_integer", value)
|
||||
}
|
||||
db.update("account_extra_values", contentValues, "name = ?", arrayOf(name))
|
||||
}
|
||||
}
|
||||
|
||||
private fun Cursor.getLongOrNull(columnIndex: Int): Long? = if (isNull(columnIndex)) null else getLong(columnIndex)
|
||||
}
|
||||
|
|
|
@ -179,7 +179,7 @@ public class LocalStore {
|
|||
*/
|
||||
private static final int THREAD_FLAG_UPDATE_BATCH_SIZE = 500;
|
||||
|
||||
public static final int DB_VERSION = 63;
|
||||
public static final int DB_VERSION = 64;
|
||||
|
||||
private final Context context;
|
||||
private final ContentResolver contentResolver;
|
||||
|
|
|
@ -73,6 +73,13 @@ class StoreSchemaDefinition implements LockableDatabase.SchemaDefinition {
|
|||
}
|
||||
|
||||
private static void dbCreateDatabaseFromScratch(SQLiteDatabase db) {
|
||||
db.execSQL("DROP TABLE IF EXISTS account_extra_values");
|
||||
db.execSQL("CREATE TABLE account_extra_values (" +
|
||||
"name TEXT NOT NULL PRIMARY KEY, " +
|
||||
"value_text TEXT, " +
|
||||
"value_integer INTEGER " +
|
||||
")");
|
||||
|
||||
db.execSQL("DROP TABLE IF EXISTS folders");
|
||||
db.execSQL("CREATE TABLE folders (" +
|
||||
"id INTEGER PRIMARY KEY," +
|
||||
|
@ -97,6 +104,15 @@ class StoreSchemaDefinition implements LockableDatabase.SchemaDefinition {
|
|||
db.execSQL("DROP INDEX IF EXISTS folder_server_id");
|
||||
db.execSQL("CREATE INDEX folder_server_id ON folders (server_id)");
|
||||
|
||||
db.execSQL("DROP TABLE IF EXISTS folder_extra_values");
|
||||
db.execSQL("CREATE TABLE folder_extra_values (" +
|
||||
"folder_id INTEGER NOT NULL, " +
|
||||
"name TEXT NOT NULL, " +
|
||||
"value_text TEXT, " +
|
||||
"value_integer INTEGER, " +
|
||||
"PRIMARY KEY (folder_id, name)" +
|
||||
")");
|
||||
|
||||
db.execSQL("DROP TABLE IF EXISTS messages");
|
||||
db.execSQL("CREATE TABLE messages (" +
|
||||
"id INTEGER PRIMARY KEY, " +
|
||||
|
@ -203,6 +219,13 @@ class StoreSchemaDefinition implements LockableDatabase.SchemaDefinition {
|
|||
db.execSQL("DROP TRIGGER IF EXISTS delete_folder");
|
||||
db.execSQL("CREATE TRIGGER delete_folder BEFORE DELETE ON folders BEGIN DELETE FROM messages WHERE old.id = folder_id; END;");
|
||||
|
||||
db.execSQL("DROP TRIGGER IF EXISTS delete_folder_extra_values");
|
||||
db.execSQL("CREATE TRIGGER delete_folder_extra_values " +
|
||||
"BEFORE DELETE ON folders " +
|
||||
"BEGIN " +
|
||||
"DELETE FROM folder_extra_values WHERE old.id = folder_id; " +
|
||||
"END;");
|
||||
|
||||
db.execSQL("DROP TRIGGER IF EXISTS delete_message");
|
||||
db.execSQL("CREATE TRIGGER delete_message " +
|
||||
"BEFORE DELETE ON messages " +
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package com.fsck.k9.mailstore.migrations
|
||||
|
||||
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
|
||||
|
||||
internal object MigrationTo64 {
|
||||
@JvmStatic
|
||||
fun addExtraValuesTables(db: SQLiteDatabase) {
|
||||
db.execSQL("CREATE TABLE account_extra_values (" +
|
||||
"name TEXT NOT NULL PRIMARY KEY, " +
|
||||
"value_text TEXT, " +
|
||||
"value_integer INTEGER " +
|
||||
")")
|
||||
|
||||
db.execSQL("CREATE TABLE folder_extra_values (" +
|
||||
"folder_id INTEGER NOT NULL, " +
|
||||
"name TEXT NOT NULL, " +
|
||||
"value_text TEXT, " +
|
||||
"value_integer INTEGER, " +
|
||||
"PRIMARY KEY (folder_id, name)" +
|
||||
")")
|
||||
|
||||
db.execSQL("CREATE TRIGGER delete_folder_extra_values " +
|
||||
"BEFORE DELETE ON folders " +
|
||||
"BEGIN " +
|
||||
"DELETE FROM folder_extra_values WHERE old.id = folder_id; " +
|
||||
"END;")
|
||||
}
|
||||
}
|
|
@ -83,6 +83,8 @@ public class Migrations {
|
|||
MigrationTo61.removeErrorsFolder(db);
|
||||
case 61:
|
||||
MigrationTo62.addServerIdColumnToFoldersTable(db);
|
||||
case 63:
|
||||
MigrationTo64.addExtraValuesTables(db);
|
||||
}
|
||||
|
||||
if (shouldBuildFtsTable) {
|
||||
|
|
|
@ -28,6 +28,10 @@ interface BackendFolder {
|
|||
fun getLatestOldMessageSeenTime(): Date
|
||||
fun setLatestOldMessageSeenTime(date: Date)
|
||||
fun getOldestMessageDate(): Date?
|
||||
fun getFolderExtraString(name: String): String?
|
||||
fun setFolderExtraString(name: String, value: String)
|
||||
fun getFolderExtraNumber(name: String): Long?
|
||||
fun setFolderExtraNumber(name: String, value: Long)
|
||||
|
||||
enum class MoreMessages {
|
||||
UNKNOWN,
|
||||
|
|
|
@ -2,4 +2,9 @@ package com.fsck.k9.backend.api
|
|||
|
||||
interface BackendStorage {
|
||||
fun getFolder(folderServerId: String): BackendFolder
|
||||
|
||||
fun getExtraString(name: String): String?
|
||||
fun setExtraString(name: String, value: String)
|
||||
fun getExtraNumber(name: String): Long?
|
||||
fun setExtraNumber(name: String, value: Long)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue