Classes
The following classes are available globally.
-
A SQLite (https://sqlite.org/) Objective-C wrapper.
Usage
The three main classes in FMDB are:
FMDatabase
- Represents a single SQLite database. Used for executing SQL statements.FMResultSet
- Represents the results of executing a query on anFMDatabase
.FMDatabaseQueue
- If you want to perform queries and updates on multiple threads, you’ll want to use this class.
See also
FMDatabasePool
- A pool ofFMDatabase
objectsFMStatement
- A wrapper forsqlite_stmt
External links
- FMDB on GitHub including introductory documentation
- SQLite web site
- FMDB mailing list
Warning
Do not instantiate a single
FMDatabase
object and use it across multiple threads. Instead, useFMDatabaseQueue
.Declaration
Objective-C
@interface FMDatabase : NSObject
Swift
class FMDatabase : NSObject
-
Objective-C wrapper for
sqlite3_stmt
This is a wrapper for a SQLite
sqlite3_stmt
. Generally when using FMDB you will not need to interact directly withFMStatement
, but rather withFMDatabase
andFMResultSet
only.See also
See moreDeclaration
Objective-C
@interface FMStatement : NSObject { void *_statement; NSString *_query; long _useCount; BOOL _inUse; }
Swift
class FMStatement : NSObject
-
Pool of
FMDatabase
objects.See also
Warning
Before using
FMDatabasePool
, please consider usingFMDatabaseQueue
instead.If you really really really know what you’re doing and
FMDatabasePool
is what you really really need (ie, you’re using a read only database), OK you can use it. But just be careful not to deadlock!For an example on deadlocking, search for:
See moreONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD
in the main.m file.Declaration
Objective-C
@interface FMDatabasePool : NSObject
Swift
class FMDatabasePool : NSObject
-
To perform queries and updates on multiple threads, you’ll want to use
FMDatabaseQueue
.Using a single instance of
FMDatabase
from multiple threads at once is a bad idea. It has always been OK to make aFMDatabase
object per thread. Just don’t share a single instance across threads, and definitely not across multiple threads at the same time.Instead, use
FMDatabaseQueue
. Here’s how to use it:First, make your queue.
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
Then use it like so:
[queue inDatabase:^(FMDatabase *db) { [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; FMResultSet *rs = [db executeQuery:@"select * from foo"]; while ([rs next]) { //… } }];
An easy way to wrap things up in a transaction can be done like this:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) { [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; // if (whoopsSomethingWrongHappened) { // *rollback = YES; // return; // } // etc… [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; }];
FMDatabaseQueue
will run the blocks on a serialized queue (hence the name of the class). So if you callFMDatabaseQueue
‘s methods from multiple threads at the same time, they will be executed in the order they are received. This way queries and updates won’t step on each other’s toes, and every one is happy.Warning
Do not instantiate a single
FMDatabase
object and use it across multiple threads. UseFMDatabaseQueue
instead.Warning
The calls to
FMDatabaseQueue
’s methods are blocking. So even though you are passing along blocks, they will not be run on another thread.@sa FMDatabase
See moreDeclaration
Objective-C
@interface FMDatabaseQueue : NSObject
Swift
class FMDatabaseQueue : NSObject
-
Declaration
Objective-C
@interface FMResultSet : NSObject
Swift
class FMResultSet : NSObject