123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- //
- // 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"
- /*
-
- 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
-
- */
-
- @implementation FMDatabaseQueue
- @synthesize path = _path;
- + (id)databaseQueueWithPath:(NSString*)aPath {
-
- FMDatabaseQueue *q = [[self alloc] initWithPath:aPath];
-
- FMDBAutorelease(q);
-
- return q;
- }
- - (id)initWithPath:(NSString*)aPath {
-
- self = [super init];
-
- if (self != nil) {
-
- _db = [FMDatabase databaseWithPath:aPath];
- FMDBRetain(_db);
-
- if (![_db open]) {
- 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);
- }
-
- return self;
- }
- - (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, ^() {
- [_db close];
- FMDBRelease(_db);
- _db = 0x00;
- });
- FMDBRelease(self);
- }
- - (FMDatabase*)database {
- if (!_db) {
- _db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]);
-
- if (![_db open]) {
- NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path);
- FMDBRelease(_db);
- _db = 0x00;
- return 0x00;
- }
- }
-
- return _db;
- }
- - (void)inDatabase:(void (^)(FMDatabase *db))block {
- 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:]");
- }
- });
-
- 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];
- }
- #if SQLITE_VERSION_NUMBER >= 3007000
- - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
-
- 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) {
- [[self database] rollbackToSavePointWithName:name error:&err];
- }
- else {
- [[self database] releaseSavePointWithName:name error:&err];
- }
-
- }
- });
- FMDBRelease(self);
- return err;
- }
- #endif
- @end
|