Swiftgram/submodules/Postbox/Sources/PostboxUpgrade_24to25.swift
2019-11-01 17:11:12 +04:00

143 lines
5.6 KiB
Swift

import Foundation
private func localChatListPinningIndexFromKeyValue(_ value: UInt16) -> UInt16? {
if value == 0 {
return nil
} else {
return UInt16.max - 1 - value
}
}
private func extractChatListKey(_ key: ValueBoxKey) -> (groupId: Int32, pinningIndex: UInt16?, index: MessageIndex, type: Int8) {
let groupIdValue = key.getInt32(0)
return (
groupId: groupIdValue,
pinningIndex: localChatListPinningIndexFromKeyValue(key.getUInt16(4)),
index: MessageIndex(
id: MessageId(
peerId: PeerId(key.getInt64(4 + 2 + 4 + 1 + 4)),
namespace: Int32(key.getInt8(4 + 2 + 4)),
id: key.getInt32(4 + 2 + 4 + 1)
),
timestamp: key.getInt32(4 + 2)
),
type: key.getInt8(4 + 2 + 4 + 1 + 4 + 8)
)
}
private struct ChatListIndexFlags: OptionSet {
var rawValue: Int8
init(rawValue: Int8) {
self.rawValue = rawValue
}
static let hasIndex = ChatListIndexFlags(rawValue: 1 << 0)
}
func postboxUpgrade_24to25(metadataTable: MetadataTable, valueBox: ValueBox, progress: (Float) -> Void) {
postboxLog("Upgrade 24->25 started")
let messageHistoryMetadataTable = ValueBoxTable(id: 10, keyType: .binary, compactValuesOnCreation: true)
let chatListTable = ValueBoxTable(id: 9, keyType: .binary, compactValuesOnCreation: true)
var peerIdToGroupId: [PeerId: Int32] = [:]
valueBox.scan(chatListTable, keys: { key in
let (groupId, _, index, type) = extractChatListKey(key)
if type == 1 {
peerIdToGroupId[index.id.peerId] = groupId
}
return true
})
let chatListIndexTable = ValueBoxTable(id: 8, keyType: .int64, compactValuesOnCreation: true)
var updatedValues: [PeerId: MemoryBuffer] = [:]
valueBox.scanInt64(chatListIndexTable, values: { key, value in
let writeBuffer = WriteBuffer()
let peerId = PeerId(key)
var flagsValue: Int8 = 0
value.read(&flagsValue, offset: 0, length: 1)
writeBuffer.write(&flagsValue, offset: 0, length: 1)
let flags = ChatListIndexFlags(rawValue: flagsValue)
if flags.contains(.hasIndex) {
var idNamespace: Int32 = 0
var idId: Int32 = 0
var idTimestamp: Int32 = 0
value.read(&idNamespace, offset: 0, length: 4)
value.read(&idId, offset: 0, length: 4)
value.read(&idTimestamp, offset: 0, length: 4)
writeBuffer.write(&idNamespace, offset: 0, length: 4)
writeBuffer.write(&idId, offset: 0, length: 4)
writeBuffer.write(&idTimestamp, offset: 0, length: 4)
}
var inclusionId: Int8 = 0
value.read(&inclusionId, offset: 0, length: 1)
if inclusionId == 0 {
} else {
if inclusionId == 1 || peerIdToGroupId[peerId] == nil {
inclusionId = 0
writeBuffer.write(&inclusionId, offset: 0, length: 1)
} else if inclusionId == 2 {
inclusionId = 1
writeBuffer.write(&inclusionId, offset: 0, length: 1)
var pinningIndexValue: UInt16 = 0
writeBuffer.write(&pinningIndexValue, offset: 0, length: 2)
var hasMinTimestamp: Int8 = 0
writeBuffer.write(&hasMinTimestamp, offset: 0, length: 1)
var groupId = peerIdToGroupId[peerId] ?? 0
writeBuffer.write(&groupId, offset: 0, length: 4)
} else if inclusionId == 3 {
inclusionId = 1
writeBuffer.write(&inclusionId, offset: 0, length: 1)
var pinningIndexValue: UInt16 = 0
value.read(&pinningIndexValue, offset: 0, length: 2)
writeBuffer.write(&pinningIndexValue, offset: 0, length: 2)
var hasMinTimestamp: Int8 = 0
value.read(&hasMinTimestamp, offset: 0, length: 1)
writeBuffer.write(&hasMinTimestamp, offset: 0, length: 1)
if hasMinTimestamp != 0 {
var minTimestampValue: Int32 = 0
value.read(&minTimestampValue, offset: 0, length: 4)
writeBuffer.write(&minTimestampValue, offset: 0, length: 4)
}
var groupId = peerIdToGroupId[peerId] ?? 0
writeBuffer.write(&groupId, offset: 0, length: 4)
} else {
assertionFailure()
}
updatedValues[peerId] = writeBuffer
}
return true
})
for (peerId, value) in updatedValues {
let key = ValueBoxKey(length: 8)
key.setInt64(0, value: peerId.toInt64())
valueBox.set(chatListIndexTable, key: key, value: value)
}
let shouldReindexUnreadCountsKey = ValueBoxKey(length: 1)
shouldReindexUnreadCountsKey.setInt8(0, value: 8)
valueBox.set(messageHistoryMetadataTable, key: shouldReindexUnreadCountsKey, value: MemoryBuffer())
let synchronizeGroupMessageStatsTable = ValueBoxTable(id: 59, keyType: .binary, compactValuesOnCreation: true)
let synchronizeGroupMessageStatsKey = ValueBoxKey(length: 4 + 4)
synchronizeGroupMessageStatsKey.setInt32(0, value: 1) //Archive
synchronizeGroupMessageStatsKey.setInt32(4, value: 0) //Messages.Cloud
valueBox.set(synchronizeGroupMessageStatsTable, key: synchronizeGroupMessageStatsKey, value: MemoryBuffer())
metadataTable.setUserVersion(25)
}