Remove “collection” concept from database types

This commit is contained in:
Max Radermacher
2024-08-20 18:22:00 -05:00
committed by GitHub
parent 4eecfbf552
commit 07baa170f7
39 changed files with 321 additions and 552 deletions

View File

@@ -1814,21 +1814,19 @@ extension %sSerializer {
database_table_name = "model_%s" % str(clazz.name)
swift_body += """
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: %s.collection(),
tableName: "%s",
columns: [
""" % (
str(clazz.name),
database_table_name,
)
swift_body += ",\n".join(
SDSTableMetadata(
tableName: "%s",
columns: [
""" % (database_table_name,)
swift_body += "\n".join(
[
" %sColumn" % str(column_property_name)
" %sColumn," % str(column_property_name)
for column_property_name in column_property_names
]
)
swift_body += """
])
]
)
}
}
"""

View File

@@ -110,8 +110,8 @@ extension BadgeManager: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
let badgeMightBeDifferent = (
databaseChanges.didUpdateInteractions
|| databaseChanges.didUpdateModel(collection: String(describing: ThreadAssociatedData.self))
|| databaseChanges.didUpdateModel(collection: String(describing: CallRecord.self))
|| databaseChanges.didUpdate(tableName: ThreadAssociatedData.databaseTableName)
|| databaseChanges.didUpdate(tableName: CallRecord.databaseTableName)
)
guard badgeMightBeDifferent else {
return

View File

@@ -348,7 +348,7 @@ extension LinkedDevicesTableViewController: DatabaseChangeDelegate {
AssertIsOnMainThread()
owsAssertDebug(AppReadiness.isAppReady)
guard databaseChanges.didUpdateModel(collection: OWSDevice.collection()) else {
guard databaseChanges.didUpdate(tableName: OWSDevice.databaseTableName) else {
return
}

View File

@@ -512,7 +512,7 @@ extension PaymentsDetailViewController: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
AssertIsOnMainThread()
guard databaseChanges.didUpdateModel(collection: TSPaymentModel.collection()) else {
guard databaseChanges.didUpdate(tableName: TSPaymentModel.table.tableName) else {
return
}

View File

@@ -139,7 +139,7 @@ extension PaymentsHistoryDataSource: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
AssertIsOnMainThread()
guard databaseChanges.didUpdateModel(collection: TSPaymentModel.collection()) else {
guard databaseChanges.didUpdate(tableName: TSPaymentModel.table.tableName) else {
return
}

View File

@@ -242,7 +242,7 @@ extension ChatListViewController: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
AssertIsOnMainThread()
if databaseChanges.didUpdateModel(collection: TSPaymentModel.collection()) {
if databaseChanges.didUpdate(tableName: TSPaymentModel.table.tableName) {
updateUnreadPaymentNotificationsCountWithSneakyTransaction()
}

View File

@@ -1129,7 +1129,7 @@ extension ConversationSettingsViewController: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
AssertIsOnMainThread()
if databaseChanges.didUpdateModel(collection: TSGroupMember.collection()) {
if databaseChanges.didUpdate(tableName: TSGroupMember.databaseTableName) {
updateMutualGroupThreads()
updateTableContents()
}

View File

@@ -180,15 +180,16 @@ extension OWSDisappearingMessagesConfigurationSerializer {
static var enabledColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "enabled", columnType: .int) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: OWSDisappearingMessagesConfiguration.collection(),
tableName: "model_OWSDisappearingMessagesConfiguration",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
durationSecondsColumn,
enabledColumn
])
SDSTableMetadata(
tableName: "model_OWSDisappearingMessagesConfiguration",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
durationSecondsColumn,
enabledColumn,
]
)
}
}

View File

@@ -660,36 +660,37 @@ extension TSThreadSerializer {
static var editTargetTimestampColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "editTargetTimestamp", columnType: .int64, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: TSThread.collection(),
tableName: "model_TSThread",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
conversationColorNameObsoleteColumn,
creationDateColumn,
isArchivedObsoleteColumn,
lastInteractionRowIdColumn,
messageDraftColumn,
mutedUntilDateObsoleteColumn,
shouldThreadBeVisibleColumn,
contactPhoneNumberColumn,
contactUUIDColumn,
groupModelColumn,
hasDismissedOffersColumn,
isMarkedUnreadObsoleteColumn,
lastVisibleSortIdOnScreenPercentageObsoleteColumn,
lastVisibleSortIdObsoleteColumn,
messageDraftBodyRangesColumn,
mentionNotificationModeColumn,
mutedUntilTimestampObsoleteColumn,
allowsRepliesColumn,
lastSentStoryTimestampColumn,
nameColumn,
addressesColumn,
storyViewModeColumn,
editTargetTimestampColumn
])
SDSTableMetadata(
tableName: "model_TSThread",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
conversationColorNameObsoleteColumn,
creationDateColumn,
isArchivedObsoleteColumn,
lastInteractionRowIdColumn,
messageDraftColumn,
mutedUntilDateObsoleteColumn,
shouldThreadBeVisibleColumn,
contactPhoneNumberColumn,
contactUUIDColumn,
groupModelColumn,
hasDismissedOffersColumn,
isMarkedUnreadObsoleteColumn,
lastVisibleSortIdOnScreenPercentageObsoleteColumn,
lastVisibleSortIdObsoleteColumn,
messageDraftBodyRangesColumn,
mentionNotificationModeColumn,
mutedUntilTimestampObsoleteColumn,
allowsRepliesColumn,
lastSentStoryTimestampColumn,
nameColumn,
addressesColumn,
storyViewModeColumn,
editTargetTimestampColumn,
]
)
}
}

View File

@@ -42,11 +42,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation TSThread
+ (NSString *)collection
{
return @"TSThread";
}
- (instancetype)initWithUniqueId:(NSString *)uniqueId
{
self = [super initWithUniqueId:uniqueId];

View File

@@ -55,6 +55,10 @@ public extension TSThread {
return true
}
var transactionFinalizationKey: String {
return "\(Self.table.tableName).\(self.uniqueId)"
}
@available(swift, obsoleted: 1.0)
func canSendChatMessagesToThread() -> Bool {
canSendChatMessagesToThread(ignoreAnnouncementOnly: false)

View File

@@ -1276,7 +1276,7 @@ public class AppSetup {
SSKEnvironment.setShared(sskEnvironment, isRunningTests: appContext.isRunningTests)
// Register renamed classes.
NSKeyedUnarchiver.setClass(OWSUserProfile.self, forClassName: OWSUserProfile.collection())
NSKeyedUnarchiver.setClass(OWSUserProfile.self, forClassName: "OWSUserProfile")
NSKeyedUnarchiver.setClass(TSGroupModelV2.self, forClassName: "TSGroupModelV2")
NSKeyedUnarchiver.setClass(PendingProfileUpdate.self, forClassName: "SignalMessaging.PendingProfileUpdate")

View File

@@ -562,42 +562,43 @@ extension TSAttachmentSerializer {
static var clientUuidColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "clientUuid", columnType: .unicodeString, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: TSAttachment.collection(),
tableName: "model_TSAttachment",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
albumMessageIdColumn,
attachmentTypeColumn,
blurHashColumn,
byteCountColumn,
captionColumn,
contentTypeColumn,
encryptionKeyColumn,
serverIdColumn,
sourceFilenameColumn,
cachedAudioDurationSecondsColumn,
cachedImageHeightColumn,
cachedImageWidthColumn,
creationTimestampColumn,
digestColumn,
isUploadedColumn,
isValidImageCachedColumn,
isValidVideoCachedColumn,
lazyRestoreFragmentIdColumn,
localRelativeFilePathColumn,
mediaSizeColumn,
pointerTypeColumn,
stateColumn,
uploadTimestampColumn,
cdnKeyColumn,
cdnNumberColumn,
isAnimatedCachedColumn,
attachmentSchemaVersionColumn,
videoDurationColumn,
clientUuidColumn
])
SDSTableMetadata(
tableName: "model_TSAttachment",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
albumMessageIdColumn,
attachmentTypeColumn,
blurHashColumn,
byteCountColumn,
captionColumn,
contentTypeColumn,
encryptionKeyColumn,
serverIdColumn,
sourceFilenameColumn,
cachedAudioDurationSecondsColumn,
cachedImageHeightColumn,
cachedImageWidthColumn,
creationTimestampColumn,
digestColumn,
isUploadedColumn,
isValidImageCachedColumn,
isValidVideoCachedColumn,
lazyRestoreFragmentIdColumn,
localRelativeFilePathColumn,
mediaSizeColumn,
pointerTypeColumn,
stateColumn,
uploadTimestampColumn,
cdnKeyColumn,
cdnNumberColumn,
isAnimatedCachedColumn,
attachmentSchemaVersionColumn,
videoDurationColumn,
clientUuidColumn,
]
)
}
}

View File

@@ -294,11 +294,6 @@ NSUInteger const TSAttachmentSchemaVersion = 1;
// TSAttachmentStream.
}
+ (NSString *)collection
{
return @"TSAttachements";
}
- (NSString *)previewText
{
NSString *attachmentString;

View File

@@ -5912,84 +5912,85 @@ extension TSInteractionSerializer {
static var archivedPaymentInfoColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "archivedPaymentInfo", columnType: .blob, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: TSInteraction.collection(),
tableName: "model_TSInteraction",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
receivedAtTimestampColumn,
timestampColumn,
uniqueThreadIdColumn,
attachmentIdsColumn,
authorIdColumn,
authorPhoneNumberColumn,
authorUUIDColumn,
bodyColumn,
callTypeColumn,
configurationDurationSecondsColumn,
configurationIsEnabledColumn,
contactShareColumn,
createdByRemoteNameColumn,
createdInExistingGroupColumn,
customMessageColumn,
envelopeDataColumn,
errorTypeColumn,
expireStartedAtColumn,
expiresAtColumn,
expiresInSecondsColumn,
groupMetaMessageColumn,
hasLegacyMessageStateColumn,
hasSyncedTranscriptColumn,
wasNotCreatedLocallyColumn,
isLocalChangeColumn,
isViewOnceCompleteColumn,
isViewOnceMessageColumn,
isVoiceMessageColumn,
legacyMessageStateColumn,
legacyWasDeliveredColumn,
linkPreviewColumn,
messageIdColumn,
messageStickerColumn,
messageTypeColumn,
mostRecentFailureTextColumn,
preKeyBundleColumn,
protocolVersionColumn,
quotedMessageColumn,
readColumn,
recipientAddressColumn,
recipientAddressStatesColumn,
senderColumn,
serverTimestampColumn,
deprecated_sourceDeviceIdColumn,
storedMessageStateColumn,
storedShouldStartExpireTimerColumn,
unregisteredAddressColumn,
verificationStateColumn,
wasReceivedByUDColumn,
infoMessageUserInfoColumn,
wasRemotelyDeletedColumn,
bodyRangesColumn,
offerTypeColumn,
serverDeliveryTimestampColumn,
eraIdColumn,
hasEndedColumn,
creatorUuidColumn,
joinedMemberUuidsColumn,
wasIdentityVerifiedColumn,
paymentCancellationColumn,
paymentNotificationColumn,
paymentRequestColumn,
viewedColumn,
serverGuidColumn,
storyAuthorUuidStringColumn,
storyTimestampColumn,
isGroupStoryReplyColumn,
storyReactionEmojiColumn,
giftBadgeColumn,
editStateColumn,
archivedPaymentInfoColumn
])
SDSTableMetadata(
tableName: "model_TSInteraction",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
receivedAtTimestampColumn,
timestampColumn,
uniqueThreadIdColumn,
attachmentIdsColumn,
authorIdColumn,
authorPhoneNumberColumn,
authorUUIDColumn,
bodyColumn,
callTypeColumn,
configurationDurationSecondsColumn,
configurationIsEnabledColumn,
contactShareColumn,
createdByRemoteNameColumn,
createdInExistingGroupColumn,
customMessageColumn,
envelopeDataColumn,
errorTypeColumn,
expireStartedAtColumn,
expiresAtColumn,
expiresInSecondsColumn,
groupMetaMessageColumn,
hasLegacyMessageStateColumn,
hasSyncedTranscriptColumn,
wasNotCreatedLocallyColumn,
isLocalChangeColumn,
isViewOnceCompleteColumn,
isViewOnceMessageColumn,
isVoiceMessageColumn,
legacyMessageStateColumn,
legacyWasDeliveredColumn,
linkPreviewColumn,
messageIdColumn,
messageStickerColumn,
messageTypeColumn,
mostRecentFailureTextColumn,
preKeyBundleColumn,
protocolVersionColumn,
quotedMessageColumn,
readColumn,
recipientAddressColumn,
recipientAddressStatesColumn,
senderColumn,
serverTimestampColumn,
deprecated_sourceDeviceIdColumn,
storedMessageStateColumn,
storedShouldStartExpireTimerColumn,
unregisteredAddressColumn,
verificationStateColumn,
wasReceivedByUDColumn,
infoMessageUserInfoColumn,
wasRemotelyDeletedColumn,
bodyRangesColumn,
offerTypeColumn,
serverDeliveryTimestampColumn,
eraIdColumn,
hasEndedColumn,
creatorUuidColumn,
joinedMemberUuidsColumn,
wasIdentityVerifiedColumn,
paymentCancellationColumn,
paymentNotificationColumn,
paymentRequestColumn,
viewedColumn,
serverGuidColumn,
storyAuthorUuidStringColumn,
storyTimestampColumn,
isGroupStoryReplyColumn,
storyReactionEmojiColumn,
giftBadgeColumn,
editStateColumn,
archivedPaymentInfoColumn,
]
)
}
}

View File

@@ -54,11 +54,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
@implementation TSInteraction
+ (NSString *)collection
{
return @"TSInteraction";
}
- (instancetype)initWithCustomUniqueId:(NSString *)uniqueId
timestamp:(uint64_t)timestamp
receivedAtTimestamp:(uint64_t)receivedAtTimestamp

View File

@@ -205,18 +205,19 @@ extension OWSMessageContentJobSerializer {
static var serverDeliveryTimestampColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "serverDeliveryTimestamp", columnType: .int64) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: OWSMessageContentJob.collection(),
tableName: "model_OWSMessageContentJob",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
createdAtColumn,
envelopeDataColumn,
plaintextDataColumn,
wasReceivedByUDColumn,
serverDeliveryTimestampColumn
])
SDSTableMetadata(
tableName: "model_OWSMessageContentJob",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
createdAtColumn,
envelopeDataColumn,
plaintextDataColumn,
wasReceivedByUDColumn,
serverDeliveryTimestampColumn,
]
)
}
}

View File

@@ -10,11 +10,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSMessageContentJob
+ (NSString *)collection
{
return @"OWSBatchMessageProcessingJob";
}
- (instancetype)initWithEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
wasReceivedByUD:(BOOL)wasReceivedByUD

View File

@@ -191,16 +191,17 @@ extension InstalledStickerSerializer {
static var contentTypeColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "contentType", columnType: .unicodeString, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: InstalledSticker.collection(),
tableName: "model_InstalledSticker",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
emojiStringColumn,
infoColumn,
contentTypeColumn
])
SDSTableMetadata(
tableName: "model_InstalledSticker",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
emojiStringColumn,
infoColumn,
contentTypeColumn,
]
)
}
}

View File

@@ -192,16 +192,17 @@ extension KnownStickerPackSerializer {
static var referenceCountColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "referenceCount", columnType: .int64) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: KnownStickerPack.collection(),
tableName: "model_KnownStickerPack",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
dateCreatedColumn,
infoColumn,
referenceCountColumn
])
SDSTableMetadata(
tableName: "model_KnownStickerPack",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
dateCreatedColumn,
infoColumn,
referenceCountColumn,
]
)
}
}

View File

@@ -230,20 +230,21 @@ extension StickerPackSerializer {
static var titleColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "title", columnType: .unicodeString, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: StickerPack.collection(),
tableName: "model_StickerPack",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
authorColumn,
coverColumn,
dateCreatedColumn,
infoColumn,
isInstalledColumn,
itemsColumn,
titleColumn
])
SDSTableMetadata(
tableName: "model_StickerPack",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
authorColumn,
coverColumn,
dateCreatedColumn,
infoColumn,
isInstalledColumn,
itemsColumn,
titleColumn,
]
)
}
}

View File

@@ -99,8 +99,11 @@ public class StoryBadgeCountManager: NSObject, Dependencies {
extension StoryBadgeCountManager: DatabaseChangeDelegate {
public func databaseChangesDidUpdate(databaseChanges: DatabaseChanges) {
if databaseChanges.didUpdateModel(collection: StoryContextAssociatedData.collection()) ||
databaseChanges.didUpdateModel(collection: StoryMessage.collection()) {
let didUpdate = (
databaseChanges.didUpdate(tableName: StoryContextAssociatedData.databaseTableName)
|| databaseChanges.didUpdate(tableName: StoryMessage.databaseTableName)
)
if didUpdate {
computeBadgeCount()
}
}

View File

@@ -213,19 +213,20 @@ extension IncomingGroupsV2MessageJobSerializer {
static var serverDeliveryTimestampColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "serverDeliveryTimestamp", columnType: .int64) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: IncomingGroupsV2MessageJob.collection(),
tableName: "model_IncomingGroupsV2MessageJob",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
createdAtColumn,
envelopeDataColumn,
plaintextDataColumn,
wasReceivedByUDColumn,
groupIdColumn,
serverDeliveryTimestampColumn
])
SDSTableMetadata(
tableName: "model_IncomingGroupsV2MessageJob",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
createdAtColumn,
envelopeDataColumn,
plaintextDataColumn,
wasReceivedByUDColumn,
groupIdColumn,
serverDeliveryTimestampColumn,
]
)
}
}

View File

@@ -10,11 +10,6 @@ NS_ASSUME_NONNULL_BEGIN
@implementation IncomingGroupsV2MessageJob
+ (NSString *)collection
{
return @"IncomingGroupsV2MessageJob";
}
- (instancetype)initWithEnvelopeData:(NSData *)envelopeData
plaintextData:(NSData *_Nullable)plaintextData
groupId:(NSData *_Nullable)groupId

View File

@@ -302,27 +302,28 @@ extension TSPaymentModelSerializer {
static var interactionUniqueIdColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "interactionUniqueId", columnType: .unicodeString, isOptional: true) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: TSPaymentModel.collection(),
tableName: "model_TSPaymentModel",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
addressUuidStringColumn,
createdTimestampColumn,
isUnreadColumn,
mcLedgerBlockIndexColumn,
mcReceiptDataColumn,
mcTransactionDataColumn,
memoMessageColumn,
mobileCoinColumn,
paymentAmountColumn,
paymentFailureColumn,
paymentStateColumn,
paymentTypeColumn,
requestUuidStringColumn,
interactionUniqueIdColumn
])
SDSTableMetadata(
tableName: "model_TSPaymentModel",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
addressUuidStringColumn,
createdTimestampColumn,
isUnreadColumn,
mcLedgerBlockIndexColumn,
mcReceiptDataColumn,
mcTransactionDataColumn,
memoMessageColumn,
mobileCoinColumn,
paymentAmountColumn,
paymentFailureColumn,
paymentStateColumn,
paymentTypeColumn,
requestUuidStringColumn,
interactionUniqueIdColumn,
]
)
}
}

View File

@@ -205,18 +205,19 @@ extension OWSRecipientIdentitySerializer {
static var verificationStateColumn: SDSColumnMetadata { SDSColumnMetadata(columnName: "verificationState", columnType: .int) }
public static var table: SDSTableMetadata {
SDSTableMetadata(collection: OWSRecipientIdentity.collection(),
tableName: "model_OWSRecipientIdentity",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
accountIdColumn,
createdAtColumn,
identityKeyColumn,
isFirstKnownKeyColumn,
verificationStateColumn
])
SDSTableMetadata(
tableName: "model_OWSRecipientIdentity",
columns: [
idColumn,
recordTypeColumn,
uniqueIdColumn,
accountIdColumn,
createdAtColumn,
identityKeyColumn,
isFirstKnownKeyColumn,
verificationStateColumn,
]
)
}
}

View File

@@ -146,68 +146,6 @@ public class GRDBDatabaseStorageAdapter: NSObject {
}
}
static var tables: [SDSTableMetadata] {
[
// Models
TSThread.table,
TSInteraction.table,
StickerPack.table,
InstalledSticker.table,
KnownStickerPack.table,
TSAttachment.table,
OWSMessageContentJob.table,
OWSRecipientIdentity.table,
OWSDisappearingMessagesConfiguration.table,
IncomingGroupsV2MessageJob.table,
TSPaymentModel.table
]
}
static var swiftTables: [TableRecord.Type] {
[
ThreadAssociatedData.self,
PendingReadReceiptRecord.self,
PendingViewedReceiptRecord.self,
MediaGalleryRecord.self,
MessageSendLog.Payload.self,
MessageSendLog.Recipient.self,
MessageSendLog.Message.self,
ProfileBadge.self,
StoryMessage.self,
StoryContextAssociatedData.self,
DonationReceipt.self,
OWSReaction.self,
TSGroupMember.self,
TSMention.self,
ExperienceUpgrade.self,
CancelledGroupRing.self,
CdsPreviousE164.self,
SpamReportingTokenRecord.self,
UsernameLookupRecord.self,
JobRecord.self,
OWSDevice.self,
SignalAccount.self,
EditRecord.self,
SignalRecipient.self,
HiddenRecipient.self,
TSPaymentsActivationRequestModel.self,
CallRecord.self,
OWSUserProfile.self,
DeletedCallRecord.self,
NicknameRecord.self,
Attachment.Record.self,
AttachmentReference.MessageAttachmentReferenceRecord.self,
AttachmentReference.StoryMessageAttachmentReferenceRecord.self,
AttachmentReference.ThreadAttachmentReferenceRecord.self,
OrphanedAttachmentRecord.self,
QueuedAttachmentDownloadRecord.self,
ArchivedPayment.self,
TSAttachmentMigration.V1AttachmentReservedFileIds.self,
QueuedBackupAttachmentDownload.self,
AttachmentUploadRecord.self,
]
}
// MARK: - DatabasePathObservation
private var darwinToken: Int32?

View File

@@ -3630,7 +3630,7 @@ public class GRDBSchemaMigrator: NSObject {
let indexUpdateSql = """
DELETE FROM \(FullTextSearchIndexer.contentTableName)
WHERE \(FullTextSearchIndexer.uniqueIdColumn) IN (\(uniqueIds.map { "\"\($0)\"" }.joined(separator: ", ")))
AND \(FullTextSearchIndexer.collectionColumn) = "\(TSInteraction.collection())"
AND \(FullTextSearchIndexer.collectionColumn) = 'TSInteraction'
"""
try transaction.database.execute(sql: indexUpdateSql)
return .success(())

View File

@@ -108,12 +108,8 @@ public extension SDSCodableModel {
var grdbId: NSNumber? { id.map { NSNumber(value: $0) } }
static func collection() -> String { String(describing: self) }
var shouldBeSaved: Bool { true }
var transactionFinalizationKey: String { "\(Self.collection()).\(uniqueId)" }
var sdsTableName: String { Self.databaseTableName }
func anyWillInsert(transaction: SDSAnyWriteTransaction) {}

View File

@@ -14,16 +14,10 @@ import GRDB
@objc
public class SDSKeyValueStore: NSObject {
// Key-value stores use "collections" to group related keys.
//
// * In GRDB, we store each model in a separate table but
// all k-v stores are in a single table.
// GRDB maintains a mapping between tables and collections.
// For the purposes of this mapping only we use dataStoreCollection.
static let dataStoreCollection = "keyvalue"
static let tableName = "keyvalue"
// By default, all reads/writes use this collection.
// Key-value stores use "collections" to group related keys.
@objc
public let collection: String
@@ -31,7 +25,6 @@ public class SDSKeyValueStore: NSObject {
static let keyColumn = SDSColumnMetadata(columnName: "key", columnType: .unicodeString, isOptional: false)
static let valueColumn = SDSColumnMetadata(columnName: "value", columnType: .blob, isOptional: false)
public static let table = SDSTableMetadata(
collection: SDSKeyValueStore.dataStoreCollection,
tableName: SDSKeyValueStore.tableName,
columns: [
collectionColumn,

View File

@@ -7,8 +7,7 @@ import Foundation
import GRDB
// TODO: We need to revise this.
@objc
public enum SDSColumnType: Int32 {
public enum SDSColumnType {
case unicodeString
case blob
case bool
@@ -18,70 +17,30 @@ public enum SDSColumnType: Int32 {
case primaryKey
}
@objc
public class SDSColumnMetadata: NSObject {
public struct SDSColumnMetadata {
@objc
public let columnName: String
@objc
public let columnType: SDSColumnType
@objc
public let isOptional: Bool
@objc
public let isUnique: Bool
// If true, this column isn't needed for deserialization and can be skipped in SELECT statements.
@objc
public let skipSelect: Bool
@objc
public init(columnName: String, columnType: SDSColumnType, isOptional: Bool = false, isUnique: Bool = false, skipSelect: Bool = false) {
public init(columnName: String, columnType: SDSColumnType, isOptional: Bool = false, isUnique: Bool = false) {
self.columnName = columnName
self.columnType = columnType
self.isOptional = isOptional
self.isUnique = isUnique
self.skipSelect = skipSelect
}
}
// MARK: -
// TODO: Consider adding uniqueIdColumn field.
@objc
public class SDSTableMetadata: NSObject {
public struct SDSTableMetadata {
@objc
public let collection: String
@objc
public let tableName: String
@objc
public let columns: [SDSColumnMetadata]
public let databaseSelectionColumns: [Column]
public let selectColumnNames: [String]
@objc
public init(collection: String, tableName: String, columns: [SDSColumnMetadata]) {
self.collection = collection
public init(tableName: String, columns: [SDSColumnMetadata]) {
self.tableName = tableName
self.columns = columns
databaseSelectionColumns = columns.filter { (columMetaData) in
return !columMetaData.skipSelect
}.map { (columMetaData) in
Column(columMetaData.columnName)
}
selectColumnNames = columns.filter { !$0.skipSelect }.map { $0.columnName }
}
public var columnNames: [String] {
return columns.map { $0.columnName }
}
}

View File

@@ -21,21 +21,12 @@ public protocol DatabaseChanges {
var storyMessageDeletedUniqueIds: Set<UniqueId> { get }
var tableNames: Set<String> { get }
var collections: Set<String> { get }
var didUpdateInteractions: Bool { get }
var didUpdateThreads: Bool { get }
var didUpdateInteractionsOrThreads: Bool { get }
// Note that this method should only be used for model
// collections, not key-value stores.
func didUpdateModel(collection: String) -> Bool
// Note: In GRDB, this will return true for _any_ key-value write.
// This should be acceptable.
func didUpdate(keyValueStore: SDSKeyValueStore) -> Bool
func didUpdate(tableName: String) -> Bool
func didUpdate(interaction: TSInteraction) -> Bool

View File

@@ -15,10 +15,8 @@ public struct DatabaseChangesSnapshot: DatabaseChanges {
public let interactionDeletedUniqueIds: Set<UniqueId>
public let storyMessageDeletedUniqueIds: Set<UniqueId>
public let tableNames: Set<String>
public let collections: Set<String>
public let didUpdateInteractions: Bool
public let didUpdateThreads: Bool
public let didUpdateInteractionsOrThreads: Bool
public let lastError: Error?
@@ -31,10 +29,8 @@ public struct DatabaseChangesSnapshot: DatabaseChanges {
interactionDeletedUniqueIds: Set<UniqueId>,
storyMessageDeletedUniqueIds: Set<UniqueId>,
tableNames: Set<String>,
collections: Set<String>,
didUpdateInteractions: Bool,
didUpdateThreads: Bool,
didUpdateInteractionsOrThreads: Bool,
lastError: Error?
) {
self.threadUniqueIds = threadUniqueIds
@@ -45,10 +41,8 @@ public struct DatabaseChangesSnapshot: DatabaseChanges {
self.interactionDeletedUniqueIds = interactionDeletedUniqueIds
self.storyMessageDeletedUniqueIds = storyMessageDeletedUniqueIds
self.tableNames = tableNames
self.collections = collections
self.didUpdateInteractions = didUpdateInteractions
self.didUpdateThreads = didUpdateThreads
self.didUpdateInteractionsOrThreads = didUpdateInteractionsOrThreads
self.lastError = lastError
}
@@ -61,22 +55,11 @@ public struct DatabaseChangesSnapshot: DatabaseChanges {
interactionDeletedUniqueIds.isEmpty &&
storyMessageDeletedUniqueIds.isEmpty &&
tableNames.isEmpty &&
collections.isEmpty &&
lastError == nil
}
private func didUpdate(collection: String) -> Bool {
collections.contains(collection)
}
public func didUpdateModel(collection: String) -> Bool {
return didUpdate(collection: collection)
}
public func didUpdate(keyValueStore: SDSKeyValueStore) -> Bool {
// GRDB: SDSKeyValueStore.dataStoreCollection
return (didUpdate(collection: keyValueStore.collection) ||
didUpdate(collection: SDSKeyValueStore.dataStoreCollection))
public func didUpdate(tableName: String) -> Bool {
return tableNames.contains(tableName)
}
public func didUpdate(interaction: TSInteraction) -> Bool {

View File

@@ -45,27 +45,13 @@ class ObservedDatabaseChanges: NSObject {
checkConcurrency()
#endif
return (_collections.isEmpty &&
_tableNames.isEmpty &&
threads.isEmpty &&
interactions.isEmpty &&
storyMessages.isEmpty &&
_lastError == nil)
}
// MARK: - Collections
private var _collections: Set<String> = Set()
func insert(collection: String) {
formUnion(collections: [collection])
}
func formUnion(collections: Set<String>) {
#if TESTABLE_BUILD
checkConcurrency()
#endif
_collections.formUnion(collections)
return (
_tableNames.isEmpty
&& threads.isEmpty
&& interactions.isEmpty
&& storyMessages.isEmpty
&& _lastError == nil
)
}
// MARK: - Table Names
@@ -417,10 +403,8 @@ extension ObservedDatabaseChanges {
let interactionDeletedUniqueIds: Set<UniqueId> = interactions.deletedUniqueIds.keys
let storyMessageDeletedUniqueIds: Set<UniqueId> = storyMessages.deletedUniqueIds.keys
let tableNames: Set<String> = _tableNames
let collections: Set<String> = _collections
let didUpdateInteractions: Bool = collections.contains(TSInteraction.collection())
let didUpdateThreads: Bool = collections.contains(TSThread.collection())
let didUpdateInteractionsOrThreads: Bool = didUpdateInteractions || didUpdateThreads
let didUpdateInteractions: Bool = tableNames.contains(TSInteraction.table.tableName)
let didUpdateThreads: Bool = tableNames.contains(TSThread.table.tableName)
let lastError = _lastError
return DatabaseChangesSnapshot(
@@ -432,10 +416,8 @@ extension ObservedDatabaseChanges {
interactionDeletedUniqueIds: interactionDeletedUniqueIds,
storyMessageDeletedUniqueIds: storyMessageDeletedUniqueIds,
tableNames: tableNames,
collections: collections,
didUpdateInteractions: didUpdateInteractions,
didUpdateThreads: didUpdateThreads,
didUpdateInteractionsOrThreads: didUpdateInteractionsOrThreads,
lastError: lastError
)
}
@@ -462,14 +444,12 @@ extension ObservedDatabaseChanges {
let interactions = self.interactions
let threads = self.threads
let storyMessages = self.storyMessages
let collections = self._collections
let tableNames = self._tableNames
lock.withLock {
committedChanges.interactions.merge(interactions)
committedChanges.threads.merge(threads)
committedChanges.storyMessages.merge(storyMessages)
committedChanges.formUnion(collections: collections)
committedChanges.formUnion(tableNames: tableNames)
}
}
@@ -512,9 +492,6 @@ extension ObservedDatabaseChanges {
uniqueIdColumnName: "\(interactionColumn: .uniqueId)"
)
)
// We need to convert db table names to "collections."
mapTableNamesToCollections()
}
private func mapRowIdsToUniqueIds(
@@ -570,35 +547,6 @@ extension ObservedDatabaseChanges {
return allUniqueIds
}
private static var tableNameToCollectionMap: [String: String] = {
var result = [String: String]()
for table in GRDBDatabaseStorageAdapter.tables {
result[table.tableName] = table.collection
}
for table in GRDBDatabaseStorageAdapter.swiftTables {
result[table.databaseTableName] = String(describing: table)
}
result[SDSKeyValueStore.tableName] = SDSKeyValueStore.dataStoreCollection
return result
}()
private func mapTableNamesToCollections() {
let tableNames = self._tableNames
guard tableNames.count > 0 else {
return
}
// If necessary, convert GRDB table names to "collections".
let tableNameToCollectionMap = Self.tableNameToCollectionMap
for tableName in tableNames {
guard let collection = tableNameToCollectionMap[tableName] else {
owsFailDebug("Unknown table: \(tableName)")
continue
}
insert(collection: collection)
}
}
}
public protocol SDSIdentifiableModel {

View File

@@ -141,6 +141,8 @@ extension FullTextSearchIndexer {
static let collectionColumn = "collection"
static let ftsContentColumn = "ftsIndexableContent"
private static let legacyCollectionName = "TSInteraction"
private static func indexableContent(for message: TSMessage, tx: SDSAnyReadTransaction) -> String? {
guard !message.isViewOnceMessage else {
// Don't index "view-once messages".
@@ -169,7 +171,7 @@ extension FullTextSearchIndexer {
VALUES
(?, ?, ?)
""",
arguments: [TSInteraction.collection(), message.uniqueId, ftsContent],
arguments: [legacyCollectionName, message.uniqueId, ftsContent],
tx: tx
)
}
@@ -186,7 +188,7 @@ extension FullTextSearchIndexer {
WHERE \(uniqueIdColumn) == ?
AND \(collectionColumn) == ?
""",
arguments: [message.uniqueId, TSInteraction.collection()],
arguments: [message.uniqueId, legacyCollectionName],
tx: tx
)
}
@@ -241,7 +243,7 @@ extension FullTextSearchIndexer {
let cursor = try Row.fetchCursor(tx.unwrapGrdbRead.database, sql: sql, arguments: [query])
while let row = try cursor.next() {
let collection: String = row[collectionColumn]
guard collection == TSInteraction.collection() else {
guard collection == legacyCollectionName else {
owsFailDebug("Found something other than a message in the FTS table")
continue
}

View File

@@ -46,21 +46,12 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
/**
* Returns the collection to which the object belongs.
*
* @return Key (string) identifying the collection
*/
+ (NSString *)collection;
// These methods should only ever be called within a GRDB write transaction.
- (void)clearRowId;
// This method is used to facilitate a database object replacement. See:
// OWSRecoverableDecryptionPlaceholder.
- (void)replaceRowId:(int64_t)rowId uniqueId:(NSString *)uniqueId;
@property (nonatomic, readonly) NSString *transactionFinalizationKey;
#pragma mark -
// GRDB TODO: As a perf optimization, we could only call these

View File

@@ -84,11 +84,6 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+ (NSString *)collection
{
return NSStringFromClass([self class]);
}
#pragma mark -
- (BOOL)shouldBeSaved
@@ -128,11 +123,6 @@ NS_ASSUME_NONNULL_BEGIN
// Do nothing.
}
- (NSString *)transactionFinalizationKey
{
return [NSString stringWithFormat:@"%@.%@", self.class.collection, self.uniqueId];
}
#pragma mark - SDSRecordDelegate
- (void)updateRowId:(int64_t)rowId

View File

@@ -63,7 +63,6 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
mockObserver.clear()
let keyValueStore = SDSKeyValueStore(collection: "test")
let otherKeyValueStore = SDSKeyValueStore(collection: "other")
self.write { transaction in
keyValueStore.setBool(true, key: "test", transaction: transaction)
}
@@ -74,12 +73,9 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
XCTAssertEqual(0, mockObserver.resetCount)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractions, false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateThreads, false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractionsOrThreads, false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: OWSDevice.collection()), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: "invalid collection name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: keyValueStore), true)
// Note: For GRDB, didUpdate(keyValueStore:) currently returns true if any key value stores was updated.
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: otherKeyValueStore), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: OWSDevice.databaseTableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: "invalid table name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: SDSKeyValueStore.tableName), true)
mockObserver.clear()
@@ -94,11 +90,9 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
XCTAssertEqual(0, mockObserver.resetCount)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractions, false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractionsOrThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: OWSDevice.collection()), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: "invalid collection name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: keyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: otherKeyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: OWSDevice.databaseTableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: "invalid table name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: SDSKeyValueStore.tableName), false)
mockObserver.clear()
@@ -120,12 +114,9 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
XCTAssertEqual(0, mockObserver.resetCount)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractions, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractionsOrThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: OWSDevice.collection()), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: "invalid collection name"), false)
// Note: For GRDB, didUpdate(keyValueStore:) currently returns true if any key value stores was updated.
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: keyValueStore), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: otherKeyValueStore), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: OWSDevice.databaseTableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: "invalid table name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: SDSKeyValueStore.tableName), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: lastMessage), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: unsavedMessage), false)
@@ -142,11 +133,9 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
XCTAssertNotNil(mockObserver.lastChange)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractions, false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractionsOrThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: OWSDevice.collection()), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: "invalid collection name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: keyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: otherKeyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: OWSDevice.databaseTableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: "invalid table name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: SDSKeyValueStore.tableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: lastMessage), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: unsavedMessage), false)
@@ -163,11 +152,9 @@ class SDSDatabaseStorageObservationTest: SSKBaseTest {
XCTAssertNotNil(mockObserver.lastChange)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractions, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateInteractionsOrThreads, true)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: OWSDevice.collection()), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdateModel(collection: "invalid collection name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: keyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(keyValueStore: otherKeyValueStore), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: OWSDevice.databaseTableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: "invalid table name"), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(tableName: SDSKeyValueStore.tableName), false)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: lastMessage), true)
XCTAssertEqual(mockObserver.lastChange?.didUpdate(interaction: unsavedMessage), false)
}

View File

@@ -254,7 +254,7 @@ extension PaymentsProcessor: DatabaseChangeDelegate {
AssertIsOnMainThread()
owsAssertDebug(AppReadiness.isAppReady)
guard databaseChanges.didUpdateModel(collection: TSPaymentModel.collection()) else {
guard databaseChanges.didUpdate(tableName: TSPaymentModel.table.tableName) else {
return
}