Add "is_deleted" column to sms/mms (#3)

* Add "is_deleted" column to sms/mms

---------

Co-authored-by: SessionHero01 <SesshioHero01@getsession.org>
pull/1706/head
SessionHero01 5 months ago committed by GitHub
parent 0819053454
commit 74f3f22e1a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1423,27 +1423,67 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
const val QUOTE_MISSING: String = "quote_missing"
const val SHARED_CONTACTS: String = "shared_contacts"
const val LINK_PREVIEWS: String = "previews"
private const val IS_DELETED_COLUMN_DEF = """
$IS_DELETED GENERATED ALWAYS AS (
($MESSAGE_BOX & ${MmsSmsColumns.Types.BASE_TYPE_MASK}) IN (${MmsSmsColumns.Types.BASE_DELETED_OUTGOING_TYPE}, ${MmsSmsColumns.Types.BASE_DELETED_INCOMING_TYPE})
) VIRTUAL
"""
const val CREATE_TABLE: String =
"CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
THREAD_ID + " INTEGER, " + DATE_SENT + " INTEGER, " + DATE_RECEIVED + " INTEGER, " + MESSAGE_BOX + " INTEGER, " +
READ + " INTEGER DEFAULT 0, " + "m_id" + " TEXT, " + "sub" + " TEXT, " +
"sub_cs" + " INTEGER, " + BODY + " TEXT, " + PART_COUNT + " INTEGER, " +
"ct_t" + " TEXT, " + CONTENT_LOCATION + " TEXT, " + ADDRESS + " TEXT, " +
ADDRESS_DEVICE_ID + " INTEGER, " +
EXPIRY + " INTEGER, " + "m_cls" + " TEXT, " + MESSAGE_TYPE + " INTEGER, " +
"v" + " INTEGER, " + MESSAGE_SIZE + " INTEGER, " + "pri" + " INTEGER, " +
"rr" + " INTEGER, " + "rpt_a" + " INTEGER, " + "resp_st" + " INTEGER, " +
STATUS + " INTEGER, " + TRANSACTION_ID + " TEXT, " + "retr_st" + " INTEGER, " +
"retr_txt" + " TEXT, " + "retr_txt_cs" + " INTEGER, " + "read_status" + " INTEGER, " +
"ct_cls" + " INTEGER, " + "resp_txt" + " TEXT, " + "d_tm" + " INTEGER, " +
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " +
NETWORK_FAILURE + " TEXT DEFAULT NULL," + "d_rpt" + " INTEGER, " +
SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + EXPIRES_IN + " INTEGER DEFAULT 0, " +
EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " +
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " +
QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1, " +
QUOTE_MISSING + " INTEGER DEFAULT 0, " + SHARED_CONTACTS + " TEXT, " + UNIDENTIFIED + " INTEGER DEFAULT 0, " +
LINK_PREVIEWS + " TEXT);"
"""CREATE TABLE $TABLE_NAME (
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
$THREAD_ID INTEGER,
$DATE_SENT INTEGER,
$DATE_RECEIVED INTEGER,
$MESSAGE_BOX INTEGER,
$READ INTEGER DEFAULT 0,
m_id TEXT,
sub TEXT,
sub_cs INTEGER,
$BODY TEXT,
$PART_COUNT INTEGER,
ct_t TEXT,
$CONTENT_LOCATION TEXT,
$ADDRESS TEXT,
$ADDRESS_DEVICE_ID INTEGER,
$EXPIRY INTEGER,
m_cls TEXT,
$MESSAGE_TYPE INTEGER,
v INTEGER,
$MESSAGE_SIZE INTEGER,
pri INTEGER,
rr INTEGER,
rpt_a INTEGER,
resp_st INTEGER,
$STATUS INTEGER,
$TRANSACTION_ID TEXT,
retr_st INTEGER,
retr_txt TEXT,
retr_txt_cs INTEGER,
read_status INTEGER,
ct_cls INTEGER,
resp_txt TEXT,
d_tm INTEGER,
$DELIVERY_RECEIPT_COUNT INTEGER DEFAULT 0,
$MISMATCHED_IDENTITIES TEXT DEFAULT NULL,
$NETWORK_FAILURE TEXT DEFAULT NULL,
d_rpt INTEGER,
$SUBSCRIPTION_ID INTEGER DEFAULT -1,
$EXPIRES_IN INTEGER DEFAULT 0,
$EXPIRE_STARTED INTEGER DEFAULT 0,
$NOTIFIED INTEGER DEFAULT 0,
$READ_RECEIPT_COUNT INTEGER DEFAULT 0,
$QUOTE_ID INTEGER DEFAULT 0,
$QUOTE_AUTHOR TEXT,
$QUOTE_BODY TEXT,
$QUOTE_ATTACHMENT INTEGER DEFAULT -1,
$QUOTE_MISSING INTEGER DEFAULT 0,
$SHARED_CONTACTS TEXT,
$UNIDENTIFIED INTEGER DEFAULT 0,
$LINK_PREVIEWS TEXT,
$IS_DELETED_COLUMN_DEF);"""
@JvmField
val CREATE_INDEXS: Array<String> = arrayOf(
@ -1454,6 +1494,9 @@ class MmsDatabase(context: Context, databaseHelper: SQLCipherOpenHelper) : Messa
"CREATE INDEX IF NOT EXISTS mms_date_sent_index ON $TABLE_NAME ($DATE_SENT);",
"CREATE INDEX IF NOT EXISTS mms_thread_date_index ON $TABLE_NAME ($THREAD_ID, $DATE_RECEIVED);"
)
const val ADD_IS_DELETED_COLUMN: String = "ALTER TABLE $TABLE_NAME ADD COLUMN $IS_DELETED_COLUMN_DEF"
private val MMS_PROJECTION: Array<String> = arrayOf(
"$TABLE_NAME.$ID AS $ID",
THREAD_ID,

@ -29,6 +29,7 @@ public interface MmsSmsColumns {
public static final String REACTIONS_LAST_SEEN = "reactions_last_seen";
public static final String HAS_MENTION = "has_mention";
public static final String IS_DELETED = "is_deleted";
public static class Types {
protected static final long TOTAL_MASK = 0xFFFFFFFF;
@ -185,6 +186,9 @@ public interface MmsSmsColumns {
}
public static boolean isDeletedMessage(long type) {
// Note: if you change the logic below, you must also change the is_deleted database column (by doing migration),
// which must have the same logic as here. See [MmsDatabase.IS_DELETED_COLUMN_DEF] or [SmsDatabase.IS_DELETED_COLUMN_DEF].
// Failing to do so will result in inconsistencies in the UI.
return (type & BASE_TYPE_MASK) == BASE_DELETED_OUTGOING_TYPE || (type & BASE_TYPE_MASK) == BASE_DELETED_INCOMING_TYPE;
}

@ -336,7 +336,7 @@ public class MmsSmsDatabase extends Database {
String order = MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC";
// make sure the last message isn't marked as deleted
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId + " AND " +
"(ifnull("+SmsDatabase.TYPE+", "+MmsDatabase.MESSAGE_BOX+") & "+BASE_TYPE_MASK+") NOT IN ("+BASE_DELETED_OUTGOING_TYPE+", "+BASE_DELETED_INCOMING_TYPE+")"; // this ugly line checks whether the type is deleted (incoming or outgoing) for either the sms table or the mms table
"NOT " + MmsSmsColumns.IS_DELETED;
try (Cursor cursor = queryTables(PROJECTION, selection, order, "1")) {
if (cursor.moveToFirst()) {

@ -69,7 +69,7 @@ public class SearchDatabase extends Database {
"FROM " + SmsDatabase.TABLE_NAME + " " +
"INNER JOIN " + SMS_FTS_TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + ID + " = " + SmsDatabase.TABLE_NAME + "." + SmsDatabase.ID + " " +
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
"WHERE " + SMS_FTS_TABLE_NAME + " MATCH ? " +
"WHERE " + SMS_FTS_TABLE_NAME + " MATCH ? " + " AND NOT " + MmsSmsColumns.IS_DELETED + " " +
"UNION ALL " +
"SELECT " +
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ADDRESS + " AS " + CONVERSATION_ADDRESS + ", " +
@ -80,7 +80,7 @@ public class SearchDatabase extends Database {
"FROM " + MmsDatabase.TABLE_NAME + " " +
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " +
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? " + " AND NOT " + MmsSmsColumns.IS_DELETED + " " +
"ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC " +
"LIMIT ?";
@ -94,7 +94,7 @@ public class SearchDatabase extends Database {
"FROM " + SmsDatabase.TABLE_NAME + " " +
"INNER JOIN " + SMS_FTS_TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + ID + " = " + SmsDatabase.TABLE_NAME + "." + SmsDatabase.ID + " " +
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + SMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
"WHERE " + SMS_FTS_TABLE_NAME + " MATCH ? AND " + SmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = ? " +
"WHERE " + SMS_FTS_TABLE_NAME + " MATCH ? AND " + SmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = ? " + " AND NOT " + MmsSmsColumns.IS_DELETED + " " +
"UNION ALL " +
"SELECT " +
ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ADDRESS + " AS " + CONVERSATION_ADDRESS + ", " +
@ -105,7 +105,7 @@ public class SearchDatabase extends Database {
"FROM " + MmsDatabase.TABLE_NAME + " " +
"INNER JOIN " + MMS_FTS_TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " " +
"INNER JOIN " + ThreadDatabase.TABLE_NAME + " ON " + MMS_FTS_TABLE_NAME + "." + THREAD_ID + " = " + ThreadDatabase.TABLE_NAME + "." + ThreadDatabase.ID + " " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? AND " + MmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = ? " +
"WHERE " + MMS_FTS_TABLE_NAME + " MATCH ? AND " + MmsDatabase.TABLE_NAME + "." + MmsSmsColumns.THREAD_ID + " = ? " + " AND NOT " + MmsSmsColumns.IS_DELETED + " " +
"ORDER BY " + MmsSmsColumns.NORMALIZED_DATE_SENT + " DESC " +
"LIMIT 500";

@ -78,6 +78,9 @@ public class SmsDatabase extends MessagingDatabase {
public static final String SUBJECT = "subject";
public static final String SERVICE_CENTER = "service_center";
private static final String IS_DELETED_COLUMN_DEF = IS_DELETED + " GENERATED ALWAYS AS ((" + TYPE +
" & " + Types.BASE_TYPE_MASK + ") IN (" + Types.BASE_DELETED_OUTGOING_TYPE + ", " + Types.BASE_DELETED_INCOMING_TYPE +")) VIRTUAL";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " integer PRIMARY KEY, " +
THREAD_ID + " INTEGER, " + ADDRESS + " TEXT, " + ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " + PERSON + " INTEGER, " +
DATE_RECEIVED + " INTEGER, " + DATE_SENT + " INTEGER, " + PROTOCOL + " INTEGER, " + READ + " INTEGER DEFAULT 0, " +
@ -85,7 +88,7 @@ public class SmsDatabase extends MessagingDatabase {
DELIVERY_RECEIPT_COUNT + " INTEGER DEFAULT 0," + SUBJECT + " TEXT, " + BODY + " TEXT, " +
MISMATCHED_IDENTITIES + " TEXT DEFAULT NULL, " + SERVICE_CENTER + " TEXT, " + SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " +
EXPIRES_IN + " INTEGER DEFAULT 0, " + EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " DEFAULT 0, " +
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNIDENTIFIED + " INTEGER DEFAULT 0);";
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + UNIDENTIFIED + " INTEGER DEFAULT 0, " + IS_DELETED_COLUMN_DEF +");";
public static final String[] CREATE_INDEXS = {
@ -137,6 +140,8 @@ public class SmsDatabase extends MessagingDatabase {
"DROP TABLE " + TEMP_TABLE_NAME
};
public static final String ADD_IS_DELETED_COLUMN = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN " + IS_DELETED_COLUMN_DEF;
private static final EarlyReceiptCache earlyDeliveryReceiptCache = new EarlyReceiptCache();
private static final EarlyReceiptCache earlyReadReceiptCache = new EarlyReceiptCache();

@ -90,9 +90,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
private static final int lokiV44 = 65;
private static final int lokiV45 = 66;
private static final int lokiV46 = 67;
private static final int lokiV47 = 68;
// Loki - onUpgrade(...) must be updated to use Loki version numbers if Signal makes any database changes
private static final int DATABASE_VERSION = lokiV46;
private static final int DATABASE_VERSION = lokiV47;
private static final int MIN_DATABASE_VERSION = lokiV7;
private static final String CIPHER3_DATABASE_NAME = "signal.db";
public static final String DATABASE_NAME = "signal_v4.db";
@ -628,6 +629,11 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
db.execSQL(LokiAPIDatabase.CREATE_LAST_LEGACY_MESSAGE_TABLE);
}
if (oldVersion < lokiV47) {
db.execSQL(SmsDatabase.ADD_IS_DELETED_COLUMN);
db.execSQL(MmsDatabase.ADD_IS_DELETED_COLUMN);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();

Loading…
Cancel
Save