Drop TSAttachment fields from JobRecords

This commit is contained in:
Harry
2024-12-04 13:31:41 -08:00
committed by GitHub
parent 6390423c59
commit 39557cf5b8
14 changed files with 57 additions and 343 deletions

View File

@@ -75,6 +75,5 @@
"TSRecipientReadReceipt": 12,
"TSThread": 2,
"TSUnreadIndicatorInteraction": 4,
"TestModel": 59,
"tsAttachmentMultisendJobRecord": 58
}
"TestModel": 59
}

View File

@@ -1207,7 +1207,6 @@
724D47BC2B97C57C001BE973 /* GroupV2Snapshot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BB3C5A23C6644B001651FC /* GroupV2Snapshot.swift */; };
724D47BD2B97C5B9001BE973 /* GroupsV2Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34BB3C5823C6644B001651FC /* GroupsV2Utils.swift */; };
724E68642C91FA73002199F3 /* DataHexadecimalTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 724E68632C91FA73002199F3 /* DataHexadecimalTest.swift */; };
725464EC2B9F6EB900EABFD2 /* Deprecated_TSAttachmentMultisendJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9C50FF22F495F60054A33F /* Deprecated_TSAttachmentMultisendJob.swift */; };
725464F62B9FAC7600EABFD2 /* CGPointExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C612B3284E466B00B2199A /* CGPointExtensionsTest.swift */; };
725465162BA00BE400EABFD2 /* NameResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50086B9B29DF5CB100F9C072 /* NameResolver.swift */; };
725465172BA00CDB00EABFD2 /* NewAccountDiscovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C6E446822AEDDEE007982E6 /* NewAccountDiscovery.swift */; };
@@ -2515,7 +2514,6 @@
D9AA37A02A86E0910088EFFB /* OutgoingCallEventSyncMessageTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AA379F2A86E0910088EFFB /* OutgoingCallEventSyncMessageTest.swift */; };
D9AA37A42A8A9A910088EFFB /* OutgoingGroupCallUpdateMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AA37A32A8A9A910088EFFB /* OutgoingGroupCallUpdateMessage.swift */; };
D9AD1D9528B9955C00B42E6F /* TSInfoMessage+GroupUpdateType+NSAttributedStringTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AD1D9428B9955C00B42E6F /* TSInfoMessage+GroupUpdateType+NSAttributedStringTest.swift */; };
D9AE0ACB29162C160063488B /* TSAttachmentMultisendJobRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AE0ACA29162C160063488B /* TSAttachmentMultisendJobRecord.swift */; };
D9AE0ACF29186D7F0063488B /* IncomingContactSyncJobRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AE0ACE29186D7F0063488B /* IncomingContactSyncJobRecord.swift */; };
D9AE0AD32918715E0063488B /* ReceiptCredentialRedemptionJobRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AE0AD22918715E0063488B /* ReceiptCredentialRedemptionJobRecord.swift */; };
D9AE0AD5291877600063488B /* SendGiftBadgeJobRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9AE0AD4291877600063488B /* SendGiftBadgeJobRecord.swift */; };
@@ -4243,7 +4241,6 @@
4C83AC4123C55D9C00D4F2E6 /* SignalBaseTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SignalBaseTest.swift; sourceTree = "<group>"; };
4C8A6DFB22E5499300469AE7 /* MediaZoomAnimationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaZoomAnimationController.swift; sourceTree = "<group>"; };
4C8A6DFD22E54AFA00469AE7 /* MediaInteractiveDismiss.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaInteractiveDismiss.swift; sourceTree = "<group>"; };
4C9C50FF22F495F60054A33F /* Deprecated_TSAttachmentMultisendJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Deprecated_TSAttachmentMultisendJob.swift; sourceTree = "<group>"; };
4C9D347923679C13006A4307 /* ContactStreamTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactStreamTest.swift; sourceTree = "<group>"; };
4C9D347E23689E06006A4307 /* IncomingContactSyncJobQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingContactSyncJobQueue.swift; sourceTree = "<group>"; };
4CA46F4B219CCC630038ABDE /* MediaCaptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediaCaptionView.swift; sourceTree = "<group>"; };
@@ -6289,7 +6286,6 @@
D9AA379F2A86E0910088EFFB /* OutgoingCallEventSyncMessageTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingCallEventSyncMessageTest.swift; sourceTree = "<group>"; };
D9AA37A32A8A9A910088EFFB /* OutgoingGroupCallUpdateMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingGroupCallUpdateMessage.swift; sourceTree = "<group>"; };
D9AD1D9428B9955C00B42E6F /* TSInfoMessage+GroupUpdateType+NSAttributedStringTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSInfoMessage+GroupUpdateType+NSAttributedStringTest.swift"; sourceTree = "<group>"; };
D9AE0ACA29162C160063488B /* TSAttachmentMultisendJobRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAttachmentMultisendJobRecord.swift; sourceTree = "<group>"; };
D9AE0ACE29186D7F0063488B /* IncomingContactSyncJobRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IncomingContactSyncJobRecord.swift; sourceTree = "<group>"; };
D9AE0AD22918715E0063488B /* ReceiptCredentialRedemptionJobRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiptCredentialRedemptionJobRecord.swift; sourceTree = "<group>"; };
D9AE0AD4291877600063488B /* SendGiftBadgeJobRecord.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendGiftBadgeJobRecord.swift; sourceTree = "<group>"; };
@@ -12015,7 +12011,6 @@
F9C5CA85289453B100548EEE /* JobRecords */,
D9F9A63A2BFFFCC400EF13EC /* BulkDeleteInteractionJobQueue.swift */,
D9DB37F82B72A770007B16C8 /* CallRecordDeleteAllJobQueue.swift */,
4C9C50FF22F495F60054A33F /* Deprecated_TSAttachmentMultisendJob.swift */,
886A58C9276A760600A1099B /* DonationReceiptCredentialRedemptionJobQueue.swift */,
4C9D347E23689E06006A4307 /* IncomingContactSyncJobQueue.swift */,
5008FEBB2B1811A0004E73FD /* JobQueueRunner.swift */,
@@ -13670,7 +13665,6 @@
D9AE0AD22918715E0063488B /* ReceiptCredentialRedemptionJobRecord.swift */,
D9AE0AD4291877600063488B /* SendGiftBadgeJobRecord.swift */,
D9AE0AD629187A700063488B /* SessionResetJobRecord.swift */,
D9AE0ACA29162C160063488B /* TSAttachmentMultisendJobRecord.swift */,
);
path = JobRecords;
sourceTree = "<group>";
@@ -17044,7 +17038,6 @@
D9247EA82BFD28E800DFEF6F /* DeleteForMeSyncMessageReceiver.swift in Sources */,
F9C5CC34289453B300548EEE /* DeliveryReceiptContext.swift in Sources */,
6698FC1A2980AB45004EFC30 /* DependenciesBridge.swift in Sources */,
725464EC2B9F6EB900EABFD2 /* Deprecated_TSAttachmentMultisendJob.swift in Sources */,
505C2ED629971D4E00C23FB2 /* DeviceLimitExceededError.swift in Sources */,
50E5E4B129932D9B00E15A1C /* DeviceMessage.swift in Sources */,
F9C5CE0C289453B400548EEE /* DeviceNames.swift in Sources */,
@@ -17863,7 +17856,6 @@
665C758C2C35A55300D2E4BA /* TSAttachmentMigration+ThreadWallpaper.swift in Sources */,
6660C7972C45C34A00D9C30A /* TSAttachmentMigration+TSMessage.swift in Sources */,
66A1ABE22C3311B40033C5EB /* TSAttachmentMigration.swift in Sources */,
D9AE0ACB29162C160063488B /* TSAttachmentMultisendJobRecord.swift in Sources */,
F9C5CC79289453B300548EEE /* TSAttachmentPointer+SDS.swift in Sources */,
F9C5CC78289453B300548EEE /* TSAttachmentPointer.m in Sources */,
F9C5CC7B289453B300548EEE /* TSAttachmentStream+SDS.swift in Sources */,

View File

@@ -1,116 +0,0 @@
//
// Copyright 2019 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
public struct TSAttachmentMultisendResult {
/// Resolved when the attachments are uploaded and sending is enqueued.
public let enqueuedPromise: Promise<Void>
/// Resolved when the message is sent.
public let sentPromise: Promise<Void>
}
public class TSAttachmentMultisendJobQueue {
private let jobQueueRunner: JobQueueRunner<
JobRecordFinderImpl<TSAttachmentMultisendJobRecord>,
TSAttachmentMultisendJobRunnerFactory
>
private let jobRunnerFactory: TSAttachmentMultisendJobRunnerFactory
public init(db: any DB, reachabilityManager: SSKReachabilityManager) {
self.jobRunnerFactory = TSAttachmentMultisendJobRunnerFactory()
self.jobQueueRunner = JobQueueRunner(
canExecuteJobsConcurrently: false,
db: db,
jobFinder: JobRecordFinderImpl(db: db),
jobRunnerFactory: jobRunnerFactory
)
self.jobQueueRunner.listenForReachabilityChanges(reachabilityManager: reachabilityManager)
}
public func start(appContext: AppContext) {
if appContext.isNSE { return }
jobQueueRunner.start(shouldRestartExistingJobs: appContext.isMainApp)
}
@discardableResult
public func add(
attachmentIdMap: [String: [String]],
storyMessagesToSend: [OutgoingStoryMessage],
transaction: SDSAnyWriteTransaction
) -> TSAttachmentMultisendResult {
let jobRecord = TSAttachmentMultisendJobRecord(
attachmentIdMap: attachmentIdMap,
storyMessagesToSend: storyMessagesToSend
)
jobRecord.anyInsert(transaction: transaction)
let enqueuePromise = Promise<Void>.pending()
let sendPromise = Promise<Void>.pending()
let jobFutures = TSAttachmentMultisendFutures(
enqueuedFuture: enqueuePromise.1,
sentFuture: sendPromise.1
)
transaction.addSyncCompletion {
let runner = self.jobRunnerFactory.buildRunner(jobFutures)
self.jobQueueRunner.addPersistedJob(jobRecord, runner: runner)
}
return .init(
enqueuedPromise: enqueuePromise.0,
sentPromise: sendPromise.0
)
}
}
private class TSAttachmentMultisendFutures {
/// Resolved when the attachments are uploaded and sending is enqueued.
public let enqueuedFuture: Future<Void>
/// Resolved when the message is sent.
public let sentFuture: Future<Void>
init(enqueuedFuture: Future<Void>, sentFuture: Future<Void>) {
self.enqueuedFuture = enqueuedFuture
self.sentFuture = sentFuture
}
}
private class TSAttachmentMultisendJobRunnerFactory: JobRunnerFactory {
func buildRunner() -> TSAttachmentMultisendJobRunner {
TSAttachmentMultisendJobRunner(jobFutures: nil)
}
func buildRunner(_ jobFutures: TSAttachmentMultisendFutures?) -> TSAttachmentMultisendJobRunner {
TSAttachmentMultisendJobRunner(jobFutures: jobFutures)
}
}
private class TSAttachmentMultisendJobRunner: JobRunner {
private let jobFutures: TSAttachmentMultisendFutures?
init(jobFutures: TSAttachmentMultisendFutures?) {
self.jobFutures = jobFutures
}
func runJobAttempt(_ jobRecord: TSAttachmentMultisendJobRecord) async -> JobAttemptResult {
owsFailDebug("TSAttachment is obsoleted")
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { transaction in
jobRecord.anyRemove(transaction: transaction)
}
return .finished(.success(()))
}
func didFinishJob(_ jobRecordId: JobRecord.RowId, result: JobResult) async {
switch result.ranSuccessfullyOrError {
case .success:
// When this job finishes, the send is enqueued.
// Send future resolution is handled within the job.
jobFutures?.enqueuedFuture.resolve(())
case .failure(let error):
jobFutures?.enqueuedFuture.reject(error)
}
}
}

View File

@@ -91,7 +91,6 @@ private class IncomingContactSyncJobRunner: JobRunner {
private func _runJob(_ jobRecord: IncomingContactSyncJobRecord) async throws {
let fileUrl: URL
let legacyAttachmentId: String?
switch jobRecord.downloadInfo {
case .invalid:
owsFailDebug("Invalid contact sync job!")
@@ -99,17 +98,10 @@ private class IncomingContactSyncJobRunner: JobRunner {
jobRecord.anyRemove(transaction: tx)
}
return
case .legacy(let attachmentId):
owsFailDebug("Legacy jobs no longer supported")
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { tx in
jobRecord.anyRemove(transaction: tx)
}
return
case .transient(let downloadMetadata):
fileUrl = try await DependenciesBridge.shared.attachmentDownloadManager.downloadTransientAttachment(
metadata: downloadMetadata
).awaitable()
legacyAttachmentId = nil
}
let insertedThreads = try await firstly(on: DispatchQueue.global()) {

View File

@@ -9,8 +9,6 @@ import GRDB
public final class IncomingContactSyncJobRecord: JobRecord, FactoryInitializableFromRecordType {
override class var jobRecordType: JobRecordType { .incomingContactSync }
private let legacyAttachmentId: String?
private let cdnNumber: UInt32?
private let cdnKey: String?
private let encryptionKey: Data?
@@ -19,7 +17,6 @@ public final class IncomingContactSyncJobRecord: JobRecord, FactoryInitializable
public enum DownloadInfo {
case invalid
case legacy(attachmentId: String)
case transient(AttachmentDownloads.DownloadMetadata)
}
@@ -50,64 +47,21 @@ public final class IncomingContactSyncJobRecord: JobRecord, FactoryInitializable
&& plaintextLength == nil,
"Either all fields should be set or none!"
)
if let legacyAttachmentId {
return .legacy(attachmentId: legacyAttachmentId)
}
return .invalid
}
public let isCompleteContactSync: Bool
public static func legacy(
legacyAttachmentId: String?,
isCompleteContactSync: Bool,
failureCount: UInt = 0,
status: Status = .ready
) -> IncomingContactSyncJobRecord {
return IncomingContactSyncJobRecord(
legacyAttachmentId: legacyAttachmentId,
cdnNumber: nil,
cdnKey: nil,
encryptionKey: nil,
digest: nil,
plaintextLength: nil,
isCompleteContactSync: isCompleteContactSync,
failureCount: failureCount,
status: status
)
}
public convenience init(
public init(
cdnNumber: UInt32,
cdnKey: String,
encryptionKey: Data,
digest: Data,
plaintextLength: UInt32?,
isCompleteContactSync: Bool
) {
self.init(
legacyAttachmentId: nil,
cdnNumber: cdnNumber,
cdnKey: cdnKey,
encryptionKey: encryptionKey,
digest: digest,
plaintextLength: plaintextLength,
isCompleteContactSync: isCompleteContactSync
)
}
private init(
legacyAttachmentId: String?,
cdnNumber: UInt32?,
cdnKey: String?,
encryptionKey: Data?,
digest: Data?,
plaintextLength: UInt32?,
isCompleteContactSync: Bool,
failureCount: UInt = 0,
status: Status = .ready
) {
self.legacyAttachmentId = legacyAttachmentId
self.isCompleteContactSync = isCompleteContactSync
self.cdnNumber = cdnNumber
@@ -122,11 +76,35 @@ public final class IncomingContactSyncJobRecord: JobRecord, FactoryInitializable
)
}
#if TESTABLE_BUILD
public init(
cdnNumber: UInt32?,
cdnKey: String?,
encryptionKey: Data?,
digest: Data?,
plaintextLength: UInt32?,
isCompleteContactSync: Bool,
failureCount: UInt = 0,
status: Status = .ready
) {
self.isCompleteContactSync = isCompleteContactSync
self.cdnNumber = cdnNumber
self.cdnKey = cdnKey
self.encryptionKey = encryptionKey
self.digest = digest
self.plaintextLength = plaintextLength
super.init(
failureCount: failureCount,
status: status
)
}
#endif
required init(forRecordTypeFactoryInitializationFrom decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
legacyAttachmentId = try container.decodeIfPresent(String.self, forKey: .legacyAttachmentId)
cdnNumber = try container.decodeIfPresent(UInt32.self, forKey: .ICSJR_cdnNumber)
cdnKey = try container.decodeIfPresent(String.self, forKey: .ICSJR_cdnKey)
encryptionKey = try container.decodeIfPresent(Data.self, forKey: .ICSJR_encryptionKey)
@@ -143,8 +121,6 @@ public final class IncomingContactSyncJobRecord: JobRecord, FactoryInitializable
try super.encode(to: container.superEncoder())
try container.encodeIfPresent(legacyAttachmentId, forKey: .legacyAttachmentId)
try container.encodeIfPresent(cdnNumber, forKey: .ICSJR_cdnNumber)
try container.encodeIfPresent(cdnKey, forKey: .ICSJR_cdnKey)
try container.encodeIfPresent(encryptionKey, forKey: .ICSJR_encryptionKey)

View File

@@ -49,20 +49,11 @@ extension JobRecord {
case ICSJR_digest
case ICSJR_plaintextLength
// MARK: IncomingContactSyncJobRecord & IncomingGroupSyncJobRecord
case legacyAttachmentId = "attachmentId"
// MARK: LocalUserLeaveGroupJobRecord
case replacementAdminAciString = "replacementAdminUuid"
case waitForMessageProcessing
// MARK: TSAttachmentMultisendJobRecord
case attachmentIdMap
case unsavedMessagesToSend
// MARK: SessionResetJobRecord
case contactThreadId

View File

@@ -24,7 +24,6 @@ extension JobRecord: NeedsFactoryInitializationFromRecordType {
// MARK: Values originally from SDSRecordType
case tsAttachmentMultisend = 58
case incomingContactSync = 61
case legacyMessageDecrypt = 53
case localUserLeaveGroup = 74
@@ -49,7 +48,6 @@ extension JobRecord: NeedsFactoryInitializationFromRecordType {
}
switch jobRecordType {
case .tsAttachmentMultisend: return TSAttachmentMultisendJobRecord.self
case .incomingContactSync: return IncomingContactSyncJobRecord.self
case .legacyMessageDecrypt: return LegacyMessageDecryptJobRecord.self
case .localUserLeaveGroup: return LocalUserLeaveGroupJobRecord.self
@@ -67,9 +65,6 @@ extension JobRecord.JobRecordType {
var jobRecordLabel: String {
// These values are persisted and must not change, even if they're misspelled.
switch self {
case .tsAttachmentMultisend:
// label is serialized and must remain unchanged.
return "BroadcastMediaMessage"
case .incomingContactSync:
return "IncomingContactSync"
case .legacyMessageDecrypt:

View File

@@ -1,89 +0,0 @@
//
// Copyright 2023 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
//
import Foundation
import GRDB
public final class TSAttachmentMultisendJobRecord: JobRecord, FactoryInitializableFromRecordType {
override class var jobRecordType: JobRecordType { .tsAttachmentMultisend }
/// A map from the TSAttachmentStream's to upload to their corresponding list of visible copies in individual
/// conversations. e.g. if we're broadcast-sending a picture and a video to 3 recipients, the dictionary would look
/// like:
/// [
/// pictureAttachmentId: [
/// pictureCopyAttachmentIdForRecipient1,
/// pictureCopyAttachmentIdForRecipient2,
/// pictureCopyAttachmentIdForRecipient3
/// ],
/// videoAttachmentId: [
/// videoCopyAttachmentIdForRecipient1,
/// videoCopyAttachmentIdForRecipient2,
/// videoCopyAttachmentIdForRecipient3
/// ]
/// ]
public let attachmentIdMap: [String: [String]]
// These have always been only OutgoingStoryMessages, but rather than touch the serialization
// layer, we just transform them in memory.
// This class's public API takes OutgoingStoryMessage(s) and returns OutgoingStoryMessage(s).
private let unsavedMessagesToSend: [TSOutgoingMessage]?
public var storyMessagesToSend: [OutgoingStoryMessage]? {
return unsavedMessagesToSend?.compactMap { $0 as? OutgoingStoryMessage }
}
public init(
attachmentIdMap: [String: [String]],
storyMessagesToSend: [OutgoingStoryMessage]?,
failureCount: UInt = 0,
status: Status = .ready
) {
self.attachmentIdMap = attachmentIdMap
self.unsavedMessagesToSend = storyMessagesToSend
super.init(
failureCount: failureCount,
status: status
)
}
required init(forRecordTypeFactoryInitializationFrom decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
attachmentIdMap = try LegacySDSSerializer().deserializeLegacySDSData(
try container.decode(Data.self, forKey: .attachmentIdMap),
propertyName: "attachmentIdMap"
)
unsavedMessagesToSend = try container.decodeIfPresent(
Data.self,
forKey: .unsavedMessagesToSend
).map { unsavedMessagesToSendData in
try LegacySDSSerializer().deserializeLegacySDSData(
unsavedMessagesToSendData,
propertyName: "unsavedMessagesToSend"
)
}
try super.init(baseClassDuringFactoryInitializationFrom: try container.superDecoder())
}
public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try super.encode(to: container.superEncoder())
try container.encode(
LegacySDSSerializer().serializeAsLegacySDSData(property: attachmentIdMap),
forKey: .attachmentIdMap
)
try container.encodeIfPresent(
LegacySDSSerializer().serializeAsLegacySDSData(property: unsavedMessagesToSend),
forKey: .unsavedMessagesToSend
)
}
}

View File

@@ -10,7 +10,6 @@ public class SignalMessagingJobQueues: NSObject {
public init(appReadiness: AppReadiness, db: any DB, reachabilityManager: SSKReachabilityManager) {
incomingContactSyncJobQueue = IncomingContactSyncJobQueue(appReadiness: appReadiness, db: db, reachabilityManager: reachabilityManager)
sessionResetJobQueue = SessionResetJobQueue(db: db, reachabilityManager: reachabilityManager)
tsAttachmentMultisendJobQueue = TSAttachmentMultisendJobQueue(db: db, reachabilityManager: reachabilityManager)
receiptCredentialJobQueue = DonationReceiptCredentialRedemptionJobQueue(db: db, reachabilityManager: reachabilityManager)
sendGiftBadgeJobQueue = SendGiftBadgeJobQueue(db: db, reachabilityManager: reachabilityManager)
}
@@ -23,7 +22,6 @@ public class SignalMessagingJobQueues: NSObject {
// MARK: Swift-only
public let sessionResetJobQueue: SessionResetJobQueue
public let tsAttachmentMultisendJobQueue: TSAttachmentMultisendJobQueue
public let receiptCredentialJobQueue: DonationReceiptCredentialRedemptionJobQueue
public let sendGiftBadgeJobQueue: SendGiftBadgeJobQueue
}

View File

@@ -206,14 +206,12 @@ CREATE
,"failureCount" INTEGER NOT NULL
,"label" TEXT NOT NULL
,"status" INTEGER NOT NULL
,"attachmentIdMap" BLOB
,"contactThreadId" TEXT
,"envelopeData" BLOB
,"invisibleMessage" BLOB
,"messageId" TEXT
,"removeMessageAfterSending" INTEGER
,"threadId" TEXT
,"attachmentId" TEXT
,"isMediaMessage" BOOLEAN
,"serverDeliveryTimestamp" INTEGER
,"exclusiveProcessIdentifier" TEXT
@@ -228,7 +226,6 @@ CREATE
,"receiptCredentialPresentation" BLOB
,"amount" NUMERIC
,"currencyCode" TEXT
,"unsavedMessagesToSend" BLOB
,"messageText" TEXT
,"paymentIntentClientSecret" TEXT
,"paymentMethodId" TEXT

View File

@@ -259,7 +259,6 @@ public class SSKEnvironment: NSObject {
self.localUserLeaveGroupJobQueueRef.start(appContext: CurrentAppContext())
self.callRecordDeleteAllJobQueueRef.start(appContext: CurrentAppContext())
self.bulkDeleteInteractionJobQueueRef.start(appContext: CurrentAppContext())
self.smJobQueuesRef.tsAttachmentMultisendJobQueue.start(appContext: CurrentAppContext())
self.smJobQueuesRef.incomingContactSyncJobQueue.start(appContext: CurrentAppContext())
self.smJobQueuesRef.receiptCredentialJobQueue.start(appContext: CurrentAppContext())
self.smJobQueuesRef.sendGiftBadgeJobQueue.start(appContext: CurrentAppContext())

View File

@@ -312,6 +312,7 @@ public class GRDBSchemaMigrator: NSObject {
case tsMessageAttachmentMigration3
case addEditStateToMessageAttachmentReference
case removeVersionedDMTimerCapabilities
case removeJobRecordTSAttachmentColumns
// NOTE: Every time we add a migration id, consider
// incrementing grdbSchemaVersionLatest.
@@ -373,7 +374,7 @@ public class GRDBSchemaMigrator: NSObject {
}
public static let grdbSchemaVersionDefault: UInt = 0
public static let grdbSchemaVersionLatest: UInt = 102
public static let grdbSchemaVersionLatest: UInt = 103
// An optimization for new users, we have the first migration import the latest schema
// and mark any other migrations as "already run".
@@ -3747,6 +3748,19 @@ public class GRDBSchemaMigrator: NSObject {
return .success(())
}
migrator.registerMigration(.removeJobRecordTSAttachmentColumns) { tx in
// Remove TSAttachmentMultisend records.
try tx.database.execute(sql: """
DELETE FROM model_SSKJobRecord WHERE recordType = 58;
""")
try tx.database.alter(table: "model_SSKJobRecord") { table in
table.drop(column: "attachmentId")
table.drop(column: "attachmentIdMap")
table.drop(column: "unsavedMessagesToSend")
}
return .success(())
}
// MARK: - Schema Migration Insertion Point
}

View File

@@ -66,7 +66,6 @@ public enum SDSRecordType: UInt, CaseIterable {
case experienceUpgrade = 55
case baseModel = 56
case contactQuery = 57
case tsAttachmentMultisendJobRecord = 58
case testModel = 59
case incomingGroupSyncJobRecord = 60
case incomingContactSyncJobRecord = 61

View File

@@ -16,7 +16,6 @@ class JobRecordTest: XCTestCase {
forRecordType recordType: JobRecord.JobRecordType
) -> any (JobRecord & ValidatableModel).Type {
switch recordType {
case .tsAttachmentMultisend: return TSAttachmentMultisendJobRecord.self
case .incomingContactSync: return IncomingContactSyncJobRecord.self
case .legacyMessageDecrypt: return LegacyMessageDecryptJobRecord.self
case .localUserLeaveGroup: return LocalUserLeaveGroupJobRecord.self
@@ -125,45 +124,15 @@ extension ValidatableModel where Self: JobRecord {
// MARK: - Job records
extension TSAttachmentMultisendJobRecord: ValidatableModel {
static let constants: [(TSAttachmentMultisendJobRecord, jsonData: Data)] = [
(
TSAttachmentMultisendJobRecord(
attachmentIdMap: ["once": ["upon", "a"]],
// The encoded object below has a non-story message, which is invalid in the real app.
storyMessagesToSend: [],
failureCount: 3,
status: .running
),
Data(#"{"super":{"failureCount":3,"label":"BroadcastMediaMessage","status":2,"uniqueId":"F5B3380C-B4DB-45DE-BB07-CC6BCAE97FDB","recordType":58},"attachmentIdMap":"YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGoCwwVFhscHSNVJG51bGzTDQ4PEBIUV05TLmtleXNaTlMub2JqZWN0c1YkY2xhc3OhEYACoROAA4AHVG9uY2XSDg8XGqIYGYAEgAWABlR1cG9uUWHSHh8gIVokY2xhc3NuYW1lWCRjbGFzc2VzV05TQXJyYXmiICJYTlNPYmplY3TSHh8kJVxOU0RpY3Rpb25hcnmiJiJcTlNEaWN0aW9uYXJ5CBEaJCkyN0lMUVNcYmlxfIOFh4mLjZKXmpyeoKWnrLfAyMvU2ebpAAAAAAAAAQEAAAAAAAAAJwAAAAAAAAAAAAAAAAAAAPY=","unsavedMessagesToSend":"YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGqCwwSRkdISUpLV1UkbnVsbNINDg8RWk5TLm9iamVjdHNWJGNsYXNzoRCAAoAJ3xAaExQVFg4XGBkaGxwdHh8gISIjJCUmJygpKissLS0sMC0sMy0sLSwsLCwtLSwtLCxBQiwtLV8QE3JlY2VpdmVkQXRUaW1lc3RhbXBfEBJpc1ZpZXdPbmNlQ29tcGxldGVfEBxzdG9yZWRTaG91bGRTdGFydEV4cGlyZVRpbWVyXxAPZXhwaXJlU3RhcnRlZEF0XxARaXNWaWV3T25jZU1lc3NhZ2VfEA9NVExNb2RlbFZlcnNpb25edW5pcXVlVGhyZWFkSWRfEBVoYXNMZWdhY3lNZXNzYWdlU3RhdGVWc29ydElkXxASaXNGcm9tTGlua2VkRGV2aWNlXxAcb3V0Z29pbmdNZXNzYWdlU2NoZW1hVmVyc2lvbl8QEGV4cGlyZXNJblNlY29uZHNfEBBncm91cE1ldGFNZXNzYWdlXxASbGVnYWN5TWVzc2FnZVN0YXRlXxASbGVnYWN5V2FzRGVsaXZlcmVkXmlzVm9pY2VNZXNzYWdlWWV4cGlyZXNBdF8QEWlzR3JvdXBTdG9yeVJlcGx5XXNjaGVtYVZlcnNpb25ZZWRpdFN0YXRlWXRpbWVzdGFtcFh1bmlxdWVJZF8QEnN0b3JlZE1lc3NhZ2VTdGF0ZV8QEndhc1JlbW90ZWx5RGVsZXRlZF8QE2hhc1N5bmNlZFRyYW5zY3JpcHSAA4AEgASAA4AIgASAA4AFgASAA4AEgAOAA4ADgAOABIAEgAOABIADgAOAB4AGgAOABIAEEAAIW2luIGEgZ2FsYXh5VHRpbWUTAAABjDc01WXSTE1OT1okY2xhc3NuYW1lWCRjbGFzc2VzXxARVFNPdXRnb2luZ01lc3NhZ2WnUFFSU1RVVl8QEVRTT3V0Z29pbmdNZXNzYWdlWVRTTWVzc2FnZV1UU0ludGVyYWN0aW9uWUJhc2VNb2RlbF8QE1RTWWFwRGF0YWJhc2VPYmplY3RYTVRMTW9kZWxYTlNPYmplY3TSTE1YWVdOU0FycmF5olhWAAgAEQAaACQAKQAyADcASQBMAFEAUwBeAGQAaQB0AHsAfQB\/AIEAuADOAOMBAgEUASgBOgFJAWEBaAF9AZwBrwHCAdcB7AH7AgUCGQInAjECOwJEAlkCbgKEAoYCiAKKAowCjgKQApIClAKWApgCmgKcAp4CoAKiAqQCpgKoAqoCrAKuArACsgK0ArYCuAK6ArsCxwLMAtUC2gLlAu4DAgMKAx4DKAM2A0ADVgNfA2gDbQN1AAAAAAAAAgEAAAAAAAAAWgAAAAAAAAAAAAAAAAAAA3g="}"#.utf8)
),
(
TSAttachmentMultisendJobRecord(
attachmentIdMap: ["once": ["upon", "a"]],
storyMessagesToSend: nil,
failureCount: 3,
status: .running
),
Data(#"{"super":{"failureCount":3,"label":"BroadcastMediaMessage","status":2,"uniqueId":"3EB90435-904A-46DA-951D-AF577B38ADD7","recordType":58},"attachmentIdMap":"YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8QD05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGoCwwVFhscHSNVJG51bGzTDQ4PEBIUV05TLmtleXNaTlMub2JqZWN0c1YkY2xhc3OhEYACoROAA4AHVG9uY2XSDg8XGqIYGYAEgAWABlR1cG9uUWHSHh8gIVokY2xhc3NuYW1lWCRjbGFzc2VzV05TQXJyYXmiICJYTlNPYmplY3TSHh8kJVxOU0RpY3Rpb25hcnmiJiJcTlNEaWN0aW9uYXJ5CBEaJCkyN0lMUVNcYmlxfIOFh4mLjZKXmpyeoKWnrLfAyMvU2ebpAAAAAAAAAQEAAAAAAAAAJwAAAAAAAAAAAAAAAAAAAPY="}"#.utf8)
)
]
func validate(against: TSAttachmentMultisendJobRecord) throws {
guard
attachmentIdMap == against.attachmentIdMap,
storyMessagesToSend?.count == against.storyMessagesToSend?.count,
storyMessagesToSend?.first?.uniqueId == against.storyMessagesToSend?.first?.uniqueId
else {
throw ValidatableModelError.failedToValidate
}
}
}
extension IncomingContactSyncJobRecord: ValidatableModel {
static let constants: [(IncomingContactSyncJobRecord, jsonData: Data)] = [
(
IncomingContactSyncJobRecord.legacy(
legacyAttachmentId: "darth revan",
IncomingContactSyncJobRecord(
cdnNumber: nil,
cdnKey: nil,
encryptionKey: nil,
digest: nil,
plaintextLength: nil,
isCompleteContactSync: true,
failureCount: 12,
status: .ready
@@ -171,8 +140,12 @@ extension IncomingContactSyncJobRecord: ValidatableModel {
Data(#"{"super":{"failureCount":12,"label":"IncomingContactSync","status":1,"uniqueId":"FF3753B3-B1FD-4B4A-96C3-2398EB120136","recordType":61},"isCompleteContactSync":true,"attachmentId":"darth revan"}"#.utf8)
),
(
IncomingContactSyncJobRecord.legacy(
legacyAttachmentId: nil,
IncomingContactSyncJobRecord(
cdnNumber: nil,
cdnKey: nil,
encryptionKey: nil,
digest: nil,
plaintextLength: nil,
isCompleteContactSync: false,
failureCount: 6,
status: .permanentlyFailed
@@ -201,19 +174,13 @@ extension IncomingContactSyncJobRecord: ValidatableModel {
switch (downloadInfo, against.downloadInfo) {
case (.invalid, .invalid):
break
case let (.legacy(lhsId), .legacy(rhsId)):
guard
lhsId == rhsId
else {
throw ValidatableModelError.failedToValidate
}
case let (.transient(lhsInfo), .transient(rhsInfo)):
guard
lhsInfo == rhsInfo
else {
throw ValidatableModelError.failedToValidate
}
case (.invalid, _), (.legacy, _), (.transient, _):
case (.invalid, _), (.transient, _):
throw ValidatableModelError.failedToValidate
}