mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-09 06:00:43 +00:00
Merge branch 'master' of https://github.com/peter-iakovlev/Postbox
This commit is contained in:
commit
c09f88d732
@ -1267,10 +1267,11 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = (
|
||||
"-DSQLITE_TEMP_STORE=2",
|
||||
"-DSQLITE_HAS_CODEC=1",
|
||||
"-DSQLCIPHER_CRYPTO_CC=1",
|
||||
"-DSQLITE_ENABLE_FTS3",
|
||||
"-DSQLITE_OMIT_DEPRECATED",
|
||||
"-DSQLITE_ENABLE_FTS5",
|
||||
"-DSQLITE_DEFAULT_MEMSTATUS=0",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -1394,10 +1395,11 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = (
|
||||
"-DSQLITE_TEMP_STORE=2",
|
||||
"-DSQLITE_HAS_CODEC=1",
|
||||
"-DSQLCIPHER_CRYPTO_CC=1",
|
||||
"-DSQLITE_ENABLE_FTS3",
|
||||
"-DSQLITE_OMIT_DEPRECATED",
|
||||
"-DSQLITE_ENABLE_FTS5",
|
||||
"-DSQLITE_DEFAULT_MEMSTATUS=0",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
@ -1642,10 +1644,11 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = (
|
||||
"-DSQLITE_TEMP_STORE=2",
|
||||
"-DSQLITE_HAS_CODEC=1",
|
||||
"-DSQLCIPHER_CRYPTO_CC=1",
|
||||
"-DSQLITE_ENABLE_FTS3",
|
||||
"-DSQLITE_OMIT_DEPRECATED",
|
||||
"-DSQLITE_ENABLE_FTS5",
|
||||
"-DSQLITE_DEFAULT_MEMSTATUS=0",
|
||||
);
|
||||
OTHER_SWIFT_FLAGS = "-DDEBUG";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
@ -1675,10 +1678,11 @@
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
OTHER_CFLAGS = (
|
||||
"-DSQLITE_TEMP_STORE=2",
|
||||
"-DSQLITE_HAS_CODEC=1",
|
||||
"-DSQLCIPHER_CRYPTO_CC=1",
|
||||
"-DSQLITE_ENABLE_FTS3",
|
||||
"-DSQLITE_OMIT_DEPRECATED",
|
||||
"-DSQLITE_ENABLE_FTS5",
|
||||
"-DSQLITE_DEFAULT_MEMSTATUS=0",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "org.telegram.$(PRODUCT_NAME:rfc1034identifier)";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
|
@ -3,6 +3,7 @@ import Foundation
|
||||
struct ChatListInclusionIndex {
|
||||
let topMessageIndex: MessageIndex?
|
||||
let inclusion: PeerChatListInclusion
|
||||
var tags: [UInt16]?
|
||||
|
||||
func includedIndex(peerId: PeerId) -> ChatListIndex? {
|
||||
switch inclusion {
|
||||
@ -32,6 +33,17 @@ struct ChatListInclusionIndex {
|
||||
}
|
||||
}
|
||||
|
||||
private struct ChatListIndexFlags: OptionSet {
|
||||
var rawValue: Int8
|
||||
|
||||
init(rawValue: Int8) {
|
||||
self.rawValue = rawValue
|
||||
}
|
||||
|
||||
static let hasIndex = ChatListIndexFlags(rawValue: 1 << 0)
|
||||
static let hasTags = ChatListIndexFlags(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
final class ChatListIndexTable: Table {
|
||||
static func tableSpec(_ id: Int32) -> ValueBoxTable {
|
||||
return ValueBoxTable(id: id, keyType: .int64)
|
||||
@ -66,7 +78,7 @@ final class ChatListIndexTable: Table {
|
||||
if self.updatedPreviousCachedIndices[peerId] == nil {
|
||||
self.updatedPreviousCachedIndices[peerId] = current
|
||||
}
|
||||
let updated = ChatListInclusionIndex(topMessageIndex: index, inclusion: current.inclusion)
|
||||
let updated = ChatListInclusionIndex(topMessageIndex: index, inclusion: current.inclusion, tags: current.tags)
|
||||
self.cachedIndices[peerId] = updated
|
||||
return updated
|
||||
}
|
||||
@ -76,7 +88,7 @@ final class ChatListIndexTable: Table {
|
||||
if self.updatedPreviousCachedIndices[peerId] == nil {
|
||||
self.updatedPreviousCachedIndices[peerId] = current
|
||||
}
|
||||
let updated = ChatListInclusionIndex(topMessageIndex: current.topMessageIndex, inclusion: inclusion)
|
||||
let updated = ChatListInclusionIndex(topMessageIndex: current.topMessageIndex, inclusion: inclusion, tags: current.tags)
|
||||
self.cachedIndices[peerId] = updated
|
||||
return updated
|
||||
}
|
||||
@ -88,9 +100,11 @@ final class ChatListIndexTable: Table {
|
||||
if let value = self.valueBox.get(self.table, key: self.key(peerId)) {
|
||||
let topMessageIndex: MessageIndex?
|
||||
|
||||
var hasIndex: Int8 = 0
|
||||
value.read(&hasIndex, offset: 0, length: 1)
|
||||
if hasIndex != 0 {
|
||||
var flagsValue: Int8 = 0
|
||||
value.read(&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
|
||||
@ -131,11 +145,24 @@ final class ChatListIndexTable: Table {
|
||||
preconditionFailure()
|
||||
}
|
||||
|
||||
let inclusionIndex = ChatListInclusionIndex(topMessageIndex: topMessageIndex, inclusion: inclusion)
|
||||
var tags: [UInt16]?
|
||||
if flags.contains(.hasTags) {
|
||||
var count: UInt16 = 0
|
||||
value.read(&count, offset: 0, length: 2)
|
||||
var resultTags: [UInt16] = []
|
||||
for _ in 0 ..< Int(count) {
|
||||
var tag: UInt16 = 0
|
||||
value.read(&tag, offset: 0, length: 2)
|
||||
resultTags.append(tag)
|
||||
}
|
||||
tags = resultTags
|
||||
}
|
||||
|
||||
let inclusionIndex = ChatListInclusionIndex(topMessageIndex: topMessageIndex, inclusion: inclusion, tags: tags)
|
||||
self.cachedIndices[peerId] = inclusionIndex
|
||||
return inclusionIndex
|
||||
} else {
|
||||
return ChatListInclusionIndex(topMessageIndex: nil, inclusion: .notSpecified)
|
||||
return ChatListInclusionIndex(topMessageIndex: nil, inclusion: .notSpecified, tags: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,18 +189,26 @@ final class ChatListIndexTable: Table {
|
||||
|
||||
let writeBuffer = WriteBuffer()
|
||||
|
||||
var flags: ChatListIndexFlags = []
|
||||
|
||||
if index.topMessageIndex != nil {
|
||||
flags.insert(.hasIndex)
|
||||
}
|
||||
|
||||
if index.tags != nil {
|
||||
flags.insert(.hasTags)
|
||||
}
|
||||
|
||||
var flagsValue = flags.rawValue
|
||||
writeBuffer.write(&flagsValue, offset: 0, length: 1)
|
||||
|
||||
if let topMessageIndex = index.topMessageIndex {
|
||||
var hasIndex: Int8 = 1
|
||||
writeBuffer.write(&hasIndex, offset: 0, length: 1)
|
||||
var idNamespace: Int32 = topMessageIndex.id.namespace
|
||||
var idId: Int32 = topMessageIndex.id.id
|
||||
var idTimestamp: Int32 = topMessageIndex.timestamp
|
||||
writeBuffer.write(&idNamespace, offset: 0, length: 4)
|
||||
writeBuffer.write(&idId, offset: 0, length: 4)
|
||||
writeBuffer.write(&idTimestamp, offset: 0, length: 4)
|
||||
} else {
|
||||
var hasIndex: Int8 = 0
|
||||
writeBuffer.write(&hasIndex, offset: 0, length: 1)
|
||||
}
|
||||
|
||||
switch index.inclusion {
|
||||
@ -205,6 +240,16 @@ final class ChatListIndexTable: Table {
|
||||
}
|
||||
}
|
||||
|
||||
if let tags = index.tags {
|
||||
var count = UInt16(tags.count)
|
||||
writeBuffer.write(&count, offset: 0, length: 2)
|
||||
|
||||
for tag in tags {
|
||||
var tagValue: UInt16 = tag
|
||||
writeBuffer.write(&tagValue, offset: 0, length: 2)
|
||||
}
|
||||
}
|
||||
|
||||
withExtendedLifetime(writeBuffer, {
|
||||
self.valueBox.set(self.table, key: self.key(peerId), value: writeBuffer.readBufferNoCopy())
|
||||
})
|
||||
|
@ -106,7 +106,13 @@ public final class Database {
|
||||
///
|
||||
/// - parameter SQL: A batch of zero or more semicolon-separated SQL statements.
|
||||
public func execute(_ SQL: String) -> Bool {
|
||||
return sqlite3_exec(self.handle, SQL, nil, nil, nil) == SQLITE_OK
|
||||
let res = sqlite3_exec(self.handle, SQL, nil, nil, nil)
|
||||
if res == SQLITE_OK {
|
||||
return true
|
||||
} else {
|
||||
print("SQL error \(res) on SQL")
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ import Foundation
|
||||
|
||||
public enum PeerIndexNameRepresentation: Equatable {
|
||||
case title(title: String, addressName: String?)
|
||||
case personName(first: String, last: String, addressName: String?)
|
||||
case personName(first: String, last: String, addressName: String?, phoneNumber: String?)
|
||||
|
||||
public static func ==(lhs: PeerIndexNameRepresentation, rhs: PeerIndexNameRepresentation) -> Bool {
|
||||
switch lhs {
|
||||
@ -12,14 +12,41 @@ public enum PeerIndexNameRepresentation: Equatable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .personName(lhsFirst, lhsLast, lhsAddressName):
|
||||
if case let .personName(rhsFirst, rhsLast, rhsAddressName) = rhs, lhsFirst == rhsFirst, lhsLast == rhsLast, lhsAddressName == rhsAddressName {
|
||||
case let .personName(lhsFirst, lhsLast, lhsAddressName, lhsPhoneNumber):
|
||||
if case let .personName(rhsFirst, rhsLast, rhsAddressName, rhsPhoneNumber) = rhs, lhsFirst == rhsFirst, lhsLast == rhsLast, lhsAddressName == rhsAddressName, lhsPhoneNumber == rhsPhoneNumber {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public var isEmpty: Bool {
|
||||
switch self {
|
||||
case let .title(title, addressName):
|
||||
if !title.isEmpty {
|
||||
return false
|
||||
}
|
||||
if let addressName = addressName, !addressName.isEmpty {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
case let .personName(first, last, addressName, phoneNumber):
|
||||
if !first.isEmpty {
|
||||
return false
|
||||
}
|
||||
if !last.isEmpty {
|
||||
return false
|
||||
}
|
||||
if let addressName = addressName, !addressName.isEmpty {
|
||||
return false
|
||||
}
|
||||
if let phoneNumber = phoneNumber, !phoneNumber.isEmpty {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum PeerNameIndex {
|
||||
@ -32,7 +59,7 @@ extension PeerIndexNameRepresentation {
|
||||
switch self {
|
||||
case let .title(title, _):
|
||||
return title
|
||||
case let .personName(first, last, _):
|
||||
case let .personName(first, last, _, _):
|
||||
switch index {
|
||||
case .firstNameFirst:
|
||||
return first + last
|
||||
@ -68,12 +95,15 @@ extension PeerIndexNameRepresentation {
|
||||
tokens.append(contentsOf: stringIndexTokens(addressName, transliteration: .none))
|
||||
}
|
||||
return tokens
|
||||
case let .personName(first, last, addressName):
|
||||
case let .personName(first, last, addressName, phoneNumber):
|
||||
var tokens: [ValueBoxKey] = stringIndexTokens(first, transliteration: .combined)
|
||||
tokens.append(contentsOf: stringIndexTokens(last, transliteration: .combined))
|
||||
if let addressName = addressName {
|
||||
tokens.append(contentsOf: stringIndexTokens(addressName, transliteration: .none))
|
||||
}
|
||||
if let phoneNumber = phoneNumber {
|
||||
tokens.append(contentsOf: stringIndexTokens(phoneNumber, transliteration: .none))
|
||||
}
|
||||
return tokens
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +213,15 @@ final class PeerNameIndexTable: Table {
|
||||
updatedTokens = updatedName.indexTokens
|
||||
} else {
|
||||
if let peer = self.peerTable.get(peerId) {
|
||||
updatedTokens = peer.indexName.indexTokens
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
if let associatedPeer = self.peerTable.get(associatedPeerId) {
|
||||
updatedTokens = associatedPeer.indexName.indexTokens
|
||||
} else {
|
||||
updatedTokens = []
|
||||
}
|
||||
} else {
|
||||
updatedTokens = peer.indexName.indexTokens
|
||||
}
|
||||
} else {
|
||||
//assertionFailure()
|
||||
updatedTokens = []
|
||||
|
@ -1356,8 +1356,23 @@ public final class Postbox {
|
||||
if let updatedPeer = update(currentPeer, peer) {
|
||||
self.peerTable.set(updatedPeer)
|
||||
self.currentUpdatedPeers[updatedPeer.id] = updatedPeer
|
||||
if currentPeer?.indexName != updatedPeer.indexName {
|
||||
self.peerNameIndexTable.markPeerNameUpdated(peerId: peer.id, name: updatedPeer.indexName)
|
||||
var previousIndexNameWasEmpty = true
|
||||
|
||||
if let currentPeer = currentPeer {
|
||||
if !currentPeer.indexName.isEmpty {
|
||||
previousIndexNameWasEmpty = false
|
||||
}
|
||||
}
|
||||
|
||||
let indexNameIsEmpty = updatedPeer.indexName.isEmpty
|
||||
|
||||
if !previousIndexNameWasEmpty || !indexNameIsEmpty {
|
||||
if currentPeer?.indexName != updatedPeer.indexName {
|
||||
self.peerNameIndexTable.markPeerNameUpdated(peerId: peer.id, name: updatedPeer.indexName)
|
||||
for reverseAssociatedPeerId in self.reverseAssociatedPeerTable.get(peerId: peer.id) {
|
||||
self.peerNameIndexTable.markPeerNameUpdated(peerId: reverseAssociatedPeerId, name: updatedPeer.indexName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1800,30 +1815,41 @@ public final class Postbox {
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
||||
public func searchPeers(query: String) -> Signal<[Peer], NoError> {
|
||||
return self.modify { modifier -> Signal<[Peer], NoError> in
|
||||
public func searchPeers(query: String) -> Signal<[RenderedPeer], NoError> {
|
||||
return self.modify { modifier -> Signal<[RenderedPeer], NoError> in
|
||||
var peerIds = Set<PeerId>()
|
||||
var chatPeers: [Peer] = []
|
||||
var chatPeers: [RenderedPeer] = []
|
||||
|
||||
let (chatPeerIds, contactPeerIds) = self.peerNameIndexTable.matchingPeerIds(tokens: (regular: stringIndexTokens(query, transliteration: .none), transliterated: stringIndexTokens(query, transliteration: .transliterated)), categories: [.chats, .contacts], chatListIndexTable: self.chatListIndexTable, contactTable: self.contactsTable, reverseAssociatedPeerTable: self.reverseAssociatedPeerTable)
|
||||
|
||||
for peerId in chatPeerIds {
|
||||
if let peer = self.peerTable.get(peerId) {
|
||||
chatPeers.append(peer)
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
peers[peer.id] = peer
|
||||
if let associatedPeerId = peer.associatedPeerId {
|
||||
if let associatedPeer = self.peerTable.get(associatedPeerId) {
|
||||
peers[associatedPeer.id] = associatedPeer
|
||||
}
|
||||
}
|
||||
chatPeers.append(RenderedPeer(peerId: peer.id, peers: peers))
|
||||
peerIds.insert(peerId)
|
||||
}
|
||||
}
|
||||
|
||||
var contactPeers: [Peer] = []
|
||||
var contactPeers: [RenderedPeer] = []
|
||||
for peerId in contactPeerIds {
|
||||
if !peerIds.contains(peerId) {
|
||||
if let peer = self.peerTable.get(peerId) {
|
||||
contactPeers.append(peer)
|
||||
var peers = SimpleDictionary<PeerId, Peer>()
|
||||
peers[peer.id] = peer
|
||||
contactPeers.append(RenderedPeer(peerId: peer.id, peers: peers))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
contactPeers.sort(by: { $0.indexName.indexName(.lastNameFirst) < $1.indexName.indexName(.lastNameFirst) })
|
||||
contactPeers.sort(by: { lhs, rhs in
|
||||
lhs.peers[lhs.peerId]!.indexName.indexName(.lastNameFirst) < rhs.peers[rhs.peerId]!.indexName.indexName(.lastNameFirst)
|
||||
})
|
||||
return .single(chatPeers + contactPeers)
|
||||
} |> switchToLatest
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ final class SqliteValueBox: ValueBox {
|
||||
//database = Database(path)!
|
||||
}
|
||||
|
||||
sqlite3_busy_timeout(database.handle, 10000000)
|
||||
sqlite3_busy_timeout(database.handle, 1000 * 10000)
|
||||
|
||||
var resultCode: Bool
|
||||
|
||||
@ -158,9 +158,9 @@ final class SqliteValueBox: ValueBox {
|
||||
assert(resultCode)
|
||||
resultCode = database.execute("PRAGMA synchronous=NORMAL")
|
||||
assert(resultCode)
|
||||
//database.execute("PRAGMA temp_store=MEMORY")
|
||||
resultCode = database.execute("PRAGMA wal_autocheckpoint=500")
|
||||
resultCode = database.execute("PRAGMA temp_store=MEMORY")
|
||||
assert(resultCode)
|
||||
//resultCode = database.execute("PRAGMA wal_autocheckpoint=500")
|
||||
//database.execute("PRAGMA journal_size_limit=1536")
|
||||
|
||||
/*var statement: OpaquePointer? = nil
|
||||
|
Loading…
x
Reference in New Issue
Block a user