From 43e11da0606b3bd9b8c66399b3ccc9cd78065bbb Mon Sep 17 00:00:00 2001 From: Robbie Hanson Date: Fri, 27 Mar 2015 16:17:35 -0700 Subject: [PATCH] Adding YapDatabaseHooks extension. --- .../YapDatabase.xcodeproj/project.pbxproj | 36 ++ .../Hooks/Internal/YapDatabaseHooksPrivate.h | 70 +++ .../Extensions/Hooks/YapDatabaseHooks.h | 155 +++++++ .../Extensions/Hooks/YapDatabaseHooks.m | 97 ++++ .../Hooks/YapDatabaseHooksConnection.h | 14 + .../Hooks/YapDatabaseHooksConnection.m | 112 +++++ .../Hooks/YapDatabaseHooksTransaction.h | 7 + .../Hooks/YapDatabaseHooksTransaction.m | 430 ++++++++++++++++++ .../YapDatabaseExtensionTransaction.m | 151 ++++-- 9 files changed, 1029 insertions(+), 43 deletions(-) create mode 100644 YapDatabase/Extensions/Hooks/Internal/YapDatabaseHooksPrivate.h create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooks.h create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooks.m create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.h create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.m create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.h create mode 100644 YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.m diff --git a/Testing/Xcode-mobile/YapDatabase.xcodeproj/project.pbxproj b/Testing/Xcode-mobile/YapDatabase.xcodeproj/project.pbxproj index 2a6b4edd5..340555fbe 100644 --- a/Testing/Xcode-mobile/YapDatabase.xcodeproj/project.pbxproj +++ b/Testing/Xcode-mobile/YapDatabase.xcodeproj/project.pbxproj @@ -26,6 +26,9 @@ DC2EAC3518766F5100FF4EA8 /* TestNodes.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2EAC3418766F5100FF4EA8 /* TestNodes.m */; }; DC2EAC3818767CC000FF4EA8 /* NSDictionary+YapDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2EAC3718767CC000FF4EA8 /* NSDictionary+YapDatabase.m */; }; DC36A6B71A23EEFC00DB95FB /* YapCache.m in Sources */ = {isa = PBXBuildFile; fileRef = DC36A6B61A23EEFC00DB95FB /* YapCache.m */; }; + DC36DE371AC5D3CA006D543F /* YapDatabaseHooks.m in Sources */ = {isa = PBXBuildFile; fileRef = DC36DE361AC5D3CA006D543F /* YapDatabaseHooks.m */; }; + DC36DE3B1AC60393006D543F /* YapDatabaseHooksConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = DC36DE3A1AC60393006D543F /* YapDatabaseHooksConnection.m */; }; + DC36DE401AC6060D006D543F /* YapDatabaseHooksTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = DC36DE3F1AC6060D006D543F /* YapDatabaseHooksTransaction.m */; }; DC374074185837E100DD5953 /* YapDatabaseRelationship.m in Sources */ = {isa = PBXBuildFile; fileRef = DC374073185837E100DD5953 /* YapDatabaseRelationship.m */; }; DC374079185838FD00DD5953 /* YapDatabaseRelationshipConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = DC374078185838FD00DD5953 /* YapDatabaseRelationshipConnection.m */; }; DC37407C18583C1F00DD5953 /* YapDatabaseRelationshipTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = DC37407B18583C1F00DD5953 /* YapDatabaseRelationshipTransaction.m */; }; @@ -231,6 +234,13 @@ DC2EAC3718767CC000FF4EA8 /* NSDictionary+YapDatabase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+YapDatabase.m"; sourceTree = ""; }; DC36A6B51A23EEFC00DB95FB /* YapCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YapCache.h; path = Utilities/YapCache.h; sourceTree = ""; }; DC36A6B61A23EEFC00DB95FB /* YapCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YapCache.m; path = Utilities/YapCache.m; sourceTree = ""; }; + DC36DE351AC5D3CA006D543F /* YapDatabaseHooks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YapDatabaseHooks.h; path = Hooks/YapDatabaseHooks.h; sourceTree = ""; }; + DC36DE361AC5D3CA006D543F /* YapDatabaseHooks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YapDatabaseHooks.m; path = Hooks/YapDatabaseHooks.m; sourceTree = ""; }; + DC36DE391AC60393006D543F /* YapDatabaseHooksConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YapDatabaseHooksConnection.h; path = Hooks/YapDatabaseHooksConnection.h; sourceTree = ""; }; + DC36DE3A1AC60393006D543F /* YapDatabaseHooksConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YapDatabaseHooksConnection.m; path = Hooks/YapDatabaseHooksConnection.m; sourceTree = ""; }; + DC36DE3C1AC60441006D543F /* YapDatabaseHooksPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = YapDatabaseHooksPrivate.h; path = Hooks/Internal/YapDatabaseHooksPrivate.h; sourceTree = ""; }; + DC36DE3E1AC6060D006D543F /* YapDatabaseHooksTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YapDatabaseHooksTransaction.h; path = Hooks/YapDatabaseHooksTransaction.h; sourceTree = ""; }; + DC36DE3F1AC6060D006D543F /* YapDatabaseHooksTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YapDatabaseHooksTransaction.m; path = Hooks/YapDatabaseHooksTransaction.m; sourceTree = ""; }; DC374072185837E100DD5953 /* YapDatabaseRelationship.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YapDatabaseRelationship.h; path = Relationships/YapDatabaseRelationship.h; sourceTree = ""; }; DC374073185837E100DD5953 /* YapDatabaseRelationship.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = YapDatabaseRelationship.m; path = Relationships/YapDatabaseRelationship.m; sourceTree = ""; }; DC3740751858388100DD5953 /* YapDatabaseRelationshipPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = YapDatabaseRelationshipPrivate.h; path = Relationships/Internal/YapDatabaseRelationshipPrivate.h; sourceTree = ""; }; @@ -563,6 +573,28 @@ name = Relationships; sourceTree = ""; }; + DC36DE381AC5D3D0006D543F /* Hooks */ = { + isa = PBXGroup; + children = ( + DC36DE3D1AC60445006D543F /* Internal */, + DC36DE351AC5D3CA006D543F /* YapDatabaseHooks.h */, + DC36DE361AC5D3CA006D543F /* YapDatabaseHooks.m */, + DC36DE391AC60393006D543F /* YapDatabaseHooksConnection.h */, + DC36DE3A1AC60393006D543F /* YapDatabaseHooksConnection.m */, + DC36DE3E1AC6060D006D543F /* YapDatabaseHooksTransaction.h */, + DC36DE3F1AC6060D006D543F /* YapDatabaseHooksTransaction.m */, + ); + name = Hooks; + sourceTree = ""; + }; + DC36DE3D1AC60445006D543F /* Internal */ = { + isa = PBXGroup; + children = ( + DC36DE3C1AC60441006D543F /* YapDatabaseHooksPrivate.h */, + ); + name = Internal; + sourceTree = ""; + }; DC3740711858374E00DD5953 /* Relationships */ = { isa = PBXGroup; children = ( @@ -762,6 +794,7 @@ DC3740711858374E00DD5953 /* Relationships */, DCE0CA2B18EA2A7C00F290C7 /* SearchResultsView */, DCEF93C81ABA37E3009D5604 /* CloudKit */, + DC36DE381AC5D3D0006D543F /* Hooks */, ); path = Extensions; sourceTree = ""; @@ -1180,6 +1213,7 @@ DC9B0FE0184B143800174B0F /* YapDatabaseFullTextSearchTransaction.m in Sources */, DC43439319BB8886000DE27A /* YapWhitelistBlacklist.m in Sources */, DC3D2EBD1673FF6800DFAFAA /* DDASLLogger.m in Sources */, + DC36DE371AC5D3CA006D543F /* YapDatabaseHooks.m in Sources */, DCEF93EF1ABA37E3009D5604 /* YDBCKRecord.m in Sources */, DC9B0FBB184B12C000174B0F /* YapDatabaseExtensionConnection.m in Sources */, DC3D2EBF1673FF6800DFAFAA /* DDFileLogger.m in Sources */, @@ -1195,6 +1229,7 @@ DCEF93EA1ABA37E3009D5604 /* YDBCKChangeRecord.m in Sources */, DCEF93F51ABA37E3009D5604 /* YapDatabaseCloudKitTypes.m in Sources */, DC2C98AB17E3C82900F1E04F /* YapDatabaseViewPage.mm in Sources */, + DC36DE3B1AC60393006D543F /* YapDatabaseHooksConnection.m in Sources */, DC86B2AF18EBAA600064BF6B /* YapDatabaseSearchQueue.m in Sources */, DC882C6F192C1BF3004C3166 /* YapDatabaseSecondaryIndexOptions.m in Sources */, DCA2AE00195E21BA00B5E7CA /* YapDatabaseSearchResultsViewOptions.m in Sources */, @@ -1242,6 +1277,7 @@ DCEF93F11ABA37E3009D5604 /* YapDatabaseCloudKit.m in Sources */, DC5BB36A194BDAC0001A59A0 /* DDContextFilterLogFormatter.m in Sources */, DCA2AE02195E21C000B5E7CA /* YapDatabaseSearchResultsViewTransaction.m in Sources */, + DC36DE401AC6060D006D543F /* YapDatabaseHooksTransaction.m in Sources */, DC2C98AC17E3C82900F1E04F /* YapDatabaseViewPageMetadata.m in Sources */, DCEF93F01ABA37E3009D5604 /* YDBCKRecordInfo.m in Sources */, DC9B0FF3184B154C00174B0F /* YapDatabaseFullTextSearchSnippetOptions.m in Sources */, diff --git a/YapDatabase/Extensions/Hooks/Internal/YapDatabaseHooksPrivate.h b/YapDatabase/Extensions/Hooks/Internal/YapDatabaseHooksPrivate.h new file mode 100644 index 000000000..1b60f9824 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/Internal/YapDatabaseHooksPrivate.h @@ -0,0 +1,70 @@ +#import + +#import "YapDatabase.h" +#import "YapDatabaseConnection.h" +#import "YapDatabaseTransaction.h" + +#import "YapDatabaseHooks.h" +#import "YapDatabaseHooksConnection.h" +#import "YapDatabaseHooksTransaction.h" + + +@interface YapDatabaseHooks () { +@public + + YapWhitelistBlacklist *allowedCollections; + + YDBHooks_WillInsertObject willInsertObject; + YDBHooks_DidInsertObject didInsertObject; + + YDBHooks_WillUpdateObject willUpdateObject; + YDBHooks_DidInsertObject didUpdateObject; + + YDBHooks_WillReplaceObject willReplaceObject; + YDBHooks_DidReplaceObject didReplaceObject; + + YDBHooks_WillReplaceMetadata willReplaceMetadata; + YDBHooks_DidReplaceMetadata didReplaceMetadata; + + YDBHooks_WillRemoveObject willRemoveObject; + YDBHooks_DidRemoveObject didRemoveObject; + + YDBHooks_WillRemoveObjects willRemoveObjects; + YDBHooks_DidRemoveObjects didRemoveObjects; + + YDBHooks_WillRemoveAllObjectsInAllCollections willRemoveAllObjectsInAllCollections; + YDBHooks_DidRemoveAllObjectsInAllCollections didRemoveAllObjectsInAllCollections; +} + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface YapDatabaseHooksConnection () { +@public + + __strong YapDatabaseHooks *parent; + __unsafe_unretained YapDatabaseConnection *databaseConnection; +} + +- (id)initWithParent:(YapDatabaseHooks *)inParent databaseConnection:(YapDatabaseConnection *)inDbC; + +@end + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark - +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@interface YapDatabaseHooksTransaction () { +@protected + + __unsafe_unretained YapDatabaseHooksConnection *parentConnection; + __unsafe_unretained YapDatabaseReadTransaction *databaseTransaction; +} + +- (id)initWithParentConnection:(YapDatabaseHooksConnection *)parentConnection + databaseTransaction:(YapDatabaseReadTransaction *)databaseTransaction; + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooks.h b/YapDatabase/Extensions/Hooks/YapDatabaseHooks.h new file mode 100644 index 000000000..a5d11b191 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooks.h @@ -0,0 +1,155 @@ +#import + +#import "YapDatabase.h" +#import "YapDatabaseExtension.h" +#import "YapWhitelistBlacklist.h" + +/** + * WillInsert & DidInsert + * + * An insert means that the collection/key tuple does not currently exist in the database. + * So the object & metadata items are getting inserted / added. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: +**/ +typedef void (^YDBHooks_WillInsertObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object, id metadata); + +typedef void (^YDBHooks_DidInsertObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object, id metadata); + +/** + * WillUpdate & DidUpdate + * + * An update means that the collection/key tuple currently exists in the database. + * So the object & metadata items are getting changed to the given values. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: +**/ + +typedef void (^YDBHooks_WillUpdateObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object, id metadata); + +typedef void (^YDBHooks_DidUpdateObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object, id metadata); + +/** + * WillReplaceObject & DidReplaceObject + * + * Replace means that the collection/key tuple currently exists in the database. + * Furthermore, only the object is getting changed. + * Whatever value the metadata was before isn't being modified. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceObject:forKey:inCollection: + * - replaceObject:forKey:inCollection:withSerializedObject: +**/ + +typedef void (^YDBHooks_WillReplaceObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object); + +typedef void (^YDBHooks_DidReplaceObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id object); + +/** + * WillReplaceMetadata & DidReplaceMetadata + * + * Replace means that the collection/key tuple currently exists in the database. + * Furthermore, only the metadata is getting changed. + * Whatever value the object was before isn't being modified. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceMetadata:forKey:inCollection: + * - replaceMetadata:forKey:inCollection:withSerializedMetadata: +**/ + +typedef void (^YDBHooks_WillReplaceMetadata) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id metadata); + +typedef void (^YDBHooks_DidReplaceMetadata) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key, id metadata); + +/** + * WillRemoveObject & DidRemoveObject + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectForKey:inCollection: +**/ + +typedef void (^YDBHooks_WillRemoveObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key); + +typedef void (^YDBHooks_DidRemoveObject) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSString *key); + +/** + * WillRemoveObjects & DidRemoveObjects + * + * Note: If removeObjectsForKeys:inCollection: is invoked with a particularly large array, + * then YapDatabase may invoke these methods multiple times because it may split the large array + * into multiple smaller arrays. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectsForKeys:inCollection: + * - removeAllObjectsInCollection: +**/ + +typedef void (^YDBHooks_WillRemoveObjects) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSArray *keys); + +typedef void (^YDBHooks_DidRemoveObjects) + (YapDatabaseReadWriteTransaction *transaction, NSString *collection, NSArray *keys); + +/** + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeAllObjectsInAllCollections +**/ + +typedef void (^YDBHooks_WillRemoveAllObjectsInAllCollections) + (YapDatabaseReadWriteTransaction *transaction); + +typedef void (^YDBHooks_DidRemoveAllObjectsInAllCollections) + (YapDatabaseReadWriteTransaction *transaction); + + + + +@interface YapDatabaseHooks : YapDatabaseExtension + +- (instancetype)init; + +/** + * All properties must be set BEFORE the extension is registered. + * Once registered, the properties become immutable. +**/ + +@property (atomic, strong, readwrite) YapWhitelistBlacklist *allowedCollections; + +@property (atomic, strong, readwrite) YDBHooks_WillInsertObject willInsertObject; +@property (atomic, strong, readwrite) YDBHooks_DidInsertObject didInsertObject; + +@property (atomic, strong, readwrite) YDBHooks_WillUpdateObject willUpdateObject; +@property (atomic, strong, readwrite) YDBHooks_DidInsertObject didUpdateObject; + +@property (atomic, strong, readwrite) YDBHooks_WillReplaceObject willReplaceObject; +@property (atomic, strong, readwrite) YDBHooks_DidReplaceObject didReplaceObject; + +@property (atomic, strong, readwrite) YDBHooks_WillReplaceMetadata willReplaceMetadata; +@property (atomic, strong, readwrite) YDBHooks_DidReplaceMetadata didReplaceMetadata; + +@property (atomic, strong, readwrite) YDBHooks_WillRemoveObject willRemoveObject; +@property (atomic, strong, readwrite) YDBHooks_DidRemoveObject didRemoveObject; + +@property (atomic, strong, readwrite) YDBHooks_WillRemoveObjects willRemoveObjects; +@property (atomic, strong, readwrite) YDBHooks_DidRemoveObjects didRemoveObjects; + +@property (atomic, strong, readwrite) YDBHooks_WillRemoveAllObjectsInAllCollections willRemoveAllObjectsInAllCollections; +@property (atomic, strong, readwrite) YDBHooks_DidRemoveAllObjectsInAllCollections didRemoveAllObjectsInAllCollections; + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooks.m b/YapDatabase/Extensions/Hooks/YapDatabaseHooks.m new file mode 100644 index 000000000..fbc8d1678 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooks.m @@ -0,0 +1,97 @@ +#import "YapDatabaseHooks.h" +#import "YapDatabaseHooksPrivate.h" + + +@implementation YapDatabaseHooks + +/** + * Subclasses MUST implement this method. + * + * This method is used when unregistering an extension in order to drop the related tables. + * + * @param registeredName + * The name the extension was registered using. + * The extension should be able to generated the proper table name(s) using the given registered name. + * + * @param transaction + * A readWrite transaction for proper database access. + * + * @param wasPersistent + * If YES, then the extension should drop tables from sqlite. + * If NO, then the extension should unregister the proper YapMemoryTable(s). +**/ ++ (void)dropTablesForRegisteredName:(NSString *)registeredName + withTransaction:(YapDatabaseReadWriteTransaction *)transaction + wasPersistent:(BOOL)wasPersistent +{ + // Nothing to do here... +} + +- (instancetype)init +{ + if ((self = [super init])) + { + // Nothing to do here + } + return self; +} + +/** + * Subclasses MUST implement this method IF they are non-persistent (in-memory only). + * By doing so, they allow various optimizations, such as not persisting extension info in the yap2 table. +**/ +- (BOOL)isPersistent +{ + return NO; +} + +/** + * Subclasses MUST implement this method. + * Returns a proper instance of the YapDatabaseExtensionConnection subclass. +**/ +- (YapDatabaseExtensionConnection *)newConnection:(YapDatabaseConnection *)databaseConnection +{ + return [[YapDatabaseHooksConnection alloc] initWithParent:self databaseConnection:databaseConnection]; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Properties +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +@synthesize allowedCollections = allowedCollections; + +@synthesize willInsertObject = willInsertObject; +@synthesize didInsertObject = didInsertObject; + +@synthesize willUpdateObject = willUpdateObject; +@synthesize didUpdateObject = didUpdateObject; + +@synthesize willReplaceObject = willReplaceObject; +@synthesize didReplaceObject = didReplaceObject; + +@synthesize willReplaceMetadata = willReplaceMetadata; +@synthesize didReplaceMetadata = didReplaceMetadata; + +@synthesize willRemoveObject = willRemoveObject; +@synthesize didRemoveObject = didRemoveObject; + +@synthesize willRemoveObjects = willRemoveObjects; +@synthesize didRemoveObjects = didRemoveObjects; + +@synthesize willRemoveAllObjectsInAllCollections = willRemoveAllObjectsInAllCollections; +@synthesize didRemoveAllObjectsInAllCollections = didRemoveAllObjectsInAllCollections; + +- (void)willChangeValueForKey:(NSString *)key +{ + if (self.registeredName) + { + NSString *reason = + @"YapDatabaseHooks properties cannot be changed after the extension has been registered."; + + @throw [NSException exceptionWithName:@"YapDatabaseHooks" reason:reason userInfo:nil]; + } + + [super willChangeValueForKey:key]; +} + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.h b/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.h new file mode 100644 index 000000000..7304537a2 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.h @@ -0,0 +1,14 @@ +#import +#import "YapDatabaseExtensionConnection.h" + +@class YapDatabaseHooks; + + +@interface YapDatabaseHooksConnection : YapDatabaseExtensionConnection + +/** + * Returns the parent extension instance. +**/ +@property (nonatomic, strong, readonly) YapDatabaseHooks *parent; + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.m b/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.m new file mode 100644 index 000000000..a97d83c5a --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooksConnection.m @@ -0,0 +1,112 @@ +#import "YapDatabaseHooksConnection.h" +#import "YapDatabaseHooksPrivate.h" +#import "YapDatabaseLogging.h" + +/** + * Define log level for this file: OFF, ERROR, WARN, INFO, VERBOSE + * See YapDatabaseLogging.h for more information. + **/ +#if DEBUG + static const int ydbLogLevel = YDB_LOG_LEVEL_OFF; +#else + static const int ydbLogLevel = YDB_LOG_LEVEL_OFF; +#endif +#pragma unused(ydbLogLevel) + + +@implementation YapDatabaseHooksConnection + +@synthesize parent = parent; + +- (id)initWithParent:(YapDatabaseHooks *)inParent databaseConnection:(YapDatabaseConnection *)inDbC +{ + if ((self = [super init])) + { + parent = inParent; + databaseConnection = inDbC; + } + return self; +} + +/** + * Subclasses MUST implement this method. + * Returns a reference to the parent (base class). + * + * This method is used by various general utility classes in order to + * walk-the-chain: extension <-> extConnection <-> extTransaction. + * + * For example: + * Given an extTransaction, the utility method can walk up to the base extension class, and fetch the registeredName. +**/ +- (YapDatabaseExtension *)extension +{ + return parent; +} + +/** + * YapDatabaseExtensionConnection subclasses MUST implement this method. +**/ +- (void)_flushMemoryWithFlags:(YapDatabaseConnectionFlushMemoryFlags)flags +{ + // Nothing to do here +} + +/** + * YapDatabaseExtensionConnection subclasses MUST implement this method. +**/ +- (void)getInternalChangeset:(NSMutableDictionary **)internalPtr + externalChangeset:(NSMutableDictionary **)externalPtr + hasDiskChanges:(BOOL *)hasDiskChangesPtr +{ + // Nothing to do here + + *internalPtr = nil; + *externalPtr = nil; + *hasDiskChangesPtr = NO; +} + +/** + * YapDatabaseExtensionConnection subclasses MUST implement this method. +**/ +- (void)processChangeset:(NSDictionary *)changeset +{ + // Nothing to do here +} + +/** + * Subclasses MUST implement this method. + * It should create and return a proper instance of the YapDatabaseExtensionTransaction subclass. + * + * You may optionally use different subclasses for read-only vs read-write transactions. + * Alternatively you can just store an ivar to determine the type of the transaction in order to protect as needed. +**/ +- (id)newReadTransaction:(YapDatabaseReadTransaction *)databaseTransaction +{ + YDBLogAutoTrace(); + + YapDatabaseHooksTransaction *transaction = + [[YapDatabaseHooksTransaction alloc] initWithParentConnection:self + databaseTransaction:databaseTransaction]; + + return transaction; +} + +/** + * Subclasses MUST implement this method. + * It should create and return a proper instance of the YapDatabaseExtensionTransaction subclass. + * + * You may optionally use different subclasses for read-only vs read-write transactions. + * Alternatively you can just store an ivar to determine the type of the transaction in order to protect as needed. +**/ +- (id)newReadWriteTransaction:(YapDatabaseReadWriteTransaction *)databaseTransaction +{ + YDBLogAutoTrace(); + + YapDatabaseHooksTransaction *transaction = + [[YapDatabaseHooksTransaction alloc] initWithParentConnection:self + databaseTransaction:databaseTransaction]; + + return transaction; +} + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.h b/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.h new file mode 100644 index 000000000..36807eac5 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.h @@ -0,0 +1,7 @@ +#import +#import "YapDatabaseExtensionTransaction.h" + + +@interface YapDatabaseHooksTransaction : YapDatabaseExtensionTransaction + +@end diff --git a/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.m b/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.m new file mode 100644 index 000000000..ad93d4211 --- /dev/null +++ b/YapDatabase/Extensions/Hooks/YapDatabaseHooksTransaction.m @@ -0,0 +1,430 @@ +#import "YapDatabaseHooksTransaction.h" +#import "YapDatabaseHooksPrivate.h" + + +@implementation YapDatabaseHooksTransaction + +- (id)initWithParentConnection:(YapDatabaseHooksConnection *)inParentConnection + databaseTransaction:(YapDatabaseReadTransaction *)inDatabaseTransaction +{ + if ((self = [super init])) + { + parentConnection = inParentConnection; + databaseTransaction = inDatabaseTransaction; + } + return self; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Creation +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement this method. +**/ +- (BOOL)createIfNeeded +{ + // Nothing to do here + return YES; +} + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement this method. +**/ +- (BOOL)prepareIfNeeded +{ + // Nothing to do here + return YES; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Commit & Rollback +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement this method. +**/ +- (void)didCommitTransaction +{ + parentConnection = nil; + databaseTransaction = nil; +} + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement this method. +**/ +- (void)didRollbackTransaction +{ + parentConnection = nil; + databaseTransaction = nil; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Generic Accessors +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement these methods. + * They are needed by various utility methods. +**/ +- (YapDatabaseReadTransaction *)databaseTransaction +{ + return databaseTransaction; +} + +/** + * YapDatabaseExtensionTransaction subclasses MUST implement these methods. + * They are needed by various utility methods. +**/ +- (YapDatabaseExtensionConnection *)extensionConnection +{ + return parentConnection; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Hooks +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being inserted, meaning there is not currently an entry for the collection/key tuple. +**/ +- (void)handleInsertObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withMetadata:(id)metadata + rowid:(int64_t)rowid +{ + if (parentConnection->parent->didInsertObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didInsertObject(transaction, ck.collection, ck.key, object, metadata); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being modified, meaning there is already an entry for the collection/key tuple which is being modified. +**/ +- (void)handleUpdateObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withMetadata:(id)metadata + rowid:(int64_t)rowid +{ + if (parentConnection->parent->didUpdateObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didUpdateObject(transaction, ck.collection, ck.key, object, metadata); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceObject:forKey:inCollection: + * - replaceObject:forKey:inCollection:withSerializedObject: + * + * There is already a row for the collection/key tuple, and only the object is being modified (metadata untouched). +**/ +- (void)handleReplaceObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withRowid:(int64_t)rowid +{ + if (parentConnection->parent->didReplaceObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didReplaceObject(transaction, ck.collection, ck.key, object); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceMetadata:forKey:inCollection: + * - replaceMetadata:forKey:inCollection:withSerializedMetadata: + * + * There is already a row for the collection/key tuple, and only the metadata is being modified (object untouched). +**/ +- (void)handleReplaceMetadata:(id)metadata + forCollectionKey:(YapCollectionKey *)ck + withRowid:(int64_t)rowid +{ + if (parentConnection->parent->didReplaceMetadata) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didReplaceMetadata(transaction, ck.collection, ck.key, metadata); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - touchObjectForKey:inCollection:collection: +**/ +- (void)handleTouchObjectForCollectionKey:(YapCollectionKey *)ck withRowid:(int64_t)rowid +{ + // Nothing to do here +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - touchMetadataForKey:inCollection: +**/ +- (void)handleTouchMetadataForCollectionKey:(YapCollectionKey *)ck withRowid:(int64_t)rowid +{ + // Nothing to do here +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction + * - removeObjectForKey:inCollection: +**/ +- (void)handleRemoveObjectForCollectionKey:(YapCollectionKey *)ck withRowid:(int64_t)rowid +{ + if (parentConnection->parent->didRemoveObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didRemoveObject(transaction, ck.collection, ck.key); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectsForKeys:inCollection: + * - removeAllObjectsInCollection: + * + * IMPORTANT: + * The number of items passed to this method has the following guarantee: + * count <= (SQLITE_LIMIT_VARIABLE_NUMBER - 1) + * + * The YapDatabaseReadWriteTransaction will inspect the list of keys that are to be removed, + * and then loop over them in "chunks" which are readily processable for extensions. +**/ +- (void)handleRemoveObjectsForKeys:(NSArray *)keys inCollection:(NSString *)collection withRowids:(NSArray *)rowids +{ + if (parentConnection->parent->didRemoveObjects) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didRemoveObjects(transaction, collection, keys); + } +} + +/** + * Subclasses MUST implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * + * Corresponds to [transaction removeAllObjectsInAllCollections]. +**/ +- (void)handleRemoveAllObjectsInAllCollections +{ + if (parentConnection->parent->didRemoveAllObjectsInAllCollections) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->didRemoveAllObjectsInAllCollections(transaction); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#pragma mark Pre-Hooks +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being inserted, meaning there is not currently an entry for the collection/key tuple. +**/ +- (void)handleWillInsertObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withMetadata:(id)metadata +{ + if (parentConnection->parent->willInsertObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willInsertObject(transaction, ck.collection, ck.key, object, metadata); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being modified, meaning there is already an entry for the collection/key tuple which is being modified. +**/ +- (void)handleWillUpdateObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withMetadata:(id)metadata + rowid:(int64_t)rowid +{ + if (parentConnection->parent->willUpdateObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willUpdateObject(transaction, ck.collection, ck.key, object, metadata); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceObject:forKey:inCollection: + * - replaceObject:forKey:inCollection:withSerializedObject: + * + * There is already a row for the collection/key tuple, and only the object is being modified (metadata untouched). +**/ +- (void)handleWillReplaceObject:(id)object + forCollectionKey:(YapCollectionKey *)ck + withRowid:(int64_t)rowid +{ + if (parentConnection->parent->willReplaceObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willReplaceObject(transaction, ck.collection, ck.key, object); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceMetadata:forKey:inCollection: + * - replaceMetadata:forKey:inCollection:withSerializedMetadata: + * + * There is already a row for the collection/key tuple, and only the metadata is being modified (object untouched). +**/ +- (void)handleWillReplaceMetadata:(id)metadata + forCollectionKey:(YapCollectionKey *)ck + withRowid:(int64_t)rowid +{ + if (parentConnection->parent->willReplaceMetadata) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willReplaceMetadata(transaction, ck.collection, ck.key, metadata); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectForKey:inCollection: +**/ +- (void)handleWillRemoveObjectForCollectionKey:(YapCollectionKey *)ck withRowid:(int64_t)rowid +{ + if (parentConnection->parent->willRemoveObject) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willRemoveObject(transaction, ck.collection, ck.key); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectsForKeys:inCollection: + * - removeAllObjectsInCollection: + * + * IMPORTANT: + * The number of items passed to this method has the following guarantee: + * count <= (SQLITE_LIMIT_VARIABLE_NUMBER - 1) + * + * The YapDatabaseReadWriteTransaction will inspect the list of keys that are to be removed, + * and then loop over them in "chunks" which are readily processable for extensions. +**/ +- (void)handleWillRemoveObjectsForKeys:(NSArray *)keys inCollection:(NSString *)collection withRowids:(NSArray *)rowids +{ + if (parentConnection->parent->willRemoveObjects) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willRemoveObjects(transaction, collection, keys); + } +} + +/** + * Subclasses may OPTIONALLY implement this method. + * YapDatabaseReadWriteTransaction Hook, invoked pre-op. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeAllObjectsInAllCollections +**/ +- (void)handleWillRemoveAllObjectsInAllCollections +{ + if (parentConnection->parent->willRemoveAllObjectsInAllCollections) + { + __unsafe_unretained YapDatabaseReadWriteTransaction *transaction = + (YapDatabaseReadWriteTransaction *)databaseTransaction; + + parentConnection->parent->willRemoveAllObjectsInAllCollections(transaction); + } +} + +@end diff --git a/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m b/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m index 4edb899bd..8628426b1 100644 --- a/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m +++ b/YapDatabase/Extensions/Protocol/YapDatabaseExtensionTransaction.m @@ -68,7 +68,7 @@ @implementation YapDatabaseExtensionTransaction { * as well as possibly populating the tables by enumerating over the existing rows in the database. * * The method should check to see if it has already been created. - * That is, is this a re-registration from a subsequent app launch, + * That is, is this a re-registration from a previous app launch, * or is this the first time the extension has been registered under this name? * * The recommended way of accomplishing this is via the yap2 table (which was designed for this purpose). @@ -222,10 +222,15 @@ - (YapDatabaseExtensionConnection *)extensionConnection //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction setObject:object forKey:key inCollection:collection] & - * [transaction setObject:object forKey:key inCollection:collection withMetadata:metadata] - * where the object is being inserted (value for collection/key does NOT exist at the moment this method is called). + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being inserted, meaning there is not currently an entry for the collection/key tuple. **/ - (void)handleInsertObject:(id)object forCollectionKey:(YapCollectionKey *)collectionKey @@ -236,10 +241,15 @@ - (void)handleInsertObject:(id)object } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction setObject:object forKey:key inCollection:collection] & - * [transaction setObject:object forKey:key inCollection:collection withMetadata:metadata] - * where the object is being updated (value for collection/key DOES exist, and is being updated/changed). + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being modified, meaning there is already an entry for the collection/key tuple which is being modified. **/ - (void)handleUpdateObject:(id)object forCollectionKey:(YapCollectionKey *)collectionKey @@ -250,8 +260,14 @@ - (void)handleUpdateObject:(id)object } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction replaceObject:object forKey:key inCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceObject:forKey:inCollection: + * - replaceObject:forKey:inCollection:withSerializedObject: + * + * There is already a row for the collection/key tuple, and only the object is being modified (metadata untouched). **/ - (void)handleReplaceObject:(id)object forCollectionKey:(YapCollectionKey *)collectionKey @@ -261,8 +277,14 @@ - (void)handleReplaceObject:(id)object } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction replaceMetadata:metadata forKey:key inCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceMetadata:forKey:inCollection: + * - replaceMetadata:forKey:inCollection:withSerializedMetadata: + * + * There is already a row for the collection/key tuple, and only the metadata is being modified (object untouched). **/ - (void)handleReplaceMetadata:(id)metadata forCollectionKey:(YapCollectionKey *)collectionKey @@ -272,8 +294,11 @@ - (void)handleReplaceMetadata:(id)metadata } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction touchObjectForKey:key inCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - touchObjectForKey:inCollection:collection: **/ - (void)handleTouchObjectForCollectionKey:(YapCollectionKey *)collectionKey withRowid:(int64_t)rowid { @@ -281,8 +306,11 @@ - (void)handleTouchObjectForCollectionKey:(YapCollectionKey *)collectionKey with } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction touchMetadataForKey:key inCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - touchMetadataForKey:inCollection: **/ - (void)handleTouchMetadataForCollectionKey:(YapCollectionKey *)collectionKey withRowid:(int64_t)rowid { @@ -290,8 +318,11 @@ - (void)handleTouchMetadataForCollectionKey:(YapCollectionKey *)collectionKey wi } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * Corresponds to [transaction removeObjectForKey:key inCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction + * - removeObjectForKey:inCollection: **/ - (void)handleRemoveObjectForCollectionKey:(YapCollectionKey *)collectionKey withRowid:(int64_t)rowid { @@ -299,10 +330,12 @@ - (void)handleRemoveObjectForCollectionKey:(YapCollectionKey *)collectionKey wit } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. - * - * Corresponds to [transaction removeObjectsForKeys:keys inCollection:collection] & - * [transaction removeAllObjectsInCollection:collection]. + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectsForKeys:inCollection: + * - removeAllObjectsInCollection: * * IMPORTANT: * The number of items passed to this method has the following guarantee: @@ -317,7 +350,9 @@ - (void)handleRemoveObjectsForKeys:(NSArray *)keys inCollection:(NSString *)coll } /** + * Subclasses MUST implement this method. * YapDatabaseReadWriteTransaction Hook, invoked post-op. + * * Corresponds to [transaction removeAllObjectsInAllCollections]. **/ - (void)handleRemoveAllObjectsInAllCollections @@ -332,67 +367,93 @@ - (void)handleRemoveAllObjectsInAllCollections /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction setObject:object forKey:key inCollection:collection] & - * [transaction setObject:object forKey:key inCollection:collection withMetadata:metadata] - * where the object is being inserted (value for collection/key does NOT exist at the moment this method is called). - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being inserted, meaning there is not currently an entry for the collection/key tuple. +**/ - (void)handleWillInsertObject:(id)object - forCollectionKey:(YapCollectionKey *)collectionKey - withMetadata:(id)metadata + forCollectionKey:(YapCollectionKey *)collectionKey + withMetadata:(id)metadata { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction setObject:object forKey:key inCollection:collection] & - * [transaction setObject:object forKey:key inCollection:collection withMetadata:metadata] - * where the object is being updated (value for collection/key DOES exist, and is being updated/changed). - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - setObject:forKey:inCollection: + * - setObject:forKey:inCollection:withMetadata: + * - setObject:forKey:inCollection:withMetadata:serializedObject:serializedMetadata: + * + * The row is being modified, meaning there is already an entry for the collection/key tuple which is being modified. +**/ - (void)handleWillUpdateObject:(id)object - forCollectionKey:(YapCollectionKey *)collectionKey - withMetadata:(id)metadata - rowid:(int64_t)rowid + forCollectionKey:(YapCollectionKey *)collectionKey + withMetadata:(id)metadata + rowid:(int64_t)rowid { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction replaceObject:object forKey:key inCollection:collection]. - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceObject:forKey:inCollection: + * - replaceObject:forKey:inCollection:withSerializedObject: + * + * There is already a row for the collection/key tuple, and only the object is being modified (metadata untouched). +**/ - (void)handleWillReplaceObject:(id)object - forCollectionKey:(YapCollectionKey *)collectionKey - withRowid:(int64_t)rowid + forCollectionKey:(YapCollectionKey *)collectionKey + withRowid:(int64_t)rowid { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction replaceMetadata:metadata forKey:key inCollection:collection]. - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - replaceMetadata:forKey:inCollection: + * - replaceMetadata:forKey:inCollection:withSerializedMetadata: + * + * There is already a row for the collection/key tuple, and only the metadata is being modified (object untouched). +**/ - (void)handleWillReplaceMetadata:(id)metadata - forCollectionKey:(YapCollectionKey *)collectionKey - withRowid:(int64_t)rowid + forCollectionKey:(YapCollectionKey *)collectionKey + withRowid:(int64_t)rowid { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction removeObjectForKey:key inCollection:collection]. - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectForKey:inCollection: +**/ - (void)handleWillRemoveObjectForCollectionKey:(YapCollectionKey *)collectionKey withRowid:(int64_t)rowid { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. * - * Corresponds to [transaction removeObjectsForKeys:keys inCollection:collection] & - * [transaction removeAllObjectsInCollection:collection]. + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeObjectsForKeys:inCollection: + * - removeAllObjectsInCollection: * * IMPORTANT: * The number of items passed to this method has the following guarantee: @@ -400,18 +461,22 @@ - (void)handleWillRemoveObjectForCollectionKey:(YapCollectionKey *)collectionKey * * The YapDatabaseReadWriteTransaction will inspect the list of keys that are to be removed, * and then loop over them in "chunks" which are readily processable for extensions. - **/ +**/ - (void)handleWillRemoveObjectsForKeys:(NSArray *)keys inCollection:(NSString *)collection withRowids:(NSArray *)rowids { + // Override me if needed } /** * Subclasses may OPTIONALLY implement this method. * YapDatabaseReadWriteTransaction Hook, invoked pre-op. - * Corresponds to [transaction removeAllObjectsInAllCollections]. - **/ + * + * Corresponds to the following method(s) in YapDatabaseReadWriteTransaction: + * - removeAllObjectsInAllCollections +**/ - (void)handleWillRemoveAllObjectsInAllCollections { + // Override me if needed } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////