diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index 2218a6781..a47452091 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -126,44 +126,26 @@ public class MmsDatabase extends MessageDatabase { public static final String VIEW_ONCE = "reveal_duration"; - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + + public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + THREAD_ID + " INTEGER, " + DATE_SENT + " INTEGER, " + DATE_RECEIVED + " INTEGER, " + DATE_SERVER + " INTEGER DEFAULT -1, " + 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, " + RECIPIENT_ID + " INTEGER, " + 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, " + @@ -189,8 +171,6 @@ public class MmsDatabase extends MessageDatabase { SERVER_GUID + " TEXT DEFAULT NULL);"; public static final String[] CREATE_INDEXS = { - "CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS mms_read_index ON " + TABLE_NAME + " (" + READ + ");", "CREATE INDEX IF NOT EXISTS mms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS mms_message_box_index ON " + TABLE_NAME + " (" + MESSAGE_BOX + ");", "CREATE INDEX IF NOT EXISTS mms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");", diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java index e8a5615b6..638dc7136 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/SmsDatabase.java @@ -96,7 +96,7 @@ public class SmsDatabase extends MessageDatabase { public static final String SUBJECT = "subject"; public static final String SERVICE_CENTER = "service_center"; - public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " + + public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + THREAD_ID + " INTEGER, " + RECIPIENT_ID + " INTEGER, " + ADDRESS_DEVICE_ID + " INTEGER DEFAULT 1, " + @@ -128,8 +128,6 @@ public class SmsDatabase extends MessageDatabase { SERVER_GUID + " TEXT DEFAULT NULL);"; public static final String[] CREATE_INDEXS = { - "CREATE INDEX IF NOT EXISTS sms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");", - "CREATE INDEX IF NOT EXISTS sms_read_index ON " + TABLE_NAME + " (" + READ + ");", "CREATE INDEX IF NOT EXISTS sms_read_and_notified_and_thread_id_index ON " + TABLE_NAME + "(" + READ + "," + NOTIFIED + "," + THREAD_ID + ");", "CREATE INDEX IF NOT EXISTS sms_type_index ON " + TABLE_NAME + " (" + TYPE + ");", "CREATE INDEX IF NOT EXISTS sms_date_sent_index ON " + TABLE_NAME + " (" + DATE_SENT + ", " + RECIPIENT_ID + ", " + THREAD_ID + ");", diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 418ab11a0..dc7e0bacd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -205,8 +205,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab private static final int MESSAGE_LOG_2 = 106; private static final int ABANDONED_MESSAGE_CLEANUP = 107; private static final int THREAD_AUTOINCREMENT = 108; + private static final int MMS_AUTOINCREMENT = 109; - private static final int DATABASE_VERSION = 108; + private static final int DATABASE_VERSION = 109; private static final String DATABASE_NAME = "signal.db"; private final Context context; @@ -1718,6 +1719,216 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper implements SignalDatab stopwatch.stop(TAG); } + if (oldVersion < MMS_AUTOINCREMENT) { + Stopwatch mmsStopwatch = new Stopwatch("mms-autoincrement"); + + db.execSQL("CREATE TABLE mms_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "thread_id INTEGER, " + + "date INTEGER, " + + "date_received INTEGER, " + + "date_server INTEGER DEFAULT -1, " + + "msg_box INTEGER, " + + "read INTEGER DEFAULT 0, " + + "body TEXT, " + + "part_count INTEGER, " + + "ct_l TEXT, " + + "address INTEGER, " + + "address_device_id INTEGER, " + + "exp INTEGER, " + + "m_type INTEGER, " + + "m_size INTEGER, " + + "st INTEGER, " + + "tr_id TEXT, " + + "delivery_receipt_count INTEGER DEFAULT 0, " + + "mismatched_identities TEXT DEFAULT NULL, " + + "network_failures TEXT DEFAULT NULL, " + + "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, " + + "quote_mentions BLOB DEFAULT NULL, " + + "shared_contacts TEXT, " + + "unidentified INTEGER DEFAULT 0, " + + "previews TEXT, " + + "reveal_duration INTEGER DEFAULT 0, " + + "reactions BLOB DEFAULT NULL, " + + "reactions_unread INTEGER DEFAULT 0, " + + "reactions_last_seen INTEGER DEFAULT -1, " + + "remote_deleted INTEGER DEFAULT 0, " + + "mentions_self INTEGER DEFAULT 0, " + + "notified_timestamp INTEGER DEFAULT 0, " + + "viewed_receipt_count INTEGER DEFAULT 0, " + + "server_guid TEXT DEFAULT NULL);"); + + mmsStopwatch.split("table-create"); + + db.execSQL("INSERT INTO mms_tmp SELECT _id, " + + "thread_id, " + + "date, " + + "date_received, " + + "date_server, " + + "msg_box, " + + "read, " + + "body, " + + "part_count, " + + "ct_l, " + + "address, " + + "address_device_id, " + + "exp, " + + "m_type, " + + "m_size, " + + "st, " + + "tr_id, " + + "delivery_receipt_count, " + + "mismatched_identities, " + + "network_failures, " + + "subscription_id, " + + "expires_in, " + + "expire_started, " + + "notified, " + + "read_receipt_count, " + + "quote_id, " + + "quote_author, " + + "quote_body, " + + "quote_attachment, " + + "quote_missing, " + + "quote_mentions, " + + "shared_contacts, " + + "unidentified, " + + "previews, " + + "reveal_duration, " + + "reactions, " + + "reactions_unread, " + + "reactions_last_seen, " + + "remote_deleted, " + + "mentions_self, " + + "notified_timestamp, " + + "viewed_receipt_count, " + + "server_guid " + + "FROM mms"); + + mmsStopwatch.split("table-copy"); + + db.execSQL("DROP TABLE mms"); + db.execSQL("ALTER TABLE mms_tmp RENAME TO mms"); + + mmsStopwatch.split("table-rename"); + + db.execSQL("CREATE INDEX mms_read_and_notified_and_thread_id_index ON mms(read, notified, thread_id)"); + db.execSQL("CREATE INDEX mms_message_box_index ON mms (msg_box)"); + db.execSQL("CREATE INDEX mms_date_sent_index ON mms (date, address, thread_id)"); + db.execSQL("CREATE INDEX mms_date_server_index ON mms (date_server)"); + db.execSQL("CREATE INDEX mms_thread_date_index ON mms (thread_id, date_received)"); + db.execSQL("CREATE INDEX mms_reactions_unread_index ON mms (reactions_unread)"); + + mmsStopwatch.split("indexes"); + + db.execSQL("CREATE TRIGGER mms_ai AFTER INSERT ON mms BEGIN INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END"); + db.execSQL("CREATE TRIGGER mms_ad AFTER DELETE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END"); + db.execSQL("CREATE TRIGGER mms_au AFTER UPDATE ON mms BEGIN INSERT INTO mms_fts(mms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO mms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END"); + db.execSQL("CREATE TRIGGER msl_mms_delete AFTER DELETE ON mms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 1); END"); + + mmsStopwatch.split("triggers"); + mmsStopwatch.stop(TAG); + + Stopwatch smsStopwatch = new Stopwatch("sms-autoincrement"); + + db.execSQL("CREATE TABLE sms_tmp (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + + "thread_id INTEGER, " + + "address INTEGER, " + + "address_device_id INTEGER DEFAULT 1, " + + "person INTEGER, " + + "date INTEGER, " + + "date_sent INTEGER, " + + "date_server INTEGER DEFAULT -1, " + + "protocol INTEGER, " + + "read INTEGER DEFAULT 0, " + + "status INTEGER DEFAULT -1, " + + "type INTEGER, " + + "reply_path_present INTEGER, " + + "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, " + + "reactions BLOB DEFAULT NULL, " + + "reactions_unread INTEGER DEFAULT 0, " + + "reactions_last_seen INTEGER DEFAULT -1, " + + "remote_deleted INTEGER DEFAULT 0, " + + "notified_timestamp INTEGER DEFAULT 0, " + + "server_guid TEXT DEFAULT NULL)"); + + smsStopwatch.split("table-create"); + + db.execSQL("INSERT INTO sms_tmp SELECT _id, " + + "thread_id, " + + "address, " + + "address_device_id, " + + "person, " + + "date, " + + "date_sent, " + + "date_server , " + + "protocol, " + + "read, " + + "status , " + + "type, " + + "reply_path_present, " + + "delivery_receipt_count, " + + "subject, " + + "body, " + + "mismatched_identities, " + + "service_center, " + + "subscription_id , " + + "expires_in, " + + "expire_started, " + + "notified, " + + "read_receipt_count, " + + "unidentified, " + + "reactions BLOB, " + + "reactions_unread, " + + "reactions_last_seen , " + + "remote_deleted, " + + "notified_timestamp, " + + "server_guid " + + "FROM sms"); + + smsStopwatch.split("table-copy"); + + db.execSQL("DROP TABLE sms"); + db.execSQL("ALTER TABLE sms_tmp RENAME TO sms"); + + smsStopwatch.split("table-rename"); + + db.execSQL("CREATE INDEX sms_read_and_notified_and_thread_id_index ON sms(read, notified, thread_id)"); + db.execSQL("CREATE INDEX sms_type_index ON sms (type)"); + db.execSQL("CREATE INDEX sms_date_sent_index ON sms (date_sent, address, thread_id)"); + db.execSQL("CREATE INDEX sms_date_server_index ON sms (date_server)"); + db.execSQL("CREATE INDEX sms_thread_date_index ON sms (thread_id, date)"); + db.execSQL("CREATE INDEX sms_reactions_unread_index ON sms (reactions_unread)"); + + smsStopwatch.split("indexes"); + + db.execSQL("CREATE TRIGGER sms_ai AFTER INSERT ON sms BEGIN INSERT INTO sms_fts(rowid, body, thread_id) VALUES (new._id, new.body, new.thread_id); END;"); + db.execSQL("CREATE TRIGGER sms_ad AFTER DELETE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); END;"); + db.execSQL("CREATE TRIGGER sms_au AFTER UPDATE ON sms BEGIN INSERT INTO sms_fts(sms_fts, rowid, body, thread_id) VALUES('delete', old._id, old.body, old.thread_id); INSERT INTO sms_fts(rowid, body, thread_id) VALUES(new._id, new.body, new.thread_id); END;"); + db.execSQL("CREATE TRIGGER msl_sms_delete AFTER DELETE ON sms BEGIN DELETE FROM msl_payload WHERE _id IN (SELECT payload_id FROM msl_message WHERE message_id = old._id AND is_mms = 0); END"); + + smsStopwatch.split("triggers"); + smsStopwatch.stop(TAG); + } + db.setTransactionSuccessful(); } finally { db.endTransaction(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java index 60434eb32..5086ab0b9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java +++ b/app/src/main/java/org/thoughtcrime/securesms/migrations/ApplicationMigrations.java @@ -40,8 +40,6 @@ public class ApplicationMigrations { private static final int LEGACY_CANONICAL_VERSION = 455; - public static final int CURRENT_VERSION = 36; - private static final class Version { static final int LEGACY = 1; static final int RECIPIENT_ID = 2; @@ -78,8 +76,11 @@ public class ApplicationMigrations { static final int APPLY_UNIVERSAL_EXPIRE = 34; static final int SENDER_KEY = 35; static final int SENDER_KEY_2 = 36; + static final int DB_AUTOINCREMENT = 37; } + public static final int CURRENT_VERSION = 37; + /** * This *must* be called after the {@link JobManager} has been instantiated, but *before* the call * to {@link JobManager#beginJobLoop()}. Otherwise, other non-migration jobs may have started @@ -332,6 +333,10 @@ public class ApplicationMigrations { jobs.put(Version.SENDER_KEY_2, new AttributesMigrationJob()); } + if (lastSeenVersion < Version.DB_AUTOINCREMENT) { + jobs.put(Version.DB_AUTOINCREMENT, new DatabaseMigrationJob()); + } + return jobs; }