FMDatabaseQueue.m 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //
  2. // FMDatabasePool.m
  3. // fmdb
  4. //
  5. // Created by August Mueller on 6/22/11.
  6. // Copyright 2011 Flying Meat Inc. All rights reserved.
  7. //
  8. #import "FMDatabaseQueue.h"
  9. #import "FMDatabase.h"
  10. @implementation FMDatabaseQueue
  11. @synthesize path = _path;
  12. + (id)databaseQueueWithPath:(NSString*)aPath {
  13. FMDatabaseQueue *q = [[self alloc] initWithPath:aPath];
  14. FMDBAutorelease(q);
  15. return q;
  16. }
  17. - (id)initWithPath:(NSString*)aPath {
  18. self = [super init];
  19. if (self != nil) {
  20. _db = [FMDatabase databaseWithPath:aPath];
  21. FMDBRetain(_db);
  22. if (![_db open]) {
  23. NSLog(@"Could not create database queue for path %@", aPath);
  24. FMDBRelease(self);
  25. return 0x00;
  26. }
  27. _path = FMDBReturnRetained(aPath);
  28. _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
  29. }
  30. return self;
  31. }
  32. - (void)dealloc {
  33. FMDBRelease(_db);
  34. FMDBRelease(_path);
  35. if (_queue) {
  36. dispatch_release(_queue);
  37. _queue = 0x00;
  38. }
  39. #if ! __has_feature(objc_arc)
  40. [super dealloc];
  41. #endif
  42. }
  43. - (void)close {
  44. dispatch_sync(_queue, ^() {
  45. [_db close];
  46. FMDBRelease(_db);
  47. _db = 0x00;
  48. });
  49. }
  50. - (FMDatabase*)database {
  51. if (!_db) {
  52. _db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]);
  53. if (![_db open]) {
  54. NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path);
  55. FMDBRelease(_db);
  56. _db = 0x00;
  57. return 0x00;
  58. }
  59. }
  60. return _db;
  61. }
  62. - (void)inDatabase:(void (^)(FMDatabase *db))block {
  63. dispatch_sync(_queue, ^() {
  64. FMDatabase *db = [self database];
  65. block(db);
  66. if ([db hasOpenResultSets]) {
  67. NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
  68. }
  69. });
  70. }
  71. - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
  72. dispatch_sync(_queue, ^() {
  73. BOOL shouldRollback = NO;
  74. if (useDeferred) {
  75. [[self database] beginDeferredTransaction];
  76. }
  77. else {
  78. [[self database] beginTransaction];
  79. }
  80. block([self database], &shouldRollback);
  81. if (shouldRollback) {
  82. [[self database] rollback];
  83. }
  84. else {
  85. [[self database] commit];
  86. }
  87. });
  88. }
  89. - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
  90. [self beginTransaction:YES withBlock:block];
  91. }
  92. - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
  93. [self beginTransaction:NO withBlock:block];
  94. }
  95. #if SQLITE_VERSION_NUMBER >= 3007000
  96. - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
  97. static unsigned long savePointIdx = 0;
  98. __block NSError *err = 0x00;
  99. dispatch_sync(_queue, ^() {
  100. NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
  101. BOOL shouldRollback = NO;
  102. if ([[self database] startSavePointWithName:name error:&err]) {
  103. block([self database], &shouldRollback);
  104. if (shouldRollback) {
  105. [[self database] rollbackToSavePointWithName:name error:&err];
  106. }
  107. else {
  108. [[self database] releaseSavePointWithName:name error:&err];
  109. }
  110. }
  111. });
  112. return err;
  113. }
  114. #endif
  115. @end