Skip to content

Commit

Permalink
Updates for YapDatabase 4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisballinger committed Feb 28, 2020
1 parent 4067e26 commit a626fbf
Show file tree
Hide file tree
Showing 21 changed files with 166 additions and 139 deletions.
2 changes: 1 addition & 1 deletion ChatSecureCore.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ TODO: Add long description of the pod here.
s.dependency 'ChatSecure-Push-iOS'

s.dependency 'SQLCipher', '~> 4.2.0'
s.dependency 'YapDatabase/SQLCipher', '~> 3.1.3'
s.dependency 'YapDatabase/SQLCipher', '~> 4.0'

s.dependency 'libsqlfs/SQLCipher'
s.dependency 'IOCipher/GCDWebServer'
Expand Down
7 changes: 2 additions & 5 deletions ChatSecureCore/Classes/Controllers/OTRDatabaseManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,13 @@ - (BOOL)setupYapDatabaseWithName:(NSString *)name directory:(nullable NSString*)
}
NSString *databasePath = [self.databaseDirectory stringByAppendingPathComponent:name];

self.database = [[YapDatabase alloc] initWithPath:databasePath
serializer:nil
deserializer:nil
options:options];
self.database = [[YapDatabase alloc] initWithURL:[NSURL fileURLWithPath:databasePath] options:options];

// Stop trying to setup up the database. Something went wrong. Most likely the password is incorrect.
if (self.database == nil) {
return NO;
}

self.database.connectionDefaults.objectPolicy = YapDatabasePolicyShare;
self.database.connectionDefaults.objectCacheLimit = 10000;

[self setupConnections];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ open class OTRSignalStorageManager: NSObject {
}

let query = YapDatabaseQuery(string: "WHERE (OTRYapDatabaseSignalPreKeyAccountKeySecondaryIndexColumnName) = ?", parameters: ["\(self.accountKey)"])
secondaryIndexTransaction.enumerateKeysAndObjects(matching: query, using: { (collection, key, object, stop) in
let _ = secondaryIndexTransaction.iterateKeysAndObjects(matching: query, using: { (collection, key, object, stop) in
guard let preKey = object as? OTRSignalPreKey else {
return
}
Expand Down
3 changes: 1 addition & 2 deletions ChatSecureCore/Classes/Controllers/OTRYapExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
//

import Foundation
import YapDatabase.YapDatabaseFullTextSearch
import YapDatabase.YapDatabaseSearchResultsView
import YapDatabase

open class OTRYapExtensions:NSObject {

Expand Down
2 changes: 1 addition & 1 deletion ChatSecureCore/Classes/Controllers/OTRYapViewHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import Foundation
import YapDatabase.YapDatabaseView
import YapDatabase

@objc public protocol OTRYapViewHandlerDelegateProtocol:NSObjectProtocol {

Expand Down
30 changes: 13 additions & 17 deletions ChatSecureCore/Classes/Controllers/PushStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,9 @@ class PushStorage: NSObject, PushStorageProtocol {
func unusedToken() -> TokenContainer? {
var tokenContainer:TokenContainer? = nil
self.databaseConnection.read { (transaction) -> Void in
transaction.enumerateKeysAndObjects(inCollection: PushYapCollections.unusedTokenCollection.rawValue, using: { (key, object, stop) -> Void in
if let tc = object as? TokenContainer {
tokenContainer = tc
}
stop.initialize(to: true)
transaction.iterateKeysAndObjects(inCollection: PushYapCollections.unusedTokenCollection.rawValue, using: { (key, tc: TokenContainer, stop) -> Void in
tokenContainer = tc
stop = true
})
}
return tokenContainer
Expand Down Expand Up @@ -236,18 +234,16 @@ class PushStorage: NSObject, PushStorageProtocol {
self.databaseConnection.asyncReadWrite({ (transaction) in
let collection = PushYapCollections.unusedTokenCollection.rawValue
var removeKeyArray:[String] = []
transaction.enumerateKeysAndObjects(inCollection: collection, using: { (key, object, stop) in
if let token = object as? TokenContainer {
//Check that there is an expires date otherwise remove
guard let expiresDate = token.pushToken?.expires else {
removeKeyArray.append(token.uniqueId)
return
}

// Check that the date is farther in the future than currentDate + timeBuffer
if (Date(timeIntervalSinceNow: timeBuffer).compare(expiresDate) == .orderedDescending ) {
removeKeyArray.append(token.uniqueId)
}
transaction.iterateKeysAndObjects(inCollection: collection, using: { (key, token: TokenContainer, stop) in
//Check that there is an expires date otherwise remove
guard let expiresDate = token.pushToken?.expires else {
removeKeyArray.append(token.uniqueId)
return
}

// Check that the date is farther in the future than currentDate + timeBuffer
if (Date(timeIntervalSinceNow: timeBuffer).compare(expiresDate) == .orderedDescending ) {
removeKeyArray.append(token.uniqueId)
}
})

Expand Down
8 changes: 1 addition & 7 deletions ChatSecureCore/Classes/Controllers/XMPP/OTRXMPPManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -924,13 +924,7 @@ - (void)xmppStream:(XMPPStream *)sender didFailToSendMessage:(XMPPMessage *)mess
{
DDLogWarn(@"%@: %@ %@ %@", THIS_FILE, THIS_METHOD, message, error);
[self.databaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[transaction enumerateMessagesWithElementId:message.elementID originId:message.originId stanzaId:nil block:^(id<OTRMessageProtocol> _Nonnull databaseMessage, BOOL * _Null_unspecified stop) {
if ([databaseMessage isKindOfClass:[OTRBaseMessage class]]) {
((OTRBaseMessage *)databaseMessage).error = error;
[(OTRBaseMessage *)databaseMessage saveWithTransaction:transaction];
*stop = YES;
}
}];
[transaction setMessageErrorWithElementId:message.elementID originId:message.originId stanzaId:nil error:error];
}];
}
- (void)xmppStream:(XMPPStream *)sender didFailToSendPresence:(XMPPPresence *)presence error:(NSError *)error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ import CocoaLumberjack
transaction.enumerateMessages(elementId: responseId, originId: responseId, stanzaId: nil) { (message, stop) in
if let message = message as? OTROutgoingMessage {
_deliveredMessage = message
stop.pointee = true
stop = true
}
}
if _deliveredMessage == nil {
Expand Down Expand Up @@ -146,7 +146,7 @@ import CocoaLumberjack
transaction.enumerateMessages(elementId: oid, originId: oid, stanzaId: sid) { (foundMessage, stop) in
if foundMessage.threadId == buddyUniqueId {
result = true
stop.pointee = true
stop = true
}
}
return result
Expand Down Expand Up @@ -475,6 +475,26 @@ extension String {
}

extension OTRBaseMessage {

@objc public static func message(forMessageId messageId: String, incoming: Bool, transaction: YapDatabaseReadTransaction) -> OTRMessageProtocol? {
var deliveredMessage: OTRMessageProtocol?
transaction.enumerateMessages(elementId: messageId, originId: nil, stanzaId: nil) { (message, stop) in
if message.isMessageIncoming == incoming {
deliveredMessage = message
stop = true
}
}
return deliveredMessage
}

@objc public static func message(forMessageId messageId: String, transaction: YapDatabaseReadTransaction) -> OTRMessageProtocol? {
if self is OTRIncomingMessage.Type {
return self.message(forMessageId: messageId, incoming: true, transaction: transaction)
} else {
return self.message(forMessageId: messageId, incoming: false, transaction: transaction)
}
}

/// You can override message body, for example if this is an encrypted message
convenience init(xmppMessage: XMPPMessage, body: String?, account: OTRXMPPAccount, buddy: OTRXMPPBuddy, capabilities: XMPPCapabilities) {
self.init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ import YapDatabase
if let roomMessage = message as? OTRXMPPRoomMessage,
roomMessage.senderJID == xmppMessage.from?.full {
result = roomMessage
stop.pointee = true
stop = true
} else {
DDLogWarn("Found matching MUC message but intended for different recipient \(message) \(xmppMessage)")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,21 @@ extension YapDatabaseConnection {
}
}

extension YapDatabaseReadWriteTransaction {
@objc public func setMessageError(elementId:String?, originId: String?, stanzaId:String?, error: Error) {
enumerateMessages(elementId: elementId, originId: originId, stanzaId: stanzaId) { (message, stop) in
if let databaseMessage = message as? OTRBaseMessage {
databaseMessage.error = error
databaseMessage.save(with: self)
}
}
}
}

extension YapDatabaseReadTransaction {

/// elementId is the XMPP elementId, originId and stanzaId are from XEP-0359
@objc public func enumerateMessages(elementId:String?, originId: String?, stanzaId:String?, block:@escaping (_ message:OTRMessageProtocol,_ stop:UnsafeMutablePointer<ObjCBool>) -> Void) {
public func enumerateMessages(elementId:String?, originId: String?, stanzaId:String?, block:@escaping (_ message:OTRMessageProtocol,_ stop: inout Bool) -> Void) {
guard let secondaryIndexTransaction = self.ext(SecondaryIndexName.messages) as? YapDatabaseSecondaryIndexTransaction else {
return
}
Expand All @@ -53,22 +64,22 @@ extension YapDatabaseReadTransaction {
}
let query = YapDatabaseQuery(string: queryString, parameters: parameters)

secondaryIndexTransaction.enumerateKeys(matching: query) { (collection, key, stop) -> Void in
let _ = secondaryIndexTransaction.iterateKeys(matching: query) { (collection, key, stop) -> Void in
if let message = self.object(forKey: key, inCollection: collection) as? OTRMessageProtocol {
block(message, stop)
block(message, &stop)
}
}
}

@objc public func enumerateSessions(accountKey:String, signalAddressName:String, block:@escaping (_ session:OTRSignalSession,_ stop:UnsafeMutablePointer<ObjCBool>) -> Void) {
public func enumerateSessions(accountKey:String, signalAddressName:String, block:@escaping (_ session:OTRSignalSession,_ stop: inout Bool) -> Void) {
guard let secondaryIndexTransaction = self.ext(SecondaryIndexName.signal) as? YapDatabaseSecondaryIndexTransaction else {
return
}
let queryString = "Where \(SignalIndexColumnName.session) = ?"
let query = YapDatabaseQuery(string: queryString, parameters: [OTRSignalSession.sessionKey(accountKey: accountKey, name: signalAddressName)])
secondaryIndexTransaction.enumerateKeys(matching: query) { (collection, key, stop) -> Void in
let _ = secondaryIndexTransaction.iterateKeys(matching: query) { (collection, key, stop) -> Void in
if let session = self.object(forKey: key, inCollection: collection) as? OTRSignalSession {
block(session, stop)
block(session, &stop)
}
}
}
Expand Down Expand Up @@ -97,12 +108,7 @@ extension YapDatabaseReadTransaction {
let queryString = "Where \(MessageIndexColumnName.isMessageRead) == 0"
let query = YapDatabaseQuery(string: queryString, parameters: [])

var count:UInt = 0
let success = secondaryIndexTransaction.getNumberOfRows(&count, matching: query)
if (!success) {
NSLog("Error with global numberOfUnreadMessages index")
}
return count
return secondaryIndexTransaction.numberOfRows(matching: query) ?? 0
}


Expand All @@ -114,7 +120,7 @@ extension YapDatabaseReadTransaction {
let queryString = "Where \(MessageIndexColumnName.threadId) == ? AND \(MessageIndexColumnName.isMessageRead) == 0"
let query = YapDatabaseQuery(string: queryString, parameters: [thread.threadIdentifier])
var result = [OTRMessageProtocol]()
let success = indexTransaction.enumerateKeysAndObjects(matching: query) { (collection, key, object, stop) in
let success = indexTransaction.iterateKeysAndObjects(matching: query) { (collection, key, object, stop) in
if let message = object as? OTRMessageProtocol {
result.append(message)
}
Expand All @@ -130,17 +136,17 @@ extension YapDatabaseReadTransaction {

extension YapDatabaseReadTransaction {

@objc public func enumerateUnreadMessages(_ block:@escaping (_ message:OTRMessageProtocol,_ stop:UnsafeMutablePointer<ObjCBool>) -> Void) {
public func enumerateUnreadMessages(_ block:@escaping (_ message:OTRMessageProtocol,_ stop: inout Bool) -> Void) {
guard let secondaryIndexTransaction = self.ext(SecondaryIndexName.messages) as? YapDatabaseSecondaryIndexTransaction else {
return
}
let queryString = "Where \(MessageIndexColumnName.isMessageRead) == 0"
let query = YapDatabaseQuery(string: queryString, parameters: [])
secondaryIndexTransaction.enumerateKeysAndObjects(matching: query) { (key, collection, object, stop) in
let _ = secondaryIndexTransaction.iterateKeysAndObjects(matching: query) { (key, collection, object, stop) in
if let message = object as? OTRMessageProtocol {
block(message, stop)
block(message, &stop)
} else {
DDLogError("Non-message object in messages index \(object)")
DDLogError("Non-message object in messages index \(String(describing: object))")
}
}
}
Expand Down
20 changes: 0 additions & 20 deletions ChatSecureCore/Classes/Model/Yap Storage/OTRBaseMessage.m
Original file line number Diff line number Diff line change
Expand Up @@ -272,26 +272,6 @@ + (void)deleteAllMessagesForAccountId:(NSString *)uniqueAccountId transaction:(Y
}];
}

+ (id<OTRMessageProtocol>)messageForMessageId:(NSString *)messageId incoming:(BOOL)incoming transaction:(YapDatabaseReadTransaction *)transaction {
__block id<OTRMessageProtocol> deliveredMessage = nil;
[transaction enumerateMessagesWithElementId:messageId originId:nil stanzaId:nil block:^(id<OTRMessageProtocol> _Nonnull message, BOOL * _Null_unspecified stop) {
if ([message isMessageIncoming] == incoming) {
//Media messages are not delivered until the transfer is complete. This is handled in the OTREncryptionManager.
deliveredMessage = message;
*stop = YES;
}
}];
return deliveredMessage;
}
+ (nullable id<OTRMessageProtocol>)messageForMessageId:(nonnull NSString *)messageId transaction:(nonnull YapDatabaseReadTransaction *)transaction
{
if ([self class] == [OTRIncomingMessage class]) {
return [self messageForMessageId:messageId incoming:YES transaction:transaction];
} else {
return [self messageForMessageId:messageId incoming:NO transaction:transaction];
}
}

- (id<OTRMessageProtocol>)duplicateMessage {
OTRBaseMessage *message = self;
OTRBaseMessage *newMessage = [[[self class] alloc] init];
Expand Down
9 changes: 2 additions & 7 deletions ChatSecureCore/Classes/Model/Yap Storage/OTRXMPPRoom.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import UIKit
import YapDatabase.YapDatabaseRelationship
import YapDatabase

@objc public enum RoomSecurity: Int {
/// will choose omemo if _any_ occupants have available keys
Expand Down Expand Up @@ -264,12 +264,7 @@ extension OTRXMPPRoom:OTRThreadOwner {
}
let queryString = "Where \(MessageIndexColumnName.threadId) == ? AND \(MessageIndexColumnName.isMessageRead) == 0"
let query = YapDatabaseQuery(string: queryString, parameters: [self.uniqueId])
var count:UInt = 0
let success = indexTransaction.getNumberOfRows(&count, matching: query)
if (!success) {
NSLog("Query error for OTRXMPPRoom numberOfUnreadMessagesWithTransaction")
}
return count
return indexTransaction.numberOfRows(matching: query) ?? 0
}

public var isGroupThread: Bool {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ extension OTRXMPPRoomMessage {
transaction.enumerateMessages(elementId: messageId, originId: message.originId, stanzaId: nil) { (messageProtocol, stop) in
if let message = messageProtocol as? OTRXMPPRoomMessage {
roomMessage = message
stop.pointee = true
stop = true
}
}
// Mark messages as delivered, that aren't previous incoming messages
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ extension OTRXMPPRoomOccupant {
queryString.append(")")

let query = YapDatabaseQuery(string: queryString, parameters: parameters)
let success = indexTransaction.enumerateKeysAndObjects(matching: query) { (collection, key, object, stop) in
let success = indexTransaction.iterateKeysAndObjects(matching: query) { (collection, key, object, stop) in
if let matchingOccupant = object as? OTRXMPPRoomOccupant,
matchingOccupant.jid != nil || matchingOccupant.realJID != nil {
matchingOccupants.append(matchingOccupant)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation
import ChatSecure_Push_iOS
import YapDatabase.YapDatabaseRelationship
import YapDatabase

let kDeviceAccountRelationshipEdgeName = "OTRPushDeviceAccountRelationshipEdgeName"
let kBuddyTokenRelationshipEdgeName = "OTRPushBuddyTokenRelationshipEdgeName"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,10 @@ extension OTRXMPPBuddy {
transaction: YapDatabaseReadTransaction) -> OTRXMPPBuddy? {
DDLogWarn("WARN: Using slow O(n) lookup for OTRXMPPBuddy: \(jid)")
var buddy: OTRXMPPBuddy? = nil
transaction.enumerateKeysAndObjects(inCollection: OTRXMPPBuddy.collection) { (key, object, stop) in
if let potentialMatch = object as? OTRXMPPBuddy,
potentialMatch.username == jid.bare {
transaction.iterateKeysAndObjects(inCollection: OTRXMPPBuddy.collection) { (key, potentialMatch: OTRXMPPBuddy, stop) in
if potentialMatch.username == jid.bare {
buddy = potentialMatch
stop.pointee = true
stop = true
}
}
return buddy
Expand All @@ -213,7 +212,7 @@ extension OTRXMPPBuddy {
let query = YapDatabaseQuery(string: queryString, parameters: [accountUniqueId, jid.bare])

var matchingBuddies: [OTRXMPPBuddy] = []
let success = indexTransaction.enumerateKeysAndObjects(matching: query) { (collection, key, object, stop) in
let success = indexTransaction.iterateKeysAndObjects(matching: query) { (collection, key, object, stop) in
if let matchingBuddy = object as? OTRXMPPBuddy {
matchingBuddies.append(matchingBuddy)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

import Foundation
import YapDatabase.YapDatabaseActionManager
import YapDatabase
import YapTaskQueue

@objc public enum BuddyActionType: Int {
Expand Down
2 changes: 0 additions & 2 deletions ChatSecureCore/Public/OTRBaseMessage.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)deleteAllMessagesWithTransaction:(nonnull YapDatabaseReadWriteTransaction*)transaction;
+ (void)deleteAllMessagesForBuddyId:(nonnull NSString *)uniqueBuddyId transaction:(nonnull YapDatabaseReadWriteTransaction*)transaction;
+ (void)deleteAllMessagesForAccountId:(nonnull NSString *)uniqueAccountId transaction:(nonnull YapDatabaseReadWriteTransaction*)transaction;
+ (nullable id<OTRMessageProtocol>)messageForMessageId:(nonnull NSString *)messageId incoming:(BOOL)incoming transaction:(nonnull YapDatabaseReadTransaction *)transaction;
+ (nullable id<OTRMessageProtocol>)messageForMessageId:(nonnull NSString *)messageId transaction:(nonnull YapDatabaseReadTransaction *)transaction;

- (nullable OTRXMPPBuddy*) buddyWithTransaction:(nonnull YapDatabaseReadTransaction*)transaction;

Expand Down
Loading

0 comments on commit a626fbf

Please sign in to comment.