Migrate SMS messages into the MMS table.

This commit is contained in:
Greyson Parrelli
2022-12-14 14:52:54 -05:00
parent cb0e7ade14
commit e9d98b7d39
59 changed files with 4399 additions and 6146 deletions

View File

@@ -6,7 +6,7 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.MessageTable;
public class MmsNotificationAttachment extends Attachment {
@@ -26,11 +26,11 @@ public class MmsNotificationAttachment extends Attachment {
}
private static int getTransferStateFromStatus(int status) {
if (status == MmsTable.Status.DOWNLOAD_INITIALIZED ||
status == MmsTable.Status.DOWNLOAD_NO_CONNECTIVITY)
if (status == MessageTable.MmsStatus.DOWNLOAD_INITIALIZED ||
status == MessageTable.MmsStatus.DOWNLOAD_NO_CONNECTIVITY)
{
return AttachmentTable.TRANSFER_PROGRESS_PENDING;
} else if (status == MmsTable.Status.DOWNLOAD_CONNECTING) {
} else if (status == MessageTable.MmsStatus.DOWNLOAD_CONNECTING) {
return AttachmentTable.TRANSFER_PROGRESS_STARTED;
} else {
return AttachmentTable.TRANSFER_PROGRESS_FAILED;

View File

@@ -2,29 +2,26 @@ package org.thoughtcrime.securesms.backup
import org.thoughtcrime.securesms.database.AttachmentTable
import org.thoughtcrime.securesms.database.GroupReceiptTable
import org.thoughtcrime.securesms.database.MmsTable
import org.thoughtcrime.securesms.database.SmsTable
import org.thoughtcrime.securesms.database.MessageTable
/**
* Queries used by backup exporter to estimate total counts for various complicated tables.
*/
object BackupCountQueries {
const val mmsCount: String = "SELECT COUNT(*) FROM ${MmsTable.TABLE_NAME} WHERE ${MmsTable.EXPIRES_IN} <= 0 AND ${MmsTable.VIEW_ONCE} <= 0"
const val smsCount: String = "SELECT COUNT(*) FROM ${SmsTable.TABLE_NAME} WHERE ${SmsTable.EXPIRES_IN} <= 0"
const val mmsCount: String = "SELECT COUNT(*) FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.EXPIRES_IN} <= 0 AND ${MessageTable.VIEW_ONCE} <= 0"
@get:JvmStatic
val groupReceiptCount: String = """
SELECT COUNT(*) FROM ${GroupReceiptTable.TABLE_NAME}
INNER JOIN ${MmsTable.TABLE_NAME} ON ${GroupReceiptTable.TABLE_NAME}.${GroupReceiptTable.MMS_ID} = ${MmsTable.TABLE_NAME}.${MmsTable.ID}
WHERE ${MmsTable.TABLE_NAME}.${MmsTable.EXPIRES_IN} <= 0 AND ${MmsTable.TABLE_NAME}.${MmsTable.VIEW_ONCE} <= 0
INNER JOIN ${MessageTable.TABLE_NAME} ON ${GroupReceiptTable.TABLE_NAME}.${GroupReceiptTable.MMS_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE ${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} <= 0 AND ${MessageTable.TABLE_NAME}.${MessageTable.VIEW_ONCE} <= 0
""".trimIndent()
@get:JvmStatic
val attachmentCount: String = """
SELECT COUNT(*) FROM ${AttachmentTable.TABLE_NAME}
INNER JOIN ${MmsTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} = ${MmsTable.TABLE_NAME}.${MmsTable.ID}
WHERE ${MmsTable.TABLE_NAME}.${MmsTable.EXPIRES_IN} <= 0 AND ${MmsTable.TABLE_NAME}.${MmsTable.VIEW_ONCE} <= 0
INNER JOIN ${MessageTable.TABLE_NAME} ON ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
WHERE ${MessageTable.TABLE_NAME}.${MessageTable.EXPIRES_IN} <= 0 AND ${MessageTable.TABLE_NAME}.${MessageTable.VIEW_ONCE} <= 0
""".trimIndent()
}

View File

@@ -34,7 +34,7 @@ import org.thoughtcrime.securesms.database.EmojiSearchTable;
import org.thoughtcrime.securesms.database.GroupReceiptTable;
import org.thoughtcrime.securesms.database.KeyValueDatabase;
import org.thoughtcrime.securesms.database.MentionTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.OneTimePreKeyTable;
import org.thoughtcrime.securesms.database.PendingRetryReceiptTable;
@@ -44,7 +44,6 @@ import org.thoughtcrime.securesms.database.SenderKeyTable;
import org.thoughtcrime.securesms.database.SenderKeySharedTable;
import org.thoughtcrime.securesms.database.SessionTable;
import org.thoughtcrime.securesms.database.SignedPreKeyTable;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.StickerTable;
import org.thoughtcrime.securesms.database.model.AvatarPickerDatabase;
import org.thoughtcrime.securesms.database.model.MessageId;
@@ -99,7 +98,6 @@ public class FullBackupExporter extends FullBackupBase {
SignedPreKeyTable.TABLE_NAME,
OneTimePreKeyTable.TABLE_NAME,
SessionTable.TABLE_NAME,
SearchTable.SMS_FTS_TABLE_NAME,
SearchTable.MMS_FTS_TABLE_NAME,
EmojiSearchTable.TABLE_NAME,
SenderKeyTable.TABLE_NAME,
@@ -172,10 +170,8 @@ public class FullBackupExporter extends FullBackupBase {
for (String table : tables) {
throwIfCanceled(cancellationSignal);
if (table.equals(MmsTable.TABLE_NAME)) {
if (table.equals(MessageTable.TABLE_NAME)) {
count = exportTable(table, input, outputStream, FullBackupExporter::isNonExpiringMmsMessage, null, count, estimatedCount, cancellationSignal);
} else if (table.equals(SmsTable.TABLE_NAME)) {
count = exportTable(table, input, outputStream, FullBackupExporter::isNonExpiringSmsMessage, null, count, estimatedCount, cancellationSignal);
} else if (table.equals(ReactionTable.TABLE_NAME)) {
count = exportTable(table, input, outputStream, cursor -> isForNonExpiringMessage(input, new MessageId(CursorUtil.requireLong(cursor, ReactionTable.MESSAGE_ID), CursorUtil.requireBoolean(cursor, ReactionTable.IS_MMS))), null, count, estimatedCount, cancellationSignal);
} else if (table.equals(MentionTable.TABLE_NAME)) {
@@ -230,10 +226,8 @@ public class FullBackupExporter extends FullBackupBase {
long count = DATABASE_VERSION_RECORD_COUNT + TABLE_RECORD_COUNT_MULTIPLIER * tables.size();
for (String table : tables) {
if (table.equals(MmsTable.TABLE_NAME)) {
if (table.equals(MessageTable.TABLE_NAME)) {
count += getCount(input, BackupCountQueries.mmsCount);
} else if (table.equals(SmsTable.TABLE_NAME)) {
count += getCount(input, BackupCountQueries.smsCount);
} else if (table.equals(GroupReceiptTable.TABLE_NAME)) {
count += getCount(input, BackupCountQueries.getGroupReceiptCount());
} else if (table.equals(AttachmentTable.TABLE_NAME)) {
@@ -375,12 +369,10 @@ public class FullBackupExporter extends FullBackupBase {
}
boolean isReservedTable = table.startsWith("sqlite_");
boolean isSmsFtsSecretTable = !table.equals(SearchTable.SMS_FTS_TABLE_NAME) && table.startsWith(SearchTable.SMS_FTS_TABLE_NAME);
boolean isMmsFtsSecretTable = !table.equals(SearchTable.MMS_FTS_TABLE_NAME) && table.startsWith(SearchTable.MMS_FTS_TABLE_NAME);
boolean isEmojiFtsSecretTable = !table.equals(EmojiSearchTable.TABLE_NAME) && table.startsWith(EmojiSearchTable.TABLE_NAME);
return !isReservedTable &&
!isSmsFtsSecretTable &&
!isMmsFtsSecretTable &&
!isEmojiFtsSecretTable;
}
@@ -587,7 +579,7 @@ public class FullBackupExporter extends FullBackupBase {
private static boolean isNonExpiringMmsMessage(@NonNull Cursor cursor) {
return cursor.getLong(cursor.getColumnIndexOrThrow(MmsSmsColumns.EXPIRES_IN)) <= 0 &&
cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.VIEW_ONCE)) <= 0;
cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.VIEW_ONCE)) <= 0;
}
private static boolean isNonExpiringSmsMessage(@NonNull Cursor cursor) {
@@ -595,33 +587,15 @@ public class FullBackupExporter extends FullBackupBase {
}
private static boolean isForNonExpiringMessage(@NonNull SQLiteDatabase db, @NonNull MessageId messageId) {
if (messageId.isMms()) {
return isForNonExpiringMmsMessage(db, messageId.getId());
} else {
return isForNonExpiringSmsMessage(db, messageId.getId());
}
}
private static boolean isForNonExpiringSmsMessage(@NonNull SQLiteDatabase db, long smsId) {
String[] columns = new String[] { SmsTable.EXPIRES_IN };
String where = SmsTable.ID + " = ?";
String[] args = new String[] { String.valueOf(smsId) };
try (Cursor cursor = db.query(SmsTable.TABLE_NAME, columns, where, args, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
return isNonExpiringSmsMessage(cursor);
}
}
return false;
return isForNonExpiringMmsMessage(db, messageId.getId());
}
private static boolean isForNonExpiringMmsMessage(@NonNull SQLiteDatabase db, long mmsId) {
String[] columns = new String[] { MmsTable.RECIPIENT_ID, MmsTable.EXPIRES_IN, MmsTable.VIEW_ONCE };
String where = MmsTable.ID + " = ?";
String[] columns = new String[] { MessageTable.RECIPIENT_ID, MessageTable.EXPIRES_IN, MessageTable.VIEW_ONCE };
String where = MessageTable.ID + " = ?";
String[] args = new String[] { String.valueOf(mmsId) };
try (Cursor mmsCursor = db.query(MmsTable.TABLE_NAME, columns, where, args, null, null, null)) {
try (Cursor mmsCursor = db.query(MessageTable.TABLE_NAME, columns, where, args, null, null, null)) {
if (mmsCursor != null && mmsCursor.moveToFirst()) {
return isNonExpiringMmsMessage(mmsCursor);
}

View File

@@ -127,12 +127,11 @@ public class FullBackupImporter extends FullBackupBase {
}
private static void processStatement(@NonNull SQLiteDatabase db, SqlStatement statement) {
boolean isForSmsFtsSecretTable = statement.getStatement().contains(SearchTable.SMS_FTS_TABLE_NAME + "_");
boolean isForMmsFtsSecretTable = statement.getStatement().contains(SearchTable.MMS_FTS_TABLE_NAME + "_");
boolean isForEmojiSecretTable = statement.getStatement().contains(EmojiSearchTable.TABLE_NAME + "_");
boolean isForSqliteSecretTable = statement.getStatement().toLowerCase().startsWith("create table sqlite_");
if (isForSmsFtsSecretTable || isForMmsFtsSecretTable || isForEmojiSecretTable || isForSqliteSecretTable) {
if (isForMmsFtsSecretTable || isForEmojiSecretTable || isForSqliteSecretTable) {
Log.i(TAG, "Ignoring import for statement: " + statement.getStatement());
return;
}

View File

@@ -110,9 +110,7 @@ import org.thoughtcrime.securesms.conversation.mutiselect.forward.MultiselectFor
import org.thoughtcrime.securesms.conversation.quotes.MessageQuotesBottomSheet;
import org.thoughtcrime.securesms.conversation.ui.error.EnableCallNotificationSettingsDialog;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.model.InMemoryMessageRecord;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageId;
@@ -1198,7 +1196,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
}
public long stageOutgoingMessage(OutgoingMediaMessage message) {
MessageRecord messageRecord = MmsTable.readerFor(message, threadId).getCurrent();
MessageRecord messageRecord = MessageTable.readerFor(message, threadId).getCurrent();
if (getListAdapter() != null) {
setLastSeen(0);
@@ -1209,7 +1207,7 @@ public class ConversationFragment extends LoggingFragment implements Multiselect
}
public long stageOutgoingMessage(OutgoingTextMessage message, long messageId) {
MessageRecord messageRecord = SmsTable.readerFor(message, threadId, messageId).getCurrent();
MessageRecord messageRecord = MessageTable.readerFor(message, threadId, messageId).getCurrent();
if (getListAdapter() != null) {
setLastSeen(0);

View File

@@ -113,14 +113,7 @@ public final class SafetyNumberChangeRepository {
@WorkerThread
private @Nullable MessageRecord getMessageRecord(Long messageId, String messageType) {
try {
switch (messageType) {
case MmsSmsTable.SMS_TRANSPORT:
return SignalDatabase.sms().getMessageRecord(messageId);
case MmsSmsTable.MMS_TRANSPORT:
return SignalDatabase.mms().getMessageRecord(messageId);
default:
throw new AssertionError("no valid message type specified");
}
return SignalDatabase.mms().getMessageRecord(messageId);
} catch (NoSuchMessageException e) {
Log.i(TAG, e);
}

View File

@@ -14,8 +14,8 @@ import org.signal.paging.PagedDataSource;
import org.thoughtcrime.securesms.conversationlist.model.Conversation;
import org.thoughtcrime.securesms.conversationlist.model.ConversationFilter;
import org.thoughtcrime.securesms.conversationlist.model.ConversationReader;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.ThreadRecord;
@@ -77,9 +77,9 @@ abstract class ConversationListDataSource implements PagedDataSource<Long, Conve
recipients.add(record.getRecipient());
needsResolve.add(record.getGroupMessageSender());
if (!SmsTable.Types.isGroupV2(record.getType())) {
if (!MmsSmsColumns.Types.isGroupV2(record.getType())) {
needsResolve.add(record.getRecipient().getId());
} else if (SmsTable.Types.isGroupUpdate(record.getType())) {
} else if (MmsSmsColumns.Types.isGroupUpdate(record.getType())) {
UpdateDescription description = MessageRecord.getGv2ChangeDescription(ApplicationDependencies.getApplication(), record.getBody(), null);
needsResolve.addAll(description.getMentioned().stream().map(RecipientId::from).collect(Collectors.toList()));
}

View File

@@ -59,7 +59,6 @@ import org.thoughtcrime.securesms.components.TypingIndicatorView;
import org.thoughtcrime.securesms.components.emoji.EmojiStrings;
import org.thoughtcrime.securesms.conversationlist.model.ConversationSet;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.database.model.LiveUpdateMessage;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -509,51 +508,51 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
if (!thread.isMessageRequestAccepted()) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_message_request), defaultTint);
} else if (SmsTable.Types.isGroupUpdate(thread.getType())) {
} else if (MmsSmsColumns.Types.isGroupUpdate(thread.getType())) {
if (thread.getRecipient().isPushV2Group()) {
return emphasisAdded(context, MessageRecord.getGv2ChangeDescription(context, thread.getBody(), null), defaultTint);
} else {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_group_updated), R.drawable.ic_update_group_16, defaultTint);
}
} else if (SmsTable.Types.isGroupQuit(thread.getType())) {
} else if (MmsSmsColumns.Types.isGroupQuit(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_left_the_group), R.drawable.ic_update_group_leave_16, defaultTint);
} else if (SmsTable.Types.isKeyExchangeType(thread.getType())) {
} else if (MmsSmsColumns.Types.isKeyExchangeType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ConversationListItem_key_exchange_message), defaultTint);
} else if (SmsTable.Types.isChatSessionRefresh(thread.getType())) {
} else if (MmsSmsColumns.Types.isChatSessionRefresh(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_chat_session_refreshed), R.drawable.ic_refresh_16, defaultTint);
} else if (SmsTable.Types.isNoRemoteSessionType(thread.getType())) {
} else if (MmsSmsColumns.Types.isNoRemoteSessionType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.MessageDisplayHelper_message_encrypted_for_non_existing_session), defaultTint);
} else if (SmsTable.Types.isEndSessionType(thread.getType())) {
} else if (MmsSmsColumns.Types.isEndSessionType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_secure_session_reset), defaultTint);
} else if (MmsSmsColumns.Types.isLegacyType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported), defaultTint);
} else if (MmsSmsColumns.Types.isDraftMessageType(thread.getType())) {
String draftText = context.getString(R.string.ThreadRecord_draft);
return emphasisAdded(context, draftText + " " + thread.getBody(), defaultTint);
} else if (SmsTable.Types.isOutgoingAudioCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isOutgoingAudioCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called), R.drawable.ic_update_audio_call_outgoing_16, defaultTint);
} else if (SmsTable.Types.isOutgoingVideoCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isOutgoingVideoCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called), R.drawable.ic_update_video_call_outgoing_16, defaultTint);
} else if (SmsTable.Types.isIncomingAudioCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isIncomingAudioCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called_you), R.drawable.ic_update_audio_call_incoming_16, defaultTint);
} else if (SmsTable.Types.isIncomingVideoCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isIncomingVideoCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_called_you), R.drawable.ic_update_video_call_incoming_16, defaultTint);
} else if (SmsTable.Types.isMissedAudioCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isMissedAudioCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_missed_audio_call), R.drawable.ic_update_audio_call_missed_16, defaultTint);
} else if (SmsTable.Types.isMissedVideoCall(thread.getType())) {
} else if (MmsSmsColumns.Types.isMissedVideoCall(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_missed_video_call), R.drawable.ic_update_video_call_missed_16, defaultTint);
} else if (MmsSmsColumns.Types.isGroupCall(thread.getType())) {
return emphasisAdded(context, MessageRecord.getGroupCallUpdateDescription(context, thread.getBody(), false), defaultTint);
} else if (SmsTable.Types.isJoinedType(thread.getType())) {
} else if (MmsSmsColumns.Types.isJoinedType(thread.getType())) {
return emphasisAdded(recipientToStringAsync(thread.getRecipient().getId(), r -> new SpannableString(context.getString(R.string.ThreadRecord_s_is_on_signal, r.getDisplayName(context)))));
} else if (SmsTable.Types.isExpirationTimerUpdate(thread.getType())) {
} else if (MmsSmsColumns.Types.isExpirationTimerUpdate(thread.getType())) {
int seconds = (int) (thread.getExpiresIn() / 1000);
if (seconds <= 0) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_disappearing_messages_disabled), R.drawable.ic_update_timer_disabled_16, defaultTint);
}
String time = ExpirationUtil.getExpirationDisplayValue(context, seconds);
return emphasisAdded(context, context.getString(R.string.ThreadRecord_disappearing_message_time_updated_to_s, time), R.drawable.ic_update_timer_16, defaultTint);
} else if (SmsTable.Types.isIdentityUpdate(thread.getType())) {
} else if (MmsSmsColumns.Types.isIdentityUpdate(thread.getType())) {
return emphasisAdded(recipientToStringAsync(thread.getRecipient().getId(), r -> {
if (r.isGroup()) {
return new SpannableString(context.getString(R.string.ThreadRecord_safety_number_changed));
@@ -561,15 +560,15 @@ public final class ConversationListItem extends ConstraintLayout implements Bind
return new SpannableString(context.getString(R.string.ThreadRecord_your_safety_number_with_s_has_changed, r.getDisplayName(context)));
}
}));
} else if (SmsTable.Types.isIdentityVerified(thread.getType())) {
} else if (MmsSmsColumns.Types.isIdentityVerified(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_you_marked_verified), defaultTint);
} else if (SmsTable.Types.isIdentityDefault(thread.getType())) {
} else if (MmsSmsColumns.Types.isIdentityDefault(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_you_marked_unverified), defaultTint);
} else if (SmsTable.Types.isUnsupportedMessageType(thread.getType())) {
} else if (MmsSmsColumns.Types.isUnsupportedMessageType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_message_could_not_be_processed), defaultTint);
} else if (SmsTable.Types.isProfileChange(thread.getType())) {
} else if (MmsSmsColumns.Types.isProfileChange(thread.getType())) {
return emphasisAdded(context, "", defaultTint);
} else if (SmsTable.Types.isChangeNumber(thread.getType()) || SmsTable.Types.isBoostRequest(thread.getType())) {
} else if (MmsSmsColumns.Types.isChangeNumber(thread.getType()) || MmsSmsColumns.Types.isBoostRequest(thread.getType())) {
return emphasisAdded(context, "", defaultTint);
} else if (MmsSmsColumns.Types.isBadDecryptType(thread.getType())) {
return emphasisAdded(context, context.getString(R.string.ThreadRecord_delivery_issue), defaultTint);

View File

@@ -476,7 +476,7 @@ public class AttachmentTable extends DatabaseTable {
public void trimAllAbandonedAttachments() {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
String selectAllMmsIds = "SELECT " + MmsTable.ID + " FROM " + MmsTable.TABLE_NAME;
String selectAllMmsIds = "SELECT " + MessageTable.ID + " FROM " + MessageTable.TABLE_NAME;
String where = MMS_ID + " != " + PREUPLOAD_MESSAGE_ID + " AND " + MMS_ID + " NOT IN (" + selectAllMmsIds + ")";
int deletes = db.delete(TABLE_NAME, where, null);

View File

@@ -123,7 +123,7 @@ class GroupReceiptTable(context: Context?, databaseHelper: SignalDatabase?) : Da
fun deleteAbandonedRows() {
writableDatabase
.delete(TABLE_NAME)
.where("$MMS_ID NOT IN (SELECT ${MmsTable.ID} FROM ${MmsTable.TABLE_NAME})")
.where("$MMS_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})")
.run()
}

View File

@@ -50,7 +50,6 @@ import org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.Closeable;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -1511,9 +1510,9 @@ public class GroupTable extends DatabaseTable implements RecipientIdDatabaseRefe
public @NonNull List<GroupId> getGroupsToDisplayAsStories() throws BadGroupIdException {
String query = "SELECT " + GROUP_ID + ", (" +
"SELECT " + MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + " FROM " + MmsTable.TABLE_NAME +
" WHERE " + MmsTable.TABLE_NAME + "." + MmsTable.RECIPIENT_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID +
" AND " + MmsTable.STORY_TYPE + " > 1 ORDER BY " + MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + " DESC LIMIT 1" +
"SELECT " + MessageTable.TABLE_NAME + "." + MessageTable.DATE_RECEIVED + " FROM " + MessageTable.TABLE_NAME +
" WHERE " + MessageTable.TABLE_NAME + "." + MessageTable.RECIPIENT_ID + " = " + ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID +
" AND " + MessageTable.STORY_TYPE + " > 1 ORDER BY " + MessageTable.TABLE_NAME + "." + MessageTable.DATE_RECEIVED + " DESC LIMIT 1" +
") as active_timestamp" +
" FROM " + TABLE_NAME +
" INNER JOIN " + ThreadTable.TABLE_NAME + " ON " + ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " = " + TABLE_NAME + "." + RECIPIENT_ID +

View File

@@ -48,26 +48,26 @@ public class MediaTable extends DatabaseTable {
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.CAPTION + ", "
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.NAME + ", "
+ AttachmentTable.TABLE_NAME + "." + AttachmentTable.UPLOAD_TIMESTAMP + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.TYPE + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_SENT + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_RECEIVED + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.DATE_SERVER + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.THREAD_ID + ", "
+ MmsTable.TABLE_NAME + "." + MmsTable.RECIPIENT_ID + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.TYPE + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.DATE_SENT + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.DATE_RECEIVED + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.DATE_SERVER + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.THREAD_ID + ", "
+ MessageTable.TABLE_NAME + "." + MessageTable.RECIPIENT_ID + ", "
+ ThreadTable.TABLE_NAME + "." + ThreadTable.RECIPIENT_ID + " as " + THREAD_RECIPIENT_ID + " "
+ "FROM " + AttachmentTable.TABLE_NAME + " LEFT JOIN " + MmsTable.TABLE_NAME
+ " ON " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + " = " + MmsTable.TABLE_NAME + "." + MmsTable.ID + " "
+ "FROM " + AttachmentTable.TABLE_NAME + " LEFT JOIN " + MessageTable.TABLE_NAME
+ " ON " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + " = " + MessageTable.TABLE_NAME + "." + MessageTable.ID + " "
+ "LEFT JOIN " + ThreadTable.TABLE_NAME
+ " ON " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + " = " + MmsTable.TABLE_NAME + "." + MmsTable.THREAD_ID + " "
+ " ON " + ThreadTable.TABLE_NAME + "." + ThreadTable.ID + " = " + MessageTable.TABLE_NAME + "." + MessageTable.THREAD_ID + " "
+ "WHERE " + AttachmentTable.MMS_ID + " IN (SELECT " + MmsSmsColumns.ID
+ " FROM " + MmsTable.TABLE_NAME
+ " WHERE " + MmsTable.THREAD_ID + " __EQUALITY__ ?) AND (%s) AND "
+ MmsTable.VIEW_ONCE + " = 0 AND "
+ MmsTable.STORY_TYPE + " = 0 AND "
+ " FROM " + MessageTable.TABLE_NAME
+ " WHERE " + MessageTable.THREAD_ID + " __EQUALITY__ ?) AND (%s) AND "
+ MessageTable.VIEW_ONCE + " = 0 AND "
+ MessageTable.STORY_TYPE + " = 0 AND "
+ AttachmentTable.DATA + " IS NOT NULL AND "
+ "(" + AttachmentTable.QUOTE + " = 0 OR (" + AttachmentTable.QUOTE + " = 1 AND " + AttachmentTable.DATA_HASH + " IS NULL)) AND "
+ AttachmentTable.STICKER_PACK_ID + " IS NULL AND "
+ MmsTable.TABLE_NAME + "." + MmsTable.RECIPIENT_ID + " > 0 AND "
+ MessageTable.TABLE_NAME + "." + MessageTable.RECIPIENT_ID + " > 0 AND "
+ THREAD_RECIPIENT_ID + " > 0";
private static final String UNIQUE_MEDIA_QUERY = "SELECT "
@@ -192,16 +192,16 @@ public class MediaTable extends DatabaseTable {
public static MediaRecord from(@NonNull Cursor cursor) {
AttachmentTable attachmentDatabase = SignalDatabase.attachments();
List<DatabaseAttachment> attachments = attachmentDatabase.getAttachments(cursor);
RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.RECIPIENT_ID)));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.THREAD_ID));
boolean outgoing = MessageTable.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE)));
RecipientId recipientId = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.RECIPIENT_ID)));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.THREAD_ID));
boolean outgoing = MessageTable.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.TYPE)));
long date;
if (MmsTable.Types.isPushType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.TYPE)))) {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_SENT));
if (MessageTable.Types.isPushType(cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.TYPE)))) {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.DATE_SENT));
} else {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsTable.DATE_RECEIVED));
date = cursor.getLong(cursor.getColumnIndexOrThrow(MessageTable.DATE_RECEIVED));
}
RecipientId threadRecipient = RecipientId.from(cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_RECIPIENT_ID)));

View File

@@ -131,7 +131,7 @@ public class MentionTable extends DatabaseTable implements RecipientIdDatabaseRe
void deleteAbandonedMentions() {
SQLiteDatabase db = databaseHelper.getSignalWritableDatabase();
String where = MESSAGE_ID + " NOT IN (SELECT " + MmsTable.ID + " FROM " + MmsTable.TABLE_NAME + ") OR " + THREAD_ID + " NOT IN (SELECT " + ThreadTable.ID + " FROM " + ThreadTable.TABLE_NAME + ")";
String where = MESSAGE_ID + " NOT IN (SELECT " + MessageTable.ID + " FROM " + MessageTable.TABLE_NAME + ") OR " + THREAD_ID + " NOT IN (SELECT " + ThreadTable.ID + " FROM " + ThreadTable.TABLE_NAME + ")";
db.delete(TABLE_NAME, where, null);
}

View File

@@ -88,15 +88,9 @@ class MessageSendLogTables constructor(context: Context?, databaseHelper: Signal
val CREATE_TRIGGERS = arrayOf(
"""
CREATE TRIGGER msl_sms_delete AFTER DELETE ON ${SmsTable.TABLE_NAME}
CREATE TRIGGER msl_mms_delete AFTER DELETE ON ${org.thoughtcrime.securesms.database.MessageTable.TABLE_NAME}
BEGIN
DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MessageTable.PAYLOAD_ID} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.MESSAGE_ID} = old.${SmsTable.ID} AND ${MessageTable.IS_MMS} = 0);
END
""",
"""
CREATE TRIGGER msl_mms_delete AFTER DELETE ON ${MmsTable.TABLE_NAME}
BEGIN
DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MessageTable.PAYLOAD_ID} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.MESSAGE_ID} = old.${MmsTable.ID} AND ${MessageTable.IS_MMS} = 1);
DELETE FROM $TABLE_NAME WHERE $ID IN (SELECT ${MessageTable.PAYLOAD_ID} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.MESSAGE_ID} = old.${org.thoughtcrime.securesms.database.MessageTable.ID} AND ${MessageTable.IS_MMS} = 1);
END
""",
"""

View File

@@ -1,5 +1,7 @@
package org.thoughtcrime.securesms.database;
import androidx.annotation.VisibleForTesting;
@SuppressWarnings("UnnecessaryInterfaceModifier")
public interface MmsSmsColumns {
@@ -32,6 +34,13 @@ public interface MmsSmsColumns {
public static final String EXPORT_STATE = "export_state";
public static final String EXPORTED = "exported";
public static class Status {
public static final int STATUS_NONE = -1;
public static final int STATUS_COMPLETE = 0;
public static final int STATUS_PENDING = 0x20;
public static final int STATUS_FAILED = 0x40;
}
/**
* For storage efficiency, all types are stored within a single 64-bit integer column in the
* database. There are various areas reserved for different classes of data.
@@ -147,6 +156,8 @@ public interface MmsSmsColumns {
protected static final long SPECIAL_TYPE_PAYMENTS_ACTIVATE_REQUEST = 0x400000000L;
protected static final long SPECIAL_TYPE_PAYMENTS_ACTIVATED = 0x800000000L;
static final long IGNORABLE_TYPESMASK_WHEN_COUNTING = Types.END_SESSION_BIT | Types.KEY_EXCHANGE_IDENTITY_UPDATE_BIT | Types.KEY_EXCHANGE_IDENTITY_VERIFIED_BIT;
public static boolean isStoryReaction(long type) {
return (type & SPECIAL_TYPES_MASK) == SPECIAL_TYPE_STORY_REACTION;
}
@@ -417,7 +428,6 @@ public interface MmsSmsColumns {
return 1;
}
//
//
//

View File

@@ -35,6 +35,7 @@ import org.signal.core.util.logging.Log;
import org.signal.libsignal.protocol.util.Pair;
import org.thoughtcrime.securesms.database.MessageTable.MessageUpdate;
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.model.DisplayRecord;
import org.thoughtcrime.securesms.database.model.MessageExportStatus;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -50,6 +51,7 @@ import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
@@ -65,64 +67,53 @@ public class MmsSmsTable extends DatabaseTable {
@SuppressWarnings("unused")
private static final String TAG = Log.tag(MmsSmsTable.class);
public static final String TRANSPORT = "transport_type";
public static final String MMS_TRANSPORT = "mms";
public static final String SMS_TRANSPORT = "sms";
private static final String[] PROJECTION = { MmsSmsColumns.ID,
MmsSmsColumns.UNIQUE_ROW_ID,
private static final String[] PROJECTION = { MessageTable.TABLE_NAME + "." + MessageTable.ID + " AS " + MmsSmsColumns.ID,
MmsSmsColumns.BODY,
MmsSmsColumns.TYPE,
MmsSmsColumns.THREAD_ID,
SmsTable.RECIPIENT_ID,
SmsTable.RECIPIENT_DEVICE_ID,
MmsSmsColumns.RECIPIENT_ID,
MmsSmsColumns.RECIPIENT_DEVICE_ID,
MmsSmsColumns.DATE_SENT,
MmsSmsColumns.DATE_RECEIVED,
MmsSmsColumns.DATE_SERVER,
MmsTable.MMS_MESSAGE_TYPE,
SmsTable.SMS_STATUS,
MessageTable.MMS_MESSAGE_TYPE,
MmsSmsColumns.UNIDENTIFIED,
MmsTable.MMS_CONTENT_LOCATION,
MmsTable.MMS_TRANSACTION_ID,
MmsTable.MMS_MESSAGE_SIZE,
MmsTable.MMS_EXPIRY,
MmsTable.MMS_STATUS,
MessageTable.MMS_CONTENT_LOCATION,
MessageTable.MMS_TRANSACTION_ID,
MessageTable.MMS_MESSAGE_SIZE,
MessageTable.MMS_EXPIRY,
MessageTable.MMS_STATUS,
MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
MmsTable.NETWORK_FAILURES,
MessageTable.NETWORK_FAILURES,
MmsSmsColumns.SMS_SUBSCRIPTION_ID,
MmsSmsColumns.EXPIRES_IN,
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
TRANSPORT,
AttachmentTable.ATTACHMENT_JSON_ALIAS,
MmsTable.QUOTE_ID,
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
MmsTable.LINK_PREVIEWS,
MmsTable.VIEW_ONCE,
MessageTable.QUOTE_ID,
MessageTable.QUOTE_AUTHOR,
MessageTable.QUOTE_BODY,
MessageTable.QUOTE_MISSING,
MessageTable.QUOTE_TYPE,
MessageTable.QUOTE_MENTIONS,
MessageTable.SHARED_CONTACTS,
MessageTable.LINK_PREVIEWS,
MessageTable.VIEW_ONCE,
MmsSmsColumns.READ,
MmsSmsColumns.REACTIONS_UNREAD,
MmsSmsColumns.REACTIONS_LAST_SEEN,
MmsSmsColumns.REMOTE_DELETED,
MmsTable.MENTIONS_SELF,
MessageTable.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP,
MmsTable.MESSAGE_RANGES,
MmsTable.STORY_TYPE,
MmsTable.PARENT_STORY_ID};
MessageTable.MESSAGE_RANGES,
MessageTable.STORY_TYPE,
MessageTable.PARENT_STORY_ID};
private static final String SNIPPET_QUERY = "SELECT " + MmsSmsColumns.ID + ", 0 AS " + TRANSPORT + ", " + MmsSmsColumns.TYPE + ", " + MmsSmsColumns.DATE_RECEIVED + " FROM " + SmsTable.TABLE_NAME + " " +
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsSmsColumns.TYPE + " NOT IN (" + SmsTable.Types.PROFILE_CHANGE_TYPE + ", " + SmsTable.Types.GV1_MIGRATION_TYPE + ", " + SmsTable.Types.CHANGE_NUMBER_TYPE + ", " + SmsTable.Types.BOOST_REQUEST_TYPE + ", " + SmsTable.Types.SMS_EXPORT_TYPE + ") AND " + SmsTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " " +
"UNION ALL " +
"SELECT " + MmsSmsColumns.ID + ", 1 AS " + TRANSPORT + ", " + MmsSmsColumns.TYPE + ", " + MmsTable.DATE_RECEIVED + " FROM " + MmsTable.TABLE_NAME + " " +
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MmsTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0 " +
private static final String SNIPPET_QUERY = "SELECT " + MmsSmsColumns.ID + ", " + MmsSmsColumns.TYPE + ", " + MessageTable.DATE_RECEIVED + " FROM " + MessageTable.TABLE_NAME + " " +
"WHERE " + MmsSmsColumns.THREAD_ID + " = ? AND " + MessageTable.TYPE + " & " + GROUP_V2_LEAVE_BITS + " != " + GROUP_V2_LEAVE_BITS + " AND " + MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0 " +
"ORDER BY " + MmsSmsColumns.DATE_RECEIVED + " DESC " +
"LIMIT 1";
@@ -163,7 +154,7 @@ public class MmsSmsTable extends DatabaseTable {
String[] projection = new String[] { "COUNT(*)" };
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.DATE_RECEIVED + " >= " + timestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
try (Cursor cursor = queryTables(projection, selection, null, null, false)) {
if (cursor != null && cursor.moveToNext()) {
@@ -199,7 +190,7 @@ public class MmsSmsTable extends DatabaseTable {
List<MessageRecord> sms = SignalDatabase.sms().getMessagesInThreadAfterInclusive(origin.getThreadId(), origin.getDateReceived(), limit);
mms.addAll(sms);
Collections.sort(mms, (a, b) -> Long.compare(a.getDateReceived(), b.getDateReceived()));
Collections.sort(mms, Comparator.comparingLong(DisplayRecord::getDateReceived));
return Stream.of(mms).limit(limit).toList();
}
@@ -208,7 +199,7 @@ public class MmsSmsTable extends DatabaseTable {
public Cursor getConversation(long threadId, long offset, long limit) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
String limitStr = limit > 0 || offset > 0 ? offset + ", " + limit : null;
String query = buildQuery(PROJECTION, selection, order, limitStr, false);
@@ -222,14 +213,8 @@ public class MmsSmsTable extends DatabaseTable {
public @NonNull MessageRecord getConversationSnippet(long threadId) throws NoSuchMessageException {
try (Cursor cursor = getConversationSnippetCursor(threadId)) {
if (cursor.moveToFirst()) {
boolean isMms = CursorUtil.requireBoolean(cursor, TRANSPORT);
long id = CursorUtil.requireLong(cursor, MmsSmsColumns.ID);
if (isMms) {
return SignalDatabase.mms().getMessageRecord(id);
} else {
return SignalDatabase.sms().getMessageRecord(id);
}
long id = CursorUtil.requireLong(cursor, MmsSmsColumns.ID);
return SignalDatabase.mms().getMessageRecord(id);
} else {
throw new NoSuchMessageException("no message");
}
@@ -239,12 +224,12 @@ public class MmsSmsTable extends DatabaseTable {
@VisibleForTesting
@NonNull Cursor getConversationSnippetCursor(long threadId) {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
return db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId, threadId));
return db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId));
}
public long getConversationSnippetType(long threadId) throws NoSuchMessageException {
SQLiteDatabase db = databaseHelper.getSignalReadableDatabase();
try (Cursor cursor = db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId, threadId))) {
try (Cursor cursor = db.rawQuery(SNIPPET_QUERY, SqlUtil.buildArgs(threadId))) {
if (cursor.moveToFirst()) {
return CursorUtil.requireLong(cursor, MmsSmsColumns.TYPE);
} else {
@@ -271,7 +256,7 @@ public class MmsSmsTable extends DatabaseTable {
}
String order = MmsSmsColumns.DATE_RECEIVED + " ASC";
String selection = MmsSmsColumns.NOTIFIED + " = 0 AND " + MmsTable.STORY_TYPE + " = 0 AND (" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery + ")" : "") + ")";
String selection = MmsSmsColumns.NOTIFIED + " = 0 AND " + MessageTable.STORY_TYPE + " = 0 AND (" + MmsSmsColumns.READ + " = 0 OR " + MmsSmsColumns.REACTIONS_UNREAD + " = 1" + (stickyQuery.length() > 0 ? " OR (" + stickyQuery + ")" : "") + ")";
return queryTables(PROJECTION, selection, order, null, true);
}
@@ -283,10 +268,10 @@ public class MmsSmsTable extends DatabaseTable {
RecipientId author = messageRecord.isOutgoing() ? Recipient.self().getId() : messageRecord.getRecipient().getId();
long timestamp = messageRecord.getDateSent();
String where = MmsTable.QUOTE_ID + " = ? AND " + MmsTable.QUOTE_AUTHOR + " = ?";
String where = MessageTable.QUOTE_ID + " = ? AND " + MessageTable.QUOTE_AUTHOR + " = ?";
String[] whereArgs = SqlUtil.buildArgs(timestamp, author);
try (Cursor cursor = getReadableDatabase().query(MmsTable.TABLE_NAME, new String[]{ "1" }, where, whereArgs, null, null, null, "1")) {
try (Cursor cursor = getReadableDatabase().query(MessageTable.TABLE_NAME, new String[]{ "1" }, where, whereArgs, null, null, null, "1")) {
return cursor.moveToFirst();
}
}
@@ -309,9 +294,9 @@ public class MmsSmsTable extends DatabaseTable {
String query;
if (targetMessage.getQuote().getAuthor().equals(Recipient.self().getId())) {
query = MmsTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND (" + MmsSmsColumns.TYPE + " & " + MmsSmsColumns.Types.BASE_TYPE_MASK + ") = " + MmsSmsColumns.Types.BASE_SENT_TYPE;
query = MessageTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND (" + MmsSmsColumns.TYPE + " & " + MmsSmsColumns.Types.BASE_TYPE_MASK + ") = " + MmsSmsColumns.Types.BASE_SENT_TYPE;
} else {
query = MmsTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND " + MmsTable.RECIPIENT_ID + " = '" + targetMessage.getQuote().getAuthor().serialize() + "'";
query = MessageTable.DATE_SENT + " = " + targetMessage.getQuote().getId() + " AND " + MessageTable.RECIPIENT_ID + " = '" + targetMessage.getQuote().getAuthor().serialize() + "'";
}
try (Reader reader = new Reader(queryTables(PROJECTION, query, null, "1", false))) {
@@ -333,7 +318,7 @@ public class MmsSmsTable extends DatabaseTable {
}
RecipientId author = targetMessage.isOutgoing() ? Recipient.self().getId() : targetMessage.getRecipient().getId();
String query = MmsTable.QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + MmsTable.QUOTE_AUTHOR + " = " + author.serialize();
String query = MessageTable.QUOTE_ID + " = " + targetMessage.getDateSent() + " AND " + MessageTable.QUOTE_AUTHOR + " = " + author.serialize();
String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
List<MessageRecord> records = new ArrayList<>();
@@ -361,14 +346,14 @@ public class MmsSmsTable extends DatabaseTable {
private @NonNull String getStickyWherePartForParentStoryId(@Nullable Long parentStoryId) {
if (parentStoryId == null) {
return " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
return " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
}
return " AND " + MmsTable.PARENT_STORY_ID + " = " + parentStoryId;
return " AND " + MessageTable.PARENT_STORY_ID + " = " + parentStoryId;
}
public int getUnreadCount(long threadId) {
String selection = MmsSmsColumns.READ + " = 0 AND " + MmsTable.STORY_TYPE + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
String selection = MmsSmsColumns.READ + " = 0 AND " + MessageTable.STORY_TYPE + " = 0 AND " + MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
try (Cursor cursor = queryTables(PROJECTION, selection, null, null, false)) {
return cursor != null ? cursor.getCount() : 0;
@@ -389,10 +374,7 @@ public class MmsSmsTable extends DatabaseTable {
return 0;
}
int count = SignalDatabase.sms().getSecureMessageCount(threadId);
count += SignalDatabase.mms().getSecureMessageCount(threadId);
return count;
return SignalDatabase.mms().getSecureMessageCount(threadId);
}
public int getOutgoingSecureConversationCount(long threadId) {
@@ -400,36 +382,23 @@ public class MmsSmsTable extends DatabaseTable {
return 0;
}
int count = SignalDatabase.sms().getOutgoingSecureMessageCount(threadId);
count += SignalDatabase.mms().getOutgoingSecureMessageCount(threadId);
return count;
return SignalDatabase.mms().getOutgoingSecureMessageCount(threadId);
}
public int getConversationCount(long threadId) {
int count = SignalDatabase.sms().getMessageCountForThread(threadId);
count += SignalDatabase.mms().getMessageCountForThread(threadId);
return count;
return SignalDatabase.mms().getMessageCountForThread(threadId);
}
public int getConversationCount(long threadId, long beforeTime) {
return SignalDatabase.sms().getMessageCountForThread(threadId, beforeTime) +
SignalDatabase.mms().getMessageCountForThread(threadId, beforeTime);
return SignalDatabase.mms().getMessageCountForThread(threadId, beforeTime);
}
public int getInsecureSentCount(long threadId) {
int count = SignalDatabase.sms().getInsecureMessagesSentForThread(threadId);
count += SignalDatabase.mms().getInsecureMessagesSentForThread(threadId);
return count;
return SignalDatabase.mms().getInsecureMessagesSentForThread(threadId);
}
public int getInsecureMessageCountForInsights() {
int count = SignalDatabase.sms().getInsecureMessageCountForInsights();
count += SignalDatabase.mms().getInsecureMessageCountForInsights();
return count;
return SignalDatabase.mms().getInsecureMessageCountForInsights();
}
public int getUnexportedInsecureMessagesCount() {
@@ -437,17 +406,11 @@ public class MmsSmsTable extends DatabaseTable {
}
public int getUnexportedInsecureMessagesCount(long threadId) {
int count = SignalDatabase.sms().getUnexportedInsecureMessagesCount(threadId);
count += SignalDatabase.mms().getUnexportedInsecureMessagesCount(threadId);
return count;
return SignalDatabase.mms().getUnexportedInsecureMessagesCount(threadId);
}
public int getIncomingMeaningfulMessageCountSince(long threadId, long afterTime) {
int count = SignalDatabase.sms().getIncomingMeaningfulMessageCountSince(threadId, afterTime);
count += SignalDatabase.mms().getIncomingMeaningfulMessageCountSince(threadId, afterTime);
return count;
return SignalDatabase.mms().getIncomingMeaningfulMessageCountSince(threadId, afterTime);
}
public int getMessageCountBeforeDate(long date) {
@@ -665,7 +628,7 @@ public class MmsSmsTable extends DatabaseTable {
}
private @NonNull MessageExportState getMessageExportState(@NonNull MessageId messageId) throws NoSuchMessageException {
String table = messageId.isMms() ? MmsTable.TABLE_NAME : SmsTable.TABLE_NAME;
String table = MessageTable.TABLE_NAME;
String[] projection = SqlUtil.buildArgs(MmsSmsColumns.EXPORT_STATE);
String[] args = SqlUtil.buildArgs(messageId.getId());
@@ -704,7 +667,7 @@ public class MmsSmsTable extends DatabaseTable {
}
public void markMessageExported(@NonNull MessageId messageId) {
String table = messageId.isMms() ? MmsTable.TABLE_NAME : SmsTable.TABLE_NAME;
String table = MessageTable.TABLE_NAME;
ContentValues contentValues = new ContentValues(1);
contentValues.put(MmsSmsColumns.EXPORTED, MessageExportStatus.EXPORTED.getCode());
@@ -713,7 +676,7 @@ public class MmsSmsTable extends DatabaseTable {
}
public void markMessageExportFailed(@NonNull MessageId messageId) {
String table = messageId.isMms() ? MmsTable.TABLE_NAME : SmsTable.TABLE_NAME;
String table = MessageTable.TABLE_NAME;
ContentValues contentValues = new ContentValues(1);
contentValues.put(MmsSmsColumns.EXPORTED, MessageExportStatus.ERROR.getCode());
@@ -722,7 +685,7 @@ public class MmsSmsTable extends DatabaseTable {
}
private void setMessageExportState(@NonNull MessageId messageId, @NonNull MessageExportState messageExportState) {
String table = messageId.isMms() ? MmsTable.TABLE_NAME : SmsTable.TABLE_NAME;
String table = MessageTable.TABLE_NAME;
ContentValues contentValues = new ContentValues(1);
contentValues.put(MmsSmsColumns.EXPORT_STATE, messageExportState.toByteArray());
@@ -792,7 +755,7 @@ public class MmsSmsTable extends DatabaseTable {
public int getQuotedMessagePosition(long threadId, long quoteId, @NonNull RecipientId recipientId) {
String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0" + " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0" + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.DATE_SENT, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
@@ -815,7 +778,7 @@ public class MmsSmsTable extends DatabaseTable {
public int getMessagePositionInConversation(long threadId, long receivedTimestamp, @NonNull RecipientId recipientId) {
String order = MmsSmsColumns.DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MmsTable.STORY_TYPE + " = 0" + " AND " + MmsTable.PARENT_STORY_ID + " <= 0";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " + MessageTable.STORY_TYPE + " = 0" + " AND " + MessageTable.PARENT_STORY_ID + " <= 0";
try (Cursor cursor = queryTables(new String[]{ MmsSmsColumns.DATE_RECEIVED, MmsSmsColumns.RECIPIENT_ID, MmsSmsColumns.REMOTE_DELETED}, selection, order, null, false)) {
boolean isOwnNumber = Recipient.resolved(recipientId).isSelf();
@@ -864,12 +827,12 @@ public class MmsSmsTable extends DatabaseTable {
order = MmsSmsColumns.DATE_RECEIVED + " ASC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.DATE_RECEIVED + " < " + receivedTimestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " = " + groupStoryId;
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " = " + groupStoryId;
} else {
order = MmsSmsColumns.DATE_RECEIVED + " DESC";
selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
MmsSmsColumns.DATE_RECEIVED + " > " + receivedTimestamp + " AND " +
MmsTable.STORY_TYPE + " = 0 AND " + MmsTable.PARENT_STORY_ID + " <= 0";
MessageTable.STORY_TYPE + " = 0 AND " + MessageTable.PARENT_STORY_ID + " <= 0";
}
try (Cursor cursor = queryTables(new String[]{ "COUNT(*)" }, selection, order, null, false)) {
@@ -956,204 +919,24 @@ public class MmsSmsTable extends DatabaseTable {
attachmentJsonJoin = "NULL";
}
String[] mmsProjection = { MmsSmsColumns.DATE_SENT,
MmsSmsColumns.DATE_RECEIVED,
MmsTable.TABLE_NAME + "." + MmsTable.ID + " AS " + MmsSmsColumns.ID,
"'MMS::' || " + MmsTable.TABLE_NAME + "." + MmsTable.ID + " || '::' || " + MmsTable.DATE_SENT + " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
attachmentJsonJoin + " AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
SmsTable.BODY,
MmsSmsColumns.READ,
MmsSmsColumns.THREAD_ID,
MmsSmsColumns.TYPE,
MmsSmsColumns.RECIPIENT_ID,
MmsSmsColumns.RECIPIENT_DEVICE_ID,
MmsTable.MMS_MESSAGE_TYPE,
SmsTable.SMS_STATUS,
MmsTable.MMS_CONTENT_LOCATION,
MmsTable.MMS_TRANSACTION_ID,
MmsTable.MMS_MESSAGE_SIZE,
MmsTable.MMS_EXPIRY,
MmsTable.MMS_STATUS,
MmsTable.UNIDENTIFIED,
MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
MmsSmsColumns.SMS_SUBSCRIPTION_ID,
MmsSmsColumns.EXPIRES_IN,
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
MmsTable.NETWORK_FAILURES, TRANSPORT,
MmsTable.QUOTE_ID,
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
MmsTable.LINK_PREVIEWS,
MmsTable.VIEW_ONCE,
MmsSmsColumns.REACTIONS_UNREAD,
MmsSmsColumns.REACTIONS_LAST_SEEN,
MmsSmsColumns.DATE_SERVER,
MmsSmsColumns.REMOTE_DELETED,
MmsTable.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP,
MmsTable.MESSAGE_RANGES,
MmsTable.STORY_TYPE,
MmsTable.PARENT_STORY_ID};
String[] smsProjection = { MmsSmsColumns.DATE_SENT,
MmsSmsColumns.DATE_RECEIVED,
MmsSmsColumns.ID, "'SMS::' || " + MmsSmsColumns.ID + " || '::' || " + SmsTable.DATE_SENT + " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
"NULL AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS,
SmsTable.BODY,
MmsSmsColumns.READ,
MmsSmsColumns.THREAD_ID,
MmsSmsColumns.TYPE,
SmsTable.RECIPIENT_ID,
SmsTable.RECIPIENT_DEVICE_ID,
MmsTable.MMS_MESSAGE_TYPE,
SmsTable.SMS_STATUS,
MmsTable.MMS_CONTENT_LOCATION,
MmsTable.MMS_TRANSACTION_ID,
MmsTable.MMS_MESSAGE_SIZE,
MmsTable.MMS_EXPIRY,
MmsTable.MMS_STATUS,
MmsTable.UNIDENTIFIED,
MmsSmsColumns.DELIVERY_RECEIPT_COUNT,
MmsSmsColumns.READ_RECEIPT_COUNT,
MmsSmsColumns.MISMATCHED_IDENTITIES,
MmsSmsColumns.SMS_SUBSCRIPTION_ID,
MmsSmsColumns.EXPIRES_IN,
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
MmsTable.NETWORK_FAILURES, TRANSPORT,
MmsTable.QUOTE_ID,
MmsTable.QUOTE_AUTHOR,
MmsTable.QUOTE_BODY,
MmsTable.QUOTE_MISSING,
MmsTable.QUOTE_TYPE,
MmsTable.QUOTE_MENTIONS,
MmsTable.SHARED_CONTACTS,
MmsTable.LINK_PREVIEWS,
MmsTable.VIEW_ONCE,
MmsSmsColumns.REACTIONS_UNREAD,
MmsSmsColumns.REACTIONS_LAST_SEEN,
MmsSmsColumns.DATE_SERVER,
MmsSmsColumns.REMOTE_DELETED,
MmsTable.MENTIONS_SELF,
MmsSmsColumns.NOTIFIED_TIMESTAMP,
MmsSmsColumns.VIEWED_RECEIPT_COUNT,
MmsSmsColumns.RECEIPT_TIMESTAMP,
MmsTable.MESSAGE_RANGES,
"0 AS " + MmsTable.STORY_TYPE,
"0 AS " + MmsTable.PARENT_STORY_ID};
projection = SqlUtil.appendArg(projection, attachmentJsonJoin + " AS " + AttachmentTable.ATTACHMENT_JSON_ALIAS);
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
if (includeAttachments) {
mmsQueryBuilder.setDistinct(true);
smsQueryBuilder.setDistinct(true);
}
smsQueryBuilder.setTables(SmsTable.TABLE_NAME);
if (includeAttachments) {
mmsQueryBuilder.setTables(MmsTable.TABLE_NAME + " LEFT OUTER JOIN " + AttachmentTable.TABLE_NAME +
" ON " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + " = " + MmsTable.TABLE_NAME + "." + MmsTable.ID);
mmsQueryBuilder.setTables(MessageTable.TABLE_NAME + " LEFT OUTER JOIN " + AttachmentTable.TABLE_NAME +
" ON " + AttachmentTable.TABLE_NAME + "." + AttachmentTable.MMS_ID + " = " + MessageTable.TABLE_NAME + "." + MessageTable.ID);
} else {
mmsQueryBuilder.setTables(MmsTable.TABLE_NAME);
mmsQueryBuilder.setTables(MessageTable.TABLE_NAME);
}
Set<String> mmsColumnsPresent = new HashSet<>();
mmsColumnsPresent.add(MmsSmsColumns.ID);
mmsColumnsPresent.add(MmsSmsColumns.READ);
mmsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
mmsColumnsPresent.add(MmsSmsColumns.BODY);
mmsColumnsPresent.add(MmsSmsColumns.RECIPIENT_ID);
mmsColumnsPresent.add(MmsSmsColumns.RECIPIENT_DEVICE_ID);
mmsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES);
mmsColumnsPresent.add(MmsSmsColumns.SMS_SUBSCRIPTION_ID);
mmsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN);
mmsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED);
mmsColumnsPresent.add(MmsTable.MMS_MESSAGE_TYPE);
mmsColumnsPresent.add(MmsTable.TYPE);
mmsColumnsPresent.add(MmsTable.DATE_SENT);
mmsColumnsPresent.add(MmsTable.DATE_RECEIVED);
mmsColumnsPresent.add(MmsTable.DATE_SERVER);
mmsColumnsPresent.add(MmsTable.MMS_CONTENT_LOCATION);
mmsColumnsPresent.add(MmsTable.MMS_TRANSACTION_ID);
mmsColumnsPresent.add(MmsTable.MMS_MESSAGE_SIZE);
mmsColumnsPresent.add(MmsTable.MMS_EXPIRY);
mmsColumnsPresent.add(MmsTable.NOTIFIED);
mmsColumnsPresent.add(MmsTable.MMS_STATUS);
mmsColumnsPresent.add(MmsTable.UNIDENTIFIED);
mmsColumnsPresent.add(MmsTable.NETWORK_FAILURES);
mmsColumnsPresent.add(MmsTable.QUOTE_ID);
mmsColumnsPresent.add(MmsTable.QUOTE_AUTHOR);
mmsColumnsPresent.add(MmsTable.QUOTE_BODY);
mmsColumnsPresent.add(MmsTable.QUOTE_MISSING);
mmsColumnsPresent.add(MmsTable.QUOTE_TYPE);
mmsColumnsPresent.add(MmsTable.QUOTE_MENTIONS);
mmsColumnsPresent.add(MmsTable.SHARED_CONTACTS);
mmsColumnsPresent.add(MmsTable.LINK_PREVIEWS);
mmsColumnsPresent.add(MmsTable.VIEW_ONCE);
mmsColumnsPresent.add(MmsTable.REACTIONS_UNREAD);
mmsColumnsPresent.add(MmsTable.REACTIONS_LAST_SEEN);
mmsColumnsPresent.add(MmsTable.REMOTE_DELETED);
mmsColumnsPresent.add(MmsTable.MENTIONS_SELF);
mmsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
mmsColumnsPresent.add(MmsSmsColumns.VIEWED_RECEIPT_COUNT);
mmsColumnsPresent.add(MmsSmsColumns.RECEIPT_TIMESTAMP);
mmsColumnsPresent.add(MmsTable.MESSAGE_RANGES);
mmsColumnsPresent.add(MmsTable.STORY_TYPE);
mmsColumnsPresent.add(MmsTable.PARENT_STORY_ID);
String mmsGroupBy = includeAttachments ? MessageTable.TABLE_NAME + "." + MessageTable.ID : null;
Set<String> smsColumnsPresent = new HashSet<>();
smsColumnsPresent.add(MmsSmsColumns.ID);
smsColumnsPresent.add(MmsSmsColumns.BODY);
smsColumnsPresent.add(MmsSmsColumns.RECIPIENT_ID);
smsColumnsPresent.add(MmsSmsColumns.RECIPIENT_DEVICE_ID);
smsColumnsPresent.add(MmsSmsColumns.READ);
smsColumnsPresent.add(MmsSmsColumns.THREAD_ID);
smsColumnsPresent.add(MmsSmsColumns.DELIVERY_RECEIPT_COUNT);
smsColumnsPresent.add(MmsSmsColumns.READ_RECEIPT_COUNT);
smsColumnsPresent.add(MmsSmsColumns.MISMATCHED_IDENTITIES);
smsColumnsPresent.add(MmsSmsColumns.SMS_SUBSCRIPTION_ID);
smsColumnsPresent.add(MmsSmsColumns.EXPIRES_IN);
smsColumnsPresent.add(MmsSmsColumns.EXPIRE_STARTED);
smsColumnsPresent.add(MmsSmsColumns.NOTIFIED);
smsColumnsPresent.add(SmsTable.TYPE);
smsColumnsPresent.add(SmsTable.DATE_SENT);
smsColumnsPresent.add(SmsTable.DATE_RECEIVED);
smsColumnsPresent.add(SmsTable.DATE_SERVER);
smsColumnsPresent.add(SmsTable.SMS_STATUS);
smsColumnsPresent.add(SmsTable.UNIDENTIFIED);
smsColumnsPresent.add(SmsTable.REACTIONS_UNREAD);
smsColumnsPresent.add(SmsTable.REACTIONS_LAST_SEEN);
smsColumnsPresent.add(MmsSmsColumns.REMOTE_DELETED);
smsColumnsPresent.add(MmsSmsColumns.NOTIFIED_TIMESTAMP);
smsColumnsPresent.add(MmsSmsColumns.RECEIPT_TIMESTAMP);
smsColumnsPresent.add("0 AS " + MmsTable.STORY_TYPE);
smsColumnsPresent.add("0 AS " + MmsTable.PARENT_STORY_ID);
String mmsGroupBy = includeAttachments ? MmsTable.TABLE_NAME + "." + MmsTable.ID : null;
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, mmsGroupBy, null);
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(TRANSPORT, smsProjection, smsColumnsPresent, 4, SMS_TRANSPORT, selection, null, null, null);
SQLiteQueryBuilder unionQueryBuilder = new SQLiteQueryBuilder();
String unionQuery = unionQueryBuilder.buildUnionQuery(new String[] { smsSubQuery, mmsSubQuery }, order, limit);
SQLiteQueryBuilder outerQueryBuilder = new SQLiteQueryBuilder();
outerQueryBuilder.setTables("(" + unionQuery + ")");
return outerQueryBuilder.buildQuery(projection, null, null, null, null, null, null);
return mmsQueryBuilder.buildQuery(projection, selection, null, mmsGroupBy, null, order, limit);
}
private Cursor queryTables(String[] projection, String selection, String order, String limit, boolean includeAttachments) {
@@ -1168,25 +951,16 @@ public class MmsSmsTable extends DatabaseTable {
public static class Reader implements Closeable {
private final Cursor cursor;
private SmsTable.Reader smsReader;
private MmsTable.Reader mmsReader;
private final Cursor cursor;
private MessageTable.MmsReader mmsReader;
public Reader(Cursor cursor) {
this.cursor = cursor;
}
private SmsTable.Reader getSmsReader() {
if (smsReader == null) {
smsReader = SmsTable.readerFor(cursor);
}
return smsReader;
}
private MmsTable.Reader getMmsReader() {
private MessageTable.MmsReader getMmsReader() {
if (mmsReader == null) {
mmsReader = MmsTable.readerFor(cursor);
mmsReader = MessageTable.mmsReaderFor(cursor);
}
return mmsReader;
@@ -1200,11 +974,7 @@ public class MmsSmsTable extends DatabaseTable {
}
public MessageRecord getCurrent() {
String type = cursor.getString(cursor.getColumnIndexOrThrow(TRANSPORT));
if (MmsSmsTable.MMS_TRANSPORT.equals(type)) return getMmsReader().getCurrent();
else if (MmsSmsTable.SMS_TRANSPORT.equals(type)) return getSmsReader().getCurrent();
else throw new AssertionError("Bad type: " + type);
return getMmsReader().getCurrent();
}
@Override

View File

@@ -5,6 +5,7 @@ import android.content.Context
import android.database.Cursor
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.delete
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.ReactionRecord
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
@@ -43,15 +44,9 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
@JvmField
val CREATE_TRIGGERS = arrayOf(
"""
CREATE TRIGGER reactions_sms_delete AFTER DELETE ON ${SmsTable.TABLE_NAME}
CREATE TRIGGER reactions_mms_delete AFTER DELETE ON ${MessageTable.TABLE_NAME}
BEGIN
DELETE FROM $TABLE_NAME WHERE $MESSAGE_ID = old.${SmsTable.ID} AND $IS_MMS = 0;
END
""",
"""
CREATE TRIGGER reactions_mms_delete AFTER DELETE ON ${MmsTable.TABLE_NAME}
BEGIN
DELETE FROM $TABLE_NAME WHERE $MESSAGE_ID = old.${MmsTable.ID} AND $IS_MMS = 1;
DELETE FROM $TABLE_NAME WHERE $MESSAGE_ID = old.${MessageTable.ID} AND $IS_MMS = 1;
END
"""
)
@@ -67,8 +62,8 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
fun getReactions(messageId: MessageId): List<ReactionRecord> {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ?"
val args = SqlUtil.buildArgs(messageId.id, if (messageId.mms) 1 else 0)
val query = "$MESSAGE_ID = ?"
val args = SqlUtil.buildArgs(messageId.id)
val reactions: MutableList<ReactionRecord> = mutableListOf()
@@ -88,9 +83,9 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
val messageIdToReactions: MutableMap<MessageId, MutableList<ReactionRecord>> = mutableMapOf()
val args: List<Array<String>> = messageIds.map { SqlUtil.buildArgs(it.id, if (it.mms) 1 else 0) }
val args: List<Array<String>> = messageIds.map { SqlUtil.buildArgs(it.id) }
for (query: SqlUtil.Query in SqlUtil.buildCustomCollectionQuery("$MESSAGE_ID = ? AND $IS_MMS = ?", args)) {
for (query: SqlUtil.Query in SqlUtil.buildCustomCollectionQuery("$MESSAGE_ID = ?", args)) {
readableDatabase.query(TABLE_NAME, null, query.where, query.whereArgs, null, null, null).use { cursor ->
while (cursor.moveToNext()) {
val reaction: ReactionRecord = readReaction(cursor)
@@ -115,7 +110,6 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
fun addReaction(messageId: MessageId, reaction: ReactionRecord) {
writableDatabase.beginTransaction()
try {
val values = ContentValues().apply {
@@ -144,7 +138,6 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
fun deleteReaction(messageId: MessageId, recipientId: RecipientId) {
writableDatabase.beginTransaction()
try {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ? AND $AUTHOR_ID = ?"
@@ -171,8 +164,8 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
fun hasReaction(messageId: MessageId, reaction: ReactionRecord): Boolean {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ? AND $AUTHOR_ID = ? AND $EMOJI = ?"
val args = SqlUtil.buildArgs(messageId.id, if (messageId.mms) 1 else 0, reaction.author, reaction.emoji)
val query = "$MESSAGE_ID = ? AND $AUTHOR_ID = ? AND $EMOJI = ?"
val args = SqlUtil.buildArgs(messageId.id, reaction.author, reaction.emoji)
readableDatabase.query(TABLE_NAME, arrayOf(MESSAGE_ID), query, args, null, null, null).use { cursor ->
return cursor.moveToFirst()
@@ -180,8 +173,8 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
private fun hasReactions(messageId: MessageId): Boolean {
val query = "$MESSAGE_ID = ? AND $IS_MMS = ?"
val args = SqlUtil.buildArgs(messageId.id, if (messageId.mms) 1 else 0)
val query = "$MESSAGE_ID = ?"
val args = SqlUtil.buildArgs(messageId.id)
readableDatabase.query(TABLE_NAME, arrayOf(MESSAGE_ID), query, args, null, null, null).use { cursor ->
return cursor.moveToFirst()
@@ -199,12 +192,9 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
}
fun deleteAbandonedReactions() {
val query = """
($IS_MMS = 0 AND $MESSAGE_ID NOT IN (SELECT ${SmsTable.ID} FROM ${SmsTable.TABLE_NAME}))
OR
($IS_MMS = 1 AND $MESSAGE_ID NOT IN (SELECT ${MmsTable.ID} FROM ${MmsTable.TABLE_NAME}))
""".trimIndent()
writableDatabase.delete(TABLE_NAME, query, null)
writableDatabase
.delete(TABLE_NAME)
.where("$MESSAGE_ID NOT IN (SELECT ${MessageTable.ID} FROM ${MessageTable.TABLE_NAME})")
.run()
}
}

View File

@@ -3305,8 +3305,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
INNER JOIN ${ThreadTable.TABLE_NAME} AS t ON t.${ThreadTable.RECIPIENT_ID} = r.$ID
WHERE
r.$PROFILE_SHARING = 0 AND (
EXISTS(SELECT 1 FROM ${SmsTable.TABLE_NAME} WHERE ${SmsTable.THREAD_ID} = t.${ThreadTable.ID} AND ${SmsTable.DATE_RECEIVED} < ?) OR
EXISTS(SELECT 1 FROM ${MmsTable.TABLE_NAME} WHERE ${MmsTable.THREAD_ID} = t.${ThreadTable.ID} AND ${MmsTable.DATE_RECEIVED} < ?)
EXISTS(SELECT 1 FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.THREAD_ID} = t.${ThreadTable.ID} AND ${MessageTable.DATE_RECEIVED} < ?)
)
""".trimIndent()

View File

@@ -13,7 +13,6 @@ import org.signal.core.util.SqlUtil
@SuppressLint("RecipientIdDatabaseReferenceUsage", "ThreadIdDatabaseReferenceUsage") // Handles updates via triggers
class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTable(context, databaseHelper) {
companion object {
const val SMS_FTS_TABLE_NAME = "sms_fts"
const val MMS_FTS_TABLE_NAME = "mms_fts"
const val ID = "rowid"
const val BODY = MmsSmsColumns.BODY
@@ -27,42 +26,25 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
@Language("sql")
val CREATE_TABLE = arrayOf(
"CREATE VIRTUAL TABLE $SMS_FTS_TABLE_NAME USING fts5($BODY, $THREAD_ID UNINDEXED, content=${SmsTable.TABLE_NAME}, content_rowid=${SmsTable.ID})",
"CREATE VIRTUAL TABLE $MMS_FTS_TABLE_NAME USING fts5($BODY, $THREAD_ID UNINDEXED, content=${MmsTable.TABLE_NAME}, content_rowid=${MmsTable.ID})",
"CREATE VIRTUAL TABLE $MMS_FTS_TABLE_NAME USING fts5($BODY, $THREAD_ID UNINDEXED, content=${MessageTable.TABLE_NAME}, content_rowid=${MessageTable.ID})",
)
@Language("sql")
val CREATE_TRIGGERS = arrayOf(
"""
CREATE TRIGGER sms_ai AFTER INSERT ON ${SmsTable.TABLE_NAME} BEGIN
INSERT INTO $SMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES (new.${SmsTable.ID}, new.${SmsTable.BODY}, new.${SmsTable.THREAD_ID});
CREATE TRIGGER mms_ai AFTER INSERT ON ${MessageTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES (new.${MessageTable.ID}, new.${MessageTable.BODY}, new.${MessageTable.THREAD_ID});
END;
""",
"""
CREATE TRIGGER sms_ad AFTER DELETE ON ${SmsTable.TABLE_NAME} BEGIN
INSERT INTO $SMS_FTS_TABLE_NAME($SMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${SmsTable.ID}, old.${SmsTable.BODY}, old.${SmsTable.THREAD_ID});
CREATE TRIGGER mms_ad AFTER DELETE ON ${MessageTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($MMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${MessageTable.ID}, old.${MessageTable.BODY}, old.${MessageTable.THREAD_ID});
END;
""",
"""
CREATE TRIGGER sms_au AFTER UPDATE ON ${SmsTable.TABLE_NAME} BEGIN
INSERT INTO $SMS_FTS_TABLE_NAME($SMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${SmsTable.ID}, old.${SmsTable.BODY}, old.${SmsTable.THREAD_ID});
INSERT INTO $SMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES(new.${SmsTable.ID}, new.${SmsTable.BODY}, new.${SmsTable.THREAD_ID});
END;
""",
"""
CREATE TRIGGER mms_ai AFTER INSERT ON ${MmsTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES (new.${MmsTable.ID}, new.${MmsTable.BODY}, new.${MmsTable.THREAD_ID});
END;
""",
"""
CREATE TRIGGER mms_ad AFTER DELETE ON ${MmsTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($MMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${MmsTable.ID}, old.${MmsTable.BODY}, old.${MmsTable.THREAD_ID});
END;
""",
"""
CREATE TRIGGER mms_au AFTER UPDATE ON ${MmsTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($MMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${MmsTable.ID}, old.${MmsTable.BODY}, old.${MmsTable.THREAD_ID});
INSERT INTO $MMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES (new.${MmsTable.ID}, new.${MmsTable.BODY}, new.${MmsTable.THREAD_ID});
CREATE TRIGGER mms_au AFTER UPDATE ON ${MessageTable.TABLE_NAME} BEGIN
INSERT INTO $MMS_FTS_TABLE_NAME($MMS_FTS_TABLE_NAME, $ID, $BODY, $THREAD_ID) VALUES('delete', old.${MessageTable.ID}, old.${MessageTable.BODY}, old.${MessageTable.THREAD_ID});
INSERT INTO $MMS_FTS_TABLE_NAME($ID, $BODY, $THREAD_ID) VALUES (new.${MessageTable.ID}, new.${MessageTable.BODY}, new.${MessageTable.THREAD_ID});
END;
"""
)
@@ -70,40 +52,21 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
private const val MESSAGES_QUERY = """
SELECT
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} AS $CONVERSATION_RECIPIENT,
${SmsTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
snippet($SMS_FTS_TABLE_NAME, -1, '', '', '$SNIPPET_WRAP', 7) AS $SNIPPET,
${SmsTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
$SMS_FTS_TABLE_NAME.$THREAD_ID,
$SMS_FTS_TABLE_NAME.$BODY,
$SMS_FTS_TABLE_NAME.$ID AS $MESSAGE_ID,
0 AS $IS_MMS
FROM
${SmsTable.TABLE_NAME}
INNER JOIN $SMS_FTS_TABLE_NAME ON $SMS_FTS_TABLE_NAME.$ID = ${SmsTable.TABLE_NAME}.${SmsTable.ID}
INNER JOIN ${ThreadTable.TABLE_NAME} ON $SMS_FTS_TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
WHERE
$SMS_FTS_TABLE_NAME MATCH ? AND
${SmsTable.TABLE_NAME}.${SmsTable.TYPE} & ${MmsSmsColumns.Types.GROUP_V2_BIT} = 0 AND
${SmsTable.TABLE_NAME}.${SmsTable.TYPE} & ${MmsSmsColumns.Types.BASE_TYPE_MASK} != ${MmsSmsColumns.Types.PROFILE_CHANGE_TYPE} AND
${SmsTable.TABLE_NAME}.${SmsTable.TYPE} & ${MmsSmsColumns.Types.BASE_TYPE_MASK} != ${MmsSmsColumns.Types.GROUP_CALL_TYPE}
UNION ALL
SELECT
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} AS $CONVERSATION_RECIPIENT,
${MmsTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
${MessageTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
snippet($MMS_FTS_TABLE_NAME, -1, '', '', '$SNIPPET_WRAP', 7) AS $SNIPPET,
${MmsTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
${MessageTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
$MMS_FTS_TABLE_NAME.$THREAD_ID,
$MMS_FTS_TABLE_NAME.$BODY,
$MMS_FTS_TABLE_NAME.$ID AS $MESSAGE_ID,
1 AS $IS_MMS
FROM
${MmsTable.TABLE_NAME}
INNER JOIN $MMS_FTS_TABLE_NAME ON $MMS_FTS_TABLE_NAME.$ID = ${MmsTable.TABLE_NAME}.${MmsTable.ID}
${MessageTable.TABLE_NAME}
INNER JOIN $MMS_FTS_TABLE_NAME ON $MMS_FTS_TABLE_NAME.$ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
INNER JOIN ${ThreadTable.TABLE_NAME} ON $MMS_FTS_TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
WHERE
$MMS_FTS_TABLE_NAME MATCH ? AND
${MmsTable.TABLE_NAME}.${MmsTable.TYPE} & ${MmsSmsColumns.Types.GROUP_V2_BIT} = 0 AND
${MmsTable.TABLE_NAME}.${MmsTable.TYPE} & ${MmsSmsColumns.Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION} = 0
${MessageTable.TABLE_NAME}.${MessageTable.TYPE} & ${MmsSmsColumns.Types.GROUP_V2_BIT} = 0 AND
${MessageTable.TABLE_NAME}.${MessageTable.TYPE} & ${MmsSmsColumns.Types.SPECIAL_TYPE_PAYMENTS_NOTIFICATION} = 0
ORDER BY ${MmsSmsColumns.DATE_RECEIVED} DESC
LIMIT 500
"""
@@ -111,37 +74,20 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
private const val MESSAGES_FOR_THREAD_QUERY = """
SELECT
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} AS $CONVERSATION_RECIPIENT,
${SmsTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
snippet($SMS_FTS_TABLE_NAME, -1, '', '', '$SNIPPET_WRAP', 7) AS $SNIPPET,
${SmsTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
$SMS_FTS_TABLE_NAME.$THREAD_ID,
$SMS_FTS_TABLE_NAME.$BODY,
$SMS_FTS_TABLE_NAME.$ID AS $MESSAGE_ID,
0 AS $IS_MMS
FROM
${SmsTable.TABLE_NAME}
INNER JOIN $SMS_FTS_TABLE_NAME ON $SMS_FTS_TABLE_NAME.$ID = ${SmsTable.TABLE_NAME}.${SmsTable.ID}
INNER JOIN ${ThreadTable.TABLE_NAME} ON $SMS_FTS_TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
WHERE
$SMS_FTS_TABLE_NAME MATCH ? AND
${SmsTable.TABLE_NAME}.${MmsSmsColumns.THREAD_ID} = ?
UNION ALL
SELECT
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} AS $CONVERSATION_RECIPIENT,
${MmsTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
${MessageTable.TABLE_NAME}.${MmsSmsColumns.RECIPIENT_ID} AS $MESSAGE_RECIPIENT,
snippet($MMS_FTS_TABLE_NAME, -1, '', '', '$SNIPPET_WRAP', 7) AS $SNIPPET,
${MmsTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
${MessageTable.TABLE_NAME}.${MmsSmsColumns.DATE_RECEIVED},
$MMS_FTS_TABLE_NAME.$THREAD_ID,
$MMS_FTS_TABLE_NAME.$BODY,
$MMS_FTS_TABLE_NAME.$ID AS $MESSAGE_ID,
1 AS $IS_MMS
FROM
${MmsTable.TABLE_NAME}
INNER JOIN $MMS_FTS_TABLE_NAME ON $MMS_FTS_TABLE_NAME.$ID = ${MmsTable.TABLE_NAME}.${MmsTable.ID}
${MessageTable.TABLE_NAME}
INNER JOIN $MMS_FTS_TABLE_NAME ON $MMS_FTS_TABLE_NAME.$ID = ${MessageTable.TABLE_NAME}.${MessageTable.ID}
INNER JOIN ${ThreadTable.TABLE_NAME} ON $MMS_FTS_TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
WHERE
$MMS_FTS_TABLE_NAME MATCH ? AND
${MmsTable.TABLE_NAME}.${MmsSmsColumns.THREAD_ID} = ?
${MessageTable.TABLE_NAME}.${MmsSmsColumns.THREAD_ID} = ?
ORDER BY ${MmsSmsColumns.DATE_RECEIVED} DESC
LIMIT 500
"""
@@ -152,7 +98,7 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
return if (fullTextSearchQuery.isEmpty()) {
null
} else {
readableDatabase.rawQuery(MESSAGES_QUERY, SqlUtil.buildArgs(fullTextSearchQuery, fullTextSearchQuery))
readableDatabase.rawQuery(MESSAGES_QUERY, SqlUtil.buildArgs(fullTextSearchQuery))
}
}
@@ -161,7 +107,7 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
return if (TextUtils.isEmpty(fullTextSearchQuery)) {
null
} else {
readableDatabase.rawQuery(MESSAGES_FOR_THREAD_QUERY, SqlUtil.buildArgs(fullTextSearchQuery, threadId, fullTextSearchQuery, threadId))
readableDatabase.rawQuery(MESSAGES_FOR_THREAD_QUERY, SqlUtil.buildArgs(fullTextSearchQuery, threadId))
}
}

View File

@@ -38,8 +38,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
),
SignalDatabaseOpenHelper {
val sms: SmsTable = SmsTable(context, this)
val mms: MmsTable = MmsTable(context, this)
val mms: MessageTable = MessageTable(context, this)
val attachments: AttachmentTable = AttachmentTable(context, this, attachmentSecret)
val media: MediaTable = MediaTable(context, this)
val thread: ThreadTable = ThreadTable(context, this)
@@ -81,8 +80,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
}
override fun onCreate(db: net.zetetic.database.sqlcipher.SQLiteDatabase) {
db.execSQL(SmsTable.CREATE_TABLE)
db.execSQL(MmsTable.CREATE_TABLE)
db.execSQL(MessageTable.CREATE_TABLE)
db.execSQL(AttachmentTable.CREATE_TABLE)
db.execSQL(ThreadTable.CREATE_TABLE)
db.execSQL(IdentityTable.CREATE_TABLE)
@@ -118,8 +116,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
executeStatements(db, DistributionListTables.CREATE_TABLE)
executeStatements(db, RecipientTable.CREATE_INDEXS)
executeStatements(db, SmsTable.CREATE_INDEXS)
executeStatements(db, MmsTable.CREATE_INDEXS)
executeStatements(db, MessageTable.CREATE_INDEXS)
executeStatements(db, AttachmentTable.CREATE_INDEXS)
executeStatements(db, ThreadTable.CREATE_INDEXS)
executeStatements(db, DraftTable.CREATE_INDEXS)
@@ -280,7 +277,6 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
database.withinTransaction { db ->
instance!!.onUpgrade(db, db.getVersion(), -1)
instance!!.markCurrent(db)
instance!!.sms.deleteAbandonedMessages()
instance!!.mms.deleteAbandonedMessages()
instance!!.mms.trimEntriesForExpiredMessages()
instance!!.reactionTable.deleteAbandonedReactions()
@@ -429,7 +425,7 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
@get:JvmStatic
@get:JvmName("mms")
val mms: MmsTable
val mms: MessageTable
get() = instance!!.mms
@get:JvmStatic
@@ -475,8 +471,8 @@ open class SignalDatabase(private val context: Application, databaseSecret: Data
@get:JvmStatic
@get:JvmName("sms")
val sms: SmsTable
get() = instance!!.sms
val sms: MessageTable
get() = instance!!.mms
@get:JvmStatic
@get:JvmName("threads")

View File

@@ -36,7 +36,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
val CREATE_TABLE = """
CREATE TABLE $TABLE_NAME (
$ID INTEGER PRIMARY KEY,
$MESSAGE_ID INTEGER NOT NULL REFERENCES ${MmsTable.TABLE_NAME} (${MmsTable.ID}) ON DELETE CASCADE,
$MESSAGE_ID INTEGER NOT NULL REFERENCES ${MessageTable.TABLE_NAME} (${MessageTable.ID}) ON DELETE CASCADE,
$RECIPIENT_ID INTEGER NOT NULL REFERENCES ${RecipientTable.TABLE_NAME} (${RecipientTable.ID}) ON DELETE CASCADE,
$SENT_TIMESTAMP INTEGER NOT NULL,
$ALLOWS_REPLIES INTEGER NOT NULL,
@@ -141,9 +141,9 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
WHERE $MESSAGE_ID != $messageId
AND $SENT_TIMESTAMP = $sentTimestamp
AND $MESSAGE_ID IN (
SELECT ${MmsTable.ID}
FROM ${MmsTable.TABLE_NAME}
WHERE ${MmsTable.REMOTE_DELETED} = 0
SELECT ${MessageTable.ID}
FROM ${MessageTable.TABLE_NAME}
WHERE ${MessageTable.REMOTE_DELETED} = 0
)
)
""".trimIndent()
@@ -208,7 +208,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
.where(
"""
$SENT_TIMESTAMP = ? AND
(SELECT ${MmsTable.REMOTE_DELETED} FROM ${MmsTable.TABLE_NAME} WHERE ${MmsTable.ID} = $MESSAGE_ID) = 0
(SELECT ${MessageTable.REMOTE_DELETED} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.ID} = $MESSAGE_ID) = 0
""".trimIndent(),
sentTimestamp
)
@@ -250,10 +250,10 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
val localManifest: SentStorySyncManifest = getLocalManifest(sentTimestamp)
val query = """
SELECT ${MmsTable.TABLE_NAME}.${MmsTable.ID} as $MESSAGE_ID, ${DistributionListTables.DISTRIBUTION_ID}
FROM ${MmsTable.TABLE_NAME}
INNER JOIN ${DistributionListTables.LIST_TABLE_NAME} ON ${DistributionListTables.LIST_TABLE_NAME}.${DistributionListTables.RECIPIENT_ID} = ${MmsTable.TABLE_NAME}.${MmsTable.RECIPIENT_ID}
WHERE ${MmsTable.DATE_SENT} = $sentTimestamp AND ${DistributionListTables.DISTRIBUTION_ID} IS NOT NULL
SELECT ${MessageTable.TABLE_NAME}.${MessageTable.ID} as $MESSAGE_ID, ${DistributionListTables.DISTRIBUTION_ID}
FROM ${MessageTable.TABLE_NAME}
INNER JOIN ${DistributionListTables.LIST_TABLE_NAME} ON ${DistributionListTables.LIST_TABLE_NAME}.${DistributionListTables.RECIPIENT_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.RECIPIENT_ID}
WHERE ${MessageTable.DATE_SENT} = $sentTimestamp AND ${DistributionListTables.DISTRIBUTION_ID} IS NOT NULL
""".trimIndent()
val distributionIdToMessageId = readableDatabase.query(query).use { cursor ->
@@ -329,16 +329,16 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
$TABLE_NAME.$RECIPIENT_ID,
$ALLOWS_REPLIES,
$DISTRIBUTION_ID,
${MmsTable.REMOTE_DELETED}
${MessageTable.REMOTE_DELETED}
FROM $TABLE_NAME
INNER JOIN ${MmsTable.TABLE_NAME} ON ${MmsTable.TABLE_NAME}.${MmsTable.ID} = $TABLE_NAME.$MESSAGE_ID
INNER JOIN ${MessageTable.TABLE_NAME} ON ${MessageTable.TABLE_NAME}.${MessageTable.ID} = $TABLE_NAME.$MESSAGE_ID
WHERE $TABLE_NAME.$SENT_TIMESTAMP = ?
""".trimIndent(),
arrayOf(sentTimestamp)
).use { cursor ->
val results: MutableMap<RecipientId, SentStorySyncManifest.Entry> = mutableMapOf()
while (cursor.moveToNext()) {
val isRemoteDeleted = CursorUtil.requireBoolean(cursor, MmsTable.REMOTE_DELETED)
val isRemoteDeleted = CursorUtil.requireBoolean(cursor, MessageTable.REMOTE_DELETED)
val recipientId = RecipientId.from(CursorUtil.requireLong(cursor, RECIPIENT_ID))
val distributionId = DistributionId.from(CursorUtil.requireString(cursor, DISTRIBUTION_ID))
val distributionIdList: List<DistributionId> = if (isRemoteDeleted) emptyList() else listOf(distributionId)

View File

@@ -34,10 +34,10 @@ import org.thoughtcrime.securesms.database.DraftTable;
import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.GroupReceiptTable;
import org.thoughtcrime.securesms.database.IdentityTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.PushTable;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.groups.GroupId;
@@ -128,8 +128,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SmsTable.CREATE_TABLE);
db.execSQL(MmsTable.CREATE_TABLE);
db.execSQL(MessageTable.CREATE_TABLE);
db.execSQL(AttachmentTable.CREATE_TABLE);
db.execSQL(ThreadTable.CREATE_TABLE);
db.execSQL(IdentityTable.CREATE_TABLE);
@@ -139,8 +138,7 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
db.execSQL(RecipientTable.CREATE_TABLE);
db.execSQL(GroupReceiptTable.CREATE_TABLE);
executeStatements(db, SmsTable.CREATE_INDEXS);
executeStatements(db, MmsTable.CREATE_INDEXS);
executeStatements(db, MessageTable.CREATE_INDEXS);
executeStatements(db, AttachmentTable.CREATE_INDEXS);
executeStatements(db, ThreadTable.CREATE_INDEXS);
executeStatements(db, DraftTable.CREATE_INDEXS);
@@ -404,10 +402,10 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
Cursor cursor = null;
try {
cursor = db.query(SmsTable.TABLE_NAME,
new String[] { SmsTable.ID, SmsTable.BODY, SmsTable.TYPE},
SmsTable.TYPE + " & ? == 0",
new String[] {String.valueOf(SmsTable.Types.ENCRYPTION_MASK)},
cursor = db.query("sms",
new String[] { "_id", "body", "type"},
"type & ? == 0",
new String[] {String.valueOf(MmsSmsColumns.Types.ENCRYPTION_MASK)},
null, null, null);
while (cursor.moveToNext()) {
@@ -418,10 +416,10 @@ public class ClassicOpenHelper extends SQLiteOpenHelper {
String encryptedBody = masterCipher.encryptBody(body);
ContentValues update = new ContentValues();
update.put(SmsTable.BODY, encryptedBody);
update.put(SmsTable.TYPE, type | 0x80000000); // Inline now deprecated symmetric encryption type
update.put("body", encryptedBody);
update.put("type", type | 0x80000000); // Inline now deprecated symmetric encryption type
db.update(SmsTable.TABLE_NAME, update, SmsTable.ID + " = ?",
db.update("sms", update, "_id = ?",
new String[] {String.valueOf(id)});
}
} finally {

View File

@@ -23,6 +23,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V164_ThreadDatabase
import org.thoughtcrime.securesms.database.helpers.migration.V165_MmsMessageBoxPaymentTransactionIndexMigration
import org.thoughtcrime.securesms.database.helpers.migration.V166_ThreadAndMessageForeignKeys
import org.thoughtcrime.securesms.database.helpers.migration.V167_RecreateReactionTriggers
import org.thoughtcrime.securesms.database.helpers.migration.V168_SingleMessageTableMigration
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@@ -31,7 +32,7 @@ object SignalDatabaseMigrations {
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
const val DATABASE_VERSION = 167
const val DATABASE_VERSION = 168
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -110,6 +111,10 @@ object SignalDatabaseMigrations {
if (oldVersion < 167) {
V167_RecreateReactionTriggers.migrate(context, db, oldVersion, newVersion)
}
if (oldVersion < 168) {
V168_SingleMessageTableMigration.migrate(context, db, oldVersion, newVersion)
}
}
@JvmStatic

View File

@@ -0,0 +1,91 @@
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.SqlUtil
object V168_SingleMessageTableMigration : SignalDatabaseMigration {
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val nextMmsId = SqlUtil.getNextAutoIncrementId(db, "mms")
db.execSQL("DROP TRIGGER msl_sms_delete")
db.execSQL("DROP TRIGGER reactions_sms_delete")
db.execSQL("DROP TABLE sms_fts") // Will drop all other related fts tables
db.execSQL(
"""
INSERT INTO mms
SELECT
_id + $nextMmsId,
date_sent,
date_received,
date_server,
thread_id,
recipient_id,
recipient_device_id,
type,
body,
read,
null,
0,
0,
0,
status,
null,
subscription_id,
receipt_timestamp,
delivery_receipt_count,
read_receipt_count,
0,
mismatched_identities,
null,
expires_in,
expire_started,
notified,
0,
0,
null,
0,
null,
0,
null,
unidentified,
null,
0,
reactions_unread,
reactions_last_seen,
remote_deleted,
0,
notified_timestamp,
server_guid,
null,
0,
0,
export_state,
exported
FROM sms
"""
)
db.execSQL("DROP TABLE sms")
db.execSQL(
"""
UPDATE reaction
SET message_id = message_id + $nextMmsId
WHERE is_mms = 0
"""
)
db.execSQL(
"""
UPDATE msl_message
SET message_id = message_id + $nextMmsId
WHERE is_mms = 0
"""
)
// TODO search index?
// TODO jobs?
}
}

View File

@@ -23,7 +23,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.recipients.Recipient;
/**
@@ -72,7 +71,7 @@ public abstract class DisplayRecord {
return
MmsSmsColumns.Types.isFailedMessageType(type) ||
MmsSmsColumns.Types.isPendingSecureSmsFallbackType(type) ||
deliveryStatus >= SmsTable.Status.STATUS_FAILED;
deliveryStatus >= MmsSmsColumns.Status.STATUS_FAILED;
}
public boolean isPending() {
@@ -113,23 +112,23 @@ public abstract class DisplayRecord {
}
public boolean isKeyExchange() {
return SmsTable.Types.isKeyExchangeType(type);
return MmsSmsColumns.Types.isKeyExchangeType(type);
}
public boolean isEndSession() {
return SmsTable.Types.isEndSessionType(type);
return MmsSmsColumns.Types.isEndSessionType(type);
}
public boolean isGroupUpdate() {
return SmsTable.Types.isGroupUpdate(type);
return MmsSmsColumns.Types.isGroupUpdate(type);
}
public boolean isGroupV2() {
return SmsTable.Types.isGroupV2(type);
return MmsSmsColumns.Types.isGroupV2(type);
}
public boolean isGroupQuit() {
return SmsTable.Types.isGroupQuit(type);
return MmsSmsColumns.Types.isGroupQuit(type);
}
public boolean isGroupAction() {
@@ -137,55 +136,55 @@ public abstract class DisplayRecord {
}
public boolean isExpirationTimerUpdate() {
return SmsTable.Types.isExpirationTimerUpdate(type);
return MmsSmsColumns.Types.isExpirationTimerUpdate(type);
}
public boolean isCallLog() {
return SmsTable.Types.isCallLog(type);
return MmsSmsColumns.Types.isCallLog(type);
}
public boolean isJoined() {
return SmsTable.Types.isJoinedType(type);
return MmsSmsColumns.Types.isJoinedType(type);
}
public boolean isIncomingAudioCall() {
return SmsTable.Types.isIncomingAudioCall(type);
return MmsSmsColumns.Types.isIncomingAudioCall(type);
}
public boolean isIncomingVideoCall() {
return SmsTable.Types.isIncomingVideoCall(type);
return MmsSmsColumns.Types.isIncomingVideoCall(type);
}
public boolean isOutgoingAudioCall() {
return SmsTable.Types.isOutgoingAudioCall(type);
return MmsSmsColumns.Types.isOutgoingAudioCall(type);
}
public boolean isOutgoingVideoCall() {
return SmsTable.Types.isOutgoingVideoCall(type);
return MmsSmsColumns.Types.isOutgoingVideoCall(type);
}
public final boolean isMissedAudioCall() {
return SmsTable.Types.isMissedAudioCall(type);
return MmsSmsColumns.Types.isMissedAudioCall(type);
}
public final boolean isMissedVideoCall() {
return SmsTable.Types.isMissedVideoCall(type);
return MmsSmsColumns.Types.isMissedVideoCall(type);
}
public final boolean isGroupCall() {
return SmsTable.Types.isGroupCall(type);
return MmsSmsColumns.Types.isGroupCall(type);
}
public boolean isVerificationStatusChange() {
return SmsTable.Types.isIdentityDefault(type) || SmsTable.Types.isIdentityVerified(type);
return MmsSmsColumns.Types.isIdentityDefault(type) || MmsSmsColumns.Types.isIdentityVerified(type);
}
public boolean isProfileChange() {
return SmsTable.Types.isProfileChange(type);
return MmsSmsColumns.Types.isProfileChange(type);
}
public boolean isChangeNumber() {
return SmsTable.Types.isChangeNumber(type);
return MmsSmsColumns.Types.isChangeNumber(type);
}
public boolean isBoostRequest() {
@@ -216,8 +215,8 @@ public abstract class DisplayRecord {
}
public boolean isDelivered() {
return (deliveryStatus >= SmsTable.Status.STATUS_COMPLETE &&
deliveryStatus < SmsTable.Status.STATUS_PENDING) || deliveryReceiptCount > 0;
return (deliveryStatus >= MmsSmsColumns.Status.STATUS_COMPLETE &&
deliveryStatus < MmsSmsColumns.Status.STATUS_PENDING) || deliveryReceiptCount > 0;
}
public boolean isRemoteViewed() {
@@ -229,7 +228,7 @@ public abstract class DisplayRecord {
}
public boolean isPendingInsecureSmsFallback() {
return SmsTable.Types.isPendingInsecureSmsFallbackType(type);
return MmsSmsColumns.Types.isPendingInsecureSmsFallbackType(type);
}
public boolean isPaymentNotification() {

View File

@@ -29,8 +29,8 @@ import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.contactshare.Contact;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SmsTable.Status;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsSmsColumns.Status;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
@@ -122,11 +122,11 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
@Override
@WorkerThread
public SpannableString getDisplayBody(@NonNull Context context) {
if (MmsTable.Types.isChatSessionRefresh(type)) {
if (MessageTable.Types.isChatSessionRefresh(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_bad_encrypted_mms_message));
} else if (MmsTable.Types.isDuplicateMessageType(type)) {
} else if (MessageTable.Types.isDuplicateMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message));
} else if (MmsTable.Types.isNoRemoteSessionType(type)) {
} else if (MessageTable.Types.isNoRemoteSessionType(type)) {
return emphasisAdded(context.getString(R.string.MmsMessageRecord_mms_message_encrypted_for_non_existing_session));
} else if (isLegacyMessage()) {
return emphasisAdded(context.getString(R.string.MessageRecord_message_encrypted_with_a_legacy_protocol_version_that_is_no_longer_supported));
@@ -182,7 +182,7 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
Quote quote = updateQuote(context, getQuote(), attachments);
List<DatabaseAttachment> slideAttachments = attachments.stream().filter(a -> !contactAttachments.contains(a)).filter(a -> !linkPreviewAttachments.contains(a)).collect(Collectors.toList());
SlideDeck slideDeck = MmsTable.Reader.buildSlideDeck(context, slideAttachments);
SlideDeck slideDeck = MessageTable.MmsReader.buildSlideDeck(context, slideAttachments);
return new MediaMmsMessageRecord(getId(), getRecipient(), getIndividualRecipient(), getRecipientDeviceId(), getDateSent(), getDateReceived(), getServerTimestamp(), getDeliveryReceiptCount(), getThreadId(), getBody(), slideDeck,
getType(), getIdentityKeyMismatches(), getNetworkFailures(), getSubscriptionId(), getExpiresIn(), getExpireStarted(), isViewOnce(),

View File

@@ -16,6 +16,21 @@ data class MessageId(
return "$id|$mms"
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as MessageId
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
return id.hashCode()
}
companion object {
/**
* Returns null for invalid IDs. Useful when pulling a possibly-unset ID from a database, or something like that.

View File

@@ -42,7 +42,6 @@ import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.components.emoji.EmojiProvider;
import org.thoughtcrime.securesms.components.emoji.parsing.EmojiParser;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
import org.thoughtcrime.securesms.database.model.databaseprotos.BodyRangeList;
@@ -494,7 +493,7 @@ public abstract class MessageRecord extends DisplayRecord {
}
public boolean isPush() {
return SmsTable.Types.isPushType(type) && !SmsTable.Types.isForcedSms(type);
return MmsSmsColumns.Types.isPushType(type) && !MmsSmsColumns.Types.isForcedSms(type);
}
public long getTimestamp() {
@@ -509,15 +508,15 @@ public abstract class MessageRecord extends DisplayRecord {
}
public boolean isForcedSms() {
return SmsTable.Types.isForcedSms(type);
return MmsSmsColumns.Types.isForcedSms(type);
}
public boolean isIdentityVerified() {
return SmsTable.Types.isIdentityVerified(type);
return MmsSmsColumns.Types.isIdentityVerified(type);
}
public boolean isIdentityDefault() {
return SmsTable.Types.isIdentityDefault(type);
return MmsSmsColumns.Types.isIdentityDefault(type);
}
public boolean isIdentityMismatchFailure() {
@@ -525,23 +524,23 @@ public abstract class MessageRecord extends DisplayRecord {
}
public boolean isBundleKeyExchange() {
return SmsTable.Types.isBundleKeyExchange(type);
return MmsSmsColumns.Types.isBundleKeyExchange(type);
}
public boolean isContentBundleKeyExchange() {
return SmsTable.Types.isContentBundleKeyExchange(type);
return MmsSmsColumns.Types.isContentBundleKeyExchange(type);
}
public boolean isRateLimited() {
return SmsTable.Types.isRateLimited(type);
return MmsSmsColumns.Types.isRateLimited(type);
}
public boolean isIdentityUpdate() {
return SmsTable.Types.isIdentityUpdate(type);
return MmsSmsColumns.Types.isIdentityUpdate(type);
}
public boolean isCorruptedKeyExchange() {
return SmsTable.Types.isCorruptedKeyExchange(type);
return MmsSmsColumns.Types.isCorruptedKeyExchange(type);
}
public boolean isBadDecryptType() {
@@ -557,11 +556,11 @@ public abstract class MessageRecord extends DisplayRecord {
}
public boolean isInvalidVersionKeyExchange() {
return SmsTable.Types.isInvalidVersionKeyExchange(type);
return MmsSmsColumns.Types.isInvalidVersionKeyExchange(type);
}
public boolean isGroupV1MigrationEvent() {
return SmsTable.Types.isGroupV1MigrationEvent(type);
return MmsSmsColumns.Types.isGroupV1MigrationEvent(type);
}
public @NonNull GroupMigrationMembershipChange getGroupV1MigrationMembershipChanges() {

View File

@@ -23,8 +23,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SmsTable.Status;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsSmsColumns.Status;
import org.thoughtcrime.securesms.database.model.databaseprotos.GiftBadge;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -117,9 +117,9 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord {
@Override
public SpannableString getDisplayBody(@NonNull Context context) {
if (status == MmsTable.Status.DOWNLOAD_INITIALIZED) {
if (status == MessageTable.MmsStatus.DOWNLOAD_INITIALIZED) {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_multimedia_message));
} else if (status == MmsTable.Status.DOWNLOAD_CONNECTING) {
} else if (status == MessageTable.MmsStatus.DOWNLOAD_CONNECTING) {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_downloading_mms_message));
} else {
return emphasisAdded(context.getString(R.string.NotificationMmsMessageRecord_error_downloading_mms_message));

View File

@@ -25,7 +25,6 @@ import androidx.annotation.WorkerThread;
import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -68,7 +67,7 @@ public class SmsMessageRecord extends MessageRecord {
@Override
@WorkerThread
public SpannableString getDisplayBody(@NonNull Context context) {
if (SmsTable.Types.isChatSessionRefresh(type)) {
if (MmsSmsColumns.Types.isChatSessionRefresh(type)) {
return emphasisAdded(context.getString(R.string.MessageRecord_chat_session_refreshed));
} else if (isCorruptedKeyExchange()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_received_corrupted_key_exchange_message));
@@ -82,17 +81,17 @@ public class SmsMessageRecord extends MessageRecord {
return new SpannableString("");
} else if (isKeyExchange() && !isOutgoing()) {
return emphasisAdded(context.getString(R.string.ConversationItem_received_key_exchange_message_tap_to_process));
} else if (SmsTable.Types.isDuplicateMessageType(type)) {
} else if (MmsSmsColumns.Types.isDuplicateMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_duplicate_message));
} else if (SmsTable.Types.isNoRemoteSessionType(type)) {
} else if (MmsSmsColumns.Types.isNoRemoteSessionType(type)) {
return emphasisAdded(context.getString(R.string.MessageDisplayHelper_message_encrypted_for_non_existing_session));
} else if (isEndSession() && isOutgoing()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset));
} else if (isEndSession()) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_secure_session_reset_s, getIndividualRecipient().getDisplayName(context)));
} else if (SmsTable.Types.isUnsupportedMessageType(type)) {
} else if (MmsSmsColumns.Types.isUnsupportedMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_this_message_could_not_be_processed_because_it_was_sent_from_a_newer_version));
} else if (SmsTable.Types.isInvalidMessageType(type)) {
} else if (MmsSmsColumns.Types.isInvalidMessageType(type)) {
return emphasisAdded(context.getString(R.string.SmsMessageRecord_error_handling_incoming_message));
} else {
return super.getDisplayBody(context);

View File

@@ -1,14 +1,13 @@
package org.thoughtcrime.securesms.database.model;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
final class StatusUtil {
private StatusUtil() {}
static boolean isDelivered(long deliveryStatus, int deliveryReceiptCount) {
return (deliveryStatus >= SmsTable.Status.STATUS_COMPLETE &&
deliveryStatus < SmsTable.Status.STATUS_PENDING) || deliveryReceiptCount > 0;
return (deliveryStatus >= MmsSmsColumns.Status.STATUS_COMPLETE &&
deliveryStatus < MmsSmsColumns.Status.STATUS_PENDING) || deliveryReceiptCount > 0;
}
static boolean isPending(long type) {
@@ -20,10 +19,10 @@ final class StatusUtil {
static boolean isFailed(long type, long deliveryStatus) {
return MmsSmsColumns.Types.isFailedMessageType(type) ||
MmsSmsColumns.Types.isPendingSecureSmsFallbackType(type) ||
deliveryStatus >= SmsTable.Status.STATUS_FAILED;
deliveryStatus >= MmsSmsColumns.Status.STATUS_FAILED;
}
static boolean isVerificationStatusChange(long type) {
return SmsTable.Types.isIdentityDefault(type) || SmsTable.Types.isIdentityVerified(type);
return MmsSmsColumns.Types.isIdentityDefault(type) || MmsSmsColumns.Types.isIdentityVerified(type);
}
}

View File

@@ -23,7 +23,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.database.ThreadTable.Extra;
import org.thoughtcrime.securesms.recipients.Recipient;
@@ -146,11 +145,11 @@ public final class ThreadRecord {
}
public boolean isOutgoingAudioCall() {
return SmsTable.Types.isOutgoingAudioCall(type);
return MmsSmsColumns.Types.isOutgoingAudioCall(type);
}
public boolean isOutgoingVideoCall() {
return SmsTable.Types.isOutgoingVideoCall(type);
return MmsSmsColumns.Types.isOutgoingVideoCall(type);
}
public boolean isVerificationStatusChange() {
@@ -170,7 +169,7 @@ public final class ThreadRecord {
}
public boolean isPendingInsecureSmsFallback() {
return SmsTable.Types.isPendingInsecureSmsFallbackType(type);
return MmsSmsColumns.Types.isPendingInsecureSmsFallbackType(type);
}
public boolean isDelivered() {

View File

@@ -5,9 +5,7 @@ import org.signal.smsexporter.ExportableMessage
import org.signal.smsexporter.SmsExportState
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
import org.thoughtcrime.securesms.database.MessageTable
import org.thoughtcrime.securesms.database.MmsTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.SmsTable
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
@@ -32,9 +30,9 @@ class SignalSmsExportReader(
private const val CURSOR_LIMIT = 1000
}
private var smsReader: SmsTable.Reader? = null
private var smsReader: MessageTable.SmsReader? = null
private var smsDone: Boolean = false
private var mmsReader: MmsTable.Reader? = null
private var mmsReader: MessageTable.MmsReader? = null
private var mmsDone: Boolean = false
override fun iterator(): Iterator<ExportableMessage> {
@@ -55,7 +53,7 @@ class SignalSmsExportReader(
smsReader?.close()
smsReader = null
val refreshedSmsReader = SmsTable.readerFor(smsDatabase.getUnexportedInsecureMessages(CURSOR_LIMIT))
val refreshedSmsReader = MessageTable.smsReaderFor(smsDatabase.getUnexportedInsecureMessages(CURSOR_LIMIT))
if (refreshedSmsReader.count > 0) {
smsReader = refreshedSmsReader
return
@@ -69,7 +67,7 @@ class SignalSmsExportReader(
mmsReader?.close()
mmsReader = null
val refreshedMmsReader = MmsTable.readerFor(mmsDatabase.getUnexportedInsecureMessages(CURSOR_LIMIT))
val refreshedMmsReader = MessageTable.mmsReaderFor(mmsDatabase.getUnexportedInsecureMessages(CURSOR_LIMIT))
if (refreshedMmsReader.count > 0) {
mmsReader = refreshedMmsReader
return

View File

@@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.contactshare.VCardUtil;
import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MessageTable.InsertResult;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.groups.GroupId;
@@ -110,8 +109,8 @@ public class MmsDownloadJob extends BaseJob {
throw new NotReadyException();
}
MessageTable database = SignalDatabase.mms();
Optional<MmsTable.MmsNotificationInfo> notification = database.getNotification(messageId);
MessageTable database = SignalDatabase.mms();
Optional<MessageTable.MmsNotificationInfo> notification = database.getNotification(messageId);
if (!notification.isPresent()) {
Log.w(TAG, "No notification for ID: " + messageId);
@@ -127,7 +126,7 @@ public class MmsDownloadJob extends BaseJob {
throw new MmsException("Not registered");
}
database.markDownloadState(messageId, MmsTable.Status.DOWNLOAD_CONNECTING);
database.markDownloadState(messageId, MessageTable.MmsStatus.DOWNLOAD_CONNECTING);
String contentLocation = notification.get().getContentLocation();
byte[] transactionId = new byte[0];
@@ -153,17 +152,17 @@ public class MmsDownloadJob extends BaseJob {
storeRetrievedMms(contentLocation, messageId, threadId, retrieveConf, notification.get().getSubscriptionId(), notification.get().getFrom());
} catch (ApnUnavailableException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId, MmsTable.Status.DOWNLOAD_APN_UNAVAILABLE,
handleDownloadError(messageId, threadId, MessageTable.MmsStatus.DOWNLOAD_APN_UNAVAILABLE,
automatic);
} catch (MmsException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId,
MmsTable.Status.DOWNLOAD_HARD_FAILURE,
MessageTable.MmsStatus.DOWNLOAD_HARD_FAILURE,
automatic);
} catch (MmsRadioException | IOException e) {
Log.w(TAG, e);
handleDownloadError(messageId, threadId,
MmsTable.Status.DOWNLOAD_SOFT_FAILURE,
MessageTable.MmsStatus.DOWNLOAD_SOFT_FAILURE,
automatic);
}
}
@@ -171,7 +170,7 @@ public class MmsDownloadJob extends BaseJob {
@Override
public void onFailure() {
MessageTable database = SignalDatabase.mms();
database.markDownloadState(messageId, MmsTable.Status.DOWNLOAD_SOFT_FAILURE);
database.markDownloadState(messageId, MessageTable.MmsStatus.DOWNLOAD_SOFT_FAILURE);
if (automatic) {
database.markIncomingNotificationReceived(threadId);

View File

@@ -18,7 +18,6 @@ import org.thoughtcrime.securesms.database.GroupTable;
import org.thoughtcrime.securesms.database.GroupReceiptTable;
import org.thoughtcrime.securesms.database.GroupReceiptTable.GroupReceiptInfo;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
@@ -382,7 +381,7 @@ public final class PushGroupSendJob extends PushSendJob {
@NonNull Set<IdentityKeyMismatch> existingIdentityMismatches)
throws RetryLaterException, ProofRequiredException
{
MmsTable database = SignalDatabase.mms();
MessageTable database = SignalDatabase.mms();
RecipientAccessList accessList = new RecipientAccessList(target);
List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(accessList.requireIdByAddress(result.getAddress()))).toList();

View File

@@ -12,9 +12,7 @@ import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.conversation.ConversationMessage.ConversationMessageFactory;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.MmsMessageRecord;
import org.thoughtcrime.securesms.mms.PartAuthority;
@@ -78,14 +76,14 @@ class LongMessageRepository {
@WorkerThread
private Optional<MmsMessageRecord> getMmsMessage(@NonNull MessageTable mmsDatabase, long messageId) {
try (Cursor cursor = mmsDatabase.getMessageCursor(messageId)) {
return Optional.ofNullable((MmsMessageRecord) MmsTable.readerFor(cursor).getNext());
return Optional.ofNullable((MmsMessageRecord) MessageTable.mmsReaderFor(cursor).getNext());
}
}
@WorkerThread
private Optional<MessageRecord> getSmsMessage(@NonNull MessageTable smsDatabase, long messageId) {
try (Cursor cursor = smsDatabase.getMessageCursor(messageId)) {
return Optional.ofNullable(SmsTable.readerFor(cursor).getNext());
return Optional.ofNullable(MessageTable.smsReaderFor(cursor).getNext());
}
}

View File

@@ -35,7 +35,6 @@ import java.util.List;
public final class MessageDetailsFragment extends FullScreenDialogFragment {
private static final String MESSAGE_ID_EXTRA = "message_id";
private static final String TYPE_EXTRA = "type";
private static final String RECIPIENT_EXTRA = "recipient_id";
private GlideRequests glideRequests;
@@ -49,7 +48,6 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
Bundle args = new Bundle();
args.putLong(MESSAGE_ID_EXTRA, message.getId());
args.putString(TYPE_EXTRA, message.isMms() ? MmsSmsTable.MMS_TRANSPORT : MmsSmsTable.SMS_TRANSPORT);
args.putParcelable(RECIPIENT_EXTRA, recipientId);
dialogFragment.setArguments(args);
@@ -102,9 +100,8 @@ public final class MessageDetailsFragment extends FullScreenDialogFragment {
private void initializeViewModel() {
final RecipientId recipientId = requireArguments().getParcelable(RECIPIENT_EXTRA);
final String type = requireArguments().getString(TYPE_EXTRA);
final Long messageId = requireArguments().getLong(MESSAGE_ID_EXTRA, -1);
final Factory factory = new Factory(recipientId, type, messageId);
final Factory factory = new Factory(recipientId, messageId);
viewModel = new ViewModelProvider(this, factory).get(MessageDetailsViewModel.class);
viewModel.getMessageDetails().observe(this, details -> {

View File

@@ -37,8 +37,8 @@ public final class MessageDetailsRepository {
private final Context context = ApplicationDependencies.getApplication();
@NonNull LiveData<MessageRecord> getMessageRecord(String type, Long messageId) {
return new MessageRecordLiveData(new MessageId(messageId, type.equals(MmsSmsTable.MMS_TRANSPORT)));
@NonNull LiveData<MessageRecord> getMessageRecord(Long messageId) {
return new MessageRecordLiveData(new MessageId(messageId, true));
}
@NonNull LiveData<MessageDetails> getMessageDetails(@Nullable MessageRecord messageRecord) {

View File

@@ -17,11 +17,11 @@ final class MessageDetailsViewModel extends ViewModel {
private final LiveData<Recipient> recipient;
private final LiveData<MessageDetails> messageDetails;
private MessageDetailsViewModel(RecipientId recipientId, String type, Long messageId) {
private MessageDetailsViewModel(RecipientId recipientId, Long messageId) {
recipient = Recipient.live(recipientId).getLiveData();
MessageDetailsRepository repository = new MessageDetailsRepository();
LiveData<MessageRecord> messageRecord = repository.getMessageRecord(type, messageId);
LiveData<MessageRecord> messageRecord = repository.getMessageRecord(messageId);
messageDetails = Transformations.switchMap(messageRecord, repository::getMessageDetails);
}
@@ -37,18 +37,16 @@ final class MessageDetailsViewModel extends ViewModel {
static final class Factory implements ViewModelProvider.Factory {
private final RecipientId recipientId;
private final String type;
private final Long messageId;
Factory(RecipientId recipientId, String type, Long messageId) {
Factory(RecipientId recipientId, Long messageId) {
this.recipientId = recipientId;
this.type = type;
this.messageId = messageId;
}
@Override
public @NonNull <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
return Objects.requireNonNull(modelClass.cast(new MessageDetailsViewModel(recipientId, type, messageId)));
return Objects.requireNonNull(modelClass.cast(new MessageDetailsViewModel(recipientId, messageId)));
}
}
}

View File

@@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.database.GroupReceiptTable.GroupReceiptInfo;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MessageTable.InsertResult;
import org.thoughtcrime.securesms.database.MessageTable.SyncMessageId;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.MmsSmsTable;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.PaymentTable;
@@ -2164,8 +2163,8 @@ public final class MessageContentProcessor {
null,
true);
MmsTable database = SignalDatabase.mms();
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
MessageTable database = SignalDatabase.mms();
long threadId = SignalDatabase.threads().getOrCreateThreadIdFor(recipient);
long messageId;
List<DatabaseAttachment> attachments;

View File

@@ -10,8 +10,7 @@ import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.crypto.MasterSecret;
import org.thoughtcrime.securesms.database.AttachmentTable;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.MmsTable.Reader;
import org.thoughtcrime.securesms.database.MessageTable.MmsReader;
import org.thoughtcrime.securesms.database.PushTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -251,7 +250,7 @@ public class LegacyMigrationJob extends MigrationJob {
Log.i(TAG, pendingAttachments.size() + " pending parts.");
for (DatabaseAttachment attachment : pendingAttachments) {
final Reader reader = MmsTable.readerFor(mmsDb.getMessageCursor(attachment.getMmsId()));
final MmsReader reader = MessageTable.mmsReaderFor(mmsDb.getMessageCursor(attachment.getMmsId()));
final MessageRecord record = reader.getNext();
if (attachment.hasData()) {

View File

@@ -4,9 +4,7 @@ import android.content.Context;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.MessageTable;
import org.thoughtcrime.securesms.database.MmsTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import java.util.Comparator;
@@ -55,8 +53,8 @@ public class ExpiringMessageManager {
private class LoadTask implements Runnable {
public void run() {
SmsTable.Reader smsReader = SmsTable.readerFor(smsDatabase.getExpirationStartedMessages());
MmsTable.Reader mmsReader = MmsTable.readerFor(mmsDatabase.getExpirationStartedMessages());
MessageTable.SmsReader smsReader = MessageTable.smsReaderFor(smsDatabase.getExpirationStartedMessages());
MessageTable.MmsReader mmsReader = MessageTable.mmsReaderFor(mmsDatabase.getExpirationStartedMessages());
MessageRecord messageRecord;

View File

@@ -6,7 +6,7 @@ import android.content.Intent;
import android.telephony.SmsMessage;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.MmsSmsColumns;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.JobManager;
import org.thoughtcrime.securesms.jobs.SmsSentJob;
@@ -55,9 +55,9 @@ public class SmsDeliveryListener extends BroadcastReceiver {
// Note: https://stackoverflow.com/a/33240109
if ("3gpp2".equals(intent.getStringExtra("format"))) {
Log.w(TAG, "Correcting for CDMA delivery receipt...");
if (status >> 24 <= 0) status = SmsTable.Status.STATUS_COMPLETE;
else if (status >> 24 == 2) status = SmsTable.Status.STATUS_PENDING;
else if (status >> 24 == 3) status = SmsTable.Status.STATUS_FAILED;
if (status >> 24 <= 0) status = MmsSmsColumns.Status.STATUS_COMPLETE;
else if (status >> 24 == 2) status = MmsSmsColumns.Status.STATUS_PENDING;
else if (status >> 24 == 3) status = MmsSmsColumns.Status.STATUS_FAILED;
}
jobManager.add(new SmsSentJob(messageId, isMultipart, DELIVERED_SMS_ACTION, status, runAttempt));

View File

@@ -40,7 +40,6 @@ import org.thoughtcrime.securesms.database.MmsSmsTable;
import org.thoughtcrime.securesms.database.NoSuchMessageException;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.SmsTable;
import org.thoughtcrime.securesms.database.ThreadTable;
import org.thoughtcrime.securesms.database.model.MessageId;
import org.thoughtcrime.securesms.database.model.MessageRecord;
@@ -113,7 +112,7 @@ public class MessageSender {
final long threadId,
final boolean forceSms,
@Nullable final String metricId,
final SmsTable.InsertListener insertListener)
final MessageTable.InsertListener insertListener)
{
Log.i(TAG, "Sending text message to " + message.getRecipient().getId() + ", thread: " + threadId);
MessageTable database = SignalDatabase.sms();
@@ -139,7 +138,7 @@ public class MessageSender {
public static void sendStories(@NonNull final Context context,
@NonNull final List<OutgoingMediaMessage> messages,
@Nullable final String metricId,
@Nullable final SmsTable.InsertListener insertListener)
@Nullable final MessageTable.InsertListener insertListener)
{
Log.i(TAG, "Sending story messages to " + messages.size() + " targets.");
ThreadTable threadTable = SignalDatabase.threads();
@@ -253,7 +252,7 @@ public class MessageSender {
final long threadId,
final boolean forceSms,
@Nullable final String metricId,
@Nullable final SmsTable.InsertListener insertListener)
@Nullable final MessageTable.InsertListener insertListener)
{
Log.i(TAG, "Sending media message to " + message.getRecipient().getId() + ", thread: " + threadId);
try {
@@ -285,7 +284,7 @@ public class MessageSender {
final OutgoingMediaMessage message,
final Collection<PreUploadResult> preUploadResults,
final long threadId,
final SmsTable.InsertListener insertListener)
final MessageTable.InsertListener insertListener)
{
Log.i(TAG, "Sending media message with pre-uploads to " + message.getRecipient().getId() + ", thread: " + threadId + ", pre-uploads: " + preUploadResults);
Preconditions.checkArgument(message.getAttachments().isEmpty(), "If the media is pre-uploaded, there should be no attachments on the message.");

View File

@@ -2,8 +2,8 @@ package org.thoughtcrime.securesms.stories.viewer.reply.group
import org.signal.paging.PagedDataSource
import org.thoughtcrime.securesms.conversation.ConversationMessage
import org.thoughtcrime.securesms.database.MessageTable
import org.thoughtcrime.securesms.database.MmsSmsColumns
import org.thoughtcrime.securesms.database.MmsTable
import org.thoughtcrime.securesms.database.SignalDatabase
import org.thoughtcrime.securesms.database.model.MessageId
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
@@ -18,9 +18,9 @@ class StoryGroupReplyDataSource(private val parentStoryId: Long) : PagedDataSour
val results: MutableList<ReplyBody> = ArrayList(length)
SignalDatabase.mms.getStoryReplies(parentStoryId).use { cursor ->
cursor.moveToPosition(start - 1)
val reader = MmsTable.Reader(cursor)
val mmsReader = MessageTable.MmsReader(cursor)
while (cursor.moveToNext() && cursor.position < start + length) {
results.add(readRowFromRecord(reader.current as MmsMessageRecord))
results.add(readRowFromRecord(mmsReader.current as MmsMessageRecord))
}
}