Change delimiter in address fields from ASCII 0 to 1 (#5863)
Fixes search by sender name. Co-authored-by: Fath <fath@147dda1a2773.ant.amazon.com>
This commit is contained in:
parent
343ead3fda
commit
722e6b923f
4 changed files with 68 additions and 7 deletions
|
@ -12,7 +12,7 @@ import timber.log.Timber;
|
|||
|
||||
|
||||
class StoreSchemaDefinition implements SchemaDefinition {
|
||||
static final int DB_VERSION = 83;
|
||||
static final int DB_VERSION = 84;
|
||||
|
||||
private final MigrationsHelper migrationsHelper;
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package com.fsck.k9.storage.migrations
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import androidx.core.database.getStringOrNull
|
||||
import com.fsck.k9.helper.map
|
||||
|
||||
/**
|
||||
* Write the address fields to use ASCII 1 instead of ASCII 0 as separator.
|
||||
* Separator was previously ASCII 0 but this caused problems with LIKE and searching.
|
||||
*/
|
||||
internal class MigrationTo84(private val db: SQLiteDatabase) {
|
||||
|
||||
fun rewriteAddresses() {
|
||||
val addressSets = db.rawQuery(
|
||||
"SELECT id, to_list, cc_list, bcc_list, reply_to_list, sender_list FROM messages WHERE empty = 0 AND deleted = 0",
|
||||
null
|
||||
).use { cursor ->
|
||||
cursor.map {
|
||||
|
||||
val messageId = it.getLong(0)
|
||||
|
||||
messageId to AddressSet(
|
||||
toList = it.getStringOrNull(1),
|
||||
ccList = it.getStringOrNull(2),
|
||||
bccList = it.getStringOrNull(3),
|
||||
replyToList = it.getStringOrNull(4),
|
||||
senderList = it.getStringOrNull(5)
|
||||
)
|
||||
}.toMap()
|
||||
}
|
||||
|
||||
for ((messageId, addressSet) in addressSets) {
|
||||
rewriteAddresses(messageId, addressSet)
|
||||
}
|
||||
}
|
||||
|
||||
private fun rewriteAddress(inAddress: String?): String? {
|
||||
return inAddress?.replace(oldChar = '\u0000', newChar = '\u0001')
|
||||
}
|
||||
|
||||
private fun rewriteAddresses(messageId: Long, addressSet: AddressSet) {
|
||||
val cv = ContentValues().apply {
|
||||
put("to_list", rewriteAddress(addressSet.toList))
|
||||
put("cc_list", rewriteAddress(addressSet.ccList))
|
||||
put("bcc_list", rewriteAddress(addressSet.bccList))
|
||||
put("reply_to_list", rewriteAddress(addressSet.replyToList))
|
||||
put("sender_list", rewriteAddress(addressSet.senderList))
|
||||
}
|
||||
db.update("messages", cv, "id = ?", arrayOf(messageId.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
private data class AddressSet(
|
||||
val toList: String?,
|
||||
val ccList: String?,
|
||||
val bccList: String?,
|
||||
val replyToList: String?,
|
||||
val senderList: String?
|
||||
)
|
|
@ -29,5 +29,6 @@ object Migrations {
|
|||
if (oldVersion < 81) MigrationTo81(db).addNotificationsTable()
|
||||
if (oldVersion < 82) MigrationTo82(db).addNewMessageColumn()
|
||||
if (oldVersion < 83) MigrationTo83(db, migrationsHelper).rewriteHighestKnownUid()
|
||||
if (oldVersion < 84) MigrationTo84(db).rewriteAddresses()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,11 +219,11 @@ public class Address implements Serializable {
|
|||
int pairEndIndex = 0;
|
||||
int addressEndIndex = 0;
|
||||
while (pairStartIndex < length) {
|
||||
pairEndIndex = addressList.indexOf(",\u0000", pairStartIndex);
|
||||
pairEndIndex = addressList.indexOf(",\u0001", pairStartIndex);
|
||||
if (pairEndIndex == -1) {
|
||||
pairEndIndex = length;
|
||||
}
|
||||
addressEndIndex = addressList.indexOf(";\u0000", pairStartIndex);
|
||||
addressEndIndex = addressList.indexOf(";\u0001", pairStartIndex);
|
||||
String address = null;
|
||||
String personal = null;
|
||||
if (addressEndIndex == -1 || addressEndIndex > pairEndIndex) {
|
||||
|
@ -241,8 +241,8 @@ public class Address implements Serializable {
|
|||
/**
|
||||
* Packs an address list into a String that is very quick to read
|
||||
* and parse. Packed lists can be unpacked with unpackAddressList()
|
||||
* The packed list is a ",\u0000" separated list of:
|
||||
* address;\u0000personal
|
||||
* The packed list is a ",\u0001" separated list of:
|
||||
* address;\u0001personal
|
||||
* @param addresses Array of addresses to pack.
|
||||
* @return Packed addresses.
|
||||
*/
|
||||
|
@ -256,13 +256,13 @@ public class Address implements Serializable {
|
|||
sb.append(address.getAddress());
|
||||
String personal = address.getPersonal();
|
||||
if (personal != null) {
|
||||
sb.append(";\u0000");
|
||||
sb.append(";\u0001");
|
||||
// Escape quotes in the address part on the way in
|
||||
personal = personal.replaceAll("\"", "\\\"");
|
||||
sb.append(personal);
|
||||
}
|
||||
if (i < count - 1) {
|
||||
sb.append(",\u0000");
|
||||
sb.append(",\u0001");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
|
Loading…
Reference in a new issue