From e686a09ce4c31b077ebde72aa5fee865c10cf7e7 Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Tue, 6 Dec 2022 18:32:44 -0500 Subject: [PATCH] Convert GroupReceiptTable to kotlin. --- .../securesms/database/GroupReceiptTable.java | 204 ------------------ .../securesms/database/GroupReceiptTable.kt | 148 +++++++++++++ 2 files changed, 148 insertions(+), 204 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.java create mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.java b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.java deleted file mode 100644 index 677416ea8e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.java +++ /dev/null @@ -1,204 +0,0 @@ -package org.thoughtcrime.securesms.database; - - -import android.content.ContentValues; -import android.content.Context; -import android.database.Cursor; - -import androidx.annotation.NonNull; - -import org.signal.libsignal.protocol.util.Pair; -import org.thoughtcrime.securesms.recipients.RecipientId; -import org.signal.core.util.SqlUtil; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; - -import javax.annotation.Nullable; - -public class GroupReceiptTable extends DatabaseTable implements RecipientIdDatabaseReference { - - public static final String TABLE_NAME = "group_receipts"; - - private static final String ID = "_id"; - public static final String MMS_ID = "mms_id"; - static final String RECIPIENT_ID = "address"; - private static final String STATUS = "status"; - private static final String TIMESTAMP = "timestamp"; - private static final String UNIDENTIFIED = "unidentified"; - - public static final int STATUS_UNKNOWN = -1; - public static final int STATUS_UNDELIVERED = 0; - public static final int STATUS_DELIVERED = 1; - public static final int STATUS_READ = 2; - public static final int STATUS_VIEWED = 3; - public static final int STATUS_SKIPPED = 4; - - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + - MMS_ID + " INTEGER, " + RECIPIENT_ID + " INTEGER, " + STATUS + " INTEGER, " + TIMESTAMP + " INTEGER, " + UNIDENTIFIED + " INTEGER DEFAULT 0);"; - - public static final String[] CREATE_INDEXES = { - "CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", - }; - - public GroupReceiptTable(Context context, SignalDatabase databaseHelper) { - super(context, databaseHelper); - } - - public void insert(Collection recipientIds, long mmsId, int status, long timestamp) { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - - List contentValues = new ArrayList<>(recipientIds.size()); - for (RecipientId recipientId : recipientIds) { - ContentValues values = new ContentValues(4); - values.put(MMS_ID, mmsId); - values.put(RECIPIENT_ID, recipientId.serialize()); - values.put(STATUS, status); - values.put(TIMESTAMP, timestamp); - contentValues.add(values); - } - - List statements = SqlUtil.buildBulkInsert(TABLE_NAME, new String[] { MMS_ID, RECIPIENT_ID, STATUS, TIMESTAMP }, contentValues); - for (SqlUtil.Query statement : statements) { - db.execSQL(statement.getWhere(), statement.getWhereArgs()); - } - } - - public void update(@NonNull RecipientId recipientId, long mmsId, int status, long timestamp) { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - ContentValues values = new ContentValues(2); - values.put(STATUS, status); - values.put(TIMESTAMP, timestamp); - - db.update(TABLE_NAME, values, MMS_ID + " = ? AND " + RECIPIENT_ID + " = ? AND " + STATUS + " < ?", - new String[] {String.valueOf(mmsId), recipientId.serialize(), String.valueOf(status)}); - } - - public void setUnidentified(Collection> results, long mmsId) { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - - db.beginTransaction(); - try { - String query = MMS_ID + " = ? AND " + RECIPIENT_ID + " = ?"; - - for (Pair result : results) { - ContentValues values = new ContentValues(1); - values.put(UNIDENTIFIED, result.second() ? 1 : 0); - - db.update(TABLE_NAME, values, query, new String[]{ String.valueOf(mmsId), result.first().serialize()}); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - } - - public void setSkipped(Collection recipients, long mmsId) { - SQLiteDatabase db = getWritableDatabase(); - - db.beginTransaction(); - try { - String query = MMS_ID + " = ? AND " + RECIPIENT_ID + " = ?"; - - for (RecipientId recipient : recipients) { - ContentValues values = new ContentValues(1); - values.put(STATUS, STATUS_SKIPPED); - - db.update(TABLE_NAME, values, query, new String[]{ String.valueOf(mmsId), recipient.serialize()}); - } - - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - } - } - - public @NonNull List getGroupReceiptInfo(long mmsId) { - SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - List results = new LinkedList<>(); - - try (Cursor cursor = db.query(TABLE_NAME, null, MMS_ID + " = ?", new String[] {String.valueOf(mmsId)}, null, null, null)) { - while (cursor != null && cursor.moveToNext()) { - results.add(new GroupReceiptInfo(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID))), - cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)), - cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)), - cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1)); - } - } - - return results; - } - - public @Nullable GroupReceiptInfo getGroupReceiptInfo(long mmsId, @NonNull RecipientId recipientId) { - SQLiteDatabase db = databaseHelper.getSignalReadableDatabase(); - String query = MMS_ID + " = ? AND " + RECIPIENT_ID + " = ?"; - String[] args = SqlUtil.buildArgs(mmsId, recipientId); - - try (Cursor cursor = db.query(TABLE_NAME, null, query, args, null, null, "1")) { - if (cursor.moveToFirst()) { - return new GroupReceiptInfo(RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT_ID))), - cursor.getInt(cursor.getColumnIndexOrThrow(STATUS)), - cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)), - cursor.getInt(cursor.getColumnIndexOrThrow(UNIDENTIFIED)) == 1); - } - } - - return null; - } - - void deleteRowsForMessage(long mmsId) { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - db.delete(TABLE_NAME, MMS_ID + " = ?", new String[] {String.valueOf(mmsId)}); - } - - void deleteAbandonedRows() { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - db.delete(TABLE_NAME, MMS_ID + " NOT IN (SELECT " + MmsTable.ID + " FROM " + MmsTable.TABLE_NAME + ")", null); - } - - void deleteAllRows() { - SQLiteDatabase db = databaseHelper.getSignalWritableDatabase(); - db.delete(TABLE_NAME, null, null); - } - - @Override - public void remapRecipient(@NonNull RecipientId fromId, @NonNull RecipientId toId) { - ContentValues groupReceiptValues = new ContentValues(); - groupReceiptValues.put(RECIPIENT_ID, toId.serialize()); - - getWritableDatabase().update(TABLE_NAME, groupReceiptValues, RECIPIENT_ID + " = ?", SqlUtil.buildArgs(fromId)); - } - - public static class GroupReceiptInfo { - private final RecipientId recipientId; - private final int status; - private final long timestamp; - private final boolean unidentified; - - GroupReceiptInfo(@NonNull RecipientId recipientId, int status, long timestamp, boolean unidentified) { - this.recipientId = recipientId; - this.status = status; - this.timestamp = timestamp; - this.unidentified = unidentified; - } - - public @NonNull RecipientId getRecipientId() { - return recipientId; - } - - public int getStatus() { - return status; - } - - public long getTimestamp() { - return timestamp; - } - - public boolean isUnidentified() { - return unidentified; - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt new file mode 100644 index 0000000000..66be58294c --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/GroupReceiptTable.kt @@ -0,0 +1,148 @@ +package org.thoughtcrime.securesms.database + +import android.content.ContentValues +import android.content.Context +import androidx.core.content.contentValuesOf +import org.signal.core.util.SqlUtil +import org.signal.core.util.delete +import org.signal.core.util.readToList +import org.signal.core.util.requireBoolean +import org.signal.core.util.requireInt +import org.signal.core.util.requireLong +import org.signal.core.util.select +import org.signal.core.util.update +import org.signal.core.util.withinTransaction +import org.signal.libsignal.protocol.util.Pair +import org.thoughtcrime.securesms.recipients.RecipientId + +class GroupReceiptTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseTable(context, databaseHelper), RecipientIdDatabaseReference { + companion object { + const val TABLE_NAME = "group_receipts" + private const val ID = "_id" + const val MMS_ID = "mms_id" + const val RECIPIENT_ID = "address" + private const val STATUS = "status" + private const val TIMESTAMP = "timestamp" + private const val UNIDENTIFIED = "unidentified" + const val STATUS_UNKNOWN = -1 + const val STATUS_UNDELIVERED = 0 + const val STATUS_DELIVERED = 1 + const val STATUS_READ = 2 + const val STATUS_VIEWED = 3 + const val STATUS_SKIPPED = 4 + + const val CREATE_TABLE = """ + CREATE TABLE $TABLE_NAME ( + $ID INTEGER PRIMARY KEY, + $MMS_ID INTEGER, + $RECIPIENT_ID INTEGER, + $STATUS INTEGER, + $TIMESTAMP INTEGER, + $UNIDENTIFIED INTEGER DEFAULT 0 + ) + """ + + @JvmField + val CREATE_INDEXES = arrayOf( + "CREATE INDEX IF NOT EXISTS group_receipt_mms_id_index ON $TABLE_NAME ($MMS_ID);" + ) + } + + fun insert(recipientIds: Collection, mmsId: Long, status: Int, timestamp: Long) { + val contentValues: List = recipientIds.map { recipientId -> + contentValuesOf( + MMS_ID to mmsId, + RECIPIENT_ID to recipientId.serialize(), + STATUS to status, + TIMESTAMP to timestamp + ) + } + + val statements = SqlUtil.buildBulkInsert(TABLE_NAME, arrayOf(MMS_ID, RECIPIENT_ID, STATUS, TIMESTAMP), contentValues) + for (statement in statements) { + writableDatabase.execSQL(statement.where, statement.whereArgs) + } + } + + fun update(recipientId: RecipientId, mmsId: Long, status: Int, timestamp: Long) { + writableDatabase + .update(TABLE_NAME) + .values( + STATUS to status, + TIMESTAMP to timestamp + ) + .where("$MMS_ID = ? AND $RECIPIENT_ID = ? AND $STATUS < ?", mmsId.toString(), recipientId.serialize(), status.toString()) + .run() + } + + fun setUnidentified(results: Collection>, mmsId: Long) { + writableDatabase.withinTransaction { db -> + for (result in results) { + db.update(TABLE_NAME) + .values(UNIDENTIFIED to if (result.second()) 1 else 0) + .where("$MMS_ID = ? AND $RECIPIENT_ID = ?", mmsId.toString(), result.first().serialize()) + .run() + } + } + } + + fun setSkipped(recipients: Collection, mmsId: Long) { + writableDatabase.withinTransaction { db -> + for (recipient in recipients) { + db.update(TABLE_NAME) + .values(STATUS to STATUS_SKIPPED) + .where("$MMS_ID = ? AND $RECIPIENT_ID = ?", mmsId.toString(), recipient.serialize()) + .run() + } + } + } + + fun getGroupReceiptInfo(mmsId: Long): List { + return readableDatabase + .select() + .from(TABLE_NAME) + .where("$MMS_ID = ?", mmsId) + .run() + .readToList { cursor -> + GroupReceiptInfo( + recipientId = RecipientId.from(cursor.requireLong(RECIPIENT_ID)), + status = cursor.requireInt(STATUS), + timestamp = cursor.requireLong(TIMESTAMP), + isUnidentified = cursor.requireBoolean(UNIDENTIFIED) + ) + } + } + + fun deleteRowsForMessage(mmsId: Long) { + writableDatabase + .delete(TABLE_NAME) + .where("$MMS_ID = ?", mmsId) + .run() + } + + fun deleteAbandonedRows() { + writableDatabase + .delete(TABLE_NAME) + .where("$MMS_ID NOT IN (SELECT ${MmsTable.ID} FROM ${MmsTable.TABLE_NAME})") + .run() + } + + fun deleteAllRows() { + writableDatabase.delete(TABLE_NAME).run() + } + + override fun remapRecipient(fromId: RecipientId, toId: RecipientId) { + writableDatabase + .update(TABLE_NAME) + .values(RECIPIENT_ID to toId.serialize()) + .where("$RECIPIENT_ID = ?", fromId) + .run() + } + + data class GroupReceiptInfo( + val recipientId: RecipientId, + val status: Int, + val timestamp: Long, + val isUnidentified: Boolean + ) +}