session-ios-yap-database/YapDatabase/YapDatabaseTransaction.h

804 lines
37 KiB
Objective-C

#import <Foundation/Foundation.h>
@class YapDatabaseConnection;
@class YapDatabaseExtensionTransaction;
NS_ASSUME_NONNULL_BEGIN
/**
* Welcome to YapDatabase!
*
* The project page has a wealth of documentation if you have any questions.
* https://github.com/yapstudios/YapDatabase
*
* If you're new to the project you may want to visit the wiki.
* https://github.com/yapstudios/YapDatabase/wiki
*
* Transactions represent atomic access to a database.
* There are two types of transactions:
* - Read-Only transactions
* - Read-Write transactions
*
* Once a transaction is started, all data access within the transaction from that point forward until completion
* represents an atomic "snapshot" of the current state of the database. For example, if a read-write operation
* occurs in parallel with a read-only transaction, the read-only transaction won't see the changes made by
* the read-write operation. But once the read-write operation completes, all transactions started from that point
* forward will see the changes.
*
* You first create and configure a YapDatabase instance.
* Then you can spawn one or more connections to the database file.
* Each connection allows you to execute transactions in a serial fashion.
* For concurrent access, you can create multiple connections,
* and execute transactions on each connection simulataneously.
*
* Concurrency is straight-forward. Here are the rules:
*
* - You can have multiple connections.
* - Every connection is thread-safe.
* - You can have multiple read-only transactions simultaneously without blocking.
* (Each simultaneous transaction would be going through a separate connection.)
* - You can have multiple read-only transactions and a single read-write transaction simultaneously without blocking.
* (Each simultaneous transaction would be going through a separate connection.)
* - There can only be a single transaction per connection at a time.
* (Transactions go through a per-connection serial queue.)
* - There can only be a single read-write transaction at a time.
* (Read-write transactions go through a per-database serial queue.)
**/
/**
* A YapDatabaseReadTransaction encompasses a single read-only database transaction.
* You can execute multiple operations within a single transaction.
*
* A transaction allows you to safely access the database as needed in a thread-safe and optimized manner.
**/
@interface YapDatabaseReadTransaction : NSObject
/**
* Transactions are light-weight objects created by connections.
*
* Connections are the parent objects of transactions.
* Connections own the transaction objects.
*
* Transactions store nearly all their state in the parent connection object.
* This reduces the memory requirements for transactions objects,
* and reduces the overhead associated in creating them.
**/
@property (nonatomic, unsafe_unretained, readonly) YapDatabaseConnection *connection;
/**
* The userInfo property allows arbitrary info to be associated with the transaction.
* This propery is not used by YapDatabaseTransaction in any way.
*
* Keep in mind that transactions are short lived objects.
* Each transaction is a new/different transaction object.
**/
@property (nonatomic, strong, readwrite, nullable) id userInfo;
#pragma mark Count
/**
* Returns the total number of collections.
* Each collection may have 1 or more key/object pairs.
**/
- (NSUInteger)numberOfCollections;
/**
* Returns the total number of keys in the given collection.
* Returns zero if the collection doesn't exist (or all key/object pairs from the collection have been removed).
**/
- (NSUInteger)numberOfKeysInCollection:(nullable NSString *)collection;
/**
* Returns the total number of key/object pairs in the entire database (including all collections).
**/
- (NSUInteger)numberOfKeysInAllCollections;
#pragma mark List
/**
* Returns a list of all collection names.
*
* If the list of collections is really big, it may be more efficient to enumerate them instead.
* @see enumerateCollectionsUsingBlock:
**/
- (NSArray<NSString *> *)allCollections;
/**
* Returns a list of all keys in the given collection.
*
* If the list of keys is really big, it may be more efficient to enumerate them instead.
* @see enumerateKeysInCollection:usingBlock:
**/
- (NSArray<NSString *> *)allKeysInCollection:(nullable NSString *)collection;
#pragma mark Object & Metadata
/**
* Object access.
* Objects are automatically deserialized using database's configured deserializer.
**/
- (nullable id)objectForKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Returns whether or not the given key/collection exists in the database.
**/
- (BOOL)hasObjectForKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Provides access to both object and metadata in a single call.
*
* @return YES if the key exists in the database. NO otherwise, in which case both object and metadata will be nil.
**/
- (BOOL)getObject:(__nullable id * __nullable)objectPtr
metadata:(__nullable id * __nullable)metadataPtr
forKey:(NSString *)key
inCollection:(nullable NSString *)collection;
/**
* Provides access to the metadata.
* This fetches directly from the metadata dictionary stored in memory, and thus never hits the disk.
**/
- (nullable id)metadataForKey:(NSString *)key inCollection:(nullable NSString *)collection;
#pragma mark Primitive
/**
* Primitive access.
* This method is available in-case you have a need to fetch the raw serializedObject from the database.
*
* This method is slower than objectForKey:inCollection:, since that method makes use of the objectCache.
* In contrast, this method always fetches the raw data from disk.
*
* @see objectForKey:inCollection:
**/
- (nullable NSData *)serializedObjectForKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Primitive access.
* This method is available in-case you have a need to fetch the raw serializedMetadata from the database.
*
* This method is slower than metadataForKey:inCollection:, since that method makes use of the metadataCache.
* In contrast, this method always fetches the raw data from disk.
*
* @see metadataForKey:inCollection:
**/
- (nullable NSData *)serializedMetadataForKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Primitive access.
* This method is available in-case you have a need to fetch the raw serialized forms from the database.
*
* This method is slower than getObject:metadata:forKey:inCollection:, since that method makes use of the caches.
* In contrast, this method always fetches the raw data from disk.
*
* @see getObject:metadata:forKey:inCollection:
**/
- (BOOL)getSerializedObject:(NSData * __nullable * __nullable)serializedObjectPtr
serializedMetadata:(NSData * __nullable * __nullable)serializedMetadataPtr
forKey:(NSString *)key
inCollection:(nullable NSString *)collection;
#pragma mark Enumerate
/**
* Fast enumeration over all the collections in the database.
*
* This uses a "SELECT collection FROM database" operation,
* and then steps over the results invoking the given block handler.
**/
- (void)enumerateCollectionsUsingBlock:(void (^)(NSString *collection, BOOL *stop))block;
/**
* This method is rarely needed, but may be helpful in certain situations.
*
* This method may be used if you have the key, but not the collection for a particular item.
* Please note that this is not the ideal situation.
*
* Since there may be numerous collections for a given key, this method enumerates all possible collections.
**/
- (void)enumerateCollectionsForKey:(NSString *)key usingBlock:(void (^)(NSString *collection, BOOL *stop))block;
/**
* Fast enumeration over all keys in the given collection.
*
* This uses a "SELECT key FROM database WHERE collection = ?" operation,
* and then steps over the results invoking the given block handler.
**/
- (void)enumerateKeysInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, BOOL *stop))block;
/**
* Fast enumeration over all keys in the given collection.
*
* This uses a "SELECT collection, key FROM database" operation,
* and then steps over the results invoking the given block handler.
**/
- (void)enumerateKeysInAllCollectionsUsingBlock:(void (^)(NSString *collection, NSString *key, BOOL *stop))block;
/**
* Fast enumeration over all objects in the database.
*
* This uses a "SELECT key, object from database WHERE collection = ?" operation, and then steps over the results,
* deserializing each object, and then invoking the given block handler.
*
* If you only need to enumerate over certain objects (e.g. keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the serialization step for those objects you're not interested in.
**/
- (void)enumerateKeysAndObjectsInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, id object, BOOL *stop))block;
/**
* Fast enumeration over objects in the database for which you're interested in.
* The filter block allows you to decide which objects you're interested in.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given key.
* If the filter block returns NO, then the block handler is skipped for the given key,
* which avoids the cost associated with deserializing the object.
**/
- (void)enumerateKeysAndObjectsInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, id object, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *key))filter;
/**
* Enumerates all key/object pairs in all collections.
*
* The enumeration is sorted by collection. That is, it will enumerate fully over a single collection
* before moving onto another collection.
*
* If you only need to enumerate over certain objects (e.g. subset of collections, or keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the serialization step for those objects you're not interested in.
**/
- (void)enumerateKeysAndObjectsInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, id object, BOOL *stop))block;
/**
* Enumerates all key/object pairs in all collections.
* The filter block allows you to decide which objects you're interested in.
*
* The enumeration is sorted by collection. That is, it will enumerate fully over a single collection
* before moving onto another collection.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given
* collection/key pair. If the filter block returns NO, then the block handler is skipped for the given pair,
* which avoids the cost associated with deserializing the object.
**/
- (void)enumerateKeysAndObjectsInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, id object, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *collection, NSString *key))filter;
/**
* Fast enumeration over all keys and associated metadata in the given collection.
*
* This uses a "SELECT key, metadata FROM database WHERE collection = ?" operation and steps over the results.
*
* If you only need to enumerate over certain items (e.g. keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the deserialization step for those items you're not interested in.
*
* Keep in mind that you cannot modify the collection mid-enumeration (just like any other kind of enumeration).
**/
- (void)enumerateKeysAndMetadataInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, __nullable id metadata, BOOL *stop))block;
/**
* Fast enumeration over all keys and associated metadata in the given collection.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given key.
* If the filter block returns NO, then the block handler is skipped for the given key,
* which avoids the cost associated with deserializing the object.
*
* Keep in mind that you cannot modify the collection mid-enumeration (just like any other kind of enumeration).
**/
- (void)enumerateKeysAndMetadataInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, __nullable id metadata, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *key))filter;
/**
* Fast enumeration over all key/metadata pairs in all collections.
*
* This uses a "SELECT metadata FROM database ORDER BY collection ASC" operation, and steps over the results.
*
* If you only need to enumerate over certain objects (e.g. keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the deserialization step for those objects you're not interested in.
*
* Keep in mind that you cannot modify the database mid-enumeration (just like any other kind of enumeration).
**/
- (void)enumerateKeysAndMetadataInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, __nullable id metadata, BOOL *stop))block;
/**
* Fast enumeration over all key/metadata pairs in all collections.
*
* This uses a "SELECT metadata FROM database ORDER BY collection ASC" operation and steps over the results.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given key.
* If the filter block returns NO, then the block handler is skipped for the given key,
* which avoids the cost associated with deserializing the object.
*
* Keep in mind that you cannot modify the database mid-enumeration (just like any other kind of enumeration).
**/
- (void)enumerateKeysAndMetadataInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, __nullable id metadata, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *collection, NSString *key))filter;
/**
* Fast enumeration over all rows in the database.
*
* This uses a "SELECT key, data, metadata from database WHERE collection = ?" operation,
* and then steps over the results, deserializing each object & metadata, and then invoking the given block handler.
*
* If you only need to enumerate over certain rows (e.g. keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the serialization step for those rows you're not interested in.
**/
- (void)enumerateRowsInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, id object, __nullable id metadata, BOOL *stop))block;
/**
* Fast enumeration over rows in the database for which you're interested in.
* The filter block allows you to decide which rows you're interested in.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given key.
* If the filter block returns NO, then the block handler is skipped for the given key,
* which avoids the cost associated with deserializing the object & metadata.
**/
- (void)enumerateRowsInCollection:(nullable NSString *)collection
usingBlock:(void (^)(NSString *key, id object, __nullable id metadata, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *key))filter;
/**
* Enumerates all rows in all collections.
*
* The enumeration is sorted by collection. That is, it will enumerate fully over a single collection
* before moving onto another collection.
*
* If you only need to enumerate over certain rows (e.g. subset of collections, or keys with a particular prefix),
* consider using the alternative version below which provides a filter,
* allowing you to skip the serialization step for those objects you're not interested in.
**/
- (void)enumerateRowsInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, id object, __nullable id metadata, BOOL *stop))block;
/**
* Enumerates all rows in all collections.
* The filter block allows you to decide which objects you're interested in.
*
* The enumeration is sorted by collection. That is, it will enumerate fully over a single collection
* before moving onto another collection.
*
* From the filter block, simply return YES if you'd like the block handler to be invoked for the given
* collection/key pair. If the filter block returns NO, then the block handler is skipped for the given pair,
* which avoids the cost associated with deserializing the object.
**/
- (void)enumerateRowsInAllCollectionsUsingBlock:
(void (^)(NSString *collection, NSString *key, id object, __nullable id metadata, BOOL *stop))block
withFilter:(nullable BOOL (^)(NSString *collection, NSString *key))filter;
/**
* Enumerates over the given list of keys (unordered).
*
* This method is faster than fetching individual items as it optimizes cache access.
* That is, it will first enumerate over items in the cache and then fetch items from the database,
* thus optimizing the cache and reducing query size.
*
* If any keys are missing from the database, the 'object' parameter will be nil.
*
* IMPORTANT:
* Due to cache optimizations, the items may not be enumerated in the same order as the 'keys' parameter.
**/
- (void)enumerateObjectsForKeys:(NSArray<NSString *> *)keys
inCollection:(nullable NSString *)collection
unorderedUsingBlock:(void (^)(NSUInteger keyIndex, id __nullable object, BOOL *stop))block;
/**
* Enumerates over the given list of keys (unordered).
*
* This method is faster than fetching individual items as it optimizes cache access.
* That is, it will first enumerate over items in the cache and then fetch items from the database,
* thus optimizing the cache and reducing query size.
*
* If any keys are missing from the database, the 'metadata' parameter will be nil.
*
* IMPORTANT:
* Due to cache optimizations, the items may not be enumerated in the same order as the 'keys' parameter.
**/
- (void)enumerateMetadataForKeys:(NSArray<NSString *> *)keys
inCollection:(nullable NSString *)collection
unorderedUsingBlock:(void (^)(NSUInteger keyIndex, __nullable id metadata, BOOL *stop))block;
/**
* Enumerates over the given list of keys (unordered).
*
* This method is faster than fetching individual items as it optimizes cache access.
* That is, it will first enumerate over items in the cache and then fetch items from the database,
* thus optimizing the cache and reducing query size.
*
* If any keys are missing from the database, the 'object' and 'metadata' parameter will be nil.
*
* IMPORTANT:
* Due to cache optimizations, the items may not be enumerated in the same order as the 'keys' parameter.
**/
- (void)enumerateRowsForKeys:(NSArray<NSString *> *)keys
inCollection:(nullable NSString *)collection
unorderedUsingBlock:(void (^)(NSUInteger keyIndex, __nullable id object, __nullable id metadata, BOOL *stop))block;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Extensions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Returns an extension transaction corresponding to the extension type registered under the given name.
* If the extension has not yet been opened, it is done so automatically.
*
* @return
* A subclass of YapDatabaseExtensionTransaction,
* according to the type of extension registered under the given name.
*
* One must register an extension with the database before it can be accessed from within connections or transactions.
* After registration everything works automatically using just the registered extension name.
*
* @see [YapDatabase registerExtension:withName:]
**/
- (nullable __kindof YapDatabaseExtensionTransaction *)extension:(NSString *)extensionName;
- (nullable __kindof YapDatabaseExtensionTransaction *)ext:(NSString *)extensionName; // <-- Shorthand (same as extension: method)
NS_ASSUME_NONNULL_END
@end
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark -
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@interface YapDatabaseReadWriteTransaction : YapDatabaseReadTransaction
NS_ASSUME_NONNULL_BEGIN
/**
* Under normal circumstances, when a read-write transaction block completes,
* the changes are automatically committed. If, however, something goes wrong and
* you'd like to abort and discard all changes made within the transaction,
* then invoke this method.
*
* You should generally return (exit the transaction block) after invoking this method.
* Any changes made within the the transaction before and after invoking this method will be discarded.
**/
- (void)rollback;
/**
* The YapDatabaseModifiedNotification is posted following a readwrite transaction which made changes.
*
* These notifications are used in a variety of ways:
* - They may be used as a general notification mechanism to detect changes to the database.
* - They may be used by extensions to post change information.
* For example, YapDatabaseView will post the index changes, which can easily be used to animate a tableView.
* - They are integrated into the architecture of long-lived transactions in order to maintain a steady state.
*
* Thus it is recommended you integrate your own notification information into this existing notification,
* as opposed to broadcasting your own separate notification.
*
* For more information, and code samples, please see the wiki article:
* https://github.com/yapstudios/YapDatabase/wiki/YapDatabaseModifiedNotification
**/
@property (nonatomic, strong, readwrite, nullable) id yapDatabaseModifiedNotificationCustomObject;
#pragma mark Object & Metadata
/**
* Sets the object for the given key/collection.
* The object is automatically serialized using the database's configured objectSerializer.
*
* If you pass nil for the object, then this method will remove the row from the database (if it exists).
* This method implicitly sets the associated metadata to nil.
*
* @param object
* The object to store in the database.
* This object is automatically serialized using the database's configured objectSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
**/
- (void)setObject:(nullable id)object forKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Sets the object & metadata for the given key/collection.
*
* If you pass nil for the object, then this method will remove the row from the database (if it exists).
*
* @param object
* The object to store in the database.
* This object is automatically serialized using the database's configured objectSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
*
* @param metadata
* The metadata to store in the database.
* This metadata is automatically serialized using the database's configured metadataSerializer.
* The metadata is optional. You can pass nil for the metadata is unneeded.
* If non-nil then the metadata is also written to the database (metadata is also persistent).
**/
- (void)setObject:(nullable id)object
forKey:(NSString *)key
inCollection:(nullable NSString *)collection
withMetadata:(nullable id)metadata;
/**
* Sets the object & metadata for the given key/collection.
*
* If you pass nil for the object, then this method will remove the row from the database (if it exists).
*
* This method allows for a bit of optimization if you happen to already have a serialized version of
* the object and/or metadata. For example, if you downloaded an object in serialized form,
* and you still have the raw serialized NSData, then you can use this method to skip the serialization step
* when storing the object to the database.
*
* @param object
* The object to store in the database.
* This object is automatically serialized using the database's configured objectSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
*
* @param metadata
* The metadata to store in the database.
* This metadata is automatically serialized using the database's configured metadataSerializer.
* The metadata is optional. You can pass nil for the metadata is unneeded.
* If non-nil then the metadata is also written to the database (metadata is also persistent).
*
* @param preSerializedObject
* This value is optional.
* If non-nil then the object serialization step is skipped, and this value is used instead.
* It is assumed that preSerializedObject is equal to what we would get if we ran the object through
* the database's configured objectSerializer.
*
* @param preSerializedMetadata
* This value is optional.
* If non-nil then the metadata serialization step is skipped, and this value is used instead.
* It is assumed that preSerializedMetadata is equal to what we would get if we ran the metadata through
* the database's configured metadataSerializer.
*
* The preSerializedObject is only used if object is non-nil.
* The preSerializedMetadata is only used if metadata is non-nil.
**/
- (void)setObject:(nullable id)object forKey:(NSString *)key
inCollection:(nullable NSString *)collection
withMetadata:(nullable id)metadata
serializedObject:(nullable NSData *)preSerializedObject
serializedMetadata:(nullable NSData *)preSerializedMetadata;
/**
* If a row with the given key/collection exists, then replaces the object for that row with the new value.
*
* It only replaces the object. The metadata for the row doesn't change.
* If there is no row in the database for the given key/collection then this method does nothing.
*
* If you pass nil for the object, then this method will remove the row from the database (if it exists).
*
* @param object
* The object to store in the database.
* This object is automatically serialized using the database's configured objectSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
**/
- (void)replaceObject:(nullable id)object forKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* If a row with the given key/collection exists, then replaces the object for that row with the new value.
*
* It only replaces the object. The metadata for the row doesn't change.
* If there is no row in the database for the given key/collection then this method does nothing.
*
* If you pass nil for the object, then this method will remove the row from the database (if it exists).
*
* This method allows for a bit of optimization if you happen to already have a serialized version of
* the object and/or metadata. For example, if you downloaded an object in serialized form,
* and you still have the raw serialized NSData, then you can use this method to skip the serialization step
* when storing the object to the database.
*
* @param object
* The object to store in the database.
* This object is automatically serialized using the database's configured objectSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
*
* @param preSerializedObject
* This value is optional.
* If non-nil then the object serialization step is skipped, and this value is used instead.
* It is assumed that preSerializedObject is equal to what we would get if we ran the object through
* the database's configured objectSerializer.
**/
- (void)replaceObject:(nullable id)object
forKey:(NSString *)key
inCollection:(nullable NSString *)collection
withSerializedObject:(nullable NSData *)preSerializedObject;
/**
* If a row with the given key/collection exists, then replaces the metadata for that row with the new value.
*
* It only replaces the metadata. The object for the row doesn't change.
* If there is no row in the database for the given key/collection then this method does nothing.
*
* If you pass nil for the metadata, any metadata previously associated with the key/collection is removed.
*
* @param metadata
* The metadata to store in the database.
* This metadata is automatically serialized using the database's configured metadataSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
**/
- (void)replaceMetadata:(nullable id)metadata forKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* If a row with the given key/collection exists, then replaces the metadata for that row with the new value.
*
* It only replaces the metadata. The object for the row doesn't change.
* If there is no row in the database for the given key/collection then this method does nothing.
*
* If you pass nil for the metadata, any metadata previously associated with the key/collection is removed.
*
* This method allows for a bit of optimization if you happen to already have a serialized version of
* the object and/or metadata. For example, if you downloaded an object in serialized form,
* and you still have the raw serialized NSData, then you can use this method to skip the serialization step
* when storing the object to the database.
*
* @param metadata
* The metadata to store in the database.
* This metadata is automatically serialized using the database's configured metadataSerializer.
*
* @param key
* The lookup key.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* This value should not be nil. If a nil key is passed, then this method does nothing.
*
* @param collection
* The lookup collection.
* The <collection, key> tuple is used to uniquely identify the row in the database.
* If a nil collection is passed, then the collection is implicitly the empty string (@"").
*
* @param preSerializedMetadata
* This value is optional.
* If non-nil then the metadata serialization step is skipped, and this value is used instead.
* It is assumed that preSerializedMetadata is equal to what we would get if we ran the metadata through
* the database's configured metadataSerializer.
**/
- (void)replaceMetadata:(nullable id)metadata
forKey:(NSString *)key
inCollection:(nullable NSString *)collection
withSerializedMetadata:(nullable NSData *)preSerializedMetadata;
#pragma mark Touch
/**
* You can touch an object if you want to mark it as updated without actually writing any changes to disk.
*
* For example:
*
* You have a BNBook object in your database.
* One of the properties of the book object is a URL pointing to an image for the front cover of the book.
* This image gets changed on the server. Thus the UI representation of the book needs to be updated
* to reflect the updated image on the server. You realize that all your views are already listening for
* YapDatabaseModified notifications, so if you update the object in the database then all your views are
* already wired to update the UI appropriately. However, the actual object itself didn't change. So while
* there technically isn't any reason to update the object on disk, doing so would be the easiest way to
* keep the UI up-to-date. So what you really want is a way to "mark" the object as updated, without actually
* incurring the overhead of rewriting it to disk.
*
* And this is exactly what the touch methods were designed for.
* It won't actually cause the object to get rewritten to disk.
* However, it will mark the object as "updated" within the YapDatabaseModified notification,
* so any UI components listening for changes will see this object as updated, and can update as appropriate.
*
* - touchObjectForKey:inCollection:
* Similar to calling replaceObject:forKey:inCollection: and passing the object that already exists.
* But without the overhead of fetching the object, or re-writing it to disk.
*
* - touchMetadataForKey:inCollection:
* Similar to calling replaceMetadata:forKey:inCollection: and passing the metadata that already exists.
* But without the overhead of fetching the metadata, or re-writing it to disk.
*
* - touchRowForKey:inCollection:
* Similar to calling setObject:forKey:inCollection:withMetadata: and passing the object & metadata the already exist.
* But without the overhead of fetching the items, or re-writing them to disk.
*
* Note: It is safe to touch items during enumeration.
* Normally, altering the database while enumerating it will result in an exception (just like altering an array
* while enumerating it). However, it's safe to touch items during enumeration.
**/
- (void)touchObjectForKey:(NSString *)key inCollection:(nullable NSString *)collection;
- (void)touchMetadataForKey:(NSString *)key inCollection:(nullable NSString *)collection;
- (void)touchRowForKey:(NSString *)key inCollection:(nullable NSString *)collection;
#pragma mark Remove
/**
* Deletes the database row with the given key/collection.
*
* This method is automatically called if you invoke
* setObject:forKey:collection: and pass a nil object.
**/
- (void)removeObjectForKey:(NSString *)key inCollection:(nullable NSString *)collection;
/**
* Deletes the database rows with the given keys in the given collection.
**/
- (void)removeObjectsForKeys:(NSArray<NSString *> *)keys inCollection:(nullable NSString *)collection;
/**
* Deletes every key/object pair from the given collection.
* No trace of the collection will remain afterwards.
**/
- (void)removeAllObjectsInCollection:(nullable NSString *)collection;
/**
* Removes every key/object pair in the entire database (from all collections).
**/
- (void)removeAllObjectsInAllCollections;
#pragma mark Completion
/**
* It's often useful to compose code into various reusable functions which take a
* YapDatabaseReadWriteTransaction as a parameter. However, the ability to compose code
* in this manner is often prevented by the need to perform a task after the commit has finished.
*
* The end result is that programmers either end up copy-pasting code,
* or hack together a solution that involves functions returning completion blocks.
*
* This method solves the dilemma by allowing encapsulated code to register its own commit completionBlock.
**/
- (void)addCompletionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(dispatch_block_t)completionBlock;
@end
NS_ASSUME_NONNULL_END