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

826 lines
36 KiB
Objective-C

#import <Foundation/Foundation.h>
#import "YapCollectionKey.h"
@class YapDatabase;
@class YapDatabaseReadTransaction;
@class YapDatabaseReadWriteTransaction;
@class YapDatabaseExtensionConnection;
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
*
* From a single YapDatabase instance you can create multiple connections.
* Each connection is thread-safe and may be used concurrently with other connections.
*
* Multiple connections can simultaneously read from the database.
* Multiple connections can simultaneously read from the database while another connection is modifying the database.
* For example, the main thread could be reading from the database via connection A,
* while a background thread is writing to the database via connection B.
*
* However, only a single connection may be writing to the database at any one time.
* This is an inherent limitation of the underlying sqlite database.
*
* A connection instance is thread-safe, and operates by serializing access to itself.
* Thus you can share a single connection between multiple threads.
* But for conncurrent access between multiple threads you must use multiple connections.
**/
typedef NS_ENUM(NSInteger, YapDatabasePolicy) {
YapDatabasePolicyContainment = 0,
YapDatabasePolicyShare = 1,
YapDatabasePolicyCopy = 2,
};
#ifndef YapDatabaseEnforcePermittedTransactions
#if DEBUG
#define YapDatabaseEnforcePermittedTransactions 1
#else
#define YapDatabaseEnforcePermittedTransactions 0
#endif
#endif
#if YapDatabaseEnforcePermittedTransactions
typedef NS_OPTIONS(NSUInteger, YapDatabasePermittedTransactions) {
YDB_SyncReadTransaction = 1 << 0, // 000001
YDB_AsyncReadTransaction = 1 << 1, // 000010
YDB_SyncReadWriteTransaction = 1 << 2, // 000100
YDB_AsyncReadWriteTransaction = 1 << 3, // 001000
YDB_AnyReadTransaction = (YDB_SyncReadTransaction | YDB_AsyncReadTransaction), // 000011
YDB_AnyReadWriteTransaction = (YDB_SyncReadWriteTransaction | YDB_AsyncReadWriteTransaction), // 001100
YDB_AnySyncTransaction = (YDB_SyncReadTransaction | YDB_SyncReadWriteTransaction), // 000101
YDB_AnyAsyncTransaction = (YDB_AsyncReadTransaction | YDB_AsyncReadWriteTransaction), // 001010
YDB_AnyTransaction = (YDB_AnyReadTransaction | YDB_AnyReadWriteTransaction), // 001111
YDB_MainThreadOnly = 1 << 4, // 010000
};
#endif
typedef NS_OPTIONS(NSUInteger, YapDatabaseConnectionFlushMemoryFlags) {
YapDatabaseConnectionFlushMemoryFlags_None = 0,
YapDatabaseConnectionFlushMemoryFlags_Caches = 1 << 0,
YapDatabaseConnectionFlushMemoryFlags_Statements = 1 << 1,
YapDatabaseConnectionFlushMemoryFlags_Internal = 1 << 2,
YapDatabaseConnectionFlushMemoryFlags_All = (YapDatabaseConnectionFlushMemoryFlags_Caches |
YapDatabaseConnectionFlushMemoryFlags_Statements |
YapDatabaseConnectionFlushMemoryFlags_Internal ),
};
@interface YapDatabaseConnection : NSObject
/**
* A database connection maintains a strong reference to its parent.
*
* This is to enforce the following core architecture rule:
* A database instance cannot be deallocated if a corresponding connection is stil alive.
**/
@property (nonatomic, strong, readonly) YapDatabase *database;
/**
* The optional name property assists in debugging.
* It is only used internally for log statements.
**/
@property (atomic, copy, readwrite) NSString *name;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Cache
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Each database connection maintains an independent cache of deserialized objects.
* This reduces disk IO and the overhead of the deserialization process.
* You can optionally configure the cache size, or disable it completely.
*
* The cache is properly kept in sync with the atomic snapshot architecture of the database system.
*
* You can configure the objectCache at any time, including within readBlocks or readWriteBlocks.
* To disable the object cache entirely, set objectCacheEnabled to NO.
* To use an inifinite cache size, set the objectCacheLimit to zero.
*
* By default the objectCache is enabled and has a limit of 250.
*
* New connections will inherit the default values set by the parent database object.
* Thus the default values for new connection instances are configurable.
*
* @see YapDatabase defaultObjectCacheEnabled
* @see YapDatabase defaultObjectCacheLimit
*
* Also see the wiki for a bit more info:
* https://github.com/yapstudios/YapDatabase/wiki/Cache
**/
@property (atomic, assign, readwrite) BOOL objectCacheEnabled;
@property (atomic, assign, readwrite) NSUInteger objectCacheLimit;
/**
* Each database connection maintains an independent cache of deserialized metadata.
* This reduces disk IO and the overhead of the deserialization process.
* You can optionally configure the cache size, or disable it completely.
*
* The cache is properly kept in sync with the atomic snapshot architecture of the database system.
*
* You can configure the metadataCache at any time, including within readBlocks or readWriteBlocks.
* To disable the metadata cache entirely, set metadataCacheEnabled to NO.
* To use an inifinite cache size, set the metadataCacheLimit to zero.
*
* By default the metadataCache is enabled and has a limit of 250.
*
* New connections will inherit the default values set by the parent database object.
* Thus the default values for new connection instances are configurable.
*
* @see YapDatabase defaultMetadataCacheEnabled
* @see YapDatabase defaultMetadataCacheLimit
*
* Also see the wiki for a bit more info:
* https://github.com/yapstudios/YapDatabase/wiki/Cache
**/
@property (atomic, assign, readwrite) BOOL metadataCacheEnabled;
@property (atomic, assign, readwrite) NSUInteger metadataCacheLimit;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Policy
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* YapDatabase can use various optimizations to reduce overhead and memory footprint.
* The policy properties allow you to opt in to these optimizations when ready.
*
* The default value is YapDatabasePolicyContainment.
*
* It is the slowest, but also the safest policy.
* The other policies require a little more work, and little deeper understanding.
*
* These optimizations are discussed extensively in the wiki article "Performance Pro":
* https://github.com/yapstudios/YapDatabase/wiki/Performance-Pro
**/
@property (atomic, assign, readwrite) YapDatabasePolicy objectPolicy;
@property (atomic, assign, readwrite) YapDatabasePolicy metadataPolicy;
/**
* When architecting your application, you will likely create a few dedicated connections for particular uses.
* This property allows you to enforce only allowed transaction types for your dedicated connections.
*
* --- Example 1: ---
*
* You have a connection designed for use on the main thread which uses a longLivedReadTransaction.
* Ideally this connection has the following constraints:
* - May only be used on the main thread
* - Can only be used for synchronous read transactions
*
* The idea is to ensure that a read transaction on the main thread never blocks.
* Thus you don't want background threads potentially tying up the connection.
* Remember: transactions go through a serial per-connection queue.
* And similarly, you don't want asynchronous operations of any kind. As that would be the equivalent of
* using the connection on a background thread.
*
* To enforce this, you can do something like this within your app:
*
* uiDatabaseConnection.permittedTransactions = YDB_SyncReadTransaction | YDB_MainThreadOnly;
* [uiDatabaseConnection beginLongLivedReadTransaction];
*
* --- Example 2: ---
*
* You have a dedicated connection designed for read-only operations in background tasks.
* And you want to make sure that no read-write transactions are accidentally invoked on this connection,
* as that would slow your background tasks (which are designed to asynchronous, but generally very fast).
*
* To enforce this, you can do something like this within your app:
*
* roDatabaseConnection.permittedTransactions = YDB_AnyReadTransaction;
*
* --- Example 3: ---
*
* You have an internal databaseConnection within some highly asynchronous manager class.
* You've designed just about every method to be asynchronous,
* and you want to make sure you always remember to use asynchronous transactions.
*
* So, for debugging purposes, you do something like this:
*
* #if DEBUG
* databaseConnection.permittedTransactions = YBD_AnyAsyncTransaction;
* #endif
*
*
* The default value is YDB_AnyTransaction.
**/
#if YapDatabaseEnforcePermittedTransactions
@property (atomic, assign, readwrite) YapDatabasePermittedTransactions permittedTransactions;
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark State
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* The snapshot number is the internal synchronization state primitive for the connection.
* It's generally only useful for database internals,
* but it can sometimes come in handy for general debugging of your app.
*
* The snapshot is a simple 64-bit number that gets incremented upon every readwrite transaction
* that makes modifications to the database. Due to the concurrent architecture of YapDatabase,
* there may be multiple concurrent connections that are inspecting the database at similar times,
* yet they are looking at slightly different "snapshots" of the database.
*
* The snapshot number may thus be inspected to determine (in a general fashion) what state the connection
* is in compared with other connections.
*
* You may also query YapDatabase.snapshot to determine the most up-to-date snapshot among all connections.
*
* Example:
*
* YapDatabase *database = [[YapDatabase alloc] init...];
* database.snapshot; // returns zero
*
* YapDatabaseConnection *connection1 = [database newConnection];
* YapDatabaseConnection *connection2 = [database newConnection];
*
* connection1.snapshot; // returns zero
* connection2.snapshot; // returns zero
*
* [connection1 readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction){
* [transaction setObject:objectA forKey:keyA];
* }];
*
* database.snapshot; // returns 1
* connection1.snapshot; // returns 1
* connection2.snapshot; // returns 1
*
* [connection1 asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction){
* [transaction setObject:objectB forKey:keyB];
* [NSThread sleepForTimeInterval:1.0]; // sleep for 1 second
*
* connection1.snapshot; // returns 1 (we know it will turn into 2 once the transaction completes)
* } completion:^{
*
* connection1.snapshot; // returns 2
* }];
*
* [connection2 asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction){
* [NSThread sleepForTimeInterval:5.0]; // sleep for 5 seconds
*
* connection2.snapshot; // returns 1. See why?
* }];
*
* It's because connection2 started its transaction when the database was in snapshot 1.
* Thus, for the duration of its transaction, the database remains in that state.
*
* However, once connection2 completes its transaction, it will automatically update itself to snapshot 2.
*
* In general, the snapshot is primarily for internal use.
* However, it may come in handy for some tricky edge-case bugs (why doesn't my connection see that other commit?)
**/
@property (atomic, assign, readonly) uint64_t snapshot;
/**
* Returns the number of pending/active transactions for the connection.
*
* Note that if a transaction is currently in progress (active),
* it's still considered "pending" since it hasn't completed yet.
*
* This is a generalized way to estimate the load on a connection,
* and can be used for load balancing, such as done by YapDatabaseConnectionPool.
**/
@property (atomic, assign, readonly) uint64_t pendingTransactionCount;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Transactions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Read-only access to the database.
*
* The given block can run concurrently with sibling connections,
* regardless of whether the sibling connections are executing read-only or read-write transactions.
*
* The only time this method ever blocks is if another thread is currently using this connection instance
* to execute a readBlock or readWriteBlock. Recall that you may create multiple connections for concurrent access.
*
* This method is synchronous.
**/
- (void)readWithBlock:(void (^)(YapDatabaseReadTransaction *transaction))block;
/**
* Read-write access to the database.
*
* Only a single read-write block can execute among all sibling connections.
* Thus this method may block if another sibling connection is currently executing a read-write block.
**/
- (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block;
/**
* Read-only access to the database.
*
* The given block can run concurrently with sibling connections,
* regardless of whether the sibling connections are executing read-only or read-write transactions.
*
* This method is asynchronous.
**/
- (void)asyncReadWithBlock:(void (^)(YapDatabaseReadTransaction *transaction))block;
/**
* Read-only access to the database.
*
* The given block can run concurrently with sibling connections,
* regardless of whether the sibling connections are executing read-only or read-write transactions.
*
* This method is asynchronous.
*
* An optional completion block may be used.
* The completionBlock will be invoked on the main thread (dispatch_get_main_queue()).
**/
- (void)asyncReadWithBlock:(void (^)(YapDatabaseReadTransaction *transaction))block
completionBlock:(nullable dispatch_block_t)completionBlock;
/**
* Read-only access to the database.
*
* The given block can run concurrently with sibling connections,
* regardless of whether the sibling connections are executing read-only or read-write transactions.
*
* This method is asynchronous.
*
* An optional completion block may be used.
* Additionally the dispatch_queue to invoke the completion block may also be specified.
* If NULL, dispatch_get_main_queue() is automatically used.
**/
- (void)asyncReadWithBlock:(void (^)(YapDatabaseReadTransaction *transaction))block
completionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(nullable dispatch_block_t)completionBlock;
/**
* Read-write access to the database.
*
* Only a single read-write block can execute among all sibling connections.
* Thus this method may block if another sibling connection is currently executing a read-write block.
*
* This method is asynchronous.
**/
- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block;
/**
* Read-write access to the database.
*
* Only a single read-write block can execute among all sibling connections.
* Thus the execution of the block may be delayed if another sibling connection
* is currently executing a read-write block.
*
* This method is asynchronous.
*
* An optional completion block may be used.
* The completionBlock will be invoked on the main thread (dispatch_get_main_queue()).
**/
- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block
completionBlock:(nullable dispatch_block_t)completionBlock;
/**
* Read-write access to the database.
*
* Only a single read-write block can execute among all sibling connections.
* Thus the execution of the block may be delayed if another sibling connection
* is currently executing a read-write block.
*
* This method is asynchronous.
*
* An optional completion block may be used.
* Additionally the dispatch_queue to invoke the completion block may also be specified.
* If NULL, dispatch_get_main_queue() is automatically used.
**/
- (void)asyncReadWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block
completionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(nullable dispatch_block_t)completionBlock;
/**
* It's sometimes useful to find out when all previously queued transactions on a connection have completed.
* For example, you may have multiple methods (perhaps scattered across multiple classes) that may queue
* asyncReadWriteTransaction's on a particular databaseConnection. And you'd like to know when all
* the queued readWriteTransactions have completed.
*
* One way to accomplish this is simply to queue an asyncReadTransaction on the databaseConnection.
* Since all transactions on a databaseConnection are queued onto a serial dispatch queue, you'll know that once
* your asyncReadTransaction is running, all previously scheduled transactions have completed.
*
* Although the above technique works, the 'flushTransactionsWithCompletionQueue:completionBlock:'
* is a more efficient way to accomplish this task. (And a more elegant & readable way too.)
*
* @param completionQueue
* The dispatch_queue to invoke the completionBlock on.
* If NULL, dispatch_get_main_queue() is automatically used.
*
* @param completionBlock
* The block to invoke once all previously scheduled transactions have completed.
**/
- (void)flushTransactionsWithCompletionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(nullable dispatch_block_t)completionBlock;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Long-Lived Transactions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Invoke this method to start a long-lived read-only transaction.
* This allows you to effectively create a stable state for the connection.
* This is most often used for connections that service the main thread for UI data.
*
* For a complete discussion, please see the wiki page:
* https://github.com/yapstudios/YapDatabase/wiki/LongLivedReadTransactions
**/
- (NSArray<NSNotification *> *)beginLongLivedReadTransaction;
- (NSArray<NSNotification *> *)endLongLivedReadTransaction;
- (BOOL)isInLongLivedReadTransaction;
/**
* A long-lived read-only transaction is most often setup on a connection that is designed to be read-only.
* But sometimes we forget, and a read-write transaction gets added that uses the read-only connection.
* This will implicitly end the long-lived read-only transaction. Oops.
*
* This is a bug waiting to happen.
* And when it does happen, it will be one of those bugs that's nearly impossible to reproduce.
* So its better to have an early warning system to help you fix the bug before it occurs.
*
* For a complete discussion, please see the wiki page:
* https://github.com/yapstudios/YapDatabase/wiki/LongLivedReadTransactions
*
* In debug mode (#if DEBUG), these exceptions are turned ON by default.
* In non-debug mode (#if !DEBUG), these exceptions are turned OFF by default.
**/
- (void)enableExceptionsForImplicitlyEndingLongLivedReadTransaction;
- (void)disableExceptionsForImplicitlyEndingLongLivedReadTransaction;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Changesets
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* A YapDatabaseModifiedNotification is posted for every readwrite transaction that makes changes to the database.
*
* Given one or more notifications, these methods allow you to easily
* query to see if a change affects a given collection, key, or combinary.
*
* This is most often used in conjunction with longLivedReadTransactions.
*
* For more information on longLivedReadTransaction, see the following wiki article:
* https://github.com/yapstudios/YapDatabase/wiki/LongLivedReadTransactions
**/
// Query for any change to a collection
- (BOOL)hasChangeForCollection:(NSString *)collection inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasObjectChangeForCollection:(NSString *)collection inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasMetadataChangeForCollection:(NSString *)collection inNotifications:(NSArray<NSNotification *> *)notifications;
// Query for a change to a particular key/collection tuple
- (BOOL)hasChangeForKey:(NSString *)key
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasObjectChangeForKey:(NSString *)key
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasMetadataChangeForKey:(NSString *)key
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
// Query for a change to a particular set of keys in a collection
- (BOOL)hasChangeForAnyKeys:(NSSet *)keys
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasObjectChangeForAnyKeys:(NSSet *)keys
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
- (BOOL)hasMetadataChangeForAnyKeys:(NSSet *)keys
inCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications;
// Advanced query techniques
/**
* Returns YES if [transaction removeAllObjectsInCollection:] was invoked on the collection,
* or if [transaction removeAllObjectsInAllCollections] was invoked
* during any of the commits represented by the given notifications.
*
* If this was the case then YapDatabase may not have tracked every single key within the collection.
* And thus a key that was removed via clearing the collection may not show up while enumerating changedKeys.
*
* This method is designed to be used in conjunction with the enumerateChangedKeys.... methods (below).
* The hasChange... methods (above) already take this into account.
**/
- (BOOL)didClearCollection:(NSString *)collection inNotifications:(NSArray<NSNotification *> *)notifications;
/**
* Returns YES if [transaction removeAllObjectsInAllCollections] was invoked
* during any of the commits represented by the given notifications.
*
* If this was the case then YapDatabase may not have tracked every single key within every single collection.
* And thus a key that was removed via clearing the database may not show up while enumerating changedKeys.
*
* This method is designed to be used in conjunction with the enumerateChangedKeys.... methods (below).
* The hasChange... methods (above) already take this into account.
**/
- (BOOL)didClearAllCollectionsInNotifications:(NSArray<NSNotification *> *)notifications;
/**
* Allows you to enumerate all the changed keys in the given collection, for the given commits.
*
* Keep in mind that if [transaction removeAllObjectsInCollection:] was invoked on the given collection
* or [transaction removeAllObjectsInAllCollections] was invoked
* during any of the commits represented by the given notifications,
* then the key may not be included in the enumeration.
* You must use didClearCollection:inNotifications: or didClearAllCollectionsInNotifications:
* if you need to handle that case.
*
* @see didClearCollection:inNotifications:
* @see didClearAllCollectionsInNotifications:
**/
- (void)enumerateChangedKeysInCollection:(NSString *)collection
inNotifications:(NSArray<NSNotification *> *)notifications
usingBlock:(void (^)(NSString *key, BOOL *stop))block;
/**
* Allows you to enumerate all the changed collection/key tuples for the given commits.
*
* Keep in mind that if [transaction removeAllObjectsInCollection:] was invoked on the given collection
* or [transaction removeAllObjectsInAllCollections] was invoked
* during any of the commits represented by the given notifications,
* then the collection/key tuple may not be included in the enumeration.
* You must use didClearCollection:inNotifications: or didClearAllCollectionsInNotifications:
* if you need to handle that case.
*
* @see didClearCollection:inNotifications:
* @see didClearAllCollectionsInNotifications:
**/
- (void)enumerateChangedCollectionKeysInNotifications:(NSArray<NSNotification *> *)notifications
usingBlock:(void (^)(YapCollectionKey *ck, BOOL *stop))block;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Extensions
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Creates or fetches the extension with the given name.
* If this connection has not yet initialized the proper extension connection, it is done automatically.
*
* @return
* A subclass of YapDatabaseExtensionConnection,
* 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:
**/
- (__kindof YapDatabaseExtensionConnection *)extension:(NSString *)extensionName;
- (__kindof YapDatabaseExtensionConnection *)ext:(NSString *)extensionName; // <-- Shorthand (same as extension: method)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Memory
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This method may be used to flush the internal caches used by the connection,
* as well as flushing pre-compiled sqlite statements.
* Depending upon how often you use the database connection,
* you may want to be more or less aggressive on how much stuff you flush.
*
* YapDatabaseConnectionFlushMemoryFlags_None:
* No-op. Doesn't flush anything.
*
* YapDatabaseConnectionFlushMemoryFlags_Caches:
* Flushes all caches, including the object cache and metadata cache.
*
* YapDatabaseConnectionFlushMemoryFlags_Statements:
* Flushes all pre-compiled sqlite statements.
*
* YapDatabaseConnectionFlushMemoryFlags_Internal
* Flushes internal memory used by sqlite instance via sqlite_db_release_memory.
* Generally this means cached database pages.
*
* YapDatabaseConnectionFlushMemoryFlags_All:
* Full flush of everything (caches, statements, internal)
**/
- (void)flushMemoryWithFlags:(YapDatabaseConnectionFlushMemoryFlags)flags;
#if TARGET_OS_IOS || TARGET_OS_TV
/**
* When a UIApplicationDidReceiveMemoryWarningNotification is received,
* the code automatically invokes flushMemoryWithFlags and passes the set flags.
*
* The default value is YapDatabaseConnectionFlushMemoryFlags_All.
*
* @see flushMemoryWithFlags:
**/
@property (atomic, assign, readwrite) YapDatabaseConnectionFlushMemoryFlags autoFlushMemoryFlags;
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Pragma
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Returns the current synchronous configuration via "PRAGMA synchronous;".
* Allows you to verify that sqlite accepted your synchronous configuration request.
**/
- (NSString *)pragmaSynchronous;
/**
* Returns the current page_size configuration via "PRAGMA page_size;".
* Allows you to verify that sqlite accepted your page_size configuration request.
**/
- (NSInteger)pragmaPageSize;
/**
* Returns the currently memory mapped I/O configureation via "PRAGMA mmap_size;".
* Allows you to verify that sqlite accepted your mmap_size configuration request.
*
* Memory mapping may be disabled by sqlite's compile-time options.
* Or it may restrict the mmap_size to something smaller than requested.
**/
- (NSInteger)pragmaMMapSize;
/**
* Upgrade Notice:
*
* The "auto_vacuum=FULL" was not properly set until YapDatabase v2.5.
* And thus if you have an app that was using YapDatabase prior to this version,
* then the existing database file will continue to operate in "auto_vacuum=NONE" mode.
* This means the existing database file won't be properly truncated as you delete information from the db.
* That is, the data will be removed, but the pages will be moved to the freelist,
* and the file itself will remain the same size on disk. (I.e. the file size can grow, but not shrink.)
* To correct this problem, you should run the vacuum operation at least once.
* After it is run, the "auto_vacuum=FULL" mode will be set,
* and the database file size will automatically shrink in the future (as you delete data).
*
* @returns Result from "PRAGMA auto_vacuum;" command, as a readable string:
* - NONE
* - FULL
* - INCREMENTAL
* - UNKNOWN (future proofing)
*
* If the return value is NONE, then you should run the vacuum operation at some point
* in order to properly reconfigure the database.
*
* Concerning Method Invocation:
*
* You can invoke this method as a standalone method on the connection:
*
* NSString *value = [databaseConnection pragmaAutoVacuum]
*
* Or you can invoke this method within a transaction:
*
* [databaseConnection asyncReadWithBlock:^(YapDatabaseReadTransaction *transaction){
* NSString *value = [databaseConnection pragmaAutoVacuum];
* }];
**/
- (NSString *)pragmaAutoVacuum;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Vacuum
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Performs a VACUUM on the sqlite database.
*
* This method operates as a synchronous ReadWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* For more infomation on the VACUUM operation, see the sqlite docs:
* http://sqlite.org/lang_vacuum.html
*
* Remember that YapDatabase operates in WAL mode, with "auto_vacuum=FULL" set.
*
* @see pragmaAutoVacuum
**/
- (void)vacuum;
/**
* Performs a VACUUM on the sqlite database.
*
* This method operates as an asynchronous readWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* For more infomation on the VACUUM operation, see the sqlite docs:
* http://sqlite.org/lang_vacuum.html
*
* Remember that YapDatabase operates in WAL mode, with "auto_vacuum=FULL" set.
*
* An optional completion block may be used.
* The completionBlock will be invoked on the main thread (dispatch_get_main_queue()).
*
* @see pragmaAutoVacuum
**/
- (void)asyncVacuumWithCompletionBlock:(nullable dispatch_block_t)completionBlock;
/**
* Performs a VACUUM on the sqlite database.
*
* This method operates as an asynchronous readWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* For more infomation on the VACUUM operation, see the sqlite docs:
* http://sqlite.org/lang_vacuum.html
*
* Remember that YapDatabase operates in WAL mode, with "auto_vacuum=FULL" set.
*
* An optional completion block may be used.
* Additionally the dispatch_queue to invoke the completion block may also be specified.
* If NULL, dispatch_get_main_queue() is automatically used.
*
* @see pragmaAutoVacuum
**/
- (void)asyncVacuumWithCompletionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(nullable dispatch_block_t)completionBlock;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma mark Backup
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* This method backs up the database by exporting all the tables to another sqlite database.
*
* This method operates as a synchronous ReadWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* The database will be backed up as it exists at the moment this transaction operates.
* That is, it will backup everything in the sqlite file, as well as everything in the WAL file.
*
* For more information on the BACKUP operation, see the sqlite docs:
* https://www.sqlite.org/c3ref/backup_finish.html
*
* As stated in the sqlite docs, it is your responsibilty to ensure that nothing else is
* currently using the backupDatabase.
**/
- (NSError *)backupToPath:(NSString *)backupDatabasePath;
/**
* This method backs up the database by exporting all the tables to another sqlite database.
*
* This method operates as an asynchronous readWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* The database will be backed up as it exists at the moment this transaction operates.
* That is, it will backup everything in the sqlite file, as well as everything in the WAL file.
*
* An optional completion block may be used.
* The completionBlock will be invoked on the main thread (dispatch_get_main_queue()).
*
* For more information on the BACKUP operation, see the sqlite docs:
* https://www.sqlite.org/c3ref/backup_finish.html
*
* As stated in the sqlite docs, it is your responsibilty to ensure that nothing else is
* currently using the backupDatabase.
*
* @return
* A NSProgress instance that may be used to track the backup progress.
* The progress in cancellable, meaning that invoking [progress cancel] will abort the backup operation.
**/
- (NSProgress *)asyncBackupToPath:(NSString *)backupDatabasePath
completionBlock:(nullable void (^)(NSError * _Nullable))completionBlock;
/**
* This method backs up the database by exporting all the tables to another sqlite database.
*
* This method operates as an asynchronous readWrite "transaction".
* That is, it behaves in a similar fashion, and you may treat it as if it is a ReadWrite transaction.
*
* The database will be backed up as it exists at the moment this transaction operates.
* That is, it will backup everything in the sqlite file, as well as everything in the WAL file.
*
* An optional completion block may be used.
* Additionally the dispatch_queue to invoke the completion block may also be specified.
* If NULL, dispatch_get_main_queue() is automatically used.
*
* For more information on the BACKUP operation, see the sqlite docs:
* https://www.sqlite.org/c3ref/backup_finish.html
*
* As stated in the sqlite docs, it is your responsibilty to ensure that nothing else is
* currently using the backupDatabase.
*
* @return
* A NSProgress instance that may be used to track the backup progress.
* The progress in cancellable, meaning that invoking [progress cancel] will abort the backup operation.
**/
- (NSProgress *)asyncBackupToPath:(NSString *)backupDatabasePath
completionQueue:(nullable dispatch_queue_t)completionQueue
completionBlock:(nullable void (^)(NSError * _Nullable))completionBlock;
@end
NS_ASSUME_NONNULL_END