Conflicts:
	Postbox/SqliteInterface.swift
This commit is contained in:
overtake 2017-04-08 18:06:22 +03:00
commit e43f479b7c
10 changed files with 261 additions and 213 deletions

View File

@ -184,8 +184,6 @@
D0D511041D64D91C00A97B8A /* IpcNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = D0D511031D64D75200A97B8A /* IpcNotifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; D0D949F31D35302600740E02 /* RandomAccessResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */; };
D0D949F51D35353900740E02 /* MappedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D949F41D35353900740E02 /* MappedFile.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 */; }; D0DA44481E4C7D1E005FDCA7 /* PostboxAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */; };
D0DA44491E4C7D1E005FDCA7 /* 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 */; }; 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 */; }; D0E3A79E1B28B50400A402D9 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3A79D1B28B50400A402D9 /* Message.swift */; };
D0E3A7A21B28B7DC00A402D9 /* Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3A7A11B28B7DC00A402D9 /* Media.swift */; }; D0E3A7A21B28B7DC00A402D9 /* Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3A7A11B28B7DC00A402D9 /* Media.swift */; };
D0F019FD1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.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 */; }; D0F3CC721DDE1CDC008148FA /* ItemCacheTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */; };
D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */; }; D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */; };
D0F53BF31E794C6700117362 /* PeerChatStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F53BF21E794C6700117362 /* PeerChatStateView.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 = "<group>"; }; D0D511031D64D75200A97B8A /* IpcNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IpcNotifier.h; sourceTree = "<group>"; };
D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomAccessResourceTests.swift; sourceTree = "<group>"; }; D0D949F21D35302600740E02 /* RandomAccessResourceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RandomAccessResourceTests.swift; sourceTree = "<group>"; };
D0D949F41D35353900740E02 /* MappedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappedFile.swift; sourceTree = "<group>"; }; D0D949F41D35353900740E02 /* MappedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappedFile.swift; sourceTree = "<group>"; };
D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IncrementalUpgrade.swift; sourceTree = "<group>"; };
D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxAccess.swift; sourceTree = "<group>"; }; D0DA44471E4C7D1E005FDCA7 /* PostboxAccess.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxAccess.swift; sourceTree = "<group>"; };
D0DF0C8E1D81A350008AEB01 /* PeerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerView.swift; sourceTree = "<group>"; }; D0DF0C8E1D81A350008AEB01 /* PeerView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerView.swift; sourceTree = "<group>"; };
D0E1DE141C5E1C6900C7826E /* ViewTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewTracker.swift; sourceTree = "<group>"; }; D0E1DE141C5E1C6900C7826E /* ViewTracker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewTracker.swift; sourceTree = "<group>"; };
@ -394,6 +395,8 @@
D0E3A79D1B28B50400A402D9 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; }; D0E3A79D1B28B50400A402D9 /* Message.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Message.swift; sourceTree = "<group>"; };
D0E3A7A11B28B7DC00A402D9 /* Media.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Media.swift; sourceTree = "<group>"; }; D0E3A7A11B28B7DC00A402D9 /* Media.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Media.swift; sourceTree = "<group>"; };
D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMergedOperationLogView.swift; sourceTree = "<group>"; }; D0F019FC1E1DA0CC00F05AB3 /* PeerMergedOperationLogView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerMergedOperationLogView.swift; sourceTree = "<group>"; };
D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Upgrades.swift; sourceTree = "<group>"; };
D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PostboxUpgrade_12to13.swift; sourceTree = "<group>"; };
D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheTable.swift; sourceTree = "<group>"; }; D0F3CC711DDE1CDC008148FA /* ItemCacheTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheTable.swift; sourceTree = "<group>"; };
D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheMetaTable.swift; sourceTree = "<group>"; }; D0F3CC731DDE1EB9008148FA /* ItemCacheMetaTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ItemCacheMetaTable.swift; sourceTree = "<group>"; };
D0F53BF21E794C6700117362 /* PeerChatStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatStateView.swift; sourceTree = "<group>"; }; D0F53BF21E794C6700117362 /* PeerChatStateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerChatStateView.swift; sourceTree = "<group>"; };
@ -519,7 +522,8 @@
D0DA443F1E4C7834005FDCA7 /* Upgrade */ = { D0DA443F1E4C7834005FDCA7 /* Upgrade */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D0DA44401E4C7868005FDCA7 /* IncrementalUpgrade.swift */, D0F02CDE1E99223D0065DEE2 /* Upgrades.swift */,
D0F02CE11E9922F50065DEE2 /* PostboxUpgrade_12to13.swift */,
); );
name = Upgrade; name = Upgrade;
sourceTree = "<group>"; sourceTree = "<group>";
@ -902,7 +906,6 @@
D03229EF1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */, D03229EF1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */,
D050F2671E4A5B5A00988324 /* TimestampBasedMessageAttributesTable.swift in Sources */, D050F2671E4A5B5A00988324 /* TimestampBasedMessageAttributesTable.swift in Sources */,
D050F2681E4A5B5A00988324 /* TimestampBasedMessageAttributesIndexTable.swift in Sources */, D050F2681E4A5B5A00988324 /* TimestampBasedMessageAttributesIndexTable.swift in Sources */,
D0DA44421E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */,
D050F2691E4A5B5A00988324 /* MultiplePeersView.swift in Sources */, D050F2691E4A5B5A00988324 /* MultiplePeersView.swift in Sources */,
C2A315BE1E2E733900D89000 /* PeerMergedOperationLogIndexTable.swift in Sources */, C2A315BE1E2E733900D89000 /* PeerMergedOperationLogIndexTable.swift in Sources */,
C2A315BF1E2E733900D89000 /* PeerMergedOperationLogView.swift in Sources */, C2A315BF1E2E733900D89000 /* PeerMergedOperationLogView.swift in Sources */,
@ -994,6 +997,7 @@
D0F7B1C01E045C62007EB8A5 /* StringIndexTokens.swift in Sources */, D0F7B1C01E045C62007EB8A5 /* StringIndexTokens.swift in Sources */,
D0F7B1CA1E045C6A007EB8A5 /* MessageHistoryUnsentTable.swift in Sources */, D0F7B1CA1E045C6A007EB8A5 /* MessageHistoryUnsentTable.swift in Sources */,
D0BEAF6B1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */, D0BEAF6B1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */,
D0F02CE01E99223E0065DEE2 /* Upgrades.swift in Sources */,
D0F7B1D01E045C6A007EB8A5 /* KeychainTable.swift in Sources */, D0F7B1D01E045C6A007EB8A5 /* KeychainTable.swift in Sources */,
D0BEAF6E1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */, D0BEAF6E1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */,
D0B4184F1D7DFE20004562A4 /* ChatListHolesView.swift in Sources */, D0B4184F1D7DFE20004562A4 /* ChatListHolesView.swift in Sources */,
@ -1007,6 +1011,7 @@
D0B418321D7DFE16004562A4 /* SqliteValueBox.swift in Sources */, D0B418321D7DFE16004562A4 /* SqliteValueBox.swift in Sources */,
D073CE741DCBF3B4007511FD /* Peer.swift in Sources */, D073CE741DCBF3B4007511FD /* Peer.swift in Sources */,
D073CE7A1DCBF3B4007511FD /* PeerReadState.swift in Sources */, D073CE7A1DCBF3B4007511FD /* PeerReadState.swift in Sources */,
D0F02CE31E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */,
D073CE801DCBF3B4007511FD /* PeerChatInterfaceState.swift in Sources */, D073CE801DCBF3B4007511FD /* PeerChatInterfaceState.swift in Sources */,
D0F7B1C81E045C6A007EB8A5 /* MessageHistoryOperation.swift in Sources */, D0F7B1C81E045C6A007EB8A5 /* MessageHistoryOperation.swift in Sources */,
D0B844031DAB91A7005F29E1 /* PeerView.swift in Sources */, D0B844031DAB91A7005F29E1 /* PeerView.swift in Sources */,
@ -1024,7 +1029,6 @@
D03229EE1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */, D03229EE1E6B33FD0000AF9C /* SqliteInterface.swift in Sources */,
D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */, D0F9E8631C579F0200037222 /* MediaCleanupTable.swift in Sources */,
D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */, D0F3CC741DDE1EB9008148FA /* ItemCacheMetaTable.swift in Sources */,
D0DA44411E4C7868005FDCA7 /* IncrementalUpgrade.swift in Sources */,
D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */, D08D451F1D5D2CA700A7428A /* RatingTable.swift in Sources */,
D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */, D07CFF831DCA909100761F81 /* PeerChatInterfaceStateTable.swift in Sources */,
D0F9E86F1C5A0E7600037222 /* KeychainTable.swift in Sources */, D0F9E86F1C5A0E7600037222 /* KeychainTable.swift in Sources */,
@ -1116,6 +1120,7 @@
D08775031E3E3E7400A97350 /* PreferencesEntry.swift in Sources */, D08775031E3E3E7400A97350 /* PreferencesEntry.swift in Sources */,
D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */, D0AB0B901D65D4AB002C78E7 /* UnsentMessageIndicesView.swift in Sources */,
D0BEAF6A1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */, D0BEAF6A1E54B5FB00BD963D /* AccountManagerMetadataTable.swift in Sources */,
D0F02CDF1E99223D0065DEE2 /* Upgrades.swift in Sources */,
D08775001E3E3D9F00A97350 /* PreferencesTable.swift in Sources */, D08775001E3E3D9F00A97350 /* PreferencesTable.swift in Sources */,
D0BEAF6D1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */, D0BEAF6D1E54B77900BD963D /* AccountManagerRecordTable.swift in Sources */,
D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */, D03120F81DA53FF4006A2A60 /* PeerPresenceTable.swift in Sources */,
@ -1129,6 +1134,7 @@
D0C735281C864DF300BB3149 /* PeerChatStateTable.swift in Sources */, D0C735281C864DF300BB3149 /* PeerChatStateTable.swift in Sources */,
D0AAD1B31E3266B100D5B9DE /* TimestampBasedMessageAttributesTable.swift in Sources */, D0AAD1B31E3266B100D5B9DE /* TimestampBasedMessageAttributesTable.swift in Sources */,
D01F7D9B1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift in Sources */, D01F7D9B1CBEC390008765C9 /* MessageHistoryInvalidatedReadStateTable.swift in Sources */,
D0F02CE21E9922F50065DEE2 /* PostboxUpgrade_12to13.swift in Sources */,
D055BD331B7D3D2D00F06C0A /* MediaBox.swift in Sources */, D055BD331B7D3D2D00F06C0A /* MediaBox.swift in Sources */,
D0C674CC1CBB14A700183765 /* PeerReadState.swift in Sources */, D0C674CC1CBB14A700183765 /* PeerReadState.swift in Sources */,
D0D510F41D63BA8400A97B8A /* PostboxTransaction.swift in Sources */, D0D510F41D63BA8400A97B8A /* PostboxTransaction.swift in Sources */,

View File

@ -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<ValueBox, NoError>
}

View File

@ -33,18 +33,20 @@ final class PeerMergedOperationLogIndexTable: Table {
func remove(tag: PeerOperationLogTag, mergedIndices: [Int32]) { func remove(tag: PeerOperationLogTag, mergedIndices: [Int32]) {
for index in mergedIndices { 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)) self.valueBox.remove(self.table, key: self.key(tag: tag, index: index))
} }
} }
func getTagLocalIndices(tag: PeerOperationLogTag, fromMergedIndex: Int32, limit: Int) -> [(PeerId, Int32)] { func getTagLocalIndices(tag: PeerOperationLogTag, fromMergedIndex: Int32, limit: Int) -> [(PeerId, Int32, Int32)] {
var result: [(PeerId, 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 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 peerIdValue: Int64 = 0
var tagLocalIndexValue: Int32 = 0 var tagLocalIndexValue: Int32 = 0
value.read(&peerIdValue, offset: 0, length: 8) value.read(&peerIdValue, offset: 0, length: 8)
value.read(&tagLocalIndexValue, offset: 0, length: 4) value.read(&tagLocalIndexValue, offset: 0, length: 4)
result.append((PeerId(peerIdValue), tagLocalIndexValue)) result.append((PeerId(peerIdValue), tagLocalIndexValue, key.getInt32(1)))
return true return true
}, limit: limit) }, limit: limit)
return result return result

View File

@ -121,7 +121,7 @@ final class PeerOperationLogTable: Table {
private func key(peerId: PeerId, tag: PeerOperationLogTag, index: Int32) -> ValueBoxKey { private func key(peerId: PeerId, tag: PeerOperationLogTag, index: Int32) -> ValueBoxKey {
let key = ValueBoxKey(length: 8 + 1 + 4) let key = ValueBoxKey(length: 8 + 1 + 4)
key.setInt64(0, value: peerId.toInt64()) key.setInt64(0, value: peerId.toInt64())
key.setUInt8(1, value: tag.rawValue) key.setUInt8(8, value: tag.rawValue)
key.setInt32(9, value: index) key.setInt32(9, value: index)
return key return key
} }
@ -249,7 +249,7 @@ final class PeerOperationLogTable: Table {
func getMergedEntries(tag: PeerOperationLogTag, fromIndex: Int32, limit: Int) -> [PeerMergedOperationLogEntry] { func getMergedEntries(tag: PeerOperationLogTag, fromIndex: Int32, limit: Int) -> [PeerMergedOperationLogEntry] {
var entries: [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 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) { if let entry = parseMergedEntry(peerId: peerId, tag: tag, tagLocalIndex: tagLocalIndex, value) {
entries.append(entry) entries.append(entry)
@ -257,6 +257,7 @@ final class PeerOperationLogTable: Table {
assertionFailure() assertionFailure()
} }
} else { } else {
self.mergedIndexTable.remove(tag: tag, mergedIndices: [mergedIndex])
assertionFailure() assertionFailure()
} }
} }
@ -334,10 +335,12 @@ final class PeerOperationLogTable: Table {
encoder.encodeRootObject(contents) encoder.encodeRootObject(contents)
} }
let contentBuffer = encoder.readBufferNoCopy() let contentBuffer = encoder.readBufferNoCopy()
var contentBufferLength: Int32 = Int32(contentBuffer.length) withExtendedLifetime(encoder, {
buffer.write(&contentBufferLength, offset: 0, length: 4) var contentBufferLength: Int32 = Int32(contentBuffer.length)
buffer.write(contentBuffer.memory, offset: 0, length: contentBuffer.length) buffer.write(&contentBufferLength, offset: 0, length: 4)
self.valueBox.set(self.table, key: key, value: buffer) buffer.write(contentBuffer.memory, offset: 0, length: contentBuffer.length)
self.valueBox.set(self.table, key: key, value: buffer)
})
} }
} else { } else {
assertionFailure() assertionFailure()

View File

@ -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<PostboxResult, NoError> {
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 { public final class Postbox {
private let queue: Queue
private let seedConfiguration: SeedConfiguration private let seedConfiguration: SeedConfiguration
private let basePath: String private let basePath: String
private let globalMessageIdsNamespace: MessageId.Namespace private let globalMessageIdsNamespace: MessageId.Namespace
private let valueBox: ValueBox
private let ipcNotificationsDisposable = MetaDisposable() private let ipcNotificationsDisposable = MetaDisposable()
//private var pipeNotifier: PipeNotifier! //private var pipeNotifier: PipeNotifier!
private let queue = Queue(name: "org.telegram.postbox.Postbox")
private var valueBox: ValueBox!
private var transactionStateVersion: Int64 = 0 private var transactionStateVersion: Int64 = 0
private var viewTracker: ViewTracker! private var viewTracker: ViewTracker!
private var nextViewId = 0 private var nextViewId = 0
private var peerPipes: [PeerId: ValuePipe<Peer>] = [:]
private var currentUpdatedState: Coding? private var currentUpdatedState: Coding?
private var currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]] = [:] private var currentOperationsByPeerId: [PeerId: [MessageHistoryOperation]] = [:]
private var currentUpdatedChatListInclusions: [PeerId: PeerChatListInclusion] = [:] private var currentUpdatedChatListInclusions: [PeerId: PeerChatListInclusion] = [:]
@ -597,7 +642,7 @@ public final class Postbox {
private var currentReplacedContactPeerIds: Set<PeerId>? private var currentReplacedContactPeerIds: Set<PeerId>?
private var currentUpdatedMasterClientId: Int64? private var currentUpdatedMasterClientId: Int64?
private var statePipe: ValuePipe<Coding> = ValuePipe() private let statePipe: ValuePipe<Coding> = ValuePipe()
private var masterClientId = Promise<Int64>() private var masterClientId = Promise<Int64>()
private var sessionClientId: Int64 = { private var sessionClientId: Int64 = {
@ -608,60 +653,62 @@ public final class Postbox {
public let mediaBox: MediaBox public let mediaBox: MediaBox
var tables: [Table] = [] let tables: [Table]
var metadataTable: MetadataTable! let metadataTable: MetadataTable
var keychainTable: KeychainTable! let keychainTable: KeychainTable
var peerTable: PeerTable! let peerTable: PeerTable
var peerNotificationSettingsTable: PeerNotificationSettingsTable! let peerNotificationSettingsTable: PeerNotificationSettingsTable
var cachedPeerDataTable: CachedPeerDataTable! let cachedPeerDataTable: CachedPeerDataTable
var peerPresenceTable: PeerPresenceTable! let peerPresenceTable: PeerPresenceTable
var globalMessageIdsTable: GlobalMessageIdsTable! let globalMessageIdsTable: GlobalMessageIdsTable
var globallyUniqueMessageIdsTable: MessageGloballyUniqueIdTable! let globallyUniqueMessageIdsTable: MessageGloballyUniqueIdTable
var messageHistoryIndexTable: MessageHistoryIndexTable! let messageHistoryIndexTable: MessageHistoryIndexTable
var messageHistoryTable: MessageHistoryTable! let messageHistoryTable: MessageHistoryTable
var mediaTable: MessageMediaTable! let mediaTable: MessageMediaTable
var chatListIndexTable: ChatListIndexTable! let chatListIndexTable: ChatListIndexTable
var chatListTable: ChatListTable! let chatListTable: ChatListTable
var messageHistoryMetadataTable: MessageHistoryMetadataTable! let messageHistoryMetadataTable: MessageHistoryMetadataTable
var messageHistoryUnsentTable: MessageHistoryUnsentTable! let messageHistoryUnsentTable: MessageHistoryUnsentTable
var messageHistoryTagsTable: MessageHistoryTagsTable! let messageHistoryTagsTable: MessageHistoryTagsTable
var peerChatStateTable: PeerChatStateTable! let peerChatStateTable: PeerChatStateTable
var readStateTable: MessageHistoryReadStateTable! let readStateTable: MessageHistoryReadStateTable
var synchronizeReadStateTable: MessageHistorySynchronizeReadStateTable! let synchronizeReadStateTable: MessageHistorySynchronizeReadStateTable
var contactsTable: ContactTable! let contactsTable: ContactTable
var itemCollectionInfoTable: ItemCollectionInfoTable! let itemCollectionInfoTable: ItemCollectionInfoTable
var itemCollectionItemTable: ItemCollectionItemTable! let itemCollectionItemTable: ItemCollectionItemTable
var itemCollectionReverseIndexTable: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>! let itemCollectionReverseIndexTable: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>
var peerChatInterfaceStateTable: PeerChatInterfaceStateTable! let peerChatInterfaceStateTable: PeerChatInterfaceStateTable
var itemCacheMetaTable: ItemCacheMetaTable! let itemCacheMetaTable: ItemCacheMetaTable
var itemCacheTable: ItemCacheTable! let itemCacheTable: ItemCacheTable
var peerNameTokenIndexTable: ReverseIndexReferenceTable<PeerIdReverseIndexReference>! let peerNameTokenIndexTable: ReverseIndexReferenceTable<PeerIdReverseIndexReference>
var peerNameIndexTable: PeerNameIndexTable! let peerNameIndexTable: PeerNameIndexTable
var peerChatTopTaggedMessageIdsTable: PeerChatTopTaggedMessageIdsTable! let peerChatTopTaggedMessageIdsTable: PeerChatTopTaggedMessageIdsTable
var peerOperationLogMetadataTable: PeerOperationLogMetadataTable! let peerOperationLogMetadataTable: PeerOperationLogMetadataTable
var peerMergedOperationLogIndexTable: PeerMergedOperationLogIndexTable! let peerMergedOperationLogIndexTable: PeerMergedOperationLogIndexTable
var peerOperationLogTable: PeerOperationLogTable! let peerOperationLogTable: PeerOperationLogTable
var timestampBasedMessageAttributesTable: TimestampBasedMessageAttributesTable! let timestampBasedMessageAttributesTable: TimestampBasedMessageAttributesTable
var timestampBasedMessageAttributesIndexTable: TimestampBasedMessageAttributesIndexTable! let timestampBasedMessageAttributesIndexTable: TimestampBasedMessageAttributesIndexTable
var preferencesTable: PreferencesTable! let preferencesTable: PreferencesTable
var orderedItemListTable: OrderedItemListTable! let orderedItemListTable: OrderedItemListTable
var orderedItemListIndexTable: OrderedItemListIndexTable! let orderedItemListIndexTable: OrderedItemListIndexTable
//temporary //temporary
var peerRatingTable: RatingTable<PeerId>! let peerRatingTable: RatingTable<PeerId>
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.basePath = basePath
self.globalMessageIdsNamespace = globalMessageIdsNamespace self.globalMessageIdsNamespace = globalMessageIdsNamespace
self.seedConfiguration = seedConfiguration self.seedConfiguration = seedConfiguration
print("MediaBox path: \(self.basePath + "/media")") print("MediaBox path: \(self.basePath + "/media")")
//let _ = try? FileManager.default.removeItem(atPath: self.basePath)
self.mediaBox = MediaBox(basePath: self.basePath + "/media") self.mediaBox = MediaBox(basePath: self.basePath + "/media")
self.valueBox = valueBox
/*self.pipeNotifier = PipeNotifier(basePath: basePath, notify: { [weak self] in /*self.pipeNotifier = PipeNotifier(basePath: basePath, notify: { [weak self] in
//if let strongSelf = self { //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<PeerIdReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<PeerIdReverseIndexReference>.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<PeerId>(valueBox: self.valueBox, table: RatingTable<PeerId>.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<ItemCollectionItemReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>.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 { 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<PeerIdReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<PeerIdReverseIndexReference>.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<PeerId>(valueBox: self.valueBox, table: RatingTable<PeerId>.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<ItemCollectionItemReverseIndexReference>(valueBox: self.valueBox, table: ReverseIndexReferenceTable<ItemCollectionItemReverseIndexReference>.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 { private func takeNextViewId() -> Int {
let nextId = self.nextViewId let nextId = self.nextViewId
self.nextViewId += 1 self.nextViewId += 1
@ -1191,9 +1214,9 @@ public final class Postbox {
table.clearMemoryCache() table.clearMemoryCache()
} }
self.viewTracker.refreshViewsDueToExternalTransaction(fetchAroundChatEntries: self.fetchAroundChatEntries, fetchAroundHistoryEntries: self.fetchAroundHistoryEntries, fetchUnsentMessageIds: { self.viewTracker.refreshViewsDueToExternalTransaction(fetchAroundChatEntries: self.fetchAroundChatEntries, fetchAroundHistoryEntries: self.fetchAroundHistoryEntries, fetchUnsentMessageIds: {
return self.messageHistoryUnsentTable!.get() return self.messageHistoryUnsentTable.get()
}, fetchSynchronizePeerReadStateOperations: { }, fetchSynchronizePeerReadStateOperations: {
return self.synchronizeReadStateTable!.get(getCombinedPeerReadState: { peerId in return self.synchronizeReadStateTable.get(getCombinedPeerReadState: { peerId in
return self.readStateTable.getCombinedState(peerId) return self.readStateTable.getCombinedState(peerId)
}) })
}) })

View File

@ -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)
}

View File

@ -102,9 +102,6 @@ public final class SqliteInterface {
public init?(databasePath: String) { public init?(databasePath: String) {
if let database = Database(databasePath) { if let database = Database(databasePath) {
// if !database.execute("pragma schema_version") {
// return nil
// }
self.database = database self.database = database
} else { } else {
return nil return nil

View File

@ -1057,6 +1057,10 @@ final class SqliteValueBox: ValueBox {
self.deleteStatements.removeAll() self.deleteStatements.removeAll()
} }
public func dropTable(_ table: ValueBoxTable) {
self.database.execute("REMOVE FROM t\(table.id)")
}
public func drop() { public func drop() {
assert(self.queue.isCurrent()) assert(self.queue.isCurrent())
self.clearStatements() self.clearStatements()

11
Postbox/Upgrades.swift Normal file
View File

@ -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
}

View File

@ -24,5 +24,6 @@ protocol ValueBox {
func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool func exists(_ table: ValueBoxTable, key: ValueBoxKey) -> Bool
func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer) func set(_ table: ValueBoxTable, key: ValueBoxKey, value: MemoryBuffer)
func remove(_ table: ValueBoxTable, key: ValueBoxKey) func remove(_ table: ValueBoxTable, key: ValueBoxKey)
func dropTable(_ table: ValueBoxTable)
func drop() func drop()
} }