Improve updates to CdsDatabase.

fork-5.53.8
Greyson Parrelli 2022-04-26 13:59:24 -04:00
rodzic eccb796199
commit 8cb74fb776
9 zmienionych plików z 66 dodań i 30 usunięć

Wyświetl plik

@ -278,7 +278,7 @@ public class AttachmentDatabase extends Database {
}
SQLiteDatabase database = databaseHelper.getSignalReadableDatabase();
SqlUtil.Query query = SqlUtil.buildCollectionQuery(MMS_ID, mmsIds);
SqlUtil.Query query = SqlUtil.buildSingleCollectionQuery(MMS_ID, mmsIds);
Map<Long, List<DatabaseAttachment>> output = new HashMap<>();

Wyświetl plik

@ -68,13 +68,10 @@ class CdsDatabase(context: Context, databaseHelper: SignalDatabase) : Database(c
SqlUtil.buildBulkInsert(TABLE_NAME, arrayOf(E164), insertValues)
.forEach { writableDatabase.execSQL(it.where, it.whereArgs) }
for (e164 in seenE164s) {
writableDatabase
.update(TABLE_NAME)
.values(LAST_SEEN_AT to lastSeen)
.where("$E164 = ?", e164)
.run()
}
val contentValues = contentValuesOf(LAST_SEEN_AT to lastSeen)
SqlUtil.buildCollectionQuery(E164, seenE164s)
.forEach { query -> writableDatabase.update(TABLE_NAME, contentValues, query.where, query.whereArgs) }
writableDatabase.setTransactionSuccessful()
} finally {

Wyświetl plik

@ -330,7 +330,7 @@ public abstract class MessageDatabase extends Database implements MmsSmsColumns
}
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
SqlUtil.Query where = SqlUtil.buildCollectionQuery(ID, ids);
SqlUtil.Query where = SqlUtil.buildSingleCollectionQuery(ID, ids);
ContentValues values = new ContentValues();
values.put(NOTIFIED_TIMESTAMP, timestamp);

Wyświetl plik

@ -1378,7 +1378,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
db.beginTransaction()
try {
val query = SqlUtil.buildCollectionQuery(ID, ids)
val query = SqlUtil.buildSingleCollectionQuery(ID, ids)
val values = ContentValues().apply {
put(MUTE_UNTIL, until)
}
@ -2518,7 +2518,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
}
if (Util.hasItems(idsToUpdate)) {
val query = SqlUtil.buildCollectionQuery(ID, idsToUpdate)
val query = SqlUtil.buildSingleCollectionQuery(ID, idsToUpdate)
val values = ContentValues(1).apply {
put(PROFILE_SHARING, 1)
}
@ -2536,7 +2536,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
return
}
var query = SqlUtil.buildCollectionQuery(ID, recipientIds)
var query = SqlUtil.buildSingleCollectionQuery(ID, recipientIds)
val db = writableDatabase
db.query(TABLE_NAME, arrayOf(ID), "${query.where} AND $GROUPS_IN_COMMON = 0", query.whereArgs, null, null, null).use { cursor ->
@ -2547,7 +2547,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
}
if (Util.hasItems(idsToUpdate)) {
query = SqlUtil.buildCollectionQuery(ID, idsToUpdate)
query = SqlUtil.buildSingleCollectionQuery(ID, idsToUpdate)
val values = ContentValues().apply {
put(GROUPS_IN_COMMON, 1)
}

Wyświetl plik

@ -119,7 +119,7 @@ class SessionDatabase(context: Context, databaseHelper: SignalDatabase) : Databa
}
fun getAllFor(serviceId: ServiceId, addressNames: List<String?>): List<SessionRow> {
val query: SqlUtil.Query = SqlUtil.buildCollectionQuery(ADDRESS, addressNames)
val query: SqlUtil.Query = SqlUtil.buildSingleCollectionQuery(ADDRESS, addressNames)
val results: MutableList<SessionRow> = LinkedList()
val queryString = "$ACCOUNT_ID = ? AND (${query.where})"

Wyświetl plik

@ -472,7 +472,7 @@ public class ThreadDatabase extends Database {
db.beginTransaction();
try {
SqlUtil.Query query = SqlUtil.buildCollectionQuery(ID, threadIds);
SqlUtil.Query query = SqlUtil.buildSingleCollectionQuery(ID, threadIds);
ContentValues contentValues = new ContentValues();
contentValues.put(READ, ReadStatus.FORCED_UNREAD.serialize());
@ -1062,7 +1062,7 @@ public class ThreadDatabase extends Database {
public Map<RecipientId, Long> getThreadIdsIfExistsFor(@NonNull RecipientId ... recipientIds) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
SqlUtil.Query query = SqlUtil.buildCollectionQuery(RECIPIENT_ID, Arrays.asList(recipientIds));
SqlUtil.Query query = SqlUtil.buildSingleCollectionQuery(RECIPIENT_ID, Arrays.asList(recipientIds));
Map<RecipientId, Long> results = new HashMap<>();
try (Cursor cursor = db.query(TABLE_NAME, new String[]{ ID, RECIPIENT_ID }, query.getWhere(), query.getWhereArgs(), null, null, null, "1")) {
@ -1140,7 +1140,7 @@ public class ThreadDatabase extends Database {
public @NonNull List<RecipientId> getRecipientIdsForThreadIds(Collection<Long> threadIds) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
SqlUtil.Query query = SqlUtil.buildCollectionQuery(ID, threadIds);
SqlUtil.Query query = SqlUtil.buildSingleCollectionQuery(ID, threadIds);
List<RecipientId> ids = new ArrayList<>(threadIds.size());
try (Cursor cursor = db.query(TABLE_NAME, new String[] { RECIPIENT_ID }, query.getWhere(), query.getWhereArgs(), null, null, null)) {

Wyświetl plik

@ -7,8 +7,6 @@ import android.database.Cursor;
import androidx.annotation.NonNull;
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;
@ -67,7 +65,7 @@ public class UnknownStorageIdDatabase extends Database {
*/
public List<StorageId> getAllWithTypes(List<Integer> types) {
List<StorageId> ids = new ArrayList<>();
SqlUtil.Query query = SqlUtil.buildCollectionQuery(TYPE, types);
SqlUtil.Query query = SqlUtil.buildSingleCollectionQuery(TYPE, types);
try (Cursor cursor = databaseHelper.getSignalReadableDatabase().query(TABLE_NAME, null, query.getWhere(), query.getWhereArgs(), null, null, null)) {
while (cursor != null && cursor.moveToNext()) {

Wyświetl plik

@ -183,8 +183,33 @@ object SqlUtil {
return Query("($selection) AND ($qualifier)", fullArgs.toTypedArray())
}
/**
* A convenient way of making queries in the form: WHERE [column] IN (?, ?, ..., ?)
* Handles breaking it
*/
@JvmStatic
fun buildCollectionQuery(column: String, values: Collection<Any?>): Query {
fun buildCollectionQuery(column: String, values: Collection<Any?>): List<Query> {
return buildCollectionQuery(column, values, MAX_QUERY_ARGS)
}
@VisibleForTesting
@JvmStatic
fun buildCollectionQuery(column: String, values: Collection<Any?>, maxSize: Int): List<Query> {
require(!values.isEmpty()) { "Must have values!" }
return values
.chunked(maxSize)
.map { batch -> buildSingleCollectionQuery(column, batch) }
}
/**
* A convenient way of making queries in the form: WHERE [column] IN (?, ?, ..., ?)
*
* Important: Should only be used if you know the number of values is < 1000. Otherwise you risk creating a SQL statement this is too large.
* Prefer [buildCollectionQuery] when possible.
*/
@JvmStatic
fun buildSingleCollectionQuery(column: String, values: Collection<Any?>): Query {
require(!values.isEmpty()) { "Must have values!" }
val query = StringBuilder()

Wyświetl plik

@ -117,26 +117,42 @@ public final class SqlUtilTest {
@Test
public void buildCollectionQuery_single() {
SqlUtil.Query updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(1));
List<SqlUtil.Query> updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(1));
assertEquals("a IN (?)", updateQuery.getWhere());
assertArrayEquals(new String[] { "1" }, updateQuery.getWhereArgs());
assertEquals(1, updateQuery.size());
assertEquals("a IN (?)", updateQuery.get(0).getWhere());
assertArrayEquals(new String[] { "1" }, updateQuery.get(0).getWhereArgs());
}
@Test
public void buildCollectionQuery_multiple() {
SqlUtil.Query updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(1, 2, 3));
List<SqlUtil.Query> updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(1, 2, 3));
assertEquals("a IN (?, ?, ?)", updateQuery.getWhere());
assertArrayEquals(new String[] { "1", "2", "3" }, updateQuery.getWhereArgs());
assertEquals(1, updateQuery.size());
assertEquals("a IN (?, ?, ?)", updateQuery.get(0).getWhere());
assertArrayEquals(new String[] { "1", "2", "3" }, updateQuery.get(0).getWhereArgs());
}
@Test
public void buildCollectionQuery_multiple_twoBatches() {
List<SqlUtil.Query> updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(1, 2, 3), 2);
assertEquals(2, updateQuery.size());
assertEquals("a IN (?, ?)", updateQuery.get(0).getWhere());
assertArrayEquals(new String[] { "1", "2" }, updateQuery.get(0).getWhereArgs());
assertEquals("a IN (?)", updateQuery.get(1).getWhere());
assertArrayEquals(new String[] { "3" }, updateQuery.get(1).getWhereArgs());
}
@Test
public void buildCollectionQuery_multipleRecipientIds() {
SqlUtil.Query updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(new TestId(1), new TestId(2), new TestId(3)));
List<SqlUtil.Query> updateQuery = SqlUtil.buildCollectionQuery("a", Arrays.asList(new TestId(1), new TestId(2), new TestId(3)));
assertEquals("a IN (?, ?, ?)", updateQuery.getWhere());
assertArrayEquals(new String[] { "1", "2", "3" }, updateQuery.getWhereArgs());
assertEquals(1, updateQuery.size());
assertEquals("a IN (?, ?, ?)", updateQuery.get(0).getWhere());
assertArrayEquals(new String[] { "1", "2", "3" }, updateQuery.get(0).getWhereArgs());
}
@Test(expected = IllegalArgumentException.class)