fmdb
fmdb copied to clipboard
Acceptable pattern for fetching from multiple tables in nested queries?
I can have Model Book
which contains a column that references Model Author
via ID. When fetching from the Book
table, I would have to do any additional fetch from Author
, if the author
column is nonempty. My question is, would the following be a valid way to accomplish this:
Database Singleton class contains a property for a FMDatabaseQueue
that is created once.
- (NSArray<Book *> *)bookObjects
{
__block NSMutableArray<Book *> *tempBooks = [NSMutableArray new];
NSString *sql = @"SELECT * FROM Book ";
[self.databaseQueue inDatabase:^(FMDatabase * db) {
FMResultSet *bookFetchResult = [db executeQuery:sql];
while ([bookFetchResult next]) {
[tempBooks addObject:[self bookWithFetchResultSet:bookFetchResult
database:db]];
}
}];
return [tempBooks copy];
}
- (Book *)populateBookWithFetchResultSet:(FMResultSet *)bookFetchResult
database:(FMDatabase *)db
{
Book *book = [Book new];
book.isbn = [bookFetchResult longForColumn:@"isbn"];
book.genre = [bookFetchResult stringForColumn:@"genre"];
if ([bookFetchResult longForColumn:@"author"]) {
book.author = (Author *)[self authorObjectWithID:@([bookFetchResult longForColumn:@"author"])
fromDatabase:db];
}
return book;
}
- (Author *)authorObjectWithID:(NSNumber)authorID
fromDatabase:(FMDatabase *)db
{
__block Author *author;
NSString *sql = [NSString stringWithFormat:@"SELECT * FROM Author WHERE authorID= '%lld';", authorID];
[self.databaseQueue inDatabase:^(FMDatabase * db) {
FMResultSet *authorFetchResult = [db executeQuery:sql];
if ([authorFetchResult next]) {
author = [self populateAuthorWithFetchResultSet:authorFetchResult
fromDatabase:db];
}
}];
return author;
}
So as you can see, while fetching Book
, there is a need to do a second fetch to Author
, to fully populate the Book
model object. All queries are done on the same _databaseQueue
, using the same FMDatabase
object that is referenced with db
, which used in these different methods.
I haven't received any open result set warnings or concurrency issues with this pattern, so far. Is this valid?
I may be missing something, but is the "author" column in your Books table the authorID (which it looks like it is from the query to fetch from the Author table)? If so, have you thought about using one query and joining the tables on authorID?
The thing is, because Books might reference the ID's of rows from multiple tables, I'm not sure if it's all that efficient to join Book on Author, and on Publisher, etc. All of which might contain references to other tables as well.