Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ccgus/fmdb.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAugust "Gus" Mueller <gus@flyingmeat.com>2015-06-17 19:45:39 +0300
committerAugust "Gus" Mueller <gus@flyingmeat.com>2015-06-17 19:45:39 +0300
commit12ac4595bc62927b75ade01144e3ae7c7dedbac4 (patch)
tree22ecebe808cd6a54adfe64d598d97e732c1fd0de
parentc4d0ae7bd6df5e234cfe3faedc661252cb048a58 (diff)
parent4b827e35c0a23258c0451b65a37152f61ae36b6b (diff)
Merge pull request #384 from thelastjedi/readme-patch-1
Added syntax highlighting in README
-rw-r--r--README.markdown191
1 files changed, 112 insertions, 79 deletions
diff --git a/README.markdown b/README.markdown
index 5eea011..35550b5 100644
--- a/README.markdown
+++ b/README.markdown
@@ -51,16 +51,20 @@ An `FMDatabase` is created with a path to a SQLite database file. This path can
(For more information on temporary and in-memory databases, read the sqlite documentation on the subject: http://www.sqlite.org/inmemorydb.html)
- FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
+```objc
+FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
+```
### Opening
Before you can interact with the database, it must be opened. Opening fails if there are insufficient resources or permissions to open and/or create the database.
- if (![db open]) {
- [db release];
- return;
- }
+```objc
+if (![db open]) {
+ [db release];
+ return;
+}
+```
### Executing Updates
@@ -76,17 +80,21 @@ Executing queries returns an `FMResultSet` object if successful, and `nil` upon
In order to iterate through the results of your query, you use a `while()` loop. You also need to "step" from one record to the other. With FMDB, the easiest way to do that is like this:
- FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
- while ([s next]) {
- //retrieve values for each record
- }
+```objc
+FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
+while ([s next]) {
+ //retrieve values for each record
+}
+```
You must always invoke `-[FMResultSet next]` before attempting to access the values returned in a query, even if you're only expecting one:
- FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
- if ([s next]) {
- int totalCount = [s intForColumnIndex:0];
- }
+```objc
+FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
+if ([s next]) {
+ int totalCount = [s intForColumnIndex:0];
+}
+```
`FMResultSet` has many methods to retrieve data in an appropriate format:
@@ -110,7 +118,9 @@ Typically, there's no need to `-close` an `FMResultSet` yourself, since that hap
When you have finished executing queries and updates on the database, you should `-close` the `FMDatabase` connection so that SQLite will relinquish any resources it has acquired during the course of its operation.
- [db close];
+```objc
+[db close];
+```
### Transactions
@@ -120,7 +130,7 @@ When you have finished executing queries and updates on the database, you should
You can use `FMDatabase`'s executeStatements:withResultBlock: to do multiple statements in a string:
-```
+```objc
NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);"
"create table bulktest2 (id integer primary key autoincrement, y text);"
"create table bulktest3 (id integer primary key autoincrement, z text);"
@@ -145,38 +155,53 @@ success = [self.db executeStatements:sql withResultBlock:^int(NSDictionary *dict
When providing a SQL statement to FMDB, you should not attempt to "sanitize" any values before insertion. Instead, you should use the standard SQLite binding syntax:
- INSERT INTO myTable VALUES (?, ?, ?)
+```sql
+INSERT INTO myTable VALUES (?, ?, ?)
+```
The `?` character is recognized by SQLite as a placeholder for a value to be inserted. The execution methods all accept a variable number of arguments (or a representation of those arguments, such as an `NSArray`, `NSDictionary`, or a `va_list`), which are properly escaped for you.
Alternatively, you may use named parameters syntax:
- INSERT INTO myTable VALUES (:id, :name, :value)
+```sql
+INSERT INTO myTable VALUES (:id, :name, :value)
+```
The parameters *must* start with a colon. SQLite itself supports other characters, but internally the Dictionary keys are prefixed with a colon, do **not** include the colon in your dictionary keys.
- NSDictionary *argsDict = [NSDictionary dictionaryWithObjectsAndKeys:@"My Name", @"name", nil];
- [db executeUpdate:@"INSERT INTO myTable (name) VALUES (:name)" withParameterDictionary:argsDict];
+```objc
+NSDictionary *argsDict = [NSDictionary dictionaryWithObjectsAndKeys:@"My Name", @"name", nil];
+[db executeUpdate:@"INSERT INTO myTable (name) VALUES (:name)" withParameterDictionary:argsDict];
+```
Thus, you SHOULD NOT do this (or anything like this):
- [db executeUpdate:[NSString stringWithFormat:@"INSERT INTO myTable VALUES (%@)", @"this has \" lots of ' bizarre \" quotes '"]];
-
+```objc
+[db executeUpdate:[NSString stringWithFormat:@"INSERT INTO myTable VALUES (%@)", @"this has \" lots of ' bizarre \" quotes '"]];
+```
Instead, you SHOULD do:
- [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @"this has \" lots of ' bizarre \" quotes '"];
+```objc
+[db executeUpdate:@"INSERT INTO myTable VALUES (?)", @"this has \" lots of ' bizarre \" quotes '"];
+```
All arguments provided to the `-executeUpdate:` method (or any of the variants that accept a `va_list` as a parameter) must be objects. The following will not work (and will result in a crash):
- [db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];
+```objc
+[db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];
+```
The proper way to insert a number is to box it in an `NSNumber` object:
- [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];
+```objc
+[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];
+```
Alternatively, you can use the `-execute*WithFormat:` variant to use `NSString`-style substitution:
- [db executeUpdateWithFormat:@"INSERT INTO myTable VALUES (%d)", 42];
+```objc
+[db executeUpdateWithFormat:@"INSERT INTO myTable VALUES (%d)", 42];
+```
Internally, the `-execute*WithFormat:` methods are properly boxing things for you. The following percent modifiers are recognized: `%@`, `%c`, `%s`, `%d`, `%D`, `%i`, `%u`, `%U`, `%hi`, `%hu`, `%qi`, `%qu`, `%f`, `%g`, `%ld`, `%lu`, `%lld`, and `%llu`. Using a modifier other than those will have unpredictable results. If, for some reason, you need the `%` character to appear in your SQL statement, you should use `%%`.
@@ -191,36 +216,42 @@ Instead, use FMDatabaseQueue. It's your friend and it's here to help. Here's h
First, make your queue.
- FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
+```objc
+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]) {
- …
- }
- }];
+```objc
+[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]];
-An easy way to wrap things up in a transaction can be done like this:
+ FMResultSet *rs = [db executeQuery:@"select * from foo"];
+ while ([rs next]) {
+ …
+ }
+}];
+```
- [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]];
+An easy way to wrap things up in a transaction can be done like this:
- if (whoopsSomethingWrongHappened) {
- *rollback = YES;
- return;
- }
- // etc…
- [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
- }];
+```objc
+[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 call FMDatabaseQueue'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.
@@ -243,48 +274,50 @@ To do this, you must:
For more information on bridging headers, see [Swift and Objective-C in the Same Project](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_76).
3. In your bridging header, add a line that says:
-
- #import "FMDB.h"
+ ```swift
+ #import "FMDB.h"
+ ```
4. Optionally, copy the `FMDatabaseVariadic.swift` from the "src/extra/Swift Extensions" folder into your project. This allows you to use `executeUpdate` and `executeQuery` with variadic parameters, rather than the `withArgumentsInArray` rendition.
If you do the above, you can then write Swift code that uses FMDatabase. For example:
- let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
- let path = documentsFolder.stringByAppendingPathComponent("test.sqlite")
+```swift
+let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
+let path = documentsFolder.stringByAppendingPathComponent("test.sqlite")
- let database = FMDatabase(path: path)
+let database = FMDatabase(path: path)
- if !database.open() {
- println("Unable to open database")
- return
- }
+if !database.open() {
+ println("Unable to open database")
+ return
+}
- if !database.executeUpdate("create table test(x text, y text, z text)", withArgumentsInArray: nil) {
- println("create table failed: \(database.lastErrorMessage())")
- }
+if !database.executeUpdate("create table test(x text, y text, z text)", withArgumentsInArray: nil) {
+ println("create table failed: \(database.lastErrorMessage())")
+}
- if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["a", "b", "c"]) {
- println("insert 1 table failed: \(database.lastErrorMessage())")
- }
+if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["a", "b", "c"]) {
+ println("insert 1 table failed: \(database.lastErrorMessage())")
+}
- if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["e", "f", "g"]) {
- println("insert 2 table failed: \(database.lastErrorMessage())")
- }
+if !database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", withArgumentsInArray: ["e", "f", "g"]) {
+ println("insert 2 table failed: \(database.lastErrorMessage())")
+}
- if let rs = database.executeQuery("select x, y, z from test", withArgumentsInArray: nil) {
- while rs.next() {
- let x = rs.stringForColumn("x")
- let y = rs.stringForColumn("y")
- let z = rs.stringForColumn("z")
- println("x = \(x); y = \(y); z = \(z)")
- }
- } else {
- println("select failed: \(database.lastErrorMessage())")
+if let rs = database.executeQuery("select x, y, z from test", withArgumentsInArray: nil) {
+ while rs.next() {
+ let x = rs.stringForColumn("x")
+ let y = rs.stringForColumn("y")
+ let z = rs.stringForColumn("z")
+ println("x = \(x); y = \(y); z = \(z)")
}
+} else {
+ println("select failed: \(database.lastErrorMessage())")
+}
- database.close()
-
+database.close()
+```
## History
@@ -311,9 +344,9 @@ And we've even added a template function to main.m (FMDBReportABugFunction) in t
* Open up fmdb project in Xcode.
* Open up main.m and modify the FMDBReportABugFunction to reproduce your bug.
- * Setup your table(s) in the code.
- * Make your query or update(s).
- * Add some assertions which demonstrate the bug.
+ * Setup your table(s) in the code.
+ * Make your query or update(s).
+ * Add some assertions which demonstrate the bug.
Then you can bring it up on the FMDB mailing list by showing your nice and compact FMDBReportABugFunction, or you can report the bug via the github FMDB bug reporter.