diff --git a/Postbox.xcodeproj/project.pbxproj b/Postbox.xcodeproj/project.pbxproj index d6d2227607..bdf7c30fc9 100644 --- a/Postbox.xcodeproj/project.pbxproj +++ b/Postbox.xcodeproj/project.pbxproj @@ -184,8 +184,6 @@ D0D511041D64D91C00A97B8A /* IpcNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D511031D64D75200A97B8A /* IpcNotifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; D0D949F31D35302600740E02 /* RandomAccessResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */; }; D0D949F51D35353900740E02 /* MappedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F41D35353900740E02 /* MappedFile.swift */; }; - D0DA44411E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */; }; - D0DA44421E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */; }; D0DA44481E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; }; D0DA44491E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; }; D0DF0C8F1D81A350008AEB01 /* PeerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DF0C8E1D81A350008AEB01 /* PeerView.swift */; }; @@ -200,6 +198,10 @@ D0E3A79E1B28B50400A402D9 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3A79D1B28B50400A402D9 /* Message.swift */; }; D0E3A7A21B28B7DC00A402D9 /* Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3A7A11B28B7DC00A402D9 /* Media.swift */; }; D0F019FD1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift */; }; + D0F02CDF1E99223D0065DEE2 /* Upgrades.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */; }; + D0F02CE01E99223E0065DEE2 /* Upgrades.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */; }; + D0F02CE21E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */; }; + D0F02CE31E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */; }; D0F3CC721DDE1CDC008148FA /* ItemCacheTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */; }; D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */; }; D0F53BF31E794C6700117362 /* PeerChatStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F53BF21E794C6700117362 /* PeerChatStateView.swift */; }; @@ -378,7 +380,6 @@ D0D511031D64D75200A97B8A /* IpcNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IpcNotifier.h; sourceTree = ""; }; D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomAccessResourceTests.swift; sourceTree = ""; }; D0D949F41D35353900740E02 /* MappedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappedFile.swift; sourceTree = ""; }; - D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IncrementalUpgrade.swift; sourceTree = ""; }; D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxAccess.swift; sourceTree = ""; }; D0DF0C8E1D81A350008AEB01 /* PeerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerView.swift; sourceTree = ""; }; D0E1DE141C5E1C6900C7826E /* ViewTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewTracker.swift; sourceTree = ""; }; @@ -394,6 +395,8 @@ D0E3A79D1B28B50400A402D9 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = ""; }; D0E3A7A11B28B7DC00A402D9 /* Media.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Media.swift; sourceTree = ""; }; D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMergedOperationLogView.swift; sourceTree = ""; }; + D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Upgrades.swift; sourceTree = ""; }; + D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_12to13.swift; sourceTree = ""; }; D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheTable.swift; sourceTree = ""; }; D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheMetaTable.swift; sourceTree = ""; }; D0F53BF21E794C6700117362 /* PeerChatStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatStateView.swift; sourceTree = ""; }; @@ -519,7 +522,8 @@ D0DA443F1E4C7834005FDCA7 /* Upgrade */ = { isa = PBXGroup; children = ( - D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */, + D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */, + D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */, ); name = Upgrade; sourceTree = ""; @@ -902,7 +906,6 @@ D03229EF1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */, D050F2671E4A5B5A00988324 /* TimestampBasedMessageAttributesTable.swift in Sources */, D050F2681E4A5B5A00988324 /* TimestampBasedMessageAttributesIndexTable.swift in Sources */, - D0DA44421E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */, D050F2691E4A5B5A00988324 /* MultiplePeersView.swift in Sources */, C2A315BE1E2E733900D89000 /* PeerMergedOperationLogIndexTable.swift in Sources */, C2A315BF1E2E733900D89000 /* PeerMergedOperationLogView.swift in Sources */, @@ -994,6 +997,7 @@ D0F7B1C01E045C62007EB8A5 /* StringIndexTokens.swift in Sources */, D0F7B1CA1E045C6A007EB8A5 /* MessageHistoryUnsentTable.swift in Sources */, D0BEAF6B1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */, + D0F02CE01E99223E0065DEE2 /* Upgrades.swift in Sources */, D0F7B1D01E045C6A007EB8A5 /* KeychainTable.swift in Sources */, D0BEAF6E1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */, D0B4184F1D7DFE20004562A4 /* ChatListHolesView.swift in Sources */, @@ -1007,6 +1011,7 @@ D0B418321D7DFE16004562A4 /* SqliteValueBox.swift in Sources */, D073CE741DCBF3B4007511FD /* Peer.swift in Sources */, D073CE7A1DCBF3B4007511FD /* PeerReadState.swift in Sources */, + D0F02CE31E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */, D073CE801DCBF3B4007511FD /* PeerChatInterfaceState.swift in Sources */, D0F7B1C81E045C6A007EB8A5 /* MessageHistoryOperation.swift in Sources */, D0B844031DAB91A7005F29E1 /* PeerView.swift in Sources */, @@ -1024,7 +1029,6 @@ D03229EE1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */, D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */, D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */, - D0DA44411E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */, D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */, D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */, D0F9E86F1C5A0E7600037222 /* KeychainTable.swift in Sources */, @@ -1116,6 +1120,7 @@ D08775031E3E3E7400A97350 /* PreferencesEntry.swift in Sources */, D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */, D0BEAF6A1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */, + D0F02CDF1E99223D0065DEE2 /* Upgrades.swift in Sources */, D08775001E3E3D9F00A97350 /* PreferencesTable.swift in Sources */, D0BEAF6D1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */, D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */, @@ -1129,6 +1134,7 @@ D0C735281C864DF300BB3149 /* PeerChatStateTable.swift in Sources */, D0AAD1B31E3266B100D5B9DE /* TimestampBasedMessageAttributesTable.swift in Sources */, D01F7D9B1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift in Sources */, + D0F02CE21E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */, D055BD331B7D3D2D00F06C0A /* MediaBox.swift in Sources */, D0C674CC1CBB14A700183765 /* PeerReadState.swift in Sources */, D0D510F41D63BA8400A97B8A /* PostboxTransaction.swift in Sources */, diff --git a/Postbox/IncrementalUpgrade.swift b/Postbox/IncrementalUpgrade.swift deleted file mode 100644 index e8431d30b2..0000000000 --- a/Postbox/IncrementalUpgrade.swift +++ /dev/null @@ -1,10 +0,0 @@ -import Foundation -#if os(macOS) - import SwiftSignalKitMac -#else - import SwiftSignalKit -#endif - -protocol IncrementalUpgrade { - func upgrade(from previous: ValueBox, tmpBasePath: String) -> Signal -} diff --git a/Postbox/PeerMergedOperationLogIndexTable.swift b/Postbox/PeerMergedOperationLogIndexTable.swift index a7cc240f14..e3a4762c4f 100644 --- a/Postbox/PeerMergedOperationLogIndexTable.swift +++ b/Postbox/PeerMergedOperationLogIndexTable.swift @@ -33,18 +33,20 @@ final class PeerMergedOperationLogIndexTable: Table { func remove(tag: PeerOperationLogTag, mergedIndices: [Int32]) { for index in mergedIndices { + assert(self.valueBox.exists(self.table, key: self.key(tag: tag, index: index))) self.valueBox.remove(self.table, key: self.key(tag: tag, index: index)) } } - func getTagLocalIndices(tag: PeerOperationLogTag, fromMergedIndex: Int32, limit: Int) -> [(PeerId, Int32)] { - var result: [(PeerId, Int32)] = [] + func getTagLocalIndices(tag: PeerOperationLogTag, fromMergedIndex: Int32, limit: Int) -> [(PeerId, Int32, Int32)] { + var result: [(PeerId, Int32, Int32)] = [] self.valueBox.range(self.table, start: self.key(tag: tag, index: fromMergedIndex == 0 ? 0 : fromMergedIndex - 1), end: self.key(tag: tag, index: Int32.max), values: { key, value in + assert(key.getUInt8(0) == tag.rawValue) var peerIdValue: Int64 = 0 var tagLocalIndexValue: Int32 = 0 value.read(&peerIdValue, offset: 0, length: 8) value.read(&tagLocalIndexValue, offset: 0, length: 4) - result.append((PeerId(peerIdValue), tagLocalIndexValue)) + result.append((PeerId(peerIdValue), tagLocalIndexValue, key.getInt32(1))) return true }, limit: limit) return result diff --git a/Postbox/PeerOperationLogTable.swift b/Postbox/PeerOperationLogTable.swift index 29b9403034..0722f6fc6f 100644 --- a/Postbox/PeerOperationLogTable.swift +++ b/Postbox/PeerOperationLogTable.swift @@ -121,7 +121,7 @@ final class PeerOperationLogTable: Table { private func key(peerId: PeerId, tag: PeerOperationLogTag, index: Int32) -> ValueBoxKey { let key = ValueBoxKey(length: 8 + 1 + 4) key.setInt64(0, value: peerId.toInt64()) - key.setUInt8(1, value: tag.rawValue) + key.setUInt8(8, value: tag.rawValue) key.setInt32(9, value: index) return key } @@ -249,7 +249,7 @@ final class PeerOperationLogTable: Table { func getMergedEntries(tag: PeerOperationLogTag, fromIndex: Int32, limit: Int) -> [PeerMergedOperationLogEntry] { var entries: [PeerMergedOperationLogEntry] = [] - for (peerId, tagLocalIndex) in self.mergedIndexTable.getTagLocalIndices(tag: tag, fromMergedIndex: fromIndex, limit: limit) { + for (peerId, tagLocalIndex, mergedIndex) in self.mergedIndexTable.getTagLocalIndices(tag: tag, fromMergedIndex: fromIndex, limit: limit) { if let value = self.valueBox.get(self.table, key: self.key(peerId: peerId, tag: tag, index: tagLocalIndex)) { if let entry = parseMergedEntry(peerId: peerId, tag: tag, tagLocalIndex: tagLocalIndex, value) { entries.append(entry) @@ -257,6 +257,7 @@ final class PeerOperationLogTable: Table { assertionFailure() } } else { + self.mergedIndexTable.remove(tag: tag, mergedIndices: [mergedIndex]) assertionFailure() } } @@ -334,10 +335,12 @@ final class PeerOperationLogTable: Table { encoder.encodeRootObject(contents) } let contentBuffer = encoder.readBufferNoCopy() - var contentBufferLength: Int32 = Int32(contentBuffer.length) - buffer.write(&contentBufferLength, offset: 0, length: 4) - buffer.write(contentBuffer.memory, offset: 0, length: contentBuffer.length) - self.valueBox.set(self.table, key: key, value: buffer) + withExtendedLifetime(encoder, { + var contentBufferLength: Int32 = Int32(contentBuffer.length) + buffer.write(&contentBufferLength, offset: 0, length: 4) + buffer.write(contentBuffer.memory, offset: 0, length: contentBuffer.length) + self.valueBox.set(self.table, key: key, value: buffer) + }) } } else { assertionFailure() diff --git a/Postbox/Postbox.swift b/Postbox/Postbox.swift index 499be08744..cc9ee81aeb 100644 --- a/Postbox/Postbox.swift +++ b/Postbox/Postbox.swift @@ -552,24 +552,69 @@ fileprivate class PipeNotifier: NSObject { } } +public enum PostboxResult { + case upgrading + case postbox(Postbox) +} + +public func openPostbox(basePath: String, globalMessageIdsNamespace: MessageId.Namespace, seedConfiguration: SeedConfiguration) -> Signal { + let queue = Queue(name: "org.telegram.postbox.Postbox") + return Signal { subscriber in + queue.async { + let _ = try? FileManager.default.createDirectory(atPath: basePath, withIntermediateDirectories: true, attributes: nil) + + loop: while true { + let valueBox = SqliteValueBox(basePath: basePath + "/db", queue: queue) + + let metadataTable = MetadataTable(valueBox: valueBox, table: MetadataTable.tableSpec(0)) + + let userVersion: Int32? = metadataTable.userVersion() + let currentUserVersion: Int32 = 13 + + if let userVersion = userVersion { + if userVersion != currentUserVersion { + if let operation = registeredUpgrades()[userVersion] { + switch operation { + case let .inplace(f): + valueBox.begin() + f(metadataTable, valueBox) + valueBox.commit() + } + continue loop + } else { + assertionFailure() + valueBox.drop() + } + } + } else { + metadataTable.setUserVersion(currentUserVersion) + } + + subscriber.putNext(.postbox(Postbox(queue: queue, basePath: basePath, globalMessageIdsNamespace: globalMessageIdsNamespace, seedConfiguration: seedConfiguration, valueBox: valueBox))) + subscriber.putCompletion() + break + } + } + + return EmptyDisposable + } +} + public final class Postbox { + private let queue: Queue private let seedConfiguration: SeedConfiguration private let basePath: String private let globalMessageIdsNamespace: MessageId.Namespace + private let valueBox: ValueBox private let ipcNotificationsDisposable = MetaDisposable() //private var pipeNotifier: PipeNotifier! - private let queue = Queue(name: "org.telegram.postbox.Postbox") - private var valueBox: ValueBox! - private var transactionStateVersion: Int64 = 0 private var viewTracker: ViewTracker! private var nextViewId = 0 - private var peerPipes: [PeerId: ValuePipe] = [:] - private var currentUpdatedState: Coding? private var currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]] = [:] private var currentUpdatedChatListInclusions: [PeerId: PeerChatListInclusion] = [:] @@ -597,7 +642,7 @@ public final class Postbox { private var currentReplacedContactPeerIds: Set? private var currentUpdatedMasterClientId: Int64? - private var statePipe: ValuePipe = ValuePipe() + private let statePipe: ValuePipe = ValuePipe() private var masterClientId = Promise() private var sessionClientId: Int64 = { @@ -608,60 +653,62 @@ public final class Postbox { public let mediaBox: MediaBox - var tables: [Table] = [] + let tables: [Table] - var metadataTable: MetadataTable! - var keychainTable: KeychainTable! - var peerTable: PeerTable! - var peerNotificationSettingsTable: PeerNotificationSettingsTable! - var cachedPeerDataTable: CachedPeerDataTable! - var peerPresenceTable: PeerPresenceTable! - var globalMessageIdsTable: GlobalMessageIdsTable! - var globallyUniqueMessageIdsTable: MessageGloballyUniqueIdTable! - var messageHistoryIndexTable: MessageHistoryIndexTable! - var messageHistoryTable: MessageHistoryTable! - var mediaTable: MessageMediaTable! - var chatListIndexTable: ChatListIndexTable! - var chatListTable: ChatListTable! - var messageHistoryMetadataTable: MessageHistoryMetadataTable! - var messageHistoryUnsentTable: MessageHistoryUnsentTable! - var messageHistoryTagsTable: MessageHistoryTagsTable! - var peerChatStateTable: PeerChatStateTable! - var readStateTable: MessageHistoryReadStateTable! - var synchronizeReadStateTable: MessageHistorySynchronizeReadStateTable! - var contactsTable: ContactTable! - var itemCollectionInfoTable: ItemCollectionInfoTable! - var itemCollectionItemTable: ItemCollectionItemTable! - var itemCollectionReverseIndexTable: ReverseIndexReferenceTable! - var peerChatInterfaceStateTable: PeerChatInterfaceStateTable! - var itemCacheMetaTable: ItemCacheMetaTable! - var itemCacheTable: ItemCacheTable! - var peerNameTokenIndexTable: ReverseIndexReferenceTable! - var peerNameIndexTable: PeerNameIndexTable! - var peerChatTopTaggedMessageIdsTable: PeerChatTopTaggedMessageIdsTable! - var peerOperationLogMetadataTable: PeerOperationLogMetadataTable! - var peerMergedOperationLogIndexTable: PeerMergedOperationLogIndexTable! - var peerOperationLogTable: PeerOperationLogTable! - var timestampBasedMessageAttributesTable: TimestampBasedMessageAttributesTable! - var timestampBasedMessageAttributesIndexTable: TimestampBasedMessageAttributesIndexTable! - var preferencesTable: PreferencesTable! - var orderedItemListTable: OrderedItemListTable! - var orderedItemListIndexTable: OrderedItemListIndexTable! + let metadataTable: MetadataTable + let keychainTable: KeychainTable + let peerTable: PeerTable + let peerNotificationSettingsTable: PeerNotificationSettingsTable + let cachedPeerDataTable: CachedPeerDataTable + let peerPresenceTable: PeerPresenceTable + let globalMessageIdsTable: GlobalMessageIdsTable + let globallyUniqueMessageIdsTable: MessageGloballyUniqueIdTable + let messageHistoryIndexTable: MessageHistoryIndexTable + let messageHistoryTable: MessageHistoryTable + let mediaTable: MessageMediaTable + let chatListIndexTable: ChatListIndexTable + let chatListTable: ChatListTable + let messageHistoryMetadataTable: MessageHistoryMetadataTable + let messageHistoryUnsentTable: MessageHistoryUnsentTable + let messageHistoryTagsTable: MessageHistoryTagsTable + let peerChatStateTable: PeerChatStateTable + let readStateTable: MessageHistoryReadStateTable + let synchronizeReadStateTable: MessageHistorySynchronizeReadStateTable + let contactsTable: ContactTable + let itemCollectionInfoTable: ItemCollectionInfoTable + let itemCollectionItemTable: ItemCollectionItemTable + let itemCollectionReverseIndexTable: ReverseIndexReferenceTable + let peerChatInterfaceStateTable: PeerChatInterfaceStateTable + let itemCacheMetaTable: ItemCacheMetaTable + let itemCacheTable: ItemCacheTable + let peerNameTokenIndexTable: ReverseIndexReferenceTable + let peerNameIndexTable: PeerNameIndexTable + let peerChatTopTaggedMessageIdsTable: PeerChatTopTaggedMessageIdsTable + let peerOperationLogMetadataTable: PeerOperationLogMetadataTable + let peerMergedOperationLogIndexTable: PeerMergedOperationLogIndexTable + let peerOperationLogTable: PeerOperationLogTable + let timestampBasedMessageAttributesTable: TimestampBasedMessageAttributesTable + let timestampBasedMessageAttributesIndexTable: TimestampBasedMessageAttributesIndexTable + let preferencesTable: PreferencesTable + let orderedItemListTable: OrderedItemListTable + let orderedItemListIndexTable: OrderedItemListIndexTable //temporary - var peerRatingTable: RatingTable! + let peerRatingTable: RatingTable - public init(basePath: String, globalMessageIdsNamespace: MessageId.Namespace, seedConfiguration: SeedConfiguration) { + fileprivate init(queue: Queue, basePath: String, globalMessageIdsNamespace: MessageId.Namespace, seedConfiguration: SeedConfiguration, valueBox: ValueBox) { + assert(queue.isCurrent()) + + self.queue = queue self.basePath = basePath self.globalMessageIdsNamespace = globalMessageIdsNamespace self.seedConfiguration = seedConfiguration print("MediaBox path: \(self.basePath + "/media")") - //let _ = try? FileManager.default.removeItem(atPath: self.basePath) - self.mediaBox = MediaBox(basePath: self.basePath + "/media") + self.valueBox = valueBox /*self.pipeNotifier = PipeNotifier(basePath: basePath, notify: { [weak self] in //if let strongSelf = self { @@ -674,7 +721,117 @@ public final class Postbox { //} })*/ - self.openDatabase() + let startTime = CFAbsoluteTimeGetCurrent() + + self.metadataTable = MetadataTable(valueBox: self.valueBox, table: MetadataTable.tableSpec(0)) + + self.keychainTable = KeychainTable(valueBox: self.valueBox, table: KeychainTable.tableSpec(1)) + self.peerTable = PeerTable(valueBox: self.valueBox, table: PeerTable.tableSpec(2)) + self.globalMessageIdsTable = GlobalMessageIdsTable(valueBox: self.valueBox, table: GlobalMessageIdsTable.tableSpec(3), namespace: self.globalMessageIdsNamespace) + self.globallyUniqueMessageIdsTable = MessageGloballyUniqueIdTable(valueBox: self.valueBox, table: MessageGloballyUniqueIdTable.tableSpec(32)) + self.messageHistoryMetadataTable = MessageHistoryMetadataTable(valueBox: self.valueBox, table: MessageHistoryMetadataTable.tableSpec(10)) + self.messageHistoryUnsentTable = MessageHistoryUnsentTable(valueBox: self.valueBox, table: MessageHistoryUnsentTable.tableSpec(11)) + self.messageHistoryTagsTable = MessageHistoryTagsTable(valueBox: self.valueBox, table: MessageHistoryTagsTable.tableSpec(12)) + self.messageHistoryIndexTable = MessageHistoryIndexTable(valueBox: self.valueBox, table: MessageHistoryIndexTable.tableSpec(4), globalMessageIdsTable: self.globalMessageIdsTable, metadataTable: self.messageHistoryMetadataTable, seedConfiguration: self.seedConfiguration) + self.mediaTable = MessageMediaTable(valueBox: self.valueBox, table: MessageMediaTable.tableSpec(6)) + self.readStateTable = MessageHistoryReadStateTable(valueBox: self.valueBox, table: MessageHistoryReadStateTable.tableSpec(14)) + self.synchronizeReadStateTable = MessageHistorySynchronizeReadStateTable(valueBox: self.valueBox, table: MessageHistorySynchronizeReadStateTable.tableSpec(15)) + self.timestampBasedMessageAttributesIndexTable = TimestampBasedMessageAttributesIndexTable(valueBox: self.valueBox, table: TimestampBasedMessageAttributesTable.tableSpec(33)) + self.timestampBasedMessageAttributesTable = TimestampBasedMessageAttributesTable(valueBox: self.valueBox, table: TimestampBasedMessageAttributesTable.tableSpec(34), indexTable: self.timestampBasedMessageAttributesIndexTable) + self.messageHistoryTable = MessageHistoryTable(valueBox: self.valueBox, table: MessageHistoryTable.tableSpec(7), messageHistoryIndexTable: self.messageHistoryIndexTable, messageMediaTable: self.mediaTable, historyMetadataTable: self.messageHistoryMetadataTable, globallyUniqueMessageIdsTable: self.globallyUniqueMessageIdsTable, unsentTable: self.messageHistoryUnsentTable, tagsTable: self.messageHistoryTagsTable, readStateTable: self.readStateTable, synchronizeReadStateTable: self.synchronizeReadStateTable) + self.peerChatStateTable = PeerChatStateTable(valueBox: self.valueBox, table: PeerChatStateTable.tableSpec(13)) + self.peerNameTokenIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(26)) + self.peerNameIndexTable = PeerNameIndexTable(valueBox: self.valueBox, table: PeerNameIndexTable.tableSpec(27), peerTable: self.peerTable, peerNameTokenIndexTable: self.peerNameTokenIndexTable) + self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16), peerNameIndexTable: self.peerNameIndexTable) + self.peerRatingTable = RatingTable(valueBox: self.valueBox, table: RatingTable.tableSpec(17)) + self.cachedPeerDataTable = CachedPeerDataTable(valueBox: self.valueBox, table: CachedPeerDataTable.tableSpec(18)) + self.peerNotificationSettingsTable = PeerNotificationSettingsTable(valueBox: self.valueBox, table: PeerNotificationSettingsTable.tableSpec(19)) + self.peerPresenceTable = PeerPresenceTable(valueBox: self.valueBox, table: PeerPresenceTable.tableSpec(20)) + self.itemCollectionInfoTable = ItemCollectionInfoTable(valueBox: self.valueBox, table: ItemCollectionInfoTable.tableSpec(21)) + self.itemCollectionReverseIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(36)) + self.itemCollectionItemTable = ItemCollectionItemTable(valueBox: self.valueBox, table: ItemCollectionItemTable.tableSpec(22), reverseIndexTable: self.itemCollectionReverseIndexTable) + self.peerChatInterfaceStateTable = PeerChatInterfaceStateTable(valueBox: self.valueBox, table: PeerChatInterfaceStateTable.tableSpec(23)) + self.itemCacheMetaTable = ItemCacheMetaTable(valueBox: self.valueBox, table: ItemCacheMetaTable.tableSpec(24)) + self.itemCacheTable = ItemCacheTable(valueBox: self.valueBox, table: ItemCacheTable.tableSpec(25)) + self.chatListIndexTable = ChatListIndexTable(valueBox: self.valueBox, table: ChatListIndexTable.tableSpec(8), peerNameIndexTable: self.peerNameIndexTable, metadataTable: self.messageHistoryMetadataTable, readStateTable: self.readStateTable, notificationSettingsTable: self.peerNotificationSettingsTable) + self.chatListTable = ChatListTable(valueBox: self.valueBox, table: ChatListTable.tableSpec(9), indexTable: self.chatListIndexTable, metadataTable: self.messageHistoryMetadataTable, seedConfiguration: self.seedConfiguration) + self.peerChatTopTaggedMessageIdsTable = PeerChatTopTaggedMessageIdsTable(valueBox: self.valueBox, table: PeerChatTopTaggedMessageIdsTable.tableSpec(28)) + self.peerOperationLogMetadataTable = PeerOperationLogMetadataTable(valueBox: self.valueBox, table: PeerOperationLogMetadataTable.tableSpec(29)) + self.peerMergedOperationLogIndexTable = PeerMergedOperationLogIndexTable(valueBox: self.valueBox, table: PeerMergedOperationLogIndexTable.tableSpec(30), metadataTable: self.peerOperationLogMetadataTable) + self.peerOperationLogTable = PeerOperationLogTable(valueBox: self.valueBox, table: PeerOperationLogTable.tableSpec(31), metadataTable: self.peerOperationLogMetadataTable, mergedIndexTable: self.peerMergedOperationLogIndexTable) + self.preferencesTable = PreferencesTable(valueBox: self.valueBox, table: PreferencesTable.tableSpec(35)) + self.orderedItemListIndexTable = OrderedItemListIndexTable(valueBox: self.valueBox, table: OrderedItemListIndexTable.tableSpec(37)) + self.orderedItemListTable = OrderedItemListTable(valueBox: self.valueBox, table: OrderedItemListTable.tableSpec(38), indexTable: self.orderedItemListIndexTable) + + var tables: [Table] = [] + tables.append(self.metadataTable) + tables.append(self.keychainTable) + tables.append(self.peerTable) + tables.append(self.globalMessageIdsTable) + tables.append(self.globallyUniqueMessageIdsTable) + tables.append(self.messageHistoryMetadataTable) + tables.append(self.messageHistoryUnsentTable) + tables.append(self.messageHistoryTagsTable) + tables.append(self.messageHistoryIndexTable) + tables.append(self.mediaTable) + tables.append(self.readStateTable) + tables.append(self.synchronizeReadStateTable) + tables.append(self.messageHistoryTable) + tables.append(self.chatListIndexTable) + tables.append(self.chatListTable) + tables.append(self.peerChatStateTable) + tables.append(self.contactsTable) + tables.append(self.peerRatingTable) + tables.append(self.peerNotificationSettingsTable) + tables.append(self.cachedPeerDataTable) + tables.append(self.peerPresenceTable) + tables.append(self.itemCollectionInfoTable) + tables.append(self.itemCollectionItemTable) + tables.append(self.itemCollectionReverseIndexTable) + tables.append(self.peerChatInterfaceStateTable) + tables.append(self.itemCacheMetaTable) + tables.append(self.itemCacheTable) + tables.append(self.peerNameIndexTable) + tables.append(self.peerNameTokenIndexTable) + tables.append(self.peerChatTopTaggedMessageIdsTable) + tables.append(self.peerOperationLogMetadataTable) + tables.append(self.peerMergedOperationLogIndexTable) + tables.append(self.peerOperationLogTable) + tables.append(self.timestampBasedMessageAttributesTable) + tables.append(self.timestampBasedMessageAttributesIndexTable) + tables.append(self.preferencesTable) + tables.append(self.orderedItemListTable) + tables.append(self.orderedItemListIndexTable) + + self.tables = tables + + self.transactionStateVersion = self.metadataTable.transactionStateVersion() + + self.viewTracker = ViewTracker(queue: self.queue, fetchEarlierHistoryEntries: self.fetchEarlierHistoryEntries, fetchLaterHistoryEntries: self.fetchLaterHistoryEntries, fetchEarlierChatEntries: self.fetchEarlierChatEntries, fetchLaterChatEntries: self.fetchLaterChatEntries, fetchAnchorIndex: self.fetchAnchorIndex, renderMessage: self.renderIntermediateMessage, getPeer: { peerId in + return self.peerTable.get(peerId) + }, getPeerNotificationSettings: { peerId in + return self.peerNotificationSettingsTable.get(peerId) + }, getCachedPeerData: { peerId in + return self.cachedPeerDataTable.get(peerId) + }, getPeerPresence: { peerId in + return self.peerPresenceTable.get(peerId) + }, getTotalUnreadCount: { + return self.messageHistoryMetadataTable.getChatListTotalUnreadCount() + }, getPeerReadState: { peerId in + return self.readStateTable.getCombinedState(peerId) + }, operationLogGetOperations: { tag, fromIndex, limit in + return self.peerOperationLogTable.getMergedEntries(tag: tag, fromIndex: fromIndex, limit: limit) + }, operationLogGetTailIndex: { tag in + return self.peerMergedOperationLogIndexTable.tailIndex(tag: tag) + }, getTimestampBasedMessageAttributesHead: { tag in + return self.timestampBasedMessageAttributesTable.head(tag: tag) + }, getPreferencesEntry: { key in + return self.preferencesTable.get(key: key) + }, unsentMessageIds: self.messageHistoryUnsentTable.get(), synchronizePeerReadStateOperations: self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in + return self.readStateTable.getCombinedState(peerId) + })) + + print("(Postbox initialization took \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms") } deinit { @@ -701,140 +858,6 @@ public final class Postbox { } } - private func openDatabase() { - self.queue.justDispatch({ - let startTime = CFAbsoluteTimeGetCurrent() - - do { - try FileManager.default.createDirectory(atPath: self.basePath, withIntermediateDirectories: true, attributes: nil) - } catch _ { - } - - //let _ = try? FileManager.default.removeItem(atPath: self.basePath + "/media") - - //#if TARGET_IPHONE_SIMULATOR - - //self.debugSaveState(name: "previous") - //self.debugRestoreState(name: "previous") - - //#endif - - self.valueBox = SqliteValueBox(basePath: self.basePath + "/db", queue: self.queue) - - self.metadataTable = MetadataTable(valueBox: self.valueBox, table: MetadataTable.tableSpec(0)) - - let userVersion: Int32? = self.metadataTable.userVersion() - let currentUserVersion: Int32 = 12 - - if userVersion != currentUserVersion { - self.valueBox.drop() - self.metadataTable.setUserVersion(currentUserVersion) - } - - self.keychainTable = KeychainTable(valueBox: self.valueBox, table: KeychainTable.tableSpec(1)) - self.peerTable = PeerTable(valueBox: self.valueBox, table: PeerTable.tableSpec(2)) - self.globalMessageIdsTable = GlobalMessageIdsTable(valueBox: self.valueBox, table: GlobalMessageIdsTable.tableSpec(3), namespace: self.globalMessageIdsNamespace) - self.globallyUniqueMessageIdsTable = MessageGloballyUniqueIdTable(valueBox: self.valueBox, table: MessageGloballyUniqueIdTable.tableSpec(32)) - self.messageHistoryMetadataTable = MessageHistoryMetadataTable(valueBox: self.valueBox, table: MessageHistoryMetadataTable.tableSpec(10)) - self.messageHistoryUnsentTable = MessageHistoryUnsentTable(valueBox: self.valueBox, table: MessageHistoryUnsentTable.tableSpec(11)) - self.messageHistoryTagsTable = MessageHistoryTagsTable(valueBox: self.valueBox, table: MessageHistoryTagsTable.tableSpec(12)) - self.messageHistoryIndexTable = MessageHistoryIndexTable(valueBox: self.valueBox, table: MessageHistoryIndexTable.tableSpec(4), globalMessageIdsTable: self.globalMessageIdsTable, metadataTable: self.messageHistoryMetadataTable, seedConfiguration: self.seedConfiguration) - self.mediaTable = MessageMediaTable(valueBox: self.valueBox, table: MessageMediaTable.tableSpec(6)) - self.readStateTable = MessageHistoryReadStateTable(valueBox: self.valueBox, table: MessageHistoryReadStateTable.tableSpec(14)) - self.synchronizeReadStateTable = MessageHistorySynchronizeReadStateTable(valueBox: self.valueBox, table: MessageHistorySynchronizeReadStateTable.tableSpec(15)) - self.timestampBasedMessageAttributesIndexTable = TimestampBasedMessageAttributesIndexTable(valueBox: self.valueBox!, table: TimestampBasedMessageAttributesTable.tableSpec(33)) - self.timestampBasedMessageAttributesTable = TimestampBasedMessageAttributesTable(valueBox: self.valueBox!, table: TimestampBasedMessageAttributesTable.tableSpec(34), indexTable: self.timestampBasedMessageAttributesIndexTable) - self.messageHistoryTable = MessageHistoryTable(valueBox: self.valueBox, table: MessageHistoryTable.tableSpec(7), messageHistoryIndexTable: self.messageHistoryIndexTable, messageMediaTable: self.mediaTable, historyMetadataTable: self.messageHistoryMetadataTable, globallyUniqueMessageIdsTable: self.globallyUniqueMessageIdsTable!, unsentTable: self.messageHistoryUnsentTable!, tagsTable: self.messageHistoryTagsTable, readStateTable: self.readStateTable, synchronizeReadStateTable: self.synchronizeReadStateTable!) - self.peerChatStateTable = PeerChatStateTable(valueBox: self.valueBox, table: PeerChatStateTable.tableSpec(13)) - self.peerNameTokenIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(26)) - self.peerNameIndexTable = PeerNameIndexTable(valueBox: self.valueBox, table: PeerNameIndexTable.tableSpec(27), peerTable: self.peerTable, peerNameTokenIndexTable: self.peerNameTokenIndexTable) - self.contactsTable = ContactTable(valueBox: self.valueBox, table: ContactTable.tableSpec(16), peerNameIndexTable: self.peerNameIndexTable) - self.peerRatingTable = RatingTable(valueBox: self.valueBox, table: RatingTable.tableSpec(17)) - self.cachedPeerDataTable = CachedPeerDataTable(valueBox: self.valueBox, table: CachedPeerDataTable.tableSpec(18)) - self.peerNotificationSettingsTable = PeerNotificationSettingsTable(valueBox: self.valueBox, table: PeerNotificationSettingsTable.tableSpec(19)) - self.peerPresenceTable = PeerPresenceTable(valueBox: self.valueBox, table: PeerPresenceTable.tableSpec(20)) - self.itemCollectionInfoTable = ItemCollectionInfoTable(valueBox: self.valueBox, table: ItemCollectionInfoTable.tableSpec(21)) - self.itemCollectionReverseIndexTable = ReverseIndexReferenceTable(valueBox: self.valueBox, table: ReverseIndexReferenceTable.tableSpec(36)) - self.itemCollectionItemTable = ItemCollectionItemTable(valueBox: self.valueBox, table: ItemCollectionItemTable.tableSpec(22), reverseIndexTable: self.itemCollectionReverseIndexTable) - self.peerChatInterfaceStateTable = PeerChatInterfaceStateTable(valueBox: self.valueBox, table: PeerChatInterfaceStateTable.tableSpec(23)) - self.itemCacheMetaTable = ItemCacheMetaTable(valueBox: self.valueBox, table: ItemCacheMetaTable.tableSpec(24)) - self.itemCacheTable = ItemCacheTable(valueBox: self.valueBox, table: ItemCacheTable.tableSpec(25)) - self.chatListIndexTable = ChatListIndexTable(valueBox: self.valueBox, table: ChatListIndexTable.tableSpec(8), peerNameIndexTable: self.peerNameIndexTable, metadataTable: self.messageHistoryMetadataTable, readStateTable: self.readStateTable, notificationSettingsTable: self.peerNotificationSettingsTable) - self.chatListTable = ChatListTable(valueBox: self.valueBox, table: ChatListTable.tableSpec(9), indexTable: self.chatListIndexTable, metadataTable: self.messageHistoryMetadataTable, seedConfiguration: self.seedConfiguration) - self.peerChatTopTaggedMessageIdsTable = PeerChatTopTaggedMessageIdsTable(valueBox: self.valueBox, table: PeerChatTopTaggedMessageIdsTable.tableSpec(28)) - self.peerOperationLogMetadataTable = PeerOperationLogMetadataTable(valueBox: self.valueBox, table: PeerOperationLogMetadataTable.tableSpec(29)) - self.peerMergedOperationLogIndexTable = PeerMergedOperationLogIndexTable(valueBox: self.valueBox, table: PeerMergedOperationLogIndexTable.tableSpec(30), metadataTable: self.peerOperationLogMetadataTable!) - self.peerOperationLogTable = PeerOperationLogTable(valueBox: self.valueBox, table: PeerOperationLogTable.tableSpec(31), metadataTable: self.peerOperationLogMetadataTable, mergedIndexTable: self.peerMergedOperationLogIndexTable) - self.preferencesTable = PreferencesTable(valueBox: self.valueBox, table: PreferencesTable.tableSpec(35)) - self.orderedItemListIndexTable = OrderedItemListIndexTable(valueBox: self.valueBox, table: OrderedItemListIndexTable.tableSpec(37)) - self.orderedItemListTable = OrderedItemListTable(valueBox: self.valueBox, table: OrderedItemListTable.tableSpec(38), indexTable: self.orderedItemListIndexTable) - - self.tables.append(self.keychainTable) - self.tables.append(self.peerTable) - self.tables.append(self.globalMessageIdsTable) - self.tables.append(self.globallyUniqueMessageIdsTable) - self.tables.append(self.messageHistoryMetadataTable) - self.tables.append(self.messageHistoryUnsentTable) - self.tables.append(self.messageHistoryTagsTable) - self.tables.append(self.messageHistoryIndexTable) - self.tables.append(self.mediaTable) - self.tables.append(self.readStateTable) - self.tables.append(self.synchronizeReadStateTable) - self.tables.append(self.messageHistoryTable) - self.tables.append(self.chatListIndexTable) - self.tables.append(self.chatListTable) - self.tables.append(self.peerChatStateTable) - self.tables.append(self.contactsTable) - self.tables.append(self.peerRatingTable) - self.tables.append(self.peerNotificationSettingsTable) - self.tables.append(self.cachedPeerDataTable) - self.tables.append(self.peerPresenceTable) - self.tables.append(self.itemCollectionInfoTable) - self.tables.append(self.itemCollectionItemTable) - self.tables.append(self.itemCollectionReverseIndexTable) - self.tables.append(self.peerChatInterfaceStateTable) - self.tables.append(self.itemCacheMetaTable) - self.tables.append(self.itemCacheTable) - self.tables.append(self.peerNameIndexTable) - self.tables.append(self.peerNameTokenIndexTable) - self.tables.append(self.peerChatTopTaggedMessageIdsTable) - self.tables.append(self.peerOperationLogMetadataTable) - self.tables.append(self.peerMergedOperationLogIndexTable) - self.tables.append(self.peerOperationLogTable) - self.tables.append(self.preferencesTable) - self.tables.append(self.orderedItemListTable) - self.tables.append(self.orderedItemListIndexTable) - - self.transactionStateVersion = self.metadataTable.transactionStateVersion() - - self.viewTracker = ViewTracker(queue: self.queue, fetchEarlierHistoryEntries: self.fetchEarlierHistoryEntries, fetchLaterHistoryEntries: self.fetchLaterHistoryEntries, fetchEarlierChatEntries: self.fetchEarlierChatEntries, fetchLaterChatEntries: self.fetchLaterChatEntries, fetchAnchorIndex: self.fetchAnchorIndex, renderMessage: self.renderIntermediateMessage, getPeer: { peerId in - return self.peerTable.get(peerId) - }, getPeerNotificationSettings: { peerId in - return self.peerNotificationSettingsTable.get(peerId) - }, getCachedPeerData: { peerId in - return self.cachedPeerDataTable.get(peerId) - }, getPeerPresence: { peerId in - return self.peerPresenceTable.get(peerId) - }, getTotalUnreadCount: { - return self.messageHistoryMetadataTable.getChatListTotalUnreadCount() - }, getPeerReadState: { peerId in - return self.readStateTable.getCombinedState(peerId) - }, operationLogGetOperations: { tag, fromIndex, limit in - return self.peerOperationLogTable.getMergedEntries(tag: tag, fromIndex: fromIndex, limit: limit) - }, operationLogGetTailIndex: { tag in - return self.peerMergedOperationLogIndexTable.tailIndex(tag: tag) - }, getTimestampBasedMessageAttributesHead: { tag in - return self.timestampBasedMessageAttributesTable.head(tag: tag) - }, getPreferencesEntry: { key in - return self.preferencesTable.get(key: key) - }, unsentMessageIds: self.messageHistoryUnsentTable!.get(), synchronizePeerReadStateOperations: self.synchronizeReadStateTable!.get(getCombinedPeerReadState: { peerId in - return self.readStateTable.getCombinedState(peerId) - })) - - print("(Postbox initialization took \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms") - }) - } - private func takeNextViewId() -> Int { let nextId = self.nextViewId self.nextViewId += 1 @@ -1191,9 +1214,9 @@ public final class Postbox { table.clearMemoryCache() } self.viewTracker.refreshViewsDueToExternalTransaction(fetchAroundChatEntries: self.fetchAroundChatEntries, fetchAroundHistoryEntries: self.fetchAroundHistoryEntries, fetchUnsentMessageIds: { - return self.messageHistoryUnsentTable!.get() + return self.messageHistoryUnsentTable.get() }, fetchSynchronizePeerReadStateOperations: { - return self.synchronizeReadStateTable!.get(getCombinedPeerReadState: { peerId in + return self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in return self.readStateTable.getCombinedState(peerId) }) }) diff --git a/Postbox/PostboxUpgrade_12to13.swift b/Postbox/PostboxUpgrade_12to13.swift new file mode 100644 index 0000000000..873abb859f --- /dev/null +++ b/Postbox/PostboxUpgrade_12to13.swift @@ -0,0 +1,11 @@ +import Foundation + +func postboxUpgrade_12to13(metadataTable: MetadataTable, valueBox: ValueBox) { + // drop PeerMergedOperationLogIndexTable + valueBox.dropTable(ValueBoxTable(id: 30, keyType: .binary)) + + // drop PeerOperationLogTable + valueBox.dropTable(ValueBoxTable(id: 31, keyType: .binary)) + + metadataTable.setUserVersion(13) +} diff --git a/Postbox/SqliteInterface.swift b/Postbox/SqliteInterface.swift index 5d392f28e3..8aef02210b 100644 --- a/Postbox/SqliteInterface.swift +++ b/Postbox/SqliteInterface.swift @@ -102,9 +102,6 @@ public final class SqliteInterface { public init?(databasePath: String) { if let database = Database(databasePath) { -// if !database.execute("pragma schema_version") { -// return nil -// } self.database = database } else { return nil diff --git a/Postbox/SqliteValueBox.swift b/Postbox/SqliteValueBox.swift index 5cc4f2e4c1..d5183e31fc 100644 --- a/Postbox/SqliteValueBox.swift +++ b/Postbox/SqliteValueBox.swift @@ -1057,6 +1057,10 @@ final class SqliteValueBox: ValueBox { self.deleteStatements.removeAll() } + public func dropTable(_ table: ValueBoxTable) { + self.database.execute("REMOVE FROM t\(table.id)") + } + public func drop() { assert(self.queue.isCurrent()) self.clearStatements() diff --git a/Postbox/Upgrades.swift b/Postbox/Upgrades.swift new file mode 100644 index 0000000000..6c70a9d015 --- /dev/null +++ b/Postbox/Upgrades.swift @@ -0,0 +1,11 @@ +import Foundation + +enum PostboxUpgradeOperation { + case inplace((MetadataTable, ValueBox) -> Void) +} + +func registeredUpgrades() -> [Int32: PostboxUpgradeOperation] { + var dict: [Int32: PostboxUpgradeOperation] = [:] + dict[12] = .inplace(postboxUpgrade_12to13) + return dict +} diff --git a/Postbox/ValueBox.swift b/Postbox/ValueBox.swift index 9fe68e47b7..3dd987a8af 100644 --- a/Postbox/ValueBox.swift +++ b/Postbox/ValueBox.swift @@ -24,5 +24,6 @@ protocol ValueBox { func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer) func remove(_ table: ValueBoxTable, key: ValueBoxKey) + func dropTable(_ table: ValueBoxTable) func drop() }