Improve handling of unknown IDs in storage service.

This commit is contained in:
Greyson Parrelli
2022-04-04 09:54:50 -04:00
committed by Cody Henthorne
parent e2c54eef77
commit b34ca8ca2f
7 changed files with 139 additions and 77 deletions

View File

@@ -9,6 +9,7 @@ import androidx.annotation.Nullable;
import com.annimon.stream.Stream;
import org.signal.core.util.CursorUtil;
import org.thoughtcrime.securesms.util.Base64;
import org.signal.core.util.SqlUtil;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
@@ -46,13 +47,10 @@ public class UnknownStorageIdDatabase extends Database {
public List<StorageId> getAllUnknownIds() {
List<StorageId> keys = new ArrayList<>();
String query = TYPE + " > ?";
String[] args = SqlUtil.buildArgs(StorageId.largestKnownType());
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, query, args, null, null, null)) {
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, null, null, null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
String keyEncoded = cursor.getString(cursor.getColumnIndexOrThrow(STORAGE_ID));
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
String keyEncoded = CursorUtil.requireString(cursor, STORAGE_ID);
int type = CursorUtil.requireInt(cursor, TYPE);
try {
keys.add(StorageId.forType(Base64.decode(keyEncoded), type));
} catch (IOException e) {
@@ -64,13 +62,35 @@ public class UnknownStorageIdDatabase extends Database {
return keys;
}
/**
* Gets all StorageIds of items with the specified types.
*/
public List<StorageId> getAllWithTypes(List<Integer> types) {
List<StorageId> ids = new ArrayList<>();
SqlUtil.Query query = SqlUtil.buildCollectionQuery(TYPE, types);
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, query.getWhere(), query.getWhereArgs(), null, null, null)) {
while (cursor != null && cursor.moveToNext()) {
String keyEncoded = CursorUtil.requireString(cursor, STORAGE_ID);
int type = CursorUtil.requireInt(cursor, TYPE);
try {
ids.add(StorageId.forType(Base64.decode(keyEncoded), type));
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
return ids;
}
public @Nullable SignalStorageRecord getById(@NonNull byte[] rawId) {
String query = STORAGE_ID + " = ?";
String[] args = new String[] { Base64.encodeBytes(rawId) };
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, query, args, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE));
int type = CursorUtil.requireInt(cursor, TYPE);
return SignalStorageRecord.forUnknown(StorageId.forType(rawId, type));
} else {
return null;
@@ -78,22 +98,6 @@ public class UnknownStorageIdDatabase extends Database {
}
}
public void applyStorageSyncUpdates(@NonNull Collection<SignalStorageRecord> inserts,
@NonNull Collection<SignalStorageRecord> deletes)
{
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
db.beginTransaction();
try {
insert(inserts);
delete(Stream.of(deletes).map(SignalStorageRecord::getId).toList());
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
public void insert(@NonNull Collection<SignalStorageRecord> inserts) {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
@@ -120,13 +124,6 @@ public class UnknownStorageIdDatabase extends Database {
}
}
public void deleteByType(int type) {
String query = TYPE + " = ?";
String[] args = new String[]{String.valueOf(type)};
databaseHelper.getSignalWritableDatabase().delete(TABLE_NAME, query, args);
}
public void deleteAll() {
databaseHelper.getSignalWritableDatabase().delete(TABLE_NAME, null, null);
}

View File

@@ -197,8 +197,9 @@ object SignalDatabaseMigrations {
private const val STORY_SENDS = 136
private const val STORY_TYPE_AND_DISTRIBUTION = 137
private const val CLEAN_DELETED_DISTRIBUTION_LISTS = 138
private const val REMOVE_KNOWN_UNKNOWNS = 139
const val DATABASE_VERSION = 138
const val DATABASE_VERSION = 139
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -2535,6 +2536,11 @@ object SignalDatabaseMigrations {
""".trimIndent()
)
}
if (oldVersion < REMOVE_KNOWN_UNKNOWNS) {
val count: Int = db.delete("storage_key", "type <= ?", SqlUtil.buildArgs(4))
Log.i(TAG, "Cleaned up $count invalid unknown records.")
}
}
@JvmStatic