mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-20 16:49:40 +01:00
Improve performance from thread being updated to data available to render.
This commit is contained in:
@@ -19,6 +19,6 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
$ID INTEGER PRIMARY KEY
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
|
||||
UNIQUE ($CALL_ID, $PEER, $CALL_LINK) ON CONFLICT FAIL,
|
||||
CHECK (($PEER IS NULL AND $CALL_LINK IS NOT NULL) OR ($PEER IS NOT NULL AND $CALL_LINK IS NULL))
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val CREATE_INDEXES = arrayOf(
|
||||
"CREATE INDEX call_call_id_index ON $TABLE_NAME ($CALL_ID)",
|
||||
@@ -760,7 +760,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
|
||||
${RecipientTable.TABLE_NAME}.${RecipientTable.PHONE} GLOB ? OR
|
||||
${RecipientTable.TABLE_NAME}.${RecipientTable.EMAIL} GLOB ?
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
SqlUtil.buildQuery(selection, 0, 0, glob, glob, glob, glob)
|
||||
} else {
|
||||
SqlUtil.buildQuery("")
|
||||
@@ -854,7 +854,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
|
||||
LEFT JOIN ${GroupTable.TABLE_NAME} ON ${GroupTable.TABLE_NAME}.${GroupTable.RECIPIENT_ID} = ${RecipientTable.TABLE_NAME}.${RecipientTable.ID}
|
||||
WHERE true_parent = p.$ID ${if (queryClause.where.isNotEmpty()) "AND ${queryClause.where}" else ""}
|
||||
$offsetLimit
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
return readableDatabase.query(
|
||||
statement,
|
||||
|
||||
@@ -23,7 +23,7 @@ class ChatColorsTable(context: Context, databaseHelper: SignalDatabase) : Databa
|
||||
$ID INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
$CHAT_COLORS BLOB
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
}
|
||||
|
||||
fun getById(chatColorsId: ChatColors.Id): ChatColors {
|
||||
|
||||
@@ -31,7 +31,7 @@ class DonationReceiptTable(context: Context, databaseHelper: SignalDatabase) : D
|
||||
$CURRENCY TEXT NOT NULL,
|
||||
$SUBSCRIPTION_LEVEL INTEGER NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
"CREATE INDEX IF NOT EXISTS donation_receipt_type_index ON $TABLE_NAME ($TYPE)",
|
||||
|
||||
@@ -28,7 +28,6 @@ import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.signal.libsignal.zkgroup.groups.GroupMasterKey
|
||||
@@ -171,7 +170,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
WHERE ${MembershipTable.TABLE_NAME}.${MembershipTable.GROUP_ID} = $TABLE_NAME.$GROUP_ID
|
||||
) as $MEMBER_GROUP_CONCAT
|
||||
FROM $TABLE_NAME
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
val CREATE_TABLES = arrayOf(CREATE_TABLE, MembershipTable.CREATE_TABLE)
|
||||
}
|
||||
@@ -193,7 +192,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
$RECIPIENT_ID INTEGER NOT NULL,
|
||||
UNIQUE($GROUP_ID, $RECIPIENT_ID)
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,7 +370,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
WHERE $ACTIVE = 1 AND ${MembershipTable.TABLE_NAME}.${MembershipTable.RECIPIENT_ID} IN (${subquery.where})
|
||||
GROUP BY ${MembershipTable.TABLE_NAME}.${MembershipTable.GROUP_ID}
|
||||
ORDER BY $TITLE COLLATE NOCASE ASC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return databaseHelper.signalReadableDatabase.query(statement, subquery.whereArgs)
|
||||
}
|
||||
@@ -383,7 +382,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
$JOINED_GROUP_SELECT
|
||||
WHERE ${query.where}
|
||||
ORDER BY $TITLE COLLATE NOCASE ASC
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val cursor = databaseHelper.signalReadableDatabase.query(statement, query.whereArgs)
|
||||
return Reader(cursor)
|
||||
@@ -432,7 +431,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
FROM ${MembershipTable.TABLE_NAME}
|
||||
INNER JOIN $TABLE_NAME ON ${MembershipTable.TABLE_NAME}.${MembershipTable.GROUP_ID} = $TABLE_NAME.$GROUP_ID
|
||||
WHERE $query
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
return Reader(readableDatabase.query(selection, queryArgs))
|
||||
}
|
||||
@@ -444,7 +443,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
INNER JOIN ${ThreadTable.TABLE_NAME} ON ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID} = $TABLE_NAME.$RECIPIENT_ID
|
||||
WHERE ${query.where}
|
||||
ORDER BY ${ThreadTable.TABLE_NAME}.${ThreadTable.DATE} DESC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return Reader(databaseHelper.signalReadableDatabase.rawQuery(sql, query.whereArgs))
|
||||
}
|
||||
@@ -534,7 +533,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
) as $MEMBER_GROUP_CONCAT
|
||||
FROM $TABLE_NAME
|
||||
WHERE $MEMBER_GROUP_CONCAT = ?
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return readableDatabase.rawQuery(statement, buildArgs(joinedTestMembers)).use { cursor ->
|
||||
if (cursor.moveToNext()) {
|
||||
@@ -577,7 +576,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
FROM ${MembershipTable.TABLE_NAME}
|
||||
INNER JOIN $TABLE_NAME ON ${MembershipTable.TABLE_NAME}.${MembershipTable.GROUP_ID} = $TABLE_NAME.$GROUP_ID
|
||||
LEFT JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$RECIPIENT_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID}
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
var query = "${MembershipTable.TABLE_NAME}.${MembershipTable.RECIPIENT_ID} = ?"
|
||||
var args = buildArgs(recipientId)
|
||||
@@ -1291,7 +1290,7 @@ class GroupTable(context: Context?, databaseHelper: SignalDatabase?) : DatabaseT
|
||||
)
|
||||
)
|
||||
ORDER BY active_timestamp DESC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return readableDatabase
|
||||
.query(query)
|
||||
|
||||
@@ -65,7 +65,7 @@ class LocalMetricsDatabase private constructor(
|
||||
$SPLIT_NAME TEXT NOT NULL,
|
||||
$DURATION INTEGER NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
private val CREATE_INDEXES = arrayOf(
|
||||
"CREATE INDEX events_create_at_index ON $TABLE_NAME ($CREATED_AT)",
|
||||
@@ -99,7 +99,7 @@ class LocalMetricsDatabase private constructor(
|
||||
SELECT $EVENT_ID, $EVENT_NAME, SUM($DURATION) AS $DURATION
|
||||
FROM $TABLE_NAME
|
||||
GROUP BY $EVENT_ID
|
||||
""".trimIndent()
|
||||
"""
|
||||
}
|
||||
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
@@ -231,7 +231,7 @@ class LocalMetricsDatabase private constructor(
|
||||
OFFSET (SELECT COUNT(*)
|
||||
FROM $table
|
||||
WHERE $where) * $percent / 100 - 1
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
readableDatabase.rawQuery(query, null).use { cursor ->
|
||||
return if (cursor.moveToFirst()) {
|
||||
|
||||
@@ -70,7 +70,7 @@ class LogDatabase private constructor(
|
||||
$BODY TEXT,
|
||||
$SIZE INTEGER
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
private val CREATE_INDEXES = arrayOf(
|
||||
"CREATE INDEX keep_longer_index ON $TABLE_NAME ($KEEP_LONGER)",
|
||||
|
||||
@@ -6,7 +6,6 @@ import android.database.Cursor
|
||||
import org.signal.core.util.requireInt
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
import org.thoughtcrime.securesms.util.MediaUtil
|
||||
@@ -80,7 +79,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${AttachmentTable.STICKER_PACK_ID} IS NULL AND
|
||||
${MessageTable.TABLE_NAME}.${MessageTable.FROM_RECIPIENT_ID} > 0 AND
|
||||
$THREAD_RECIPIENT_ID > 0
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
private val UNIQUE_MEDIA_QUERY = """
|
||||
SELECT
|
||||
@@ -92,14 +91,14 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${AttachmentTable.STICKER_PACK_ID} IS NULL AND
|
||||
${AttachmentTable.TRANSFER_STATE} = ${AttachmentTable.TRANSFER_PROGRESS_DONE}
|
||||
GROUP BY ${AttachmentTable.DATA}
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
private val GALLERY_MEDIA_QUERY = String.format(
|
||||
BASE_MEDIA_QUERY,
|
||||
"""
|
||||
${AttachmentTable.CONTENT_TYPE} NOT LIKE 'image/svg%' AND
|
||||
(${AttachmentTable.CONTENT_TYPE} LIKE 'image/%' OR ${AttachmentTable.CONTENT_TYPE} LIKE 'video/%')
|
||||
""".toSingleLine()
|
||||
"""
|
||||
)
|
||||
|
||||
private val AUDIO_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, "${AttachmentTable.CONTENT_TYPE} LIKE 'audio/%'")
|
||||
@@ -113,7 +112,7 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${AttachmentTable.CONTENT_TYPE} NOT LIKE 'video/%' AND
|
||||
${AttachmentTable.CONTENT_TYPE} NOT LIKE 'audio/%' AND
|
||||
${AttachmentTable.CONTENT_TYPE} NOT LIKE 'text/x-signal-plain'
|
||||
)""".toSingleLine()
|
||||
)"""
|
||||
)
|
||||
|
||||
private fun applyEqualityOperator(threadId: Long, query: String): String {
|
||||
@@ -224,20 +223,20 @@ class MediaTable internal constructor(context: Context?, databaseHelper: SignalD
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} DESC,
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC,
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID} DESC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
),
|
||||
Oldest(
|
||||
"""
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID} ASC,
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC,
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.ROW_ID} ASC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
),
|
||||
Largest(
|
||||
"""
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.SIZE} DESC,
|
||||
${AttachmentTable.TABLE_NAME}.${AttachmentTable.DISPLAY_ORDER} DESC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
);
|
||||
|
||||
private val postFix: String
|
||||
|
||||
@@ -55,7 +55,6 @@ import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.toOptional
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.signal.libsignal.protocol.IdentityKey
|
||||
@@ -363,7 +362,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
'${AttachmentTable.UPLOAD_TIMESTAMP}', ${AttachmentTable.TABLE_NAME}.${AttachmentTable.UPLOAD_TIMESTAMP}
|
||||
)
|
||||
) AS ${AttachmentTable.ATTACHMENT_JSON_ALIAS}
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
private const val IS_STORY_CLAUSE = "$STORY_TYPE > 0 AND $REMOTE_DELETED = 0"
|
||||
private const val RAW_ID_WHERE = "$TABLE_NAME.$ID = ?"
|
||||
@@ -390,7 +389,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
${MessageTypes.SMS_EXPORT_TYPE}
|
||||
)
|
||||
ORDER BY $DATE_RECEIVED DESC LIMIT 1
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
private val IS_CALL_TYPE_CLAUSE = """(
|
||||
($TYPE = ${MessageTypes.INCOMING_AUDIO_CALL_TYPE})
|
||||
@@ -406,7 +405,13 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
($TYPE = ${MessageTypes.MISSED_VIDEO_CALL_TYPE})
|
||||
OR
|
||||
($TYPE = ${MessageTypes.GROUP_CALL_TYPE})
|
||||
)""".toSingleLine()
|
||||
)"""
|
||||
|
||||
private val outgoingTypeClause: String by lazy {
|
||||
MessageTypes.OUTGOING_MESSAGE_TYPES
|
||||
.map { "($TABLE_NAME.$TYPE & ${MessageTypes.BASE_TYPE_MASK} = $it)" }
|
||||
.joinToString(" OR ")
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun mmsReaderFor(cursor: Cursor): MmsReader {
|
||||
@@ -620,7 +625,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
UPDATE $TABLE_NAME
|
||||
SET $TYPE = ($TYPE & ${MessageTypes.TOTAL_MASK - maskOff} | $maskOn )
|
||||
WHERE $ID = ?
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
buildArgs(id)
|
||||
)
|
||||
|
||||
@@ -640,7 +645,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$BODY = ?,
|
||||
$TYPE = ($TYPE & ${MessageTypes.TOTAL_MASK - maskOff} | $maskOn)
|
||||
WHERE $ID = ?
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
arrayOf(body, messageId.toString() + "")
|
||||
)
|
||||
|
||||
@@ -729,7 +734,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
val results: List<MarkedMessageInfo> = readableDatabase
|
||||
.select(ID, TO_RECIPIENT_ID, DATE_SENT, THREAD_ID, STORY_TYPE)
|
||||
.from(TABLE_NAME)
|
||||
.where("""$ID IN (${Util.join(messageIds, ",")}) AND (${getOutgoingTypeClause()}) AND ($TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} = ${MessageTypes.SPECIAL_TYPE_GIFT_BADGE}) AND $VIEWED_RECEIPT_COUNT = 0""")
|
||||
.where("""$ID IN (${Util.join(messageIds, ",")}) AND ($outgoingTypeClause) AND ($TYPE & ${MessageTypes.SPECIAL_TYPES_MASK} = ${MessageTypes.SPECIAL_TYPE_GIFT_BADGE}) AND $VIEWED_RECEIPT_COUNT = 0""")
|
||||
.run()
|
||||
.readToList { it.toMarkedMessageInfo(outgoing = true) }
|
||||
|
||||
@@ -1294,7 +1299,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
null
|
||||
}
|
||||
|
||||
var where = "$IS_STORY_CLAUSE AND (${getOutgoingTypeClause()})"
|
||||
var where = "$IS_STORY_CLAUSE AND ($outgoingTypeClause)"
|
||||
val whereArgs: Array<String>
|
||||
|
||||
if (threadId == null) {
|
||||
@@ -1309,12 +1314,12 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
fun getAllOutgoingStories(reverse: Boolean, limit: Int): Reader {
|
||||
val where = "$IS_STORY_CLAUSE AND (${getOutgoingTypeClause()})"
|
||||
val where = "$IS_STORY_CLAUSE AND ($outgoingTypeClause)"
|
||||
return MmsReader(rawQueryWithAttachments(where, null, reverse, limit.toLong()))
|
||||
}
|
||||
|
||||
fun markAllIncomingStoriesRead(): List<MarkedMessageInfo> {
|
||||
val where = "$IS_STORY_CLAUSE AND NOT (${getOutgoingTypeClause()}) AND $READ = 0"
|
||||
val where = "$IS_STORY_CLAUSE AND NOT ($outgoingTypeClause) AND $READ = 0"
|
||||
val markedMessageInfos = setMessagesRead(where, null)
|
||||
notifyConversationListListeners()
|
||||
return markedMessageInfos
|
||||
@@ -1328,7 +1333,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
fun markAllFailedStoriesNotified() {
|
||||
val where = "$IS_STORY_CLAUSE AND (${getOutgoingTypeClause()}) AND $NOTIFIED = 0 AND ($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_FAILED_TYPE}"
|
||||
val where = "$IS_STORY_CLAUSE AND ($outgoingTypeClause) AND $NOTIFIED = 0 AND ($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_FAILED_TYPE}"
|
||||
|
||||
writableDatabase
|
||||
.update("$TABLE_NAME INDEXED BY $INDEX_THREAD_DATE")
|
||||
@@ -1340,7 +1345,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
|
||||
fun markOnboardingStoryRead() {
|
||||
val recipientId = SignalStore.releaseChannelValues().releaseChannelRecipientId ?: return
|
||||
val where = "$IS_STORY_CLAUSE AND NOT (${getOutgoingTypeClause()}) AND $READ = 0 AND $FROM_RECIPIENT_ID = ?"
|
||||
val where = "$IS_STORY_CLAUSE AND NOT ($outgoingTypeClause) AND $READ = 0 AND $FROM_RECIPIENT_ID = ?"
|
||||
val markedMessageInfos = setMessagesRead(where, buildArgs(recipientId))
|
||||
|
||||
if (markedMessageInfos.isNotEmpty()) {
|
||||
@@ -1358,7 +1363,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
|
||||
fun getUnreadStories(recipientId: RecipientId, limit: Int): Reader {
|
||||
val threadId = threads.getThreadIdIfExistsFor(recipientId)
|
||||
val query = "$IS_STORY_CLAUSE AND NOT (${getOutgoingTypeClause()}) AND $THREAD_ID = ? AND $VIEWED_RECEIPT_COUNT = ?"
|
||||
val query = "$IS_STORY_CLAUSE AND NOT ($outgoingTypeClause) AND $THREAD_ID = ? AND $VIEWED_RECEIPT_COUNT = ?"
|
||||
val args = buildArgs(threadId, 0)
|
||||
return MmsReader(rawQueryWithAttachments(query, args, false, limit.toLong()))
|
||||
}
|
||||
@@ -1411,7 +1416,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
writableDatabase.withinTransaction { db ->
|
||||
db.select(FROM_RECIPIENT_ID)
|
||||
.from(TABLE_NAME)
|
||||
.where("$IS_STORY_CLAUSE AND $DATE_SENT IN ($timestamps) AND NOT (${getOutgoingTypeClause()}) AND $VIEWED_RECEIPT_COUNT > 0")
|
||||
.where("$IS_STORY_CLAUSE AND $DATE_SENT IN ($timestamps) AND NOT ($outgoingTypeClause) AND $VIEWED_RECEIPT_COUNT > 0")
|
||||
.run()
|
||||
.readToList { cursor -> RecipientId.from(cursor.requireLong(FROM_RECIPIENT_ID)) }
|
||||
.forEach { id -> recipients.updateLastStoryViewTimestamp(id) }
|
||||
@@ -1431,7 +1436,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
|
||||
val hasUnviewedStories = readableDatabase
|
||||
.exists(TABLE_NAME)
|
||||
.where("$IS_STORY_CLAUSE AND $THREAD_ID = ? AND $VIEWED_RECEIPT_COUNT = ? AND NOT (${getOutgoingTypeClause()})", threadId, 0)
|
||||
.where("$IS_STORY_CLAUSE AND $THREAD_ID = ? AND $VIEWED_RECEIPT_COUNT = ? AND NOT ($outgoingTypeClause)", threadId, 0)
|
||||
.run()
|
||||
|
||||
return if (hasUnviewedStories) {
|
||||
@@ -1444,7 +1449,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
fun isOutgoingStoryAlreadyInDatabase(recipientId: RecipientId, sentTimestamp: Long): Boolean {
|
||||
return readableDatabase
|
||||
.exists(TABLE_NAME)
|
||||
.where("$TO_RECIPIENT_ID = ? AND $STORY_TYPE > 0 AND $DATE_SENT = ? AND (${getOutgoingTypeClause()})", recipientId, sentTimestamp)
|
||||
.where("$TO_RECIPIENT_ID = ? AND $STORY_TYPE > 0 AND $DATE_SENT = ? AND ($outgoingTypeClause)", recipientId, sentTimestamp)
|
||||
.run()
|
||||
}
|
||||
|
||||
@@ -1467,10 +1472,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
|
||||
WHERE
|
||||
$IS_STORY_CLAUSE AND
|
||||
(${getOutgoingTypeClause()}) = 0 AND
|
||||
($outgoingTypeClause) = 0 AND
|
||||
$VIEWED_RECEIPT_COUNT = 0 AND
|
||||
$TABLE_NAME.$READ = 0
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return readableDatabase
|
||||
.rawQuery(query, null)
|
||||
@@ -1478,7 +1483,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
fun hasFailedOutgoingStory(): Boolean {
|
||||
val where = "$IS_STORY_CLAUSE AND (${getOutgoingTypeClause()}) AND $NOTIFIED = 0 AND ($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_FAILED_TYPE}"
|
||||
val where = "$IS_STORY_CLAUSE AND ($outgoingTypeClause) AND $NOTIFIED = 0 AND ($TYPE & ${MessageTypes.BASE_TYPE_MASK}) = ${MessageTypes.BASE_SENT_FAILED_TYPE}"
|
||||
return readableDatabase.exists(TABLE_NAME).where(where).run()
|
||||
}
|
||||
|
||||
@@ -1488,11 +1493,11 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$TABLE_NAME.$DATE_SENT AS sent_timestamp,
|
||||
$TABLE_NAME.$ID AS mms_id,
|
||||
${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID},
|
||||
(${getOutgoingTypeClause()}) AS is_outgoing,
|
||||
($outgoingTypeClause) AS is_outgoing,
|
||||
$VIEWED_RECEIPT_COUNT,
|
||||
$TABLE_NAME.$DATE_SENT,
|
||||
$RECEIPT_TIMESTAMP,
|
||||
(${getOutgoingTypeClause()}) = 0 AND $VIEWED_RECEIPT_COUNT = 0 AS is_unread
|
||||
($outgoingTypeClause) = 0 AND $VIEWED_RECEIPT_COUNT = 0 AS is_unread
|
||||
FROM $TABLE_NAME
|
||||
JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$THREAD_ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.ID}
|
||||
WHERE
|
||||
@@ -1506,7 +1511,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
WHEN is_outgoing = 0 AND viewed_receipt_count > 0 THEN $RECEIPT_TIMESTAMP
|
||||
WHEN is_outgoing = 1 THEN $TABLE_NAME.$DATE_SENT
|
||||
END DESC
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return readableDatabase
|
||||
.rawQuery(query, null)
|
||||
@@ -1545,7 +1550,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
fun hasSelfReplyInStory(parentStoryId: Long): Boolean {
|
||||
return readableDatabase
|
||||
.exists(TABLE_NAME)
|
||||
.where("$PARENT_STORY_ID = ? AND (${getOutgoingTypeClause()})", -parentStoryId)
|
||||
.where("$PARENT_STORY_ID = ? AND ($outgoingTypeClause)", -parentStoryId)
|
||||
.run()
|
||||
}
|
||||
|
||||
@@ -1589,7 +1594,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
FROM $TABLE_NAME
|
||||
WHERE $storiesBeforeTimestampWhere
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
val disassociateQuoteQuery = """
|
||||
UPDATE $TABLE_NAME
|
||||
@@ -1603,7 +1608,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
FROM $TABLE_NAME
|
||||
WHERE $storiesBeforeTimestampWhere
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
db.execSQL(deleteStoryRepliesQuery, sharedArgs)
|
||||
db.execSQL(disassociateQuoteQuery, sharedArgs)
|
||||
@@ -1726,7 +1731,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
|
||||
fun getIncomingMeaningfulMessageCountSince(threadId: Long, afterTime: Long): Int {
|
||||
val meaningfulMessagesQuery = buildMeaningfulMessagesQuery(threadId)
|
||||
val where = "${meaningfulMessagesQuery.where} AND $DATE_RECEIVED >= ? AND NOT (${getOutgoingTypeClause()})"
|
||||
val where = "${meaningfulMessagesQuery.where} AND $DATE_RECEIVED >= ? AND NOT ($outgoingTypeClause)"
|
||||
val whereArgs = appendArg(meaningfulMessagesQuery.whereArgs, afterTime.toString())
|
||||
|
||||
return readableDatabase
|
||||
@@ -1750,7 +1755,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$TYPE != ${MessageTypes.BOOST_REQUEST_TYPE} AND
|
||||
$TYPE & ${MessageTypes.GROUP_V2_LEAVE_BITS} != ${MessageTypes.GROUP_V2_LEAVE_BITS}
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return SqlUtil.buildQuery(query, threadId)
|
||||
}
|
||||
@@ -1809,7 +1814,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$where
|
||||
GROUP BY
|
||||
$TABLE_NAME.$ID
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
if (reverse) {
|
||||
rawQueryString += " ORDER BY $TABLE_NAME.$ID DESC"
|
||||
@@ -1851,7 +1856,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
UPDATE $TABLE_NAME
|
||||
SET $TYPE = ($TYPE & ${MessageTypes.TOTAL_MASK - maskOff} | $maskOn )
|
||||
WHERE $ID = ?
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
buildArgs(id)
|
||||
)
|
||||
|
||||
@@ -2059,10 +2064,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$READ = 0 OR
|
||||
(
|
||||
$REACTIONS_UNREAD = 1 AND
|
||||
(${getOutgoingTypeClause()})
|
||||
($outgoingTypeClause)
|
||||
)
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
val args = mutableListOf(threadId.toString())
|
||||
|
||||
@@ -2083,10 +2088,10 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$READ = 0 OR
|
||||
(
|
||||
$REACTIONS_UNREAD = 1 AND
|
||||
(${getOutgoingTypeClause()})
|
||||
($outgoingTypeClause)
|
||||
)
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
val args = mutableListOf(threadId.toString(), groupStoryId.toString())
|
||||
|
||||
@@ -2133,7 +2138,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
}
|
||||
|
||||
fun setAllMessagesRead(): List<MarkedMessageInfo> {
|
||||
return setMessagesRead("$STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND ($READ = 0 OR ($REACTIONS_UNREAD = 1 AND (${getOutgoingTypeClause()})))", null)
|
||||
return setMessagesRead("$STORY_TYPE = 0 AND $PARENT_STORY_ID <= 0 AND ($READ = 0 OR ($REACTIONS_UNREAD = 1 AND ($outgoingTypeClause)))", null)
|
||||
}
|
||||
|
||||
private fun setMessagesRead(where: String, arguments: Array<String>?): List<MarkedMessageInfo> {
|
||||
@@ -3306,7 +3311,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
$TABLE_NAME INNER JOIN ${AttachmentTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${AttachmentTable.TABLE_NAME}.${AttachmentTable.MMS_ID}
|
||||
WHERE
|
||||
${getInsecureMessageClause()} AND $EXPORTED < ${MessageExportStatus.EXPORTED.serialize()}
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
null
|
||||
).readToSingleLong()
|
||||
|
||||
@@ -3415,7 +3420,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
WHERE
|
||||
$VIEW_ONCE > 0 AND
|
||||
(${AttachmentTable.DATA} NOT NULL OR ${AttachmentTable.TRANSFER_STATE} != ?)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
val args = buildArgs(AttachmentTable.TRANSFER_PROGRESS_DONE)
|
||||
|
||||
@@ -3503,16 +3508,6 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
return result.toOptional()
|
||||
}
|
||||
|
||||
private fun getOutgoingTypeClause(): String {
|
||||
val segments: MutableList<String> = ArrayList(MessageTypes.OUTGOING_MESSAGE_TYPES.size)
|
||||
|
||||
for (outgoingMessageType in MessageTypes.OUTGOING_MESSAGE_TYPES) {
|
||||
segments.add("($TABLE_NAME.$TYPE & ${MessageTypes.BASE_TYPE_MASK} = $outgoingMessageType)")
|
||||
}
|
||||
|
||||
return segments.joinToString(" OR ")
|
||||
}
|
||||
|
||||
fun getInsecureMessageCount(): Int {
|
||||
return readableDatabase
|
||||
.select("COUNT(*)")
|
||||
@@ -4247,7 +4242,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
($TO_RECIPIENT_ID = ? OR EXISTS (SELECT 1 FROM ${GroupTable.TABLE_NAME} WHERE ${GroupTable.TABLE_NAME}.${GroupTable.RECIPIENT_ID} = $TO_RECIPIENT_ID))
|
||||
$qualifierWhere
|
||||
RETURNING $ID, $THREAD_ID, $STORY_TYPE
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
buildArgs(receiptSentTimestamp, targetTimestamp, Recipient.self().id, receiptAuthor)
|
||||
).forEach { cursor ->
|
||||
val messageId = cursor.requireLong(ID)
|
||||
@@ -4336,7 +4331,7 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
|
||||
readableDatabase
|
||||
.select(ID, THREAD_ID, EXPIRES_IN, EXPIRE_STARTED)
|
||||
.from(TABLE_NAME)
|
||||
.where("$DATE_SENT = ? AND ($FROM_RECIPIENT_ID = ? OR ($FROM_RECIPIENT_ID = ? AND ${getOutgoingTypeClause()}))", messageId.timetamp, messageId.recipientId, Recipient.self().id)
|
||||
.where("$DATE_SENT = ? AND ($FROM_RECIPIENT_ID = ? OR ($FROM_RECIPIENT_ID = ? AND $outgoingTypeClause))", messageId.timetamp, messageId.recipientId, Recipient.self().id)
|
||||
.run()
|
||||
.forEach { cursor ->
|
||||
val id = cursor.requireLong(ID)
|
||||
|
||||
@@ -53,7 +53,7 @@ class NotificationProfileDatabase(context: Context, databaseHelper: SignalDataba
|
||||
$ALLOW_ALL_CALLS INTEGER NOT NULL DEFAULT 0,
|
||||
$ALLOW_ALL_MENTIONS INTEGER NOT NULL DEFAULT 0
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
}
|
||||
|
||||
private object NotificationProfileScheduleTable {
|
||||
@@ -77,7 +77,7 @@ class NotificationProfileDatabase(context: Context, databaseHelper: SignalDataba
|
||||
$END INTEGER NOT NULL,
|
||||
$DAYS_ENABLED TEXT NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
const val CREATE_INDEX = "CREATE INDEX notification_profile_schedule_profile_index ON $TABLE_NAME ($NOTIFICATION_PROFILE_ID)"
|
||||
}
|
||||
@@ -96,7 +96,7 @@ class NotificationProfileDatabase(context: Context, databaseHelper: SignalDataba
|
||||
$RECIPIENT_ID INTEGER NOT NULL,
|
||||
UNIQUE($NOTIFICATION_PROFILE_ID, $RECIPIENT_ID) ON CONFLICT REPLACE
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
const val CREATE_INDEX = "CREATE INDEX notification_profile_allowed_members_profile_index ON $TABLE_NAME ($NOTIFICATION_PROFILE_ID)"
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class ReactionTable(context: Context, databaseHelper: SignalDatabase) : Database
|
||||
$DATE_RECEIVED INTEGER NOT NULL,
|
||||
UNIQUE($MESSAGE_ID, $AUTHOR_ID) ON CONFLICT REPLACE
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
private fun readReaction(cursor: Cursor): ReactionRecord {
|
||||
return ReactionRecord(
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.signal.libsignal.protocol.IdentityKey
|
||||
@@ -254,7 +253,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
$REPORTING_TOKEN BLOB DEFAULT NULL,
|
||||
$SYSTEM_NICKNAME TEXT DEFAULT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
"CREATE INDEX IF NOT EXISTS recipient_group_type_index ON $TABLE_NAME ($GROUP_TYPE);",
|
||||
@@ -343,7 +342,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
NULLIF($USERNAME, '')
|
||||
)
|
||||
) AS $SORT_NAME
|
||||
""".trimIndent()
|
||||
"""
|
||||
)
|
||||
|
||||
@JvmField
|
||||
@@ -385,7 +384,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
' ',
|
||||
''
|
||||
) AS $SORT_NAME
|
||||
""".trimIndent()
|
||||
"""
|
||||
)
|
||||
|
||||
private val INSIGHTS_INVITEE_LIST =
|
||||
@@ -1079,7 +1078,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
$TABLE_NAME LEFT OUTER JOIN ${IdentityTable.TABLE_NAME} ON $TABLE_NAME.$SERVICE_ID = ${IdentityTable.TABLE_NAME}.${IdentityTable.ADDRESS}
|
||||
LEFT OUTER JOIN ${GroupTable.TABLE_NAME} ON $TABLE_NAME.$GROUP_ID = ${GroupTable.TABLE_NAME}.${GroupTable.GROUP_ID}
|
||||
LEFT OUTER JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID}
|
||||
""".trimIndent()
|
||||
"""
|
||||
val out: MutableList<RecipientRecord> = ArrayList()
|
||||
val columns: Array<String> = TYPED_RECIPIENT_PROJECTION + arrayOf(
|
||||
SYSTEM_NICKNAME,
|
||||
@@ -1129,7 +1128,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
FROM ${DistributionListTables.ListTable.TABLE_NAME}
|
||||
)
|
||||
)
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
GroupType.NONE.id,
|
||||
Recipient.self().id,
|
||||
GroupType.SIGNAL_V1.id
|
||||
@@ -3158,7 +3157,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
ORDER BY $SORT_NAME, $SYSTEM_JOINED_NAME, $SEARCH_PROFILE_NAME, $PHONE
|
||||
)
|
||||
GROUP BY letter_header
|
||||
""".trimIndent(),
|
||||
""",
|
||||
searchSelection.args
|
||||
).use { cursor ->
|
||||
if (cursor.count == 0) {
|
||||
@@ -3263,7 +3262,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
$PHONE GLOB ? OR
|
||||
$EMAIL GLOB ?
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
val args = SqlUtil.buildArgs(0, 0, query, query, query, query)
|
||||
return readableDatabase.query(TABLE_NAME, SEARCH_PROJECTION, selection, args, null, null, null)
|
||||
}
|
||||
@@ -3284,7 +3283,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
$PHONE GLOB ? OR
|
||||
$EMAIL GLOB ?
|
||||
))
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return SqlUtil.Query(subquery, SqlUtil.buildArgs(0, 0, query, query, query, query))
|
||||
}
|
||||
@@ -3302,7 +3301,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
$PHONE GLOB ? OR
|
||||
$EMAIL GLOB ?
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
|
||||
return readableDatabase.query(subquery, SqlUtil.buildArgs(0, 0, query, query, query, query))
|
||||
}
|
||||
@@ -3479,7 +3478,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
r.$PROFILE_SHARING = 0 AND (
|
||||
EXISTS(SELECT 1 FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.THREAD_ID} = t.${ThreadTable.ID} AND ${MessageTable.DATE_RECEIVED} < ?)
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val idsToUpdate: MutableList<Long> = ArrayList()
|
||||
readableDatabase.rawQuery(select, whereArgs).use { cursor ->
|
||||
@@ -3998,7 +3997,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
UPDATE $TABLE_NAME
|
||||
SET $SERVICE_ID = $PNI_COLUMN
|
||||
WHERE $ID = ? AND $PNI_COLUMN NOT NULL
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
SqlUtil.buildArgs(recipientId)
|
||||
)
|
||||
|
||||
@@ -4466,7 +4465,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
INNER JOIN ${GroupTable.TABLE_NAME} ON ${GroupTable.TABLE_NAME}.${GroupTable.GROUP_ID} = ${GroupTable.MembershipTable.TABLE_NAME}.${GroupTable.MembershipTable.GROUP_ID}
|
||||
WHERE ${GroupTable.MembershipTable.TABLE_NAME}.${GroupTable.MembershipTable.RECIPIENT_ID} = $TABLE_NAME.$ID AND ${GroupTable.TABLE_NAME}.${GroupTable.ACTIVE} = 1 AND ${GroupTable.TABLE_NAME}.${GroupTable.MMS} = 0
|
||||
)
|
||||
""".toSingleLine()
|
||||
"""
|
||||
const val FILTER_GROUPS = " AND $GROUP_ID IS NULL"
|
||||
const val FILTER_ID = " AND $ID != ?"
|
||||
const val FILTER_BLOCKED = " AND $BLOCKED = ?"
|
||||
|
||||
@@ -80,7 +80,7 @@ class RemoteMegaphoneTable(context: Context, databaseHelper: SignalDatabase) : D
|
||||
$SNOOZED_AT INTEGER DEFAULT 0,
|
||||
$SEEN_COUNT INTEGER DEFAULT 0
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
const val VERSION_FINISHED = Int.MAX_VALUE
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.thoughtcrime.securesms.database
|
||||
|
||||
import io.reactivex.rxjava3.core.BackpressureStrategy
|
||||
import io.reactivex.rxjava3.core.Emitter
|
||||
import io.reactivex.rxjava3.core.Flowable
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
|
||||
/**
|
||||
* Provide a shared Rx interface to listen to database updates and ensure listeners
|
||||
* execute on [Schedulers.io].
|
||||
*/
|
||||
object RxDatabaseObserver {
|
||||
|
||||
val conversationList: Flowable<Unit> by lazy { conversationListFlowable() }
|
||||
|
||||
private fun conversationListFlowable(): Flowable<Unit> {
|
||||
val flowable = Flowable.create(
|
||||
{
|
||||
val listener = RxObserver(it)
|
||||
|
||||
ApplicationDependencies.getDatabaseObserver().registerConversationListObserver(listener)
|
||||
it.setCancellable { ApplicationDependencies.getDatabaseObserver().unregisterObserver(listener) }
|
||||
|
||||
listener.prime()
|
||||
},
|
||||
BackpressureStrategy.LATEST
|
||||
)
|
||||
|
||||
return flowable
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(Schedulers.io())
|
||||
.replay(1)
|
||||
.refCount()
|
||||
.observeOn(Schedulers.io())
|
||||
}
|
||||
|
||||
private class RxObserver(private val emitter: Emitter<Unit>) : DatabaseObserver.Observer {
|
||||
fun prime() {
|
||||
emitter.onNext(Unit)
|
||||
}
|
||||
|
||||
override fun onChanged() {
|
||||
emitter.onNext(Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ class SearchTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
WHERE
|
||||
${MessageTable.ID} >= $i AND
|
||||
${MessageTable.ID} < ${i + batchSize}
|
||||
""".trimIndent()
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
$ALLOWS_REPLIES INTEGER NOT NULL,
|
||||
$DISTRIBUTION_ID TEXT NOT NULL REFERENCES ${DistributionListTables.LIST_TABLE_NAME} (${DistributionListTables.DISTRIBUTION_ID}) ON DELETE CASCADE
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
"CREATE INDEX story_sends_recipient_id_sent_timestamp_allows_replies_index ON $TABLE_NAME ($RECIPIENT_ID, $SENT_TIMESTAMP, $ALLOWS_REPLIES)",
|
||||
@@ -110,7 +110,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
AND $MESSAGE_ID > $messageId
|
||||
AND $ALLOWS_REPLIES > ${allowsReplies.toInt()}
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
readableDatabase.rawQuery(query, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
@@ -146,7 +146,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
WHERE ${MessageTable.REMOTE_DELETED} = 0
|
||||
)
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
readableDatabase.rawQuery(query, null).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
@@ -227,7 +227,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
"""
|
||||
$SENT_TIMESTAMP = ? AND
|
||||
(SELECT ${MessageTable.REMOTE_DELETED} FROM ${MessageTable.TABLE_NAME} WHERE ${MessageTable.ID} = $MESSAGE_ID) = 0
|
||||
""".trimIndent(),
|
||||
""",
|
||||
sentTimestamp
|
||||
)
|
||||
.orderBy(MESSAGE_ID)
|
||||
@@ -272,7 +272,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
FROM ${MessageTable.TABLE_NAME}
|
||||
INNER JOIN ${DistributionListTables.LIST_TABLE_NAME} ON ${DistributionListTables.LIST_TABLE_NAME}.${DistributionListTables.RECIPIENT_ID} = ${MessageTable.TABLE_NAME}.${MessageTable.TO_RECIPIENT_ID}
|
||||
WHERE ${MessageTable.DATE_SENT} = $sentTimestamp AND ${DistributionListTables.DISTRIBUTION_ID} IS NOT NULL
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
val distributionIdToMessageId = readableDatabase.query(query).use { cursor ->
|
||||
val results: MutableMap<DistributionId, Long> = mutableMapOf()
|
||||
@@ -351,7 +351,7 @@ class StorySendTable(context: Context, databaseHelper: SignalDatabase) : Databas
|
||||
FROM $TABLE_NAME
|
||||
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()
|
||||
|
||||
@@ -23,7 +23,6 @@ import org.signal.core.util.requireInt
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.select
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
import org.signal.core.util.withinTransaction
|
||||
import org.signal.libsignal.zkgroup.InvalidInputException
|
||||
@@ -135,7 +134,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
$PINNED INTEGER DEFAULT 0,
|
||||
$UNREAD_SELF_MENTION_COUNT INTEGER DEFAULT 0
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
@JvmField
|
||||
val CREATE_INDEXS = arrayOf(
|
||||
@@ -607,7 +606,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
$UNREAD_SELF_MENTION_COUNT = $UNREAD_SELF_MENTION_COUNT + ?,
|
||||
$LAST_SCROLLED = ?
|
||||
WHERE $ID = ?
|
||||
""".toSingleLine(),
|
||||
""",
|
||||
SqlUtil.buildArgs(unreadAmount, unreadSelfMentionAmount, 0, threadId)
|
||||
)
|
||||
}
|
||||
@@ -1683,7 +1682,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
) as MembershipAlias ON MembershipAlias.${GroupTable.MembershipTable.GROUP_ID} = ${GroupTable.TABLE_NAME}.${GroupTable.GROUP_ID}
|
||||
WHERE $where
|
||||
ORDER BY $orderBy
|
||||
""".trimIndent()
|
||||
"""
|
||||
|
||||
if (limit > 0) {
|
||||
query += " LIMIT $limit"
|
||||
@@ -1693,7 +1692,7 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
query += " OFFSET $offset"
|
||||
}
|
||||
|
||||
return query.toSingleLine()
|
||||
return query
|
||||
}
|
||||
|
||||
private fun isSilentType(type: Long): Boolean {
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.signal.core.util.delete
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
|
||||
/**
|
||||
@@ -58,7 +57,7 @@ object V166_ThreadAndMessageForeignKeys : SignalDatabaseMigration {
|
||||
COUNT(*) AS thread_count
|
||||
FROM thread
|
||||
GROUP BY thread_recipient_id HAVING thread_count > 1
|
||||
""".toSingleLine()
|
||||
"""
|
||||
).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
val recipientId = cursor.requireLong("thread_recipient_id")
|
||||
|
||||
@@ -7,7 +7,6 @@ import org.signal.core.util.delete
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.signal.core.util.update
|
||||
|
||||
/**
|
||||
@@ -38,7 +37,7 @@ object V171_ThreadForeignKeyFix : SignalDatabaseMigration {
|
||||
COUNT(*) AS thread_count
|
||||
FROM thread
|
||||
GROUP BY recipient_id HAVING thread_count > 1
|
||||
""".toSingleLine()
|
||||
"""
|
||||
).use { cursor ->
|
||||
while (cursor.moveToNext()) {
|
||||
val recipientId = cursor.requireLong("recipient_id")
|
||||
|
||||
@@ -12,7 +12,6 @@ import org.signal.core.util.readToSingleObject
|
||||
import org.signal.core.util.requireLong
|
||||
import org.signal.core.util.requireNonNullString
|
||||
import org.signal.core.util.requireString
|
||||
import org.signal.core.util.toSingleLine
|
||||
import org.thoughtcrime.securesms.database.KeyValueDatabase
|
||||
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies
|
||||
import org.thoughtcrime.securesms.recipients.RecipientId
|
||||
@@ -182,7 +181,7 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration {
|
||||
from_recipient_id = ${selfId.toLong()},
|
||||
from_device_id = 1
|
||||
WHERE $outgoingClause
|
||||
""".toSingleLine()
|
||||
"""
|
||||
)
|
||||
}
|
||||
stopwatch.split("update-data")
|
||||
|
||||
@@ -33,7 +33,7 @@ class AvatarPickerDatabase(context: Context, databaseHelper: SignalDatabase) : D
|
||||
$GROUP_ID TEXT DEFAULT NULL,
|
||||
$AVATAR BLOB NOT NULL
|
||||
)
|
||||
""".trimIndent()
|
||||
"""
|
||||
}
|
||||
|
||||
fun saveAvatarForSelf(avatar: Avatar): Avatar {
|
||||
|
||||
Reference in New Issue
Block a user