mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-17 07:23:21 +01:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36b626941f | ||
|
|
0605cc0a9c |
@@ -25,8 +25,8 @@ plugins {
|
|||||||
apply(from = "static-ips.gradle.kts")
|
apply(from = "static-ips.gradle.kts")
|
||||||
|
|
||||||
val canonicalVersionCode = 1660
|
val canonicalVersionCode = 1660
|
||||||
val canonicalVersionName = "8.1.3"
|
val canonicalVersionName = "8.1.4"
|
||||||
val currentHotfixVersion = 0
|
val currentHotfixVersion = 1
|
||||||
val maxHotfixVersions = 100
|
val maxHotfixVersions = 100
|
||||||
|
|
||||||
// We don't want versions to ever end in 0 so that they don't conflict with nightly versions
|
// We don't want versions to ever end in 0 so that they don't conflict with nightly versions
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import org.signal.core.util.requireNonNullString
|
|||||||
import org.thoughtcrime.securesms.database.SQLiteDatabase
|
import org.thoughtcrime.securesms.database.SQLiteDatabase
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds column to messages to track who has deleted a given message. Because of an
|
* Adds column to messages to track who has deleted a given message. We rebuild the table
|
||||||
* OOM crash, we rebuild the table manually in batches instead of using the drop column syntax.
|
* manually instead of using ALTER TABLE to drop the column, which previously caused OOM crashes.
|
||||||
*/
|
*/
|
||||||
@Suppress("ClassName")
|
@Suppress("ClassName")
|
||||||
object V302_AddDeletedByColumn : SignalDatabaseMigration {
|
object V302_AddDeletedByColumn : SignalDatabaseMigration {
|
||||||
|
|
||||||
private val TAG = Log.tag(V302_AddDeletedByColumn::class.java)
|
private val TAG = Log.tag(V302_AddDeletedByColumn::class)
|
||||||
|
|
||||||
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||||
if (SqlUtil.columnExists(db, "message", "deleted_by")) {
|
if (SqlUtil.columnExists(db, "message", "deleted_by")) {
|
||||||
@@ -33,80 +33,140 @@ object V302_AddDeletedByColumn : SignalDatabaseMigration {
|
|||||||
}
|
}
|
||||||
stopwatch.split("drop-dependents")
|
stopwatch.split("drop-dependents")
|
||||||
|
|
||||||
db.execSQL("ALTER TABLE message ADD COLUMN deleted_by INTEGER DEFAULT NULL REFERENCES recipient (_id) ON DELETE CASCADE")
|
|
||||||
stopwatch.split("add-column")
|
|
||||||
|
|
||||||
db.execSQL("UPDATE message SET deleted_by = from_recipient_id WHERE remote_deleted > 0")
|
|
||||||
stopwatch.split("update-data")
|
|
||||||
|
|
||||||
db.execSQL(
|
db.execSQL(
|
||||||
"""
|
"""
|
||||||
CREATE TABLE message_tmp (
|
CREATE TABLE message_tmp (
|
||||||
_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
date_sent INTEGER NOT NULL,
|
date_sent INTEGER NOT NULL,
|
||||||
date_received INTEGER NOT NULL,
|
date_received INTEGER NOT NULL,
|
||||||
date_server INTEGER DEFAULT -1,
|
date_server INTEGER DEFAULT -1,
|
||||||
thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE,
|
thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE,
|
||||||
from_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
|
from_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
|
||||||
from_device_id INTEGER,
|
from_device_id INTEGER,
|
||||||
to_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
|
to_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
|
||||||
type INTEGER NOT NULL,
|
type INTEGER NOT NULL,
|
||||||
body TEXT,
|
body TEXT,
|
||||||
read INTEGER DEFAULT 0,
|
read INTEGER DEFAULT 0,
|
||||||
ct_l TEXT,
|
ct_l TEXT,
|
||||||
exp INTEGER,
|
exp INTEGER,
|
||||||
m_type INTEGER,
|
m_type INTEGER,
|
||||||
m_size INTEGER,
|
m_size INTEGER,
|
||||||
st INTEGER,
|
st INTEGER,
|
||||||
tr_id TEXT,
|
tr_id TEXT,
|
||||||
subscription_id INTEGER DEFAULT -1,
|
subscription_id INTEGER DEFAULT -1,
|
||||||
receipt_timestamp INTEGER DEFAULT -1,
|
receipt_timestamp INTEGER DEFAULT -1,
|
||||||
has_delivery_receipt INTEGER DEFAULT 0,
|
has_delivery_receipt INTEGER DEFAULT 0,
|
||||||
has_read_receipt INTEGER DEFAULT 0,
|
has_read_receipt INTEGER DEFAULT 0,
|
||||||
viewed INTEGER DEFAULT 0,
|
viewed INTEGER DEFAULT 0,
|
||||||
mismatched_identities TEXT DEFAULT NULL,
|
mismatched_identities TEXT DEFAULT NULL,
|
||||||
network_failures TEXT DEFAULT NULL,
|
network_failures TEXT DEFAULT NULL,
|
||||||
expires_in INTEGER DEFAULT 0,
|
expires_in INTEGER DEFAULT 0,
|
||||||
expire_started INTEGER DEFAULT 0,
|
expire_started INTEGER DEFAULT 0,
|
||||||
notified INTEGER DEFAULT 0,
|
notified INTEGER DEFAULT 0,
|
||||||
quote_id INTEGER DEFAULT 0,
|
quote_id INTEGER DEFAULT 0,
|
||||||
quote_author INTEGER DEFAULT 0,
|
quote_author INTEGER DEFAULT 0,
|
||||||
quote_body TEXT DEFAULT NULL,
|
quote_body TEXT DEFAULT NULL,
|
||||||
quote_missing INTEGER DEFAULT 0,
|
quote_missing INTEGER DEFAULT 0,
|
||||||
quote_mentions BLOB DEFAULT NULL,
|
quote_mentions BLOB DEFAULT NULL,
|
||||||
quote_type INTEGER DEFAULT 0,
|
quote_type INTEGER DEFAULT 0,
|
||||||
shared_contacts TEXT DEFAULT NULL,
|
shared_contacts TEXT DEFAULT NULL,
|
||||||
unidentified INTEGER DEFAULT 0,
|
unidentified INTEGER DEFAULT 0,
|
||||||
link_previews TEXT DEFAULT NULL,
|
link_previews TEXT DEFAULT NULL,
|
||||||
view_once INTEGER DEFAULT 0,
|
view_once INTEGER DEFAULT 0,
|
||||||
reactions_unread INTEGER DEFAULT 0,
|
reactions_unread INTEGER DEFAULT 0,
|
||||||
reactions_last_seen INTEGER DEFAULT -1,
|
reactions_last_seen INTEGER DEFAULT -1,
|
||||||
mentions_self INTEGER DEFAULT 0,
|
mentions_self INTEGER DEFAULT 0,
|
||||||
notified_timestamp INTEGER DEFAULT 0,
|
notified_timestamp INTEGER DEFAULT 0,
|
||||||
server_guid TEXT DEFAULT NULL,
|
server_guid TEXT DEFAULT NULL,
|
||||||
message_ranges BLOB DEFAULT NULL,
|
message_ranges BLOB DEFAULT NULL,
|
||||||
story_type INTEGER DEFAULT 0,
|
story_type INTEGER DEFAULT 0,
|
||||||
parent_story_id INTEGER DEFAULT 0,
|
parent_story_id INTEGER DEFAULT 0,
|
||||||
export_state BLOB DEFAULT NULL,
|
export_state BLOB DEFAULT NULL,
|
||||||
exported INTEGER DEFAULT 0,
|
exported INTEGER DEFAULT 0,
|
||||||
scheduled_date INTEGER DEFAULT -1,
|
scheduled_date INTEGER DEFAULT -1,
|
||||||
latest_revision_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE,
|
latest_revision_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE,
|
||||||
original_message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE,
|
original_message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE,
|
||||||
revision_number INTEGER DEFAULT 0,
|
revision_number INTEGER DEFAULT 0,
|
||||||
message_extras BLOB DEFAULT NULL,
|
message_extras BLOB DEFAULT NULL,
|
||||||
expire_timer_version INTEGER DEFAULT 1 NOT NULL,
|
expire_timer_version INTEGER DEFAULT 1 NOT NULL,
|
||||||
votes_unread INTEGER DEFAULT 0,
|
votes_unread INTEGER DEFAULT 0,
|
||||||
votes_last_seen INTEGER DEFAULT 0,
|
votes_last_seen INTEGER DEFAULT 0,
|
||||||
pinned_until INTEGER DEFAULT 0,
|
pinned_until INTEGER DEFAULT 0,
|
||||||
pinning_message_id INTEGER DEFAULT 0,
|
pinning_message_id INTEGER DEFAULT 0,
|
||||||
pinned_at INTEGER DEFAULT 0,
|
pinned_at INTEGER DEFAULT 0,
|
||||||
deleted_by INTEGER DEFAULT NULL REFERENCES recipient (_id) ON DELETE CASCADE
|
deleted_by INTEGER DEFAULT NULL REFERENCES recipient (_id) ON DELETE CASCADE
|
||||||
)
|
)
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
stopwatch.split("create-table")
|
stopwatch.split("create-table")
|
||||||
|
|
||||||
copyMessages(db)
|
db.execSQL(
|
||||||
|
"""
|
||||||
|
INSERT INTO message_tmp
|
||||||
|
SELECT
|
||||||
|
_id,
|
||||||
|
date_sent,
|
||||||
|
date_received,
|
||||||
|
date_server,
|
||||||
|
thread_id,
|
||||||
|
from_recipient_id,
|
||||||
|
from_device_id,
|
||||||
|
to_recipient_id,
|
||||||
|
type,
|
||||||
|
body,
|
||||||
|
read,
|
||||||
|
ct_l,
|
||||||
|
exp,
|
||||||
|
m_type,
|
||||||
|
m_size,
|
||||||
|
st,
|
||||||
|
tr_id,
|
||||||
|
subscription_id,
|
||||||
|
receipt_timestamp,
|
||||||
|
has_delivery_receipt,
|
||||||
|
has_read_receipt,
|
||||||
|
viewed,
|
||||||
|
mismatched_identities,
|
||||||
|
network_failures,
|
||||||
|
expires_in,
|
||||||
|
expire_started,
|
||||||
|
notified,
|
||||||
|
quote_id,
|
||||||
|
quote_author,
|
||||||
|
quote_body,
|
||||||
|
quote_missing,
|
||||||
|
quote_mentions,
|
||||||
|
quote_type,
|
||||||
|
shared_contacts,
|
||||||
|
unidentified,
|
||||||
|
link_previews,
|
||||||
|
view_once,
|
||||||
|
reactions_unread,
|
||||||
|
reactions_last_seen,
|
||||||
|
mentions_self,
|
||||||
|
notified_timestamp,
|
||||||
|
server_guid,
|
||||||
|
message_ranges,
|
||||||
|
story_type,
|
||||||
|
parent_story_id,
|
||||||
|
export_state,
|
||||||
|
exported,
|
||||||
|
scheduled_date,
|
||||||
|
latest_revision_id,
|
||||||
|
original_message_id,
|
||||||
|
revision_number,
|
||||||
|
message_extras,
|
||||||
|
expire_timer_version,
|
||||||
|
votes_unread,
|
||||||
|
votes_last_seen,
|
||||||
|
pinned_until,
|
||||||
|
pinning_message_id,
|
||||||
|
pinned_at,
|
||||||
|
CASE WHEN remote_deleted > 0 THEN from_recipient_id ELSE NULL END AS deleted_by
|
||||||
|
FROM
|
||||||
|
message
|
||||||
|
"""
|
||||||
|
)
|
||||||
stopwatch.split("copy-data")
|
stopwatch.split("copy-data")
|
||||||
|
|
||||||
db.execSQL("DROP TABLE message")
|
db.execSQL("DROP TABLE message")
|
||||||
@@ -135,85 +195,6 @@ object V302_AddDeletedByColumn : SignalDatabaseMigration {
|
|||||||
stopwatch.stop(TAG)
|
stopwatch.stop(TAG)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun copyMessages(db: SQLiteDatabase) {
|
|
||||||
val batchSize = 50_000L
|
|
||||||
|
|
||||||
val maxId = SqlUtil.getNextAutoIncrementId(db, "message")
|
|
||||||
|
|
||||||
for (i in 1..maxId step batchSize) {
|
|
||||||
db.execSQL(
|
|
||||||
"""
|
|
||||||
INSERT INTO message_tmp
|
|
||||||
SELECT
|
|
||||||
_id,
|
|
||||||
date_sent,
|
|
||||||
date_received,
|
|
||||||
date_server,
|
|
||||||
thread_id,
|
|
||||||
from_recipient_id,
|
|
||||||
from_device_id,
|
|
||||||
to_recipient_id,
|
|
||||||
type,
|
|
||||||
body,
|
|
||||||
read,
|
|
||||||
ct_l,
|
|
||||||
exp,
|
|
||||||
m_type,
|
|
||||||
m_size,
|
|
||||||
st,
|
|
||||||
tr_id,
|
|
||||||
subscription_id,
|
|
||||||
receipt_timestamp,
|
|
||||||
has_delivery_receipt,
|
|
||||||
has_read_receipt,
|
|
||||||
viewed,
|
|
||||||
mismatched_identities,
|
|
||||||
network_failures,
|
|
||||||
expires_in,
|
|
||||||
expire_started,
|
|
||||||
notified,
|
|
||||||
quote_id,
|
|
||||||
quote_author,
|
|
||||||
quote_body,
|
|
||||||
quote_missing,
|
|
||||||
quote_mentions,
|
|
||||||
quote_type,
|
|
||||||
shared_contacts,
|
|
||||||
unidentified,
|
|
||||||
link_previews,
|
|
||||||
view_once,
|
|
||||||
reactions_unread,
|
|
||||||
reactions_last_seen,
|
|
||||||
mentions_self,
|
|
||||||
notified_timestamp,
|
|
||||||
server_guid,
|
|
||||||
message_ranges,
|
|
||||||
story_type,
|
|
||||||
parent_story_id,
|
|
||||||
export_state,
|
|
||||||
exported,
|
|
||||||
scheduled_date,
|
|
||||||
latest_revision_id,
|
|
||||||
original_message_id,
|
|
||||||
revision_number,
|
|
||||||
message_extras,
|
|
||||||
expire_timer_version,
|
|
||||||
votes_unread,
|
|
||||||
votes_last_seen,
|
|
||||||
pinned_until,
|
|
||||||
pinning_message_id,
|
|
||||||
pinned_at,
|
|
||||||
deleted_by
|
|
||||||
FROM
|
|
||||||
message
|
|
||||||
WHERE
|
|
||||||
_id >= $i AND
|
|
||||||
_id < ${i + batchSize}
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAllDependentItems(db: SQLiteDatabase, tableName: String): List<SqlItem> {
|
private fun getAllDependentItems(db: SQLiteDatabase, tableName: String): List<SqlItem> {
|
||||||
return db.rawQuery("SELECT type, name, sql FROM sqlite_schema WHERE tbl_name='$tableName' AND type != 'table'").readToList { cursor ->
|
return db.rawQuery("SELECT type, name, sql FROM sqlite_schema WHERE tbl_name='$tableName' AND type != 'table'").readToList { cursor ->
|
||||||
SqlItem(
|
SqlItem(
|
||||||
|
|||||||
Reference in New Issue
Block a user