0

I have some code using the FMDB sqllite wrapper (https://github.com/ccgus/fmdb) and I'm expecting this code to be executed from multiple threads. As such, I'm using the FMDatabaseQueue class to execute all DB work.

I'm a little bit confused by the pattern, e.g.

FMDatabaseQueue *q = [FMDatabaseQueue databaseQueueWithPath:@""];
[q inDatabase:^(FMDatabase *db) {
    NSLog(@"1");
    BOOL yn = [db executeUpdate:@"CREATE TABLE IF NOT EXISTS Foo (Bar TEXT)"];
    NSLog(@"2%@", yn ? @"YES" : @"NO");
}];
NSLog(@"3");

If you look at the code above.. is it guaranteed that 3 will always be logged after 2 and 1? Such that the executing thread is blocked until the block provided to the queue actually gets to execute?

If so, should I remove any non-database work outside and after the block so that any other threads using the queue are not blocked by work that doesn't need to be synchronized across threads?

Also, do I need to call [db open] when using FMDatabaseQueue?

Marcelo
  • 9,916
  • 3
  • 43
  • 52
ConfusedNoob
  • 9,826
  • 14
  • 64
  • 85

1 Answers1

1

Yes, it's guaranteed that 3 will be logged after 1 and 2.

That's because FMDatabaseQueue -inDatabase: uses a dispatch_sync call internally to do the database operations (as you can see in the source code).

So, the recommendation would be do the less work possible inside the block, and do all the other work on your own queue.

Also, [db open] is not needed, because FMDatabaseQueue -initWithPath: (called by FMDatabaseQueue +databaseQueueWithPath:) already does that (as again, you can see in the source code).

Marcelo
  • 9,916
  • 3
  • 43
  • 52
  • Thanks. I'm guessing one should never enqueue another block from within a FMDatabase queue then either? +Thanks for the pointer to the code! – ConfusedNoob Aug 19 '13 at 00:11
  • One more question - should I loop over an FMResultSet within the block or is it OK to pass that out of the block (not sure if there's hidden smarts to clean up anything at the end of a block) – ConfusedNoob Aug 19 '13 at 00:35
  • 1
    You'll need to do the looping inside the block. – ccgus Aug 19 '13 at 03:37
  • 1
    And yes, never try and use inDatabase: recursively. – ccgus Aug 19 '13 at 03:38