ios demo version
This commit is contained in:
245
ios/Pods/FMDB/src/fmdb/FMDatabaseQueue.m
generated
Normal file
245
ios/Pods/FMDB/src/fmdb/FMDatabaseQueue.m
generated
Normal file
@@ -0,0 +1,245 @@
|
||||
//
|
||||
// FMDatabaseQueue.m
|
||||
// fmdb
|
||||
//
|
||||
// Created by August Mueller on 6/22/11.
|
||||
// Copyright 2011 Flying Meat Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#import "FMDatabaseQueue.h"
|
||||
#import "FMDatabase.h"
|
||||
|
||||
#if FMDB_SQLITE_STANDALONE
|
||||
#import <sqlite3/sqlite3.h>
|
||||
#else
|
||||
#import <sqlite3.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
Note: we call [self retain]; before using dispatch_sync, just incase
|
||||
FMDatabaseQueue is released on another thread and we're in the middle of doing
|
||||
something in dispatch_sync
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
* A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses.
|
||||
* This in turn is used for deadlock detection by seeing if inDatabase: is called on
|
||||
* the queue's dispatch queue, which should not happen and causes a deadlock.
|
||||
*/
|
||||
static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey;
|
||||
|
||||
@implementation FMDatabaseQueue
|
||||
|
||||
@synthesize path = _path;
|
||||
@synthesize openFlags = _openFlags;
|
||||
|
||||
+ (instancetype)databaseQueueWithPath:(NSString*)aPath {
|
||||
|
||||
FMDatabaseQueue *q = [[self alloc] initWithPath:aPath];
|
||||
|
||||
FMDBAutorelease(q);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
+ (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags {
|
||||
|
||||
FMDatabaseQueue *q = [[self alloc] initWithPath:aPath flags:openFlags];
|
||||
|
||||
FMDBAutorelease(q);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
+ (Class)databaseClass {
|
||||
return [FMDatabase class];
|
||||
}
|
||||
|
||||
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName {
|
||||
|
||||
self = [super init];
|
||||
|
||||
if (self != nil) {
|
||||
|
||||
_db = [[[self class] databaseClass] databaseWithPath:aPath];
|
||||
FMDBRetain(_db);
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3005000
|
||||
BOOL success = [_db openWithFlags:openFlags vfs:vfsName];
|
||||
#else
|
||||
BOOL success = [_db open];
|
||||
#endif
|
||||
if (!success) {
|
||||
NSLog(@"Could not create database queue for path %@", aPath);
|
||||
FMDBRelease(self);
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
_path = FMDBReturnRetained(aPath);
|
||||
|
||||
_queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
|
||||
dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
|
||||
_openFlags = openFlags;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags {
|
||||
return [self initWithPath:aPath flags:openFlags vfs:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithPath:(NSString*)aPath {
|
||||
|
||||
// default flags for sqlite3_open
|
||||
return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE vfs:nil];
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
return [self initWithPath:nil];
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc {
|
||||
|
||||
FMDBRelease(_db);
|
||||
FMDBRelease(_path);
|
||||
|
||||
if (_queue) {
|
||||
FMDBDispatchQueueRelease(_queue);
|
||||
_queue = 0x00;
|
||||
}
|
||||
#if ! __has_feature(objc_arc)
|
||||
[super dealloc];
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)close {
|
||||
FMDBRetain(self);
|
||||
dispatch_sync(_queue, ^() {
|
||||
[self->_db close];
|
||||
FMDBRelease(_db);
|
||||
self->_db = 0x00;
|
||||
});
|
||||
FMDBRelease(self);
|
||||
}
|
||||
|
||||
- (FMDatabase*)database {
|
||||
if (!_db) {
|
||||
_db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]);
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3005000
|
||||
BOOL success = [_db openWithFlags:_openFlags];
|
||||
#else
|
||||
BOOL success = [_db open];
|
||||
#endif
|
||||
if (!success) {
|
||||
NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path);
|
||||
FMDBRelease(_db);
|
||||
_db = 0x00;
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
return _db;
|
||||
}
|
||||
|
||||
- (void)inDatabase:(void (^)(FMDatabase *db))block {
|
||||
/* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue
|
||||
* and then check it against self to make sure we're not about to deadlock. */
|
||||
FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
|
||||
assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock");
|
||||
|
||||
FMDBRetain(self);
|
||||
|
||||
dispatch_sync(_queue, ^() {
|
||||
|
||||
FMDatabase *db = [self database];
|
||||
block(db);
|
||||
|
||||
if ([db hasOpenResultSets]) {
|
||||
NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
|
||||
|
||||
#if defined(DEBUG) && DEBUG
|
||||
NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]);
|
||||
for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) {
|
||||
FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue];
|
||||
NSLog(@"query: '%@'", [rs query]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
});
|
||||
|
||||
FMDBRelease(self);
|
||||
}
|
||||
|
||||
|
||||
- (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
|
||||
FMDBRetain(self);
|
||||
dispatch_sync(_queue, ^() {
|
||||
|
||||
BOOL shouldRollback = NO;
|
||||
|
||||
if (useDeferred) {
|
||||
[[self database] beginDeferredTransaction];
|
||||
}
|
||||
else {
|
||||
[[self database] beginTransaction];
|
||||
}
|
||||
|
||||
block([self database], &shouldRollback);
|
||||
|
||||
if (shouldRollback) {
|
||||
[[self database] rollback];
|
||||
}
|
||||
else {
|
||||
[[self database] commit];
|
||||
}
|
||||
});
|
||||
|
||||
FMDBRelease(self);
|
||||
}
|
||||
|
||||
- (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
|
||||
[self beginTransaction:YES withBlock:block];
|
||||
}
|
||||
|
||||
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
|
||||
[self beginTransaction:NO withBlock:block];
|
||||
}
|
||||
|
||||
- (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
|
||||
#if SQLITE_VERSION_NUMBER >= 3007000
|
||||
static unsigned long savePointIdx = 0;
|
||||
__block NSError *err = 0x00;
|
||||
FMDBRetain(self);
|
||||
dispatch_sync(_queue, ^() {
|
||||
|
||||
NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
|
||||
|
||||
BOOL shouldRollback = NO;
|
||||
|
||||
if ([[self database] startSavePointWithName:name error:&err]) {
|
||||
|
||||
block([self database], &shouldRollback);
|
||||
|
||||
if (shouldRollback) {
|
||||
// We need to rollback and release this savepoint to remove it
|
||||
[[self database] rollbackToSavePointWithName:name error:&err];
|
||||
}
|
||||
[[self database] releaseSavePointWithName:name error:&err];
|
||||
|
||||
}
|
||||
});
|
||||
FMDBRelease(self);
|
||||
return err;
|
||||
#else
|
||||
NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil);
|
||||
if (self.logsErrors) NSLog(@"%@", errorMessage);
|
||||
return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user