├── Podfile.lock ├── Pods ├── FMDB │ ├── LICENSE.txt │ ├── README.markdown │ └── src │ │ └── fmdb │ │ ├── FMDB.h │ │ ├── FMDatabase.h │ │ ├── FMDatabase.m │ │ ├── FMDatabaseAdditions.h │ │ ├── FMDatabaseAdditions.m │ │ ├── FMDatabasePool.h │ │ ├── FMDatabasePool.m │ │ ├── FMDatabaseQueue.h │ │ ├── FMDatabaseQueue.m │ │ ├── FMResultSet.h │ │ └── FMResultSet.m ├── Headers │ ├── Private │ │ └── FMDB │ │ │ ├── FMDB.h │ │ │ ├── FMDatabase.h │ │ │ ├── FMDatabaseAdditions.h │ │ │ ├── FMDatabasePool.h │ │ │ ├── FMDatabaseQueue.h │ │ │ └── FMResultSet.h │ └── Public │ │ └── FMDB │ │ ├── FMDB.h │ │ ├── FMDatabase.h │ │ ├── FMDatabaseAdditions.h │ │ ├── FMDatabasePool.h │ │ ├── FMDatabaseQueue.h │ │ └── FMResultSet.h ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── StriEver.xcuserdatad │ │ └── xcschemes │ │ ├── FMDB.xcscheme │ │ ├── Pods.xcscheme │ │ └── xcschememanagement.plist └── Target Support Files │ ├── FMDB │ ├── FMDB-dummy.m │ ├── FMDB-prefix.pch │ └── FMDB.xcconfig │ └── Pods │ ├── Pods-acknowledgements.markdown │ ├── Pods-acknowledgements.plist │ ├── Pods-dummy.m │ ├── Pods-frameworks.sh │ ├── Pods-resources.sh │ ├── Pods.debug.xcconfig │ └── Pods.release.xcconfig ├── README.md ├── STDBTest.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── StriEver.xcuserdatad │ └── xcschemes │ ├── STDBTest.xcscheme │ └── xcschememanagement.plist ├── STDBTest.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── StriEver.xcuserdatad │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── STDBTest ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── STDB │ ├── DBDefine.h │ ├── STDBTool.h │ ├── STDBTool.m │ └── Table.h ├── ViewController.h ├── ViewController.m └── main.m └── podfile /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMDB (2.6.2): 3 | - FMDB/standard (= 2.6.2) 4 | - FMDB/standard (2.6.2) 5 | 6 | DEPENDENCIES: 7 | - FMDB 8 | 9 | SPEC CHECKSUMS: 10 | FMDB: 854a0341b4726e53276f2a8996f06f1b80f9259a 11 | 12 | COCOAPODS: 0.39.0 13 | -------------------------------------------------------------------------------- /Pods/FMDB/LICENSE.txt: -------------------------------------------------------------------------------- 1 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 2 | by sending an email to gus@flyingmeat.com. 3 | 4 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 5 | might consider purchasing a drink of their choosing if FMDB has been useful to 6 | you. 7 | 8 | Finally, and shortly, this is the MIT License. 9 | 10 | Copyright (c) 2008-2014 Flying Meat Inc. 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining a copy 13 | of this software and associated documentation files (the "Software"), to deal 14 | in the Software without restriction, including without limitation the rights 15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the Software is 17 | furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be included in 20 | all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28 | THE SOFTWARE. -------------------------------------------------------------------------------- /Pods/FMDB/README.markdown: -------------------------------------------------------------------------------- 1 | # FMDB v2.6.2 2 | 3 | This is an Objective-C wrapper around SQLite: http://sqlite.org/ 4 | 5 | ## The FMDB Mailing List: 6 | http://groups.google.com/group/fmdb 7 | 8 | ## Read the SQLite FAQ: 9 | http://www.sqlite.org/faq.html 10 | 11 | Since FMDB is built on top of SQLite, you're going to want to read this page top to bottom at least once. And while you're there, make sure to bookmark the SQLite Documentation page: http://www.sqlite.org/docs.html 12 | 13 | ## Contributing 14 | Do you have an awesome idea that deserves to be in FMDB? You might consider pinging ccgus first to make sure he hasn't already ruled it out for some reason. Otherwise pull requests are great, and make sure you stick to the local coding conventions. However, please be patient and if you haven't heard anything from ccgus for a week or more, you might want to send a note asking what's up. 15 | 16 | ## CocoaPods 17 | 18 | [![Dependency Status](https://www.versioneye.com/objective-c/fmdb/2.3/badge.svg?style=flat)](https://www.versioneye.com/objective-c/fmdb/2.3) 19 | [![Reference Status](https://www.versioneye.com/objective-c/fmdb/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/fmdb/references) 20 | 21 | FMDB can be installed using [CocoaPods](https://cocoapods.org/). 22 | 23 | ``` 24 | pod 'FMDB' 25 | # pod 'FMDB/FTS' # FMDB with FTS 26 | # pod 'FMDB/standalone' # FMDB with latest SQLite amalgamation source 27 | # pod 'FMDB/standalone/FTS' # FMDB with latest SQLite amalgamation source and FTS 28 | # pod 'FMDB/SQLCipher' # FMDB with SQLCipher 29 | ``` 30 | 31 | **If using FMDB with [SQLCipher](https://www.zetetic.net/sqlcipher/) you must use the FMDB/SQLCipher subspec. The FMDB/SQLCipher subspec declares SQLCipher as a dependency, allowing FMDB to be compiled with the `-DSQLITE_HAS_CODEC` flag.** 32 | 33 | ## FMDB Class Reference: 34 | http://ccgus.github.io/fmdb/html/index.html 35 | 36 | ## Automatic Reference Counting (ARC) or Manual Memory Management? 37 | You can use either style in your Cocoa project. FMDB will figure out which you are using at compile time and do the right thing. 38 | 39 | ## Usage 40 | There are three main classes in FMDB: 41 | 42 | 1. `FMDatabase` - Represents a single SQLite database. Used for executing SQL statements. 43 | 2. `FMResultSet` - Represents the results of executing a query on an `FMDatabase`. 44 | 3. `FMDatabaseQueue` - If you're wanting to perform queries and updates on multiple threads, you'll want to use this class. It's described in the "Thread Safety" section below. 45 | 46 | ### Database Creation 47 | An `FMDatabase` is created with a path to a SQLite database file. This path can be one of these three: 48 | 49 | 1. A file system path. The file does not have to exist on disk. If it does not exist, it is created for you. 50 | 2. An empty string (`@""`). An empty database is created at a temporary location. This database is deleted with the `FMDatabase` connection is closed. 51 | 3. `NULL`. An in-memory database is created. This database will be destroyed with the `FMDatabase` connection is closed. 52 | 53 | (For more information on temporary and in-memory databases, read the sqlite documentation on the subject: http://www.sqlite.org/inmemorydb.html) 54 | 55 | ```objc 56 | FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"]; 57 | ``` 58 | 59 | ### Opening 60 | 61 | 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. 62 | 63 | ```objc 64 | if (![db open]) { 65 | [db release]; 66 | return; 67 | } 68 | ``` 69 | 70 | ### Executing Updates 71 | 72 | Any sort of SQL statement which is not a `SELECT` statement qualifies as an update. This includes `CREATE`, `UPDATE`, `INSERT`, `ALTER`, `COMMIT`, `BEGIN`, `DETACH`, `DELETE`, `DROP`, `END`, `EXPLAIN`, `VACUUM`, and `REPLACE` statements (plus many more). Basically, if your SQL statement does not begin with `SELECT`, it is an update statement. 73 | 74 | Executing updates returns a single value, a `BOOL`. A return value of `YES` means the update was successfully executed, and a return value of `NO` means that some error was encountered. You may invoke the `-lastErrorMessage` and `-lastErrorCode` methods to retrieve more information. 75 | 76 | ### Executing Queries 77 | 78 | A `SELECT` statement is a query and is executed via one of the `-executeQuery...` methods. 79 | 80 | Executing queries returns an `FMResultSet` object if successful, and `nil` upon failure. You should use the `-lastErrorMessage` and `-lastErrorCode` methods to determine why a query failed. 81 | 82 | 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: 83 | 84 | ```objc 85 | FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"]; 86 | while ([s next]) { 87 | //retrieve values for each record 88 | } 89 | ``` 90 | 91 | You must always invoke `-[FMResultSet next]` before attempting to access the values returned in a query, even if you're only expecting one: 92 | 93 | ```objc 94 | FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"]; 95 | if ([s next]) { 96 | int totalCount = [s intForColumnIndex:0]; 97 | } 98 | ``` 99 | 100 | `FMResultSet` has many methods to retrieve data in an appropriate format: 101 | 102 | - `intForColumn:` 103 | - `longForColumn:` 104 | - `longLongIntForColumn:` 105 | - `boolForColumn:` 106 | - `doubleForColumn:` 107 | - `stringForColumn:` 108 | - `dateForColumn:` 109 | - `dataForColumn:` 110 | - `dataNoCopyForColumn:` 111 | - `UTF8StringForColumnName:` 112 | - `objectForColumnName:` 113 | 114 | Each of these methods also has a `{type}ForColumnIndex:` variant that is used to retrieve the data based on the position of the column in the results, as opposed to the column's name. 115 | 116 | Typically, there's no need to `-close` an `FMResultSet` yourself, since that happens when either the result set is deallocated, or the parent database is closed. 117 | 118 | ### Closing 119 | 120 | 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. 121 | 122 | ```objc 123 | [db close]; 124 | ``` 125 | 126 | ### Transactions 127 | 128 | `FMDatabase` can begin and commit a transaction by invoking one of the appropriate methods or executing a begin/end transaction statement. 129 | 130 | ### Multiple Statements and Batch Stuff 131 | 132 | You can use `FMDatabase`'s executeStatements:withResultBlock: to do multiple statements in a string: 133 | 134 | ```objc 135 | NSString *sql = @"create table bulktest1 (id integer primary key autoincrement, x text);" 136 | "create table bulktest2 (id integer primary key autoincrement, y text);" 137 | "create table bulktest3 (id integer primary key autoincrement, z text);" 138 | "insert into bulktest1 (x) values ('XXX');" 139 | "insert into bulktest2 (y) values ('YYY');" 140 | "insert into bulktest3 (z) values ('ZZZ');"; 141 | 142 | success = [db executeStatements:sql]; 143 | 144 | sql = @"select count(*) as count from bulktest1;" 145 | "select count(*) as count from bulktest2;" 146 | "select count(*) as count from bulktest3;"; 147 | 148 | success = [self.db executeStatements:sql withResultBlock:^int(NSDictionary *dictionary) { 149 | NSInteger count = [dictionary[@"count"] integerValue]; 150 | XCTAssertEqual(count, 1, @"expected one record for dictionary %@", dictionary); 151 | return 0; 152 | }]; 153 | ``` 154 | 155 | ### Data Sanitization 156 | 157 | 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: 158 | 159 | ```sql 160 | INSERT INTO myTable VALUES (?, ?, ?, ?) 161 | ``` 162 | 163 | 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. 164 | 165 | And, to use that SQL with the `?` placeholders from Objective-C: 166 | 167 | ```objc 168 | NSInteger identifier = 42; 169 | NSString *name = @"Liam O'Flaherty (\"the famous Irish author\")"; 170 | NSDate *date = [NSDate date]; 171 | NSString *comment = nil; 172 | 173 | BOOL success = [db executeUpdate:@"INSERT INTO authors (identifier, name, date, comment) VALUES (?, ?, ?, ?)", @(identifier), name, date, comment ?: [NSNull null]]; 174 | if (!success) { 175 | NSLog(@"error = %@", [db lastErrorMessage]); 176 | } 177 | ``` 178 | 179 | > **Note:** Fundamental data types, like the `NSInteger` variable `identifier`, should be as a `NSNumber` objects, achieved by using the `@` syntax, shown above. Or you can use the `[NSNumber numberWithInt:identifier]` syntax, too. 180 | > 181 | > Likewise, SQL `NULL` values should be inserted as `[NSNull null]`. For example, in the case of `comment` which might be `nil` (and is in this example), you can use the `comment ?: [NSNull null]` syntax, which will insert the string if `comment` is not `nil`, but will insert `[NSNull null]` if it is `nil`. 182 | 183 | In Swift, you would use `executeUpdate(values:)`, which not only is a concise Swift syntax, but also `throws` errors for proper Swift 2 error handling: 184 | 185 | ```swift 186 | do { 187 | let identifier = 42 188 | let name = "Liam O'Flaherty (\"the famous Irish author\")" 189 | let date = NSDate() 190 | let comment: String? = nil 191 | 192 | try db.executeUpdate("INSERT INTO authors (identifier, name, date, comment) VALUES (?, ?, ?, ?)", values: [identifier, name, date, comment ?? NSNull()]) 193 | } catch { 194 | print("error = \(error)") 195 | } 196 | ``` 197 | 198 | > **Note:** In Swift, you don't have to wrap fundamental numeric types like you do in Objective-C. But if you are going to insert an optional string, you would probably use the `comment ?? NSNull()` syntax (i.e., if it is `nil`, use `NSNull`, otherwise use the string). 199 | 200 | Alternatively, you may use named parameters syntax: 201 | 202 | ```sql 203 | INSERT INTO authors (identifier, name, date, comment) VALUES (:identifier, :name, :date, :comment) 204 | ``` 205 | 206 | 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. 207 | 208 | ```objc 209 | NSDictionary *arguments = @{@"identifier": @(identifier), @"name": name, @"date": date, @"comment": comment ?: [NSNull null]}; 210 | BOOL success = [db executeUpdate:@"INSERT INTO authors (identifier, name, date, comment) VALUES (:identifier, :name, :date, :comment)" withParameterDictionary:arguments]; 211 | if (!success) { 212 | NSLog(@"error = %@", [db lastErrorMessage]); 213 | } 214 | ``` 215 | 216 | The key point is that one should not use `NSString` method `stringWithFormat` to manually insert values into the SQL statement, itself. Nor should one Swift string interpolation to insert values into the SQL. Use `?` placeholders for values to be inserted into the database (or used in `WHERE` clauses in `SELECT` statements). 217 | 218 |

Using FMDatabaseQueue and Thread Safety.

219 | 220 | Using a single instance of `FMDatabase` from multiple threads at once is a bad idea. It has always been OK to make a `FMDatabase` object *per thread*. Just don't share a single instance across threads, and definitely not across multiple threads at the same time. Bad things will eventually happen and you'll eventually get something to crash, or maybe get an exception, or maybe meteorites will fall out of the sky and hit your Mac Pro. *This would suck*. 221 | 222 | **So don't instantiate a single `FMDatabase` object and use it across multiple threads.** 223 | 224 | Instead, use `FMDatabaseQueue`. Instantiate a single `FMDatabaseQueue` and use it across multiple threads. The `FMDatabaseQueue` object will synchronize and coordinate access across the multiple threads. Here's how to use it: 225 | 226 | First, make your queue. 227 | 228 | ```objc 229 | FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; 230 | ``` 231 | 232 | Then use it like so: 233 | 234 | 235 | ```objc 236 | [queue inDatabase:^(FMDatabase *db) { 237 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1]; 238 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2]; 239 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3]; 240 | 241 | FMResultSet *rs = [db executeQuery:@"select * from foo"]; 242 | while ([rs next]) { 243 | … 244 | } 245 | }]; 246 | ``` 247 | 248 | An easy way to wrap things up in a transaction can be done like this: 249 | 250 | ```objc 251 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { 252 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @1]; 253 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @2]; 254 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @3]; 255 | 256 | if (whoopsSomethingWrongHappened) { 257 | *rollback = YES; 258 | return; 259 | } 260 | // etc… 261 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", @4]; 262 | }]; 263 | ``` 264 | 265 | The Swift equivalent would be: 266 | 267 | ```swift 268 | queue.inTransaction { db, rollback in 269 | do { 270 | try db.executeUpdate("INSERT INTO myTable VALUES (?)", values: [1]) 271 | try db.executeUpdate("INSERT INTO myTable VALUES (?)", values: [2]) 272 | try db.executeUpdate("INSERT INTO myTable VALUES (?)", values: [3]) 273 | 274 | if whoopsSomethingWrongHappened { 275 | rollback.memory = true 276 | return 277 | } 278 | 279 | try db.executeUpdate("INSERT INTO myTable VALUES (?)", values: [4]) 280 | } catch { 281 | rollback.memory = true 282 | print(error) 283 | } 284 | } 285 | ``` 286 | 287 | `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. 288 | 289 | **Note:** The calls to `FMDatabaseQueue`'s methods are blocking. So even though you are passing along blocks, they will **not** be run on another thread. 290 | 291 | ## Making custom sqlite functions, based on blocks. 292 | 293 | You can do this! For an example, look for `-makeFunctionNamed:` in main.m 294 | 295 | ## Swift 296 | 297 | You can use FMDB in Swift projects too. 298 | 299 | To do this, you must: 300 | 301 | 1. Copy the relevant `.m` and `.h` files from the FMDB `src` folder into your project. 302 | 303 | You can copy all of them (which is easiest), or only the ones you need. Likely you will need [`FMDatabase`](http://ccgus.github.io/fmdb/html/Classes/FMDatabase.html) and [`FMResultSet`](http://ccgus.github.io/fmdb/html/Classes/FMResultSet.html) at a minimum. [`FMDatabaseAdditions`](http://ccgus.github.io/fmdb/html/Categories/FMDatabase+FMDatabaseAdditions.html) provides some very useful convenience methods, so you will likely want that, too. If you are doing multithreaded access to a database, [`FMDatabaseQueue`](http://ccgus.github.io/fmdb/html/Classes/FMDatabaseQueue.html) is quite useful, too. If you choose to not copy all of the files from the `src` directory, though, you may want to update `FMDB.h` to only reference the files that you included in your project. 304 | 305 | Note, if you're copying all of the files from the `src` folder into to your project (which is recommended), you may want to drag the individual files into your project, not the folder, itself, because if you drag the folder, you won't be prompted to add the bridging header (see next point). 306 | 307 | 2. If prompted to create a "bridging header", you should do so. If not prompted and if you don't already have a bridging header, add one. 308 | 309 | 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). 310 | 311 | 3. In your bridging header, add a line that says: 312 | ```objc 313 | #import "FMDB.h" 314 | ``` 315 | 316 | 4. Use the variations of `executeQuery` and `executeUpdate` with the `sql` and `values` parameters with `try` pattern, as shown below. These renditions of `executeQuery` and `executeUpdate` both `throw` errors in true Swift 2 fashion. 317 | 318 | If you do the above, you can then write Swift code that uses `FMDatabase`. For example: 319 | 320 | ```swift 321 | let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false) 322 | let fileURL = documents.URLByAppendingPathComponent("test.sqlite") 323 | 324 | let database = FMDatabase(path: fileURL.path) 325 | 326 | if !database.open() { 327 | print("Unable to open database") 328 | return 329 | } 330 | 331 | do { 332 | try database.executeUpdate("create table test(x text, y text, z text)", values: nil) 333 | try database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", values: ["a", "b", "c"]) 334 | try database.executeUpdate("insert into test (x, y, z) values (?, ?, ?)", values: ["e", "f", "g"]) 335 | 336 | let rs = try database.executeQuery("select x, y, z from test", values: nil) 337 | while rs.next() { 338 | let x = rs.stringForColumn("x") 339 | let y = rs.stringForColumn("y") 340 | let z = rs.stringForColumn("z") 341 | print("x = \(x); y = \(y); z = \(z)") 342 | } 343 | } catch let error as NSError { 344 | print("failed: \(error.localizedDescription)") 345 | } 346 | 347 | database.close() 348 | ``` 349 | 350 | ## History 351 | 352 | The history and changes are availbe on its [GitHub page](https://github.com/ccgus/fmdb) and are summarized in the "CHANGES_AND_TODO_LIST.txt" file. 353 | 354 | ## Contributors 355 | 356 | The contributors to FMDB are contained in the "Contributors.txt" file. 357 | 358 | ## Additional projects using FMDB, which might be interesting to the discerning developer. 359 | 360 | * FMDBMigrationManager, A SQLite schema migration management system for FMDB: https://github.com/layerhq/FMDBMigrationManager 361 | * FCModel, An alternative to Core Data for people who like having direct SQL access: https://github.com/marcoarment/FCModel 362 | 363 | ## Quick notes on FMDB's coding style 364 | 365 | Spaces, not tabs. Square brackets, not dot notation. Look at what FMDB already does with curly brackets and such, and stick to that style. 366 | 367 | ## Reporting bugs 368 | 369 | Reduce your bug down to the smallest amount of code possible. You want to make it super easy for the developers to see and reproduce your bug. If it helps, pretend that the person who can fix your bug is active on shipping 3 major products, works on a handful of open source projects, has a newborn baby, and is generally very very busy. 370 | 371 | And we've even added a template function to main.m (FMDBReportABugFunction) in the FMDB distribution to help you out: 372 | 373 | * Open up fmdb project in Xcode. 374 | * Open up main.m and modify the FMDBReportABugFunction to reproduce your bug. 375 | * Setup your table(s) in the code. 376 | * Make your query or update(s). 377 | * Add some assertions which demonstrate the bug. 378 | 379 | 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. 380 | 381 | **Optional:** 382 | 383 | Figure out where the bug is, fix it, and send a patch in or bring that up on the mailing list. Make sure all the other tests run after your modifications. 384 | 385 | ## Support 386 | 387 | The support channels for FMDB are the mailing list (see above), filing a bug here, or maybe on Stack Overflow. So that is to say, support is provided by the community and on a voluntary basis. 388 | 389 | FMDB development is overseen by Gus Mueller of Flying Meat. If FMDB been helpful to you, consider purchasing an app from FM or telling all your friends about it. 390 | 391 | ## License 392 | 393 | The license for FMDB is contained in the "License.txt" file. 394 | 395 | If you happen to come across either Gus Mueller or Rob Ryan in a bar, you might consider purchasing a drink of their choosing if FMDB has been useful to you. 396 | 397 | (The drink is for them of course, shame on you for trying to keep it.) 398 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDB.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | FOUNDATION_EXPORT double FMDBVersionNumber; 4 | FOUNDATION_EXPORT const unsigned char FMDBVersionString[]; 5 | 6 | #import "FMDatabase.h" 7 | #import "FMResultSet.h" 8 | #import "FMDatabaseAdditions.h" 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabasePool.h" 11 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FMDatabase.h" 11 | 12 | 13 | /** Category of additions for `` class. 14 | 15 | ### See also 16 | 17 | - `` 18 | */ 19 | 20 | @interface FMDatabase (FMDatabaseAdditions) 21 | 22 | ///---------------------------------------- 23 | /// @name Return results of SQL to variable 24 | ///---------------------------------------- 25 | 26 | /** Return `int` value for query 27 | 28 | @param query The SQL query to be performed. 29 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 30 | 31 | @return `int` value. 32 | 33 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 34 | */ 35 | 36 | - (int)intForQuery:(NSString*)query, ...; 37 | 38 | /** Return `long` value for query 39 | 40 | @param query The SQL query to be performed. 41 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 42 | 43 | @return `long` value. 44 | 45 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 46 | */ 47 | 48 | - (long)longForQuery:(NSString*)query, ...; 49 | 50 | /** Return `BOOL` value for query 51 | 52 | @param query The SQL query to be performed. 53 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 54 | 55 | @return `BOOL` value. 56 | 57 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 58 | */ 59 | 60 | - (BOOL)boolForQuery:(NSString*)query, ...; 61 | 62 | /** Return `double` value for query 63 | 64 | @param query The SQL query to be performed. 65 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 66 | 67 | @return `double` value. 68 | 69 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 70 | */ 71 | 72 | - (double)doubleForQuery:(NSString*)query, ...; 73 | 74 | /** Return `NSString` value for query 75 | 76 | @param query The SQL query to be performed. 77 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 78 | 79 | @return `NSString` value. 80 | 81 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 82 | */ 83 | 84 | - (NSString*)stringForQuery:(NSString*)query, ...; 85 | 86 | /** Return `NSData` value for query 87 | 88 | @param query The SQL query to be performed. 89 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 90 | 91 | @return `NSData` value. 92 | 93 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 94 | */ 95 | 96 | - (NSData*)dataForQuery:(NSString*)query, ...; 97 | 98 | /** Return `NSDate` value for query 99 | 100 | @param query The SQL query to be performed. 101 | @param ... A list of parameters that will be bound to the `?` placeholders in the SQL query. 102 | 103 | @return `NSDate` value. 104 | 105 | @note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project. 106 | */ 107 | 108 | - (NSDate*)dateForQuery:(NSString*)query, ...; 109 | 110 | 111 | // Notice that there's no dataNoCopyForQuery:. 112 | // That would be a bad idea, because we close out the result set, and then what 113 | // happens to the data that we just didn't copy? Who knows, not I. 114 | 115 | 116 | ///-------------------------------- 117 | /// @name Schema related operations 118 | ///-------------------------------- 119 | 120 | /** Does table exist in database? 121 | 122 | @param tableName The name of the table being looked for. 123 | 124 | @return `YES` if table found; `NO` if not found. 125 | */ 126 | 127 | - (BOOL)tableExists:(NSString*)tableName; 128 | 129 | /** The schema of the database. 130 | 131 | This will be the schema for the entire database. For each entity, each row of the result set will include the following fields: 132 | 133 | - `type` - The type of entity (e.g. table, index, view, or trigger) 134 | - `name` - The name of the object 135 | - `tbl_name` - The name of the table to which the object references 136 | - `rootpage` - The page number of the root b-tree page for tables and indices 137 | - `sql` - The SQL that created the entity 138 | 139 | @return `FMResultSet` of schema; `nil` on error. 140 | 141 | @see [SQLite File Format](http://www.sqlite.org/fileformat.html) 142 | */ 143 | 144 | - (FMResultSet*)getSchema; 145 | 146 | /** The schema of the database. 147 | 148 | This will be the schema for a particular table as report by SQLite `PRAGMA`, for example: 149 | 150 | PRAGMA table_info('employees') 151 | 152 | This will report: 153 | 154 | - `cid` - The column ID number 155 | - `name` - The name of the column 156 | - `type` - The data type specified for the column 157 | - `notnull` - whether the field is defined as NOT NULL (i.e. values required) 158 | - `dflt_value` - The default value for the column 159 | - `pk` - Whether the field is part of the primary key of the table 160 | 161 | @param tableName The name of the table for whom the schema will be returned. 162 | 163 | @return `FMResultSet` of schema; `nil` on error. 164 | 165 | @see [table_info](http://www.sqlite.org/pragma.html#pragma_table_info) 166 | */ 167 | 168 | - (FMResultSet*)getTableSchema:(NSString*)tableName; 169 | 170 | /** Test to see if particular column exists for particular table in database 171 | 172 | @param columnName The name of the column. 173 | 174 | @param tableName The name of the table. 175 | 176 | @return `YES` if column exists in table in question; `NO` otherwise. 177 | */ 178 | 179 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName; 180 | 181 | /** Test to see if particular column exists for particular table in database 182 | 183 | @param columnName The name of the column. 184 | 185 | @param tableName The name of the table. 186 | 187 | @return `YES` if column exists in table in question; `NO` otherwise. 188 | 189 | @see columnExists:inTableWithName: 190 | 191 | @warning Deprecated - use `` instead. 192 | */ 193 | 194 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)); 195 | 196 | 197 | /** Validate SQL statement 198 | 199 | This validates SQL statement by performing `sqlite3_prepare_v2`, but not returning the results, but instead immediately calling `sqlite3_finalize`. 200 | 201 | @param sql The SQL statement being validated. 202 | 203 | @param error This is a pointer to a `NSError` object that will receive the autoreleased `NSError` object if there was any error. If this is `nil`, no `NSError` result will be returned. 204 | 205 | @return `YES` if validation succeeded without incident; `NO` otherwise. 206 | 207 | */ 208 | 209 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error; 210 | 211 | 212 | ///----------------------------------- 213 | /// @name Application identifier tasks 214 | ///----------------------------------- 215 | 216 | /** Retrieve application ID 217 | 218 | @return The `uint32_t` numeric value of the application ID. 219 | 220 | @see setApplicationID: 221 | */ 222 | 223 | - (uint32_t)applicationID; 224 | 225 | /** Set the application ID 226 | 227 | @param appID The `uint32_t` numeric value of the application ID. 228 | 229 | @see applicationID 230 | */ 231 | 232 | - (void)setApplicationID:(uint32_t)appID; 233 | 234 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 235 | /** Retrieve application ID string 236 | 237 | @return The `NSString` value of the application ID. 238 | 239 | @see setApplicationIDString: 240 | */ 241 | 242 | 243 | - (NSString*)applicationIDString; 244 | 245 | /** Set the application ID string 246 | 247 | @param string The `NSString` value of the application ID. 248 | 249 | @see applicationIDString 250 | */ 251 | 252 | - (void)setApplicationIDString:(NSString*)string; 253 | 254 | #endif 255 | 256 | ///----------------------------------- 257 | /// @name user version identifier tasks 258 | ///----------------------------------- 259 | 260 | /** Retrieve user version 261 | 262 | @return The `uint32_t` numeric value of the user version. 263 | 264 | @see setUserVersion: 265 | */ 266 | 267 | - (uint32_t)userVersion; 268 | 269 | /** Set the user-version 270 | 271 | @param version The `uint32_t` numeric value of the user version. 272 | 273 | @see userVersion 274 | */ 275 | 276 | - (void)setUserVersion:(uint32_t)version; 277 | 278 | @end 279 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabaseAdditions.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseAdditions.m 3 | // fmdb 4 | // 5 | // Created by August Mueller on 10/30/05. 6 | // Copyright 2005 Flying Meat Inc.. All rights reserved. 7 | // 8 | 9 | #import "FMDatabase.h" 10 | #import "FMDatabaseAdditions.h" 11 | #import "TargetConditionals.h" 12 | 13 | #if FMDB_SQLITE_STANDALONE 14 | #import 15 | #else 16 | #import 17 | #endif 18 | 19 | @interface FMDatabase (PrivateStuff) 20 | - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args; 21 | @end 22 | 23 | @implementation FMDatabase (FMDatabaseAdditions) 24 | 25 | #define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \ 26 | va_list args; \ 27 | va_start(args, query); \ 28 | FMResultSet *resultSet = [self executeQuery:query withArgumentsInArray:0x00 orDictionary:0x00 orVAList:args]; \ 29 | va_end(args); \ 30 | if (![resultSet next]) { return (type)0; } \ 31 | type ret = [resultSet sel:0]; \ 32 | [resultSet close]; \ 33 | [resultSet setParentDB:nil]; \ 34 | return ret; 35 | 36 | 37 | - (NSString*)stringForQuery:(NSString*)query, ... { 38 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex); 39 | } 40 | 41 | - (int)intForQuery:(NSString*)query, ... { 42 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex); 43 | } 44 | 45 | - (long)longForQuery:(NSString*)query, ... { 46 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex); 47 | } 48 | 49 | - (BOOL)boolForQuery:(NSString*)query, ... { 50 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex); 51 | } 52 | 53 | - (double)doubleForQuery:(NSString*)query, ... { 54 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex); 55 | } 56 | 57 | - (NSData*)dataForQuery:(NSString*)query, ... { 58 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex); 59 | } 60 | 61 | - (NSDate*)dateForQuery:(NSString*)query, ... { 62 | RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex); 63 | } 64 | 65 | 66 | - (BOOL)tableExists:(NSString*)tableName { 67 | 68 | tableName = [tableName lowercaseString]; 69 | 70 | FMResultSet *rs = [self executeQuery:@"select [sql] from sqlite_master where [type] = 'table' and lower(name) = ?", tableName]; 71 | 72 | //if at least one next exists, table exists 73 | BOOL returnBool = [rs next]; 74 | 75 | //close and free object 76 | [rs close]; 77 | 78 | return returnBool; 79 | } 80 | 81 | /* 82 | get table with list of tables: result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 83 | check if table exist in database (patch from OZLB) 84 | */ 85 | - (FMResultSet*)getSchema { 86 | 87 | //result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING] 88 | FMResultSet *rs = [self executeQuery:@"SELECT type, name, tbl_name, rootpage, sql FROM (SELECT * FROM sqlite_master UNION ALL SELECT * FROM sqlite_temp_master) WHERE type != 'meta' AND name NOT LIKE 'sqlite_%' ORDER BY tbl_name, type DESC, name"]; 89 | 90 | return rs; 91 | } 92 | 93 | /* 94 | get table schema: result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 95 | */ 96 | - (FMResultSet*)getTableSchema:(NSString*)tableName { 97 | 98 | //result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER] 99 | FMResultSet *rs = [self executeQuery:[NSString stringWithFormat: @"pragma table_info('%@')", tableName]]; 100 | 101 | return rs; 102 | } 103 | 104 | - (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName { 105 | 106 | BOOL returnBool = NO; 107 | 108 | tableName = [tableName lowercaseString]; 109 | columnName = [columnName lowercaseString]; 110 | 111 | FMResultSet *rs = [self getTableSchema:tableName]; 112 | 113 | //check if column is present in table schema 114 | while ([rs next]) { 115 | if ([[[rs stringForColumn:@"name"] lowercaseString] isEqualToString:columnName]) { 116 | returnBool = YES; 117 | break; 118 | } 119 | } 120 | 121 | //If this is not done FMDatabase instance stays out of pool 122 | [rs close]; 123 | 124 | return returnBool; 125 | } 126 | 127 | 128 | 129 | - (uint32_t)applicationID { 130 | #if SQLITE_VERSION_NUMBER >= 3007017 131 | uint32_t r = 0; 132 | 133 | FMResultSet *rs = [self executeQuery:@"pragma application_id"]; 134 | 135 | if ([rs next]) { 136 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 137 | } 138 | 139 | [rs close]; 140 | 141 | return r; 142 | #else 143 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 144 | if (self.logsErrors) NSLog(@"%@", errorMessage); 145 | return 0; 146 | #endif 147 | } 148 | 149 | - (void)setApplicationID:(uint32_t)appID { 150 | #if SQLITE_VERSION_NUMBER >= 3007017 151 | NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID]; 152 | FMResultSet *rs = [self executeQuery:query]; 153 | [rs next]; 154 | [rs close]; 155 | #else 156 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 157 | if (self.logsErrors) NSLog(@"%@", errorMessage); 158 | #endif 159 | } 160 | 161 | 162 | #if TARGET_OS_MAC && !TARGET_OS_IPHONE 163 | 164 | - (NSString*)applicationIDString { 165 | #if SQLITE_VERSION_NUMBER >= 3007017 166 | NSString *s = NSFileTypeForHFSTypeCode([self applicationID]); 167 | 168 | assert([s length] == 6); 169 | 170 | s = [s substringWithRange:NSMakeRange(1, 4)]; 171 | 172 | 173 | return s; 174 | #else 175 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 176 | if (self.logsErrors) NSLog(@"%@", errorMessage); 177 | return nil; 178 | #endif 179 | } 180 | 181 | - (void)setApplicationIDString:(NSString*)s { 182 | #if SQLITE_VERSION_NUMBER >= 3007017 183 | if ([s length] != 4) { 184 | NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]); 185 | } 186 | 187 | [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])]; 188 | #else 189 | NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil); 190 | if (self.logsErrors) NSLog(@"%@", errorMessage); 191 | #endif 192 | } 193 | 194 | #endif 195 | 196 | - (uint32_t)userVersion { 197 | uint32_t r = 0; 198 | 199 | FMResultSet *rs = [self executeQuery:@"pragma user_version"]; 200 | 201 | if ([rs next]) { 202 | r = (uint32_t)[rs longLongIntForColumnIndex:0]; 203 | } 204 | 205 | [rs close]; 206 | return r; 207 | } 208 | 209 | - (void)setUserVersion:(uint32_t)version { 210 | NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version]; 211 | FMResultSet *rs = [self executeQuery:query]; 212 | [rs next]; 213 | [rs close]; 214 | } 215 | 216 | #pragma clang diagnostic push 217 | #pragma clang diagnostic ignored "-Wdeprecated-implementations" 218 | 219 | - (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)) { 220 | return [self columnExists:columnName inTableWithName:tableName]; 221 | } 222 | 223 | #pragma clang diagnostic pop 224 | 225 | 226 | - (BOOL)validateSQL:(NSString*)sql error:(NSError**)error { 227 | sqlite3_stmt *pStmt = NULL; 228 | BOOL validationSucceeded = YES; 229 | 230 | int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0); 231 | if (rc != SQLITE_OK) { 232 | validationSucceeded = NO; 233 | if (error) { 234 | *error = [NSError errorWithDomain:NSCocoaErrorDomain 235 | code:[self lastErrorCode] 236 | userInfo:[NSDictionary dictionaryWithObject:[self lastErrorMessage] 237 | forKey:NSLocalizedDescriptionKey]]; 238 | } 239 | } 240 | 241 | sqlite3_finalize(pStmt); 242 | 243 | return validationSucceeded; 244 | } 245 | 246 | @end 247 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabasePool.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FMDatabase; 12 | 13 | /** Pool of `` objects. 14 | 15 | ### See also 16 | 17 | - `` 18 | - `` 19 | 20 | @warning Before using `FMDatabasePool`, please consider using `` instead. 21 | 22 | If you really really really know what you're doing and `FMDatabasePool` is what 23 | you really really need (ie, you're using a read only database), OK you can use 24 | it. But just be careful not to deadlock! 25 | 26 | For an example on deadlocking, search for: 27 | `ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD` 28 | in the main.m file. 29 | */ 30 | 31 | @interface FMDatabasePool : NSObject { 32 | NSString *_path; 33 | 34 | dispatch_queue_t _lockQueue; 35 | 36 | NSMutableArray *_databaseInPool; 37 | NSMutableArray *_databaseOutPool; 38 | 39 | __unsafe_unretained id _delegate; 40 | 41 | NSUInteger _maximumNumberOfDatabasesToCreate; 42 | int _openFlags; 43 | } 44 | 45 | /** Database path */ 46 | 47 | @property (atomic, retain) NSString *path; 48 | 49 | /** Delegate object */ 50 | 51 | @property (atomic, assign) id delegate; 52 | 53 | /** Maximum number of databases to create */ 54 | 55 | @property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate; 56 | 57 | /** Open flags */ 58 | 59 | @property (atomic, readonly) int openFlags; 60 | 61 | 62 | ///--------------------- 63 | /// @name Initialization 64 | ///--------------------- 65 | 66 | /** Create pool using path. 67 | 68 | @param aPath The file path of the database. 69 | 70 | @return The `FMDatabasePool` object. `nil` on error. 71 | */ 72 | 73 | + (instancetype)databasePoolWithPath:(NSString*)aPath; 74 | 75 | /** Create pool using path and specified flags 76 | 77 | @param aPath The file path of the database. 78 | @param openFlags Flags passed to the openWithFlags method of the database 79 | 80 | @return The `FMDatabasePool` object. `nil` on error. 81 | */ 82 | 83 | + (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags; 84 | 85 | /** Create pool using path. 86 | 87 | @param aPath The file path of the database. 88 | 89 | @return The `FMDatabasePool` object. `nil` on error. 90 | */ 91 | 92 | - (instancetype)initWithPath:(NSString*)aPath; 93 | 94 | /** Create pool using path and specified flags. 95 | 96 | @param aPath The file path of the database. 97 | @param openFlags Flags passed to the openWithFlags method of the database 98 | 99 | @return The `FMDatabasePool` object. `nil` on error. 100 | */ 101 | 102 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags; 103 | 104 | ///------------------------------------------------ 105 | /// @name Keeping track of checked in/out databases 106 | ///------------------------------------------------ 107 | 108 | /** Number of checked-in databases in pool 109 | 110 | @returns Number of databases 111 | */ 112 | 113 | - (NSUInteger)countOfCheckedInDatabases; 114 | 115 | /** Number of checked-out databases in pool 116 | 117 | @returns Number of databases 118 | */ 119 | 120 | - (NSUInteger)countOfCheckedOutDatabases; 121 | 122 | /** Total number of databases in pool 123 | 124 | @returns Number of databases 125 | */ 126 | 127 | - (NSUInteger)countOfOpenDatabases; 128 | 129 | /** Release all databases in pool */ 130 | 131 | - (void)releaseAllDatabases; 132 | 133 | ///------------------------------------------ 134 | /// @name Perform database operations in pool 135 | ///------------------------------------------ 136 | 137 | /** Synchronously perform database operations in pool. 138 | 139 | @param block The code to be run on the `FMDatabasePool` pool. 140 | */ 141 | 142 | - (void)inDatabase:(void (^)(FMDatabase *db))block; 143 | 144 | /** Synchronously perform database operations in pool using transaction. 145 | 146 | @param block The code to be run on the `FMDatabasePool` pool. 147 | */ 148 | 149 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 150 | 151 | /** Synchronously perform database operations in pool using deferred transaction. 152 | 153 | @param block The code to be run on the `FMDatabasePool` pool. 154 | */ 155 | 156 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 157 | 158 | /** Synchronously perform database operations in pool using save point. 159 | 160 | @param block The code to be run on the `FMDatabasePool` pool. 161 | 162 | @return `NSError` object if error; `nil` if successful. 163 | 164 | @warning You can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. If you need to nest, use `<[FMDatabase startSavePointWithName:error:]>` instead. 165 | */ 166 | 167 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block; 168 | 169 | @end 170 | 171 | 172 | /** FMDatabasePool delegate category 173 | 174 | This is a category that defines the protocol for the FMDatabasePool delegate 175 | */ 176 | 177 | @interface NSObject (FMDatabasePoolDelegate) 178 | 179 | /** Asks the delegate whether database should be added to the pool. 180 | 181 | @param pool The `FMDatabasePool` object. 182 | @param database The `FMDatabase` object. 183 | 184 | @return `YES` if it should add database to pool; `NO` if not. 185 | 186 | */ 187 | 188 | - (BOOL)databasePool:(FMDatabasePool*)pool shouldAddDatabaseToPool:(FMDatabase*)database; 189 | 190 | /** Tells the delegate that database was added to the pool. 191 | 192 | @param pool The `FMDatabasePool` object. 193 | @param database The `FMDatabase` object. 194 | 195 | */ 196 | 197 | - (void)databasePool:(FMDatabasePool*)pool didAddDatabase:(FMDatabase*)database; 198 | 199 | @end 200 | 201 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabasePool.m: -------------------------------------------------------------------------------- 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 | 9 | #if FMDB_SQLITE_STANDALONE 10 | #import 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "FMDatabasePool.h" 16 | #import "FMDatabase.h" 17 | 18 | @interface FMDatabasePool() 19 | 20 | - (void)pushDatabaseBackInPool:(FMDatabase*)db; 21 | - (FMDatabase*)db; 22 | 23 | @end 24 | 25 | 26 | @implementation FMDatabasePool 27 | @synthesize path=_path; 28 | @synthesize delegate=_delegate; 29 | @synthesize maximumNumberOfDatabasesToCreate=_maximumNumberOfDatabasesToCreate; 30 | @synthesize openFlags=_openFlags; 31 | 32 | 33 | + (instancetype)databasePoolWithPath:(NSString*)aPath { 34 | return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath]); 35 | } 36 | 37 | + (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags { 38 | return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath flags:openFlags]); 39 | } 40 | 41 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags { 42 | 43 | self = [super init]; 44 | 45 | if (self != nil) { 46 | _path = [aPath copy]; 47 | _lockQueue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL); 48 | _databaseInPool = FMDBReturnRetained([NSMutableArray array]); 49 | _databaseOutPool = FMDBReturnRetained([NSMutableArray array]); 50 | _openFlags = openFlags; 51 | } 52 | 53 | return self; 54 | } 55 | 56 | - (instancetype)initWithPath:(NSString*)aPath 57 | { 58 | // default flags for sqlite3_open 59 | return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE]; 60 | } 61 | 62 | - (instancetype)init { 63 | return [self initWithPath:nil]; 64 | } 65 | 66 | 67 | - (void)dealloc { 68 | 69 | _delegate = 0x00; 70 | FMDBRelease(_path); 71 | FMDBRelease(_databaseInPool); 72 | FMDBRelease(_databaseOutPool); 73 | 74 | if (_lockQueue) { 75 | FMDBDispatchQueueRelease(_lockQueue); 76 | _lockQueue = 0x00; 77 | } 78 | #if ! __has_feature(objc_arc) 79 | [super dealloc]; 80 | #endif 81 | } 82 | 83 | 84 | - (void)executeLocked:(void (^)(void))aBlock { 85 | dispatch_sync(_lockQueue, aBlock); 86 | } 87 | 88 | - (void)pushDatabaseBackInPool:(FMDatabase*)db { 89 | 90 | if (!db) { // db can be null if we set an upper bound on the # of databases to create. 91 | return; 92 | } 93 | 94 | [self executeLocked:^() { 95 | 96 | if ([self->_databaseInPool containsObject:db]) { 97 | [[NSException exceptionWithName:@"Database already in pool" reason:@"The FMDatabase being put back into the pool is already present in the pool" userInfo:nil] raise]; 98 | } 99 | 100 | [self->_databaseInPool addObject:db]; 101 | [self->_databaseOutPool removeObject:db]; 102 | 103 | }]; 104 | } 105 | 106 | - (FMDatabase*)db { 107 | 108 | __block FMDatabase *db; 109 | 110 | 111 | [self executeLocked:^() { 112 | db = [self->_databaseInPool lastObject]; 113 | 114 | BOOL shouldNotifyDelegate = NO; 115 | 116 | if (db) { 117 | [self->_databaseOutPool addObject:db]; 118 | [self->_databaseInPool removeLastObject]; 119 | } 120 | else { 121 | 122 | if (self->_maximumNumberOfDatabasesToCreate) { 123 | NSUInteger currentCount = [self->_databaseOutPool count] + [self->_databaseInPool count]; 124 | 125 | if (currentCount >= self->_maximumNumberOfDatabasesToCreate) { 126 | NSLog(@"Maximum number of databases (%ld) has already been reached!", (long)currentCount); 127 | return; 128 | } 129 | } 130 | 131 | db = [FMDatabase databaseWithPath:self->_path]; 132 | shouldNotifyDelegate = YES; 133 | } 134 | 135 | //This ensures that the db is opened before returning 136 | #if SQLITE_VERSION_NUMBER >= 3005000 137 | BOOL success = [db openWithFlags:self->_openFlags]; 138 | #else 139 | BOOL success = [db open]; 140 | #endif 141 | if (success) { 142 | if ([self->_delegate respondsToSelector:@selector(databasePool:shouldAddDatabaseToPool:)] && ![self->_delegate databasePool:self shouldAddDatabaseToPool:db]) { 143 | [db close]; 144 | db = 0x00; 145 | } 146 | else { 147 | //It should not get added in the pool twice if lastObject was found 148 | if (![self->_databaseOutPool containsObject:db]) { 149 | [self->_databaseOutPool addObject:db]; 150 | 151 | if (shouldNotifyDelegate && [self->_delegate respondsToSelector:@selector(databasePool:didAddDatabase:)]) { 152 | [self->_delegate databasePool:self didAddDatabase:db]; 153 | } 154 | } 155 | } 156 | } 157 | else { 158 | NSLog(@"Could not open up the database at path %@", self->_path); 159 | db = 0x00; 160 | } 161 | }]; 162 | 163 | return db; 164 | } 165 | 166 | - (NSUInteger)countOfCheckedInDatabases { 167 | 168 | __block NSUInteger count; 169 | 170 | [self executeLocked:^() { 171 | count = [self->_databaseInPool count]; 172 | }]; 173 | 174 | return count; 175 | } 176 | 177 | - (NSUInteger)countOfCheckedOutDatabases { 178 | 179 | __block NSUInteger count; 180 | 181 | [self executeLocked:^() { 182 | count = [self->_databaseOutPool count]; 183 | }]; 184 | 185 | return count; 186 | } 187 | 188 | - (NSUInteger)countOfOpenDatabases { 189 | __block NSUInteger count; 190 | 191 | [self executeLocked:^() { 192 | count = [self->_databaseOutPool count] + [self->_databaseInPool count]; 193 | }]; 194 | 195 | return count; 196 | } 197 | 198 | - (void)releaseAllDatabases { 199 | [self executeLocked:^() { 200 | [self->_databaseOutPool removeAllObjects]; 201 | [self->_databaseInPool removeAllObjects]; 202 | }]; 203 | } 204 | 205 | - (void)inDatabase:(void (^)(FMDatabase *db))block { 206 | 207 | FMDatabase *db = [self db]; 208 | 209 | block(db); 210 | 211 | [self pushDatabaseBackInPool:db]; 212 | } 213 | 214 | - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block { 215 | 216 | BOOL shouldRollback = NO; 217 | 218 | FMDatabase *db = [self db]; 219 | 220 | if (useDeferred) { 221 | [db beginDeferredTransaction]; 222 | } 223 | else { 224 | [db beginTransaction]; 225 | } 226 | 227 | 228 | block(db, &shouldRollback); 229 | 230 | if (shouldRollback) { 231 | [db rollback]; 232 | } 233 | else { 234 | [db commit]; 235 | } 236 | 237 | [self pushDatabaseBackInPool:db]; 238 | } 239 | 240 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 241 | [self beginTransaction:YES withBlock:block]; 242 | } 243 | 244 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 245 | [self beginTransaction:NO withBlock:block]; 246 | } 247 | 248 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block { 249 | #if SQLITE_VERSION_NUMBER >= 3007000 250 | static unsigned long savePointIdx = 0; 251 | 252 | NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++]; 253 | 254 | BOOL shouldRollback = NO; 255 | 256 | FMDatabase *db = [self db]; 257 | 258 | NSError *err = 0x00; 259 | 260 | if (![db startSavePointWithName:name error:&err]) { 261 | [self pushDatabaseBackInPool:db]; 262 | return err; 263 | } 264 | 265 | block(db, &shouldRollback); 266 | 267 | if (shouldRollback) { 268 | // We need to rollback and release this savepoint to remove it 269 | [db rollbackToSavePointWithName:name error:&err]; 270 | } 271 | [db releaseSavePointWithName:name error:&err]; 272 | 273 | [self pushDatabaseBackInPool:db]; 274 | 275 | return err; 276 | #else 277 | NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil); 278 | if (self.logsErrors) NSLog(@"%@", errorMessage); 279 | return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; 280 | #endif 281 | } 282 | 283 | @end 284 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue.h 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FMDatabase; 12 | 13 | /** To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`. 14 | 15 | Using a single instance of `` from multiple threads at once is a bad idea. It has always been OK to make a `` object *per thread*. Just don't share a single instance across threads, and definitely not across multiple threads at the same time. 16 | 17 | Instead, use `FMDatabaseQueue`. Here's how to use it: 18 | 19 | First, make your queue. 20 | 21 | FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; 22 | 23 | Then use it like so: 24 | 25 | [queue inDatabase:^(FMDatabase *db) { 26 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; 27 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; 28 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; 29 | 30 | FMResultSet *rs = [db executeQuery:@"select * from foo"]; 31 | while ([rs next]) { 32 | //… 33 | } 34 | }]; 35 | 36 | An easy way to wrap things up in a transaction can be done like this: 37 | 38 | [queue inTransaction:^(FMDatabase *db, BOOL *rollback) { 39 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]]; 40 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]]; 41 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; 42 | 43 | if (whoopsSomethingWrongHappened) { 44 | *rollback = YES; 45 | return; 46 | } 47 | // etc… 48 | [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]]; 49 | }]; 50 | 51 | `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. 52 | 53 | ### See also 54 | 55 | - `` 56 | 57 | @warning Do not instantiate a single `` object and use it across multiple threads. Use `FMDatabaseQueue` instead. 58 | 59 | @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. 60 | 61 | */ 62 | 63 | @interface FMDatabaseQueue : NSObject { 64 | NSString *_path; 65 | dispatch_queue_t _queue; 66 | FMDatabase *_db; 67 | int _openFlags; 68 | } 69 | 70 | /** Path of database */ 71 | 72 | @property (atomic, retain) NSString *path; 73 | 74 | /** Open flags */ 75 | 76 | @property (atomic, readonly) int openFlags; 77 | 78 | ///---------------------------------------------------- 79 | /// @name Initialization, opening, and closing of queue 80 | ///---------------------------------------------------- 81 | 82 | /** Create queue using path. 83 | 84 | @param aPath The file path of the database. 85 | 86 | @return The `FMDatabaseQueue` object. `nil` on error. 87 | */ 88 | 89 | + (instancetype)databaseQueueWithPath:(NSString*)aPath; 90 | 91 | /** Create queue using path and specified flags. 92 | 93 | @param aPath The file path of the database. 94 | @param openFlags Flags passed to the openWithFlags method of the database 95 | 96 | @return The `FMDatabaseQueue` object. `nil` on error. 97 | */ 98 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags; 99 | 100 | /** Create queue using path. 101 | 102 | @param aPath The file path of the database. 103 | 104 | @return The `FMDatabaseQueue` object. `nil` on error. 105 | */ 106 | 107 | - (instancetype)initWithPath:(NSString*)aPath; 108 | 109 | /** Create queue using path and specified flags. 110 | 111 | @param aPath The file path of the database. 112 | @param openFlags Flags passed to the openWithFlags method of the database 113 | 114 | @return The `FMDatabaseQueue` object. `nil` on error. 115 | */ 116 | 117 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags; 118 | 119 | /** Create queue using path and specified flags. 120 | 121 | @param aPath The file path of the database. 122 | @param openFlags Flags passed to the openWithFlags method of the database 123 | @param vfsName The name of a custom virtual file system 124 | 125 | @return The `FMDatabaseQueue` object. `nil` on error. 126 | */ 127 | 128 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName; 129 | 130 | /** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object. 131 | 132 | Subclasses can override this method to return specified Class of 'FMDatabase' subclass. 133 | 134 | @return The Class of 'FMDatabase' subclass, that will be used to instantiate database object. 135 | */ 136 | 137 | + (Class)databaseClass; 138 | 139 | /** Close database used by queue. */ 140 | 141 | - (void)close; 142 | 143 | ///----------------------------------------------- 144 | /// @name Dispatching database operations to queue 145 | ///----------------------------------------------- 146 | 147 | /** Synchronously perform database operations on queue. 148 | 149 | @param block The code to be run on the queue of `FMDatabaseQueue` 150 | */ 151 | 152 | - (void)inDatabase:(void (^)(FMDatabase *db))block; 153 | 154 | /** Synchronously perform database operations on queue, using transactions. 155 | 156 | @param block The code to be run on the queue of `FMDatabaseQueue` 157 | */ 158 | 159 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 160 | 161 | /** Synchronously perform database operations on queue, using deferred transactions. 162 | 163 | @param block The code to be run on the queue of `FMDatabaseQueue` 164 | */ 165 | 166 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block; 167 | 168 | ///----------------------------------------------- 169 | /// @name Dispatching database operations to queue 170 | ///----------------------------------------------- 171 | 172 | /** Synchronously perform database operations using save point. 173 | 174 | @param block The code to be run on the queue of `FMDatabaseQueue` 175 | */ 176 | 177 | // NOTE: you can not nest these, since calling it will pull another database out of the pool and you'll get a deadlock. 178 | // If you need to nest, use FMDatabase's startSavePointWithName:error: instead. 179 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block; 180 | 181 | @end 182 | 183 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMDatabaseQueue.m: -------------------------------------------------------------------------------- 1 | // 2 | // FMDatabaseQueue.m 3 | // fmdb 4 | // 5 | // Created by August Mueller on 6/22/11. 6 | // Copyright 2011 Flying Meat Inc. All rights reserved. 7 | // 8 | 9 | #import "FMDatabaseQueue.h" 10 | #import "FMDatabase.h" 11 | 12 | #if FMDB_SQLITE_STANDALONE 13 | #import 14 | #else 15 | #import 16 | #endif 17 | 18 | /* 19 | 20 | Note: we call [self retain]; before using dispatch_sync, just incase 21 | FMDatabaseQueue is released on another thread and we're in the middle of doing 22 | something in dispatch_sync 23 | 24 | */ 25 | 26 | /* 27 | * A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses. 28 | * This in turn is used for deadlock detection by seeing if inDatabase: is called on 29 | * the queue's dispatch queue, which should not happen and causes a deadlock. 30 | */ 31 | static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey; 32 | 33 | @implementation FMDatabaseQueue 34 | 35 | @synthesize path = _path; 36 | @synthesize openFlags = _openFlags; 37 | 38 | + (instancetype)databaseQueueWithPath:(NSString*)aPath { 39 | 40 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath]; 41 | 42 | FMDBAutorelease(q); 43 | 44 | return q; 45 | } 46 | 47 | + (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags { 48 | 49 | FMDatabaseQueue *q = [[self alloc] initWithPath:aPath flags:openFlags]; 50 | 51 | FMDBAutorelease(q); 52 | 53 | return q; 54 | } 55 | 56 | + (Class)databaseClass { 57 | return [FMDatabase class]; 58 | } 59 | 60 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName { 61 | 62 | self = [super init]; 63 | 64 | if (self != nil) { 65 | 66 | _db = [[[self class] databaseClass] databaseWithPath:aPath]; 67 | FMDBRetain(_db); 68 | 69 | #if SQLITE_VERSION_NUMBER >= 3005000 70 | BOOL success = [_db openWithFlags:openFlags vfs:vfsName]; 71 | #else 72 | BOOL success = [_db open]; 73 | #endif 74 | if (!success) { 75 | NSLog(@"Could not create database queue for path %@", aPath); 76 | FMDBRelease(self); 77 | return 0x00; 78 | } 79 | 80 | _path = FMDBReturnRetained(aPath); 81 | _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL); 82 | dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL); 83 | _openFlags = openFlags; 84 | } 85 | 86 | return self; 87 | } 88 | 89 | - (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags { 90 | return [self initWithPath:aPath flags:openFlags vfs:nil]; 91 | } 92 | 93 | - (instancetype)initWithPath:(NSString*)aPath { 94 | 95 | // default flags for sqlite3_open 96 | return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE vfs:nil]; 97 | } 98 | 99 | - (instancetype)init { 100 | return [self initWithPath:nil]; 101 | } 102 | 103 | 104 | - (void)dealloc { 105 | 106 | FMDBRelease(_db); 107 | FMDBRelease(_path); 108 | 109 | if (_queue) { 110 | FMDBDispatchQueueRelease(_queue); 111 | _queue = 0x00; 112 | } 113 | #if ! __has_feature(objc_arc) 114 | [super dealloc]; 115 | #endif 116 | } 117 | 118 | - (void)close { 119 | FMDBRetain(self); 120 | dispatch_sync(_queue, ^() { 121 | [self->_db close]; 122 | FMDBRelease(_db); 123 | self->_db = 0x00; 124 | }); 125 | FMDBRelease(self); 126 | } 127 | 128 | - (FMDatabase*)database { 129 | if (!_db) { 130 | _db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]); 131 | 132 | #if SQLITE_VERSION_NUMBER >= 3005000 133 | BOOL success = [_db openWithFlags:_openFlags]; 134 | #else 135 | BOOL success = [_db open]; 136 | #endif 137 | if (!success) { 138 | NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path); 139 | FMDBRelease(_db); 140 | _db = 0x00; 141 | return 0x00; 142 | } 143 | } 144 | 145 | return _db; 146 | } 147 | 148 | - (void)inDatabase:(void (^)(FMDatabase *db))block { 149 | /* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue 150 | * and then check it against self to make sure we're not about to deadlock. */ 151 | FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey); 152 | assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock"); 153 | 154 | FMDBRetain(self); 155 | 156 | dispatch_sync(_queue, ^() { 157 | 158 | FMDatabase *db = [self database]; 159 | block(db); 160 | 161 | if ([db hasOpenResultSets]) { 162 | NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]"); 163 | 164 | #if defined(DEBUG) && DEBUG 165 | NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]); 166 | for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) { 167 | FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue]; 168 | NSLog(@"query: '%@'", [rs query]); 169 | } 170 | #endif 171 | } 172 | }); 173 | 174 | FMDBRelease(self); 175 | } 176 | 177 | 178 | - (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block { 179 | FMDBRetain(self); 180 | dispatch_sync(_queue, ^() { 181 | 182 | BOOL shouldRollback = NO; 183 | 184 | if (useDeferred) { 185 | [[self database] beginDeferredTransaction]; 186 | } 187 | else { 188 | [[self database] beginTransaction]; 189 | } 190 | 191 | block([self database], &shouldRollback); 192 | 193 | if (shouldRollback) { 194 | [[self database] rollback]; 195 | } 196 | else { 197 | [[self database] commit]; 198 | } 199 | }); 200 | 201 | FMDBRelease(self); 202 | } 203 | 204 | - (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 205 | [self beginTransaction:YES withBlock:block]; 206 | } 207 | 208 | - (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block { 209 | [self beginTransaction:NO withBlock:block]; 210 | } 211 | 212 | - (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block { 213 | #if SQLITE_VERSION_NUMBER >= 3007000 214 | static unsigned long savePointIdx = 0; 215 | __block NSError *err = 0x00; 216 | FMDBRetain(self); 217 | dispatch_sync(_queue, ^() { 218 | 219 | NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++]; 220 | 221 | BOOL shouldRollback = NO; 222 | 223 | if ([[self database] startSavePointWithName:name error:&err]) { 224 | 225 | block([self database], &shouldRollback); 226 | 227 | if (shouldRollback) { 228 | // We need to rollback and release this savepoint to remove it 229 | [[self database] rollbackToSavePointWithName:name error:&err]; 230 | } 231 | [[self database] releaseSavePointWithName:name error:&err]; 232 | 233 | } 234 | }); 235 | FMDBRelease(self); 236 | return err; 237 | #else 238 | NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil); 239 | if (self.logsErrors) NSLog(@"%@", errorMessage); 240 | return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}]; 241 | #endif 242 | } 243 | 244 | @end 245 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMResultSet.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #ifndef __has_feature // Optional. 4 | #define __has_feature(x) 0 // Compatibility with non-clang compilers. 5 | #endif 6 | 7 | #ifndef NS_RETURNS_NOT_RETAINED 8 | #if __has_feature(attribute_ns_returns_not_retained) 9 | #define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained)) 10 | #else 11 | #define NS_RETURNS_NOT_RETAINED 12 | #endif 13 | #endif 14 | 15 | @class FMDatabase; 16 | @class FMStatement; 17 | 18 | /** Represents the results of executing a query on an ``. 19 | 20 | ### See also 21 | 22 | - `` 23 | */ 24 | 25 | @interface FMResultSet : NSObject { 26 | FMDatabase *_parentDB; 27 | FMStatement *_statement; 28 | 29 | NSString *_query; 30 | NSMutableDictionary *_columnNameToIndexMap; 31 | } 32 | 33 | ///----------------- 34 | /// @name Properties 35 | ///----------------- 36 | 37 | /** Executed query */ 38 | 39 | @property (atomic, retain) NSString *query; 40 | 41 | /** `NSMutableDictionary` mapping column names to numeric index */ 42 | 43 | @property (readonly) NSMutableDictionary *columnNameToIndexMap; 44 | 45 | /** `FMStatement` used by result set. */ 46 | 47 | @property (atomic, retain) FMStatement *statement; 48 | 49 | ///------------------------------------ 50 | /// @name Creating and closing database 51 | ///------------------------------------ 52 | 53 | /** Create result set from `` 54 | 55 | @param statement A `` to be performed 56 | 57 | @param aDB A `` to be used 58 | 59 | @return A `FMResultSet` on success; `nil` on failure 60 | */ 61 | 62 | + (instancetype)resultSetWithStatement:(FMStatement *)statement usingParentDatabase:(FMDatabase*)aDB; 63 | 64 | /** Close result set */ 65 | 66 | - (void)close; 67 | 68 | - (void)setParentDB:(FMDatabase *)newDb; 69 | 70 | ///--------------------------------------- 71 | /// @name Iterating through the result set 72 | ///--------------------------------------- 73 | 74 | /** Retrieve next row for result set. 75 | 76 | You must always invoke `next` or `nextWithError` before attempting to access the values returned in a query, even if you're only expecting one. 77 | 78 | @return `YES` if row successfully retrieved; `NO` if end of result set reached 79 | 80 | @see hasAnotherRow 81 | */ 82 | 83 | - (BOOL)next; 84 | 85 | /** Retrieve next row for result set. 86 | 87 | You must always invoke `next` or `nextWithError` before attempting to access the values returned in a query, even if you're only expecting one. 88 | 89 | @param outErr A 'NSError' object to receive any error object (if any). 90 | 91 | @return 'YES' if row successfully retrieved; 'NO' if end of result set reached 92 | 93 | @see hasAnotherRow 94 | */ 95 | 96 | - (BOOL)nextWithError:(NSError **)outErr; 97 | 98 | /** Did the last call to `` succeed in retrieving another row? 99 | 100 | @return `YES` if the last call to `` succeeded in retrieving another record; `NO` if not. 101 | 102 | @see next 103 | 104 | @warning The `hasAnotherRow` method must follow a call to ``. If the previous database interaction was something other than a call to `next`, then this method may return `NO`, whether there is another row of data or not. 105 | */ 106 | 107 | - (BOOL)hasAnotherRow; 108 | 109 | ///--------------------------------------------- 110 | /// @name Retrieving information from result set 111 | ///--------------------------------------------- 112 | 113 | /** How many columns in result set 114 | 115 | @return Integer value of the number of columns. 116 | */ 117 | 118 | - (int)columnCount; 119 | 120 | /** Column index for column name 121 | 122 | @param columnName `NSString` value of the name of the column. 123 | 124 | @return Zero-based index for column. 125 | */ 126 | 127 | - (int)columnIndexForName:(NSString*)columnName; 128 | 129 | /** Column name for column index 130 | 131 | @param columnIdx Zero-based index for column. 132 | 133 | @return columnName `NSString` value of the name of the column. 134 | */ 135 | 136 | - (NSString*)columnNameForIndex:(int)columnIdx; 137 | 138 | /** Result set integer value for column. 139 | 140 | @param columnName `NSString` value of the name of the column. 141 | 142 | @return `int` value of the result set's column. 143 | */ 144 | 145 | - (int)intForColumn:(NSString*)columnName; 146 | 147 | /** Result set integer value for column. 148 | 149 | @param columnIdx Zero-based index for column. 150 | 151 | @return `int` value of the result set's column. 152 | */ 153 | 154 | - (int)intForColumnIndex:(int)columnIdx; 155 | 156 | /** Result set `long` value for column. 157 | 158 | @param columnName `NSString` value of the name of the column. 159 | 160 | @return `long` value of the result set's column. 161 | */ 162 | 163 | - (long)longForColumn:(NSString*)columnName; 164 | 165 | /** Result set long value for column. 166 | 167 | @param columnIdx Zero-based index for column. 168 | 169 | @return `long` value of the result set's column. 170 | */ 171 | 172 | - (long)longForColumnIndex:(int)columnIdx; 173 | 174 | /** Result set `long long int` value for column. 175 | 176 | @param columnName `NSString` value of the name of the column. 177 | 178 | @return `long long int` value of the result set's column. 179 | */ 180 | 181 | - (long long int)longLongIntForColumn:(NSString*)columnName; 182 | 183 | /** Result set `long long int` value for column. 184 | 185 | @param columnIdx Zero-based index for column. 186 | 187 | @return `long long int` value of the result set's column. 188 | */ 189 | 190 | - (long long int)longLongIntForColumnIndex:(int)columnIdx; 191 | 192 | /** Result set `unsigned long long int` value for column. 193 | 194 | @param columnName `NSString` value of the name of the column. 195 | 196 | @return `unsigned long long int` value of the result set's column. 197 | */ 198 | 199 | - (unsigned long long int)unsignedLongLongIntForColumn:(NSString*)columnName; 200 | 201 | /** Result set `unsigned long long int` value for column. 202 | 203 | @param columnIdx Zero-based index for column. 204 | 205 | @return `unsigned long long int` value of the result set's column. 206 | */ 207 | 208 | - (unsigned long long int)unsignedLongLongIntForColumnIndex:(int)columnIdx; 209 | 210 | /** Result set `BOOL` value for column. 211 | 212 | @param columnName `NSString` value of the name of the column. 213 | 214 | @return `BOOL` value of the result set's column. 215 | */ 216 | 217 | - (BOOL)boolForColumn:(NSString*)columnName; 218 | 219 | /** Result set `BOOL` value for column. 220 | 221 | @param columnIdx Zero-based index for column. 222 | 223 | @return `BOOL` value of the result set's column. 224 | */ 225 | 226 | - (BOOL)boolForColumnIndex:(int)columnIdx; 227 | 228 | /** Result set `double` value for column. 229 | 230 | @param columnName `NSString` value of the name of the column. 231 | 232 | @return `double` value of the result set's column. 233 | 234 | */ 235 | 236 | - (double)doubleForColumn:(NSString*)columnName; 237 | 238 | /** Result set `double` value for column. 239 | 240 | @param columnIdx Zero-based index for column. 241 | 242 | @return `double` value of the result set's column. 243 | 244 | */ 245 | 246 | - (double)doubleForColumnIndex:(int)columnIdx; 247 | 248 | /** Result set `NSString` value for column. 249 | 250 | @param columnName `NSString` value of the name of the column. 251 | 252 | @return `NSString` value of the result set's column. 253 | 254 | */ 255 | 256 | - (NSString*)stringForColumn:(NSString*)columnName; 257 | 258 | /** Result set `NSString` value for column. 259 | 260 | @param columnIdx Zero-based index for column. 261 | 262 | @return `NSString` value of the result set's column. 263 | */ 264 | 265 | - (NSString*)stringForColumnIndex:(int)columnIdx; 266 | 267 | /** Result set `NSDate` value for column. 268 | 269 | @param columnName `NSString` value of the name of the column. 270 | 271 | @return `NSDate` value of the result set's column. 272 | */ 273 | 274 | - (NSDate*)dateForColumn:(NSString*)columnName; 275 | 276 | /** Result set `NSDate` value for column. 277 | 278 | @param columnIdx Zero-based index for column. 279 | 280 | @return `NSDate` value of the result set's column. 281 | 282 | */ 283 | 284 | - (NSDate*)dateForColumnIndex:(int)columnIdx; 285 | 286 | /** Result set `NSData` value for column. 287 | 288 | This is useful when storing binary data in table (such as image or the like). 289 | 290 | @param columnName `NSString` value of the name of the column. 291 | 292 | @return `NSData` value of the result set's column. 293 | 294 | */ 295 | 296 | - (NSData*)dataForColumn:(NSString*)columnName; 297 | 298 | /** Result set `NSData` value for column. 299 | 300 | @param columnIdx Zero-based index for column. 301 | 302 | @return `NSData` value of the result set's column. 303 | */ 304 | 305 | - (NSData*)dataForColumnIndex:(int)columnIdx; 306 | 307 | /** Result set `(const unsigned char *)` value for column. 308 | 309 | @param columnName `NSString` value of the name of the column. 310 | 311 | @return `(const unsigned char *)` value of the result set's column. 312 | */ 313 | 314 | - (const unsigned char *)UTF8StringForColumnName:(NSString*)columnName; 315 | 316 | /** Result set `(const unsigned char *)` value for column. 317 | 318 | @param columnIdx Zero-based index for column. 319 | 320 | @return `(const unsigned char *)` value of the result set's column. 321 | */ 322 | 323 | - (const unsigned char *)UTF8StringForColumnIndex:(int)columnIdx; 324 | 325 | /** Result set object for column. 326 | 327 | @param columnName `NSString` value of the name of the column. 328 | 329 | @return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object. 330 | 331 | @see objectForKeyedSubscript: 332 | */ 333 | 334 | - (id)objectForColumnName:(NSString*)columnName; 335 | 336 | /** Result set object for column. 337 | 338 | @param columnIdx Zero-based index for column. 339 | 340 | @return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object. 341 | 342 | @see objectAtIndexedSubscript: 343 | */ 344 | 345 | - (id)objectForColumnIndex:(int)columnIdx; 346 | 347 | /** Result set object for column. 348 | 349 | This method allows the use of the "boxed" syntax supported in Modern Objective-C. For example, by defining this method, the following syntax is now supported: 350 | 351 | id result = rs[@"employee_name"]; 352 | 353 | This simplified syntax is equivalent to calling: 354 | 355 | id result = [rs objectForKeyedSubscript:@"employee_name"]; 356 | 357 | which is, it turns out, equivalent to calling: 358 | 359 | id result = [rs objectForColumnName:@"employee_name"]; 360 | 361 | @param columnName `NSString` value of the name of the column. 362 | 363 | @return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object. 364 | */ 365 | 366 | - (id)objectForKeyedSubscript:(NSString *)columnName; 367 | 368 | /** Result set object for column. 369 | 370 | This method allows the use of the "boxed" syntax supported in Modern Objective-C. For example, by defining this method, the following syntax is now supported: 371 | 372 | id result = rs[0]; 373 | 374 | This simplified syntax is equivalent to calling: 375 | 376 | id result = [rs objectForKeyedSubscript:0]; 377 | 378 | which is, it turns out, equivalent to calling: 379 | 380 | id result = [rs objectForColumnName:0]; 381 | 382 | @param columnIdx Zero-based index for column. 383 | 384 | @return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object. 385 | */ 386 | 387 | - (id)objectAtIndexedSubscript:(int)columnIdx; 388 | 389 | /** Result set `NSData` value for column. 390 | 391 | @param columnName `NSString` value of the name of the column. 392 | 393 | @return `NSData` value of the result set's column. 394 | 395 | @warning If you are going to use this data after you iterate over the next row, or after you close the 396 | result set, make sure to make a copy of the data first (or just use ``/``) 397 | If you don't, you're going to be in a world of hurt when you try and use the data. 398 | 399 | */ 400 | 401 | - (NSData*)dataNoCopyForColumn:(NSString*)columnName NS_RETURNS_NOT_RETAINED; 402 | 403 | /** Result set `NSData` value for column. 404 | 405 | @param columnIdx Zero-based index for column. 406 | 407 | @return `NSData` value of the result set's column. 408 | 409 | @warning If you are going to use this data after you iterate over the next row, or after you close the 410 | result set, make sure to make a copy of the data first (or just use ``/``) 411 | If you don't, you're going to be in a world of hurt when you try and use the data. 412 | 413 | */ 414 | 415 | - (NSData*)dataNoCopyForColumnIndex:(int)columnIdx NS_RETURNS_NOT_RETAINED; 416 | 417 | /** Is the column `NULL`? 418 | 419 | @param columnIdx Zero-based index for column. 420 | 421 | @return `YES` if column is `NULL`; `NO` if not `NULL`. 422 | */ 423 | 424 | - (BOOL)columnIndexIsNull:(int)columnIdx; 425 | 426 | /** Is the column `NULL`? 427 | 428 | @param columnName `NSString` value of the name of the column. 429 | 430 | @return `YES` if column is `NULL`; `NO` if not `NULL`. 431 | */ 432 | 433 | - (BOOL)columnIsNull:(NSString*)columnName; 434 | 435 | 436 | /** Returns a dictionary of the row results mapped to case sensitive keys of the column names. 437 | 438 | @returns `NSDictionary` of the row results. 439 | 440 | @warning The keys to the dictionary are case sensitive of the column names. 441 | */ 442 | 443 | - (NSDictionary*)resultDictionary; 444 | 445 | /** Returns a dictionary of the row results 446 | 447 | @see resultDictionary 448 | 449 | @warning **Deprecated**: Please use `` instead. Also, beware that `` is case sensitive! 450 | */ 451 | 452 | - (NSDictionary*)resultDict __attribute__ ((deprecated)); 453 | 454 | ///----------------------------- 455 | /// @name Key value coding magic 456 | ///----------------------------- 457 | 458 | /** Performs `setValue` to yield support for key value observing. 459 | 460 | @param object The object for which the values will be set. This is the key-value-coding compliant object that you might, for example, observe. 461 | 462 | */ 463 | 464 | - (void)kvcMagic:(id)object; 465 | 466 | 467 | @end 468 | 469 | -------------------------------------------------------------------------------- /Pods/FMDB/src/fmdb/FMResultSet.m: -------------------------------------------------------------------------------- 1 | #import "FMResultSet.h" 2 | #import "FMDatabase.h" 3 | #import "unistd.h" 4 | 5 | #if FMDB_SQLITE_STANDALONE 6 | #import 7 | #else 8 | #import 9 | #endif 10 | 11 | @interface FMDatabase () 12 | - (void)resultSetDidClose:(FMResultSet *)resultSet; 13 | @end 14 | 15 | 16 | @implementation FMResultSet 17 | @synthesize query=_query; 18 | @synthesize statement=_statement; 19 | 20 | + (instancetype)resultSetWithStatement:(FMStatement *)statement usingParentDatabase:(FMDatabase*)aDB { 21 | 22 | FMResultSet *rs = [[FMResultSet alloc] init]; 23 | 24 | [rs setStatement:statement]; 25 | [rs setParentDB:aDB]; 26 | 27 | NSParameterAssert(![statement inUse]); 28 | [statement setInUse:YES]; // weak reference 29 | 30 | return FMDBReturnAutoreleased(rs); 31 | } 32 | 33 | - (void)finalize { 34 | [self close]; 35 | [super finalize]; 36 | } 37 | 38 | - (void)dealloc { 39 | [self close]; 40 | 41 | FMDBRelease(_query); 42 | _query = nil; 43 | 44 | FMDBRelease(_columnNameToIndexMap); 45 | _columnNameToIndexMap = nil; 46 | 47 | #if ! __has_feature(objc_arc) 48 | [super dealloc]; 49 | #endif 50 | } 51 | 52 | - (void)close { 53 | [_statement reset]; 54 | FMDBRelease(_statement); 55 | _statement = nil; 56 | 57 | // we don't need this anymore... (i think) 58 | //[_parentDB setInUse:NO]; 59 | [_parentDB resultSetDidClose:self]; 60 | _parentDB = nil; 61 | } 62 | 63 | - (int)columnCount { 64 | return sqlite3_column_count([_statement statement]); 65 | } 66 | 67 | - (NSMutableDictionary *)columnNameToIndexMap { 68 | if (!_columnNameToIndexMap) { 69 | int columnCount = sqlite3_column_count([_statement statement]); 70 | _columnNameToIndexMap = [[NSMutableDictionary alloc] initWithCapacity:(NSUInteger)columnCount]; 71 | int columnIdx = 0; 72 | for (columnIdx = 0; columnIdx < columnCount; columnIdx++) { 73 | [_columnNameToIndexMap setObject:[NSNumber numberWithInt:columnIdx] 74 | forKey:[[NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)] lowercaseString]]; 75 | } 76 | } 77 | return _columnNameToIndexMap; 78 | } 79 | 80 | - (void)kvcMagic:(id)object { 81 | 82 | int columnCount = sqlite3_column_count([_statement statement]); 83 | 84 | int columnIdx = 0; 85 | for (columnIdx = 0; columnIdx < columnCount; columnIdx++) { 86 | 87 | const char *c = (const char *)sqlite3_column_text([_statement statement], columnIdx); 88 | 89 | // check for a null row 90 | if (c) { 91 | NSString *s = [NSString stringWithUTF8String:c]; 92 | 93 | [object setValue:s forKey:[NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)]]; 94 | } 95 | } 96 | } 97 | 98 | #pragma clang diagnostic push 99 | #pragma clang diagnostic ignored "-Wdeprecated-implementations" 100 | 101 | - (NSDictionary*)resultDict { 102 | 103 | NSUInteger num_cols = (NSUInteger)sqlite3_data_count([_statement statement]); 104 | 105 | if (num_cols > 0) { 106 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols]; 107 | 108 | NSEnumerator *columnNames = [[self columnNameToIndexMap] keyEnumerator]; 109 | NSString *columnName = nil; 110 | while ((columnName = [columnNames nextObject])) { 111 | id objectValue = [self objectForColumnName:columnName]; 112 | [dict setObject:objectValue forKey:columnName]; 113 | } 114 | 115 | return FMDBReturnAutoreleased([dict copy]); 116 | } 117 | else { 118 | NSLog(@"Warning: There seem to be no columns in this set."); 119 | } 120 | 121 | return nil; 122 | } 123 | 124 | #pragma clang diagnostic pop 125 | 126 | - (NSDictionary*)resultDictionary { 127 | 128 | NSUInteger num_cols = (NSUInteger)sqlite3_data_count([_statement statement]); 129 | 130 | if (num_cols > 0) { 131 | NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols]; 132 | 133 | int columnCount = sqlite3_column_count([_statement statement]); 134 | 135 | int columnIdx = 0; 136 | for (columnIdx = 0; columnIdx < columnCount; columnIdx++) { 137 | 138 | NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)]; 139 | id objectValue = [self objectForColumnIndex:columnIdx]; 140 | [dict setObject:objectValue forKey:columnName]; 141 | } 142 | 143 | return dict; 144 | } 145 | else { 146 | NSLog(@"Warning: There seem to be no columns in this set."); 147 | } 148 | 149 | return nil; 150 | } 151 | 152 | 153 | 154 | 155 | - (BOOL)next { 156 | return [self nextWithError:nil]; 157 | } 158 | 159 | - (BOOL)nextWithError:(NSError **)outErr { 160 | 161 | int rc = sqlite3_step([_statement statement]); 162 | 163 | if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { 164 | NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [_parentDB databasePath]); 165 | NSLog(@"Database busy"); 166 | if (outErr) { 167 | *outErr = [_parentDB lastError]; 168 | } 169 | } 170 | else if (SQLITE_DONE == rc || SQLITE_ROW == rc) { 171 | // all is well, let's return. 172 | } 173 | else if (SQLITE_ERROR == rc) { 174 | NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle])); 175 | if (outErr) { 176 | *outErr = [_parentDB lastError]; 177 | } 178 | } 179 | else if (SQLITE_MISUSE == rc) { 180 | // uh oh. 181 | NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle])); 182 | if (outErr) { 183 | if (_parentDB) { 184 | *outErr = [_parentDB lastError]; 185 | } 186 | else { 187 | // If 'next' or 'nextWithError' is called after the result set is closed, 188 | // we need to return the appropriate error. 189 | NSDictionary* errorMessage = [NSDictionary dictionaryWithObject:@"parentDB does not exist" forKey:NSLocalizedDescriptionKey]; 190 | *outErr = [NSError errorWithDomain:@"FMDatabase" code:SQLITE_MISUSE userInfo:errorMessage]; 191 | } 192 | 193 | } 194 | } 195 | else { 196 | // wtf? 197 | NSLog(@"Unknown error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle])); 198 | if (outErr) { 199 | *outErr = [_parentDB lastError]; 200 | } 201 | } 202 | 203 | 204 | if (rc != SQLITE_ROW) { 205 | [self close]; 206 | } 207 | 208 | return (rc == SQLITE_ROW); 209 | } 210 | 211 | - (BOOL)hasAnotherRow { 212 | return sqlite3_errcode([_parentDB sqliteHandle]) == SQLITE_ROW; 213 | } 214 | 215 | - (int)columnIndexForName:(NSString*)columnName { 216 | columnName = [columnName lowercaseString]; 217 | 218 | NSNumber *n = [[self columnNameToIndexMap] objectForKey:columnName]; 219 | 220 | if (n) { 221 | return [n intValue]; 222 | } 223 | 224 | NSLog(@"Warning: I could not find the column named '%@'.", columnName); 225 | 226 | return -1; 227 | } 228 | 229 | 230 | 231 | - (int)intForColumn:(NSString*)columnName { 232 | return [self intForColumnIndex:[self columnIndexForName:columnName]]; 233 | } 234 | 235 | - (int)intForColumnIndex:(int)columnIdx { 236 | return sqlite3_column_int([_statement statement], columnIdx); 237 | } 238 | 239 | - (long)longForColumn:(NSString*)columnName { 240 | return [self longForColumnIndex:[self columnIndexForName:columnName]]; 241 | } 242 | 243 | - (long)longForColumnIndex:(int)columnIdx { 244 | return (long)sqlite3_column_int64([_statement statement], columnIdx); 245 | } 246 | 247 | - (long long int)longLongIntForColumn:(NSString*)columnName { 248 | return [self longLongIntForColumnIndex:[self columnIndexForName:columnName]]; 249 | } 250 | 251 | - (long long int)longLongIntForColumnIndex:(int)columnIdx { 252 | return sqlite3_column_int64([_statement statement], columnIdx); 253 | } 254 | 255 | - (unsigned long long int)unsignedLongLongIntForColumn:(NSString*)columnName { 256 | return [self unsignedLongLongIntForColumnIndex:[self columnIndexForName:columnName]]; 257 | } 258 | 259 | - (unsigned long long int)unsignedLongLongIntForColumnIndex:(int)columnIdx { 260 | return (unsigned long long int)[self longLongIntForColumnIndex:columnIdx]; 261 | } 262 | 263 | - (BOOL)boolForColumn:(NSString*)columnName { 264 | return [self boolForColumnIndex:[self columnIndexForName:columnName]]; 265 | } 266 | 267 | - (BOOL)boolForColumnIndex:(int)columnIdx { 268 | return ([self intForColumnIndex:columnIdx] != 0); 269 | } 270 | 271 | - (double)doubleForColumn:(NSString*)columnName { 272 | return [self doubleForColumnIndex:[self columnIndexForName:columnName]]; 273 | } 274 | 275 | - (double)doubleForColumnIndex:(int)columnIdx { 276 | return sqlite3_column_double([_statement statement], columnIdx); 277 | } 278 | 279 | - (NSString*)stringForColumnIndex:(int)columnIdx { 280 | 281 | if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) { 282 | return nil; 283 | } 284 | 285 | const char *c = (const char *)sqlite3_column_text([_statement statement], columnIdx); 286 | 287 | if (!c) { 288 | // null row. 289 | return nil; 290 | } 291 | 292 | return [NSString stringWithUTF8String:c]; 293 | } 294 | 295 | - (NSString*)stringForColumn:(NSString*)columnName { 296 | return [self stringForColumnIndex:[self columnIndexForName:columnName]]; 297 | } 298 | 299 | - (NSDate*)dateForColumn:(NSString*)columnName { 300 | return [self dateForColumnIndex:[self columnIndexForName:columnName]]; 301 | } 302 | 303 | - (NSDate*)dateForColumnIndex:(int)columnIdx { 304 | 305 | if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) { 306 | return nil; 307 | } 308 | 309 | return [_parentDB hasDateFormatter] ? [_parentDB dateFromString:[self stringForColumnIndex:columnIdx]] : [NSDate dateWithTimeIntervalSince1970:[self doubleForColumnIndex:columnIdx]]; 310 | } 311 | 312 | 313 | - (NSData*)dataForColumn:(NSString*)columnName { 314 | return [self dataForColumnIndex:[self columnIndexForName:columnName]]; 315 | } 316 | 317 | - (NSData*)dataForColumnIndex:(int)columnIdx { 318 | 319 | if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) { 320 | return nil; 321 | } 322 | 323 | const char *dataBuffer = sqlite3_column_blob([_statement statement], columnIdx); 324 | int dataSize = sqlite3_column_bytes([_statement statement], columnIdx); 325 | 326 | if (dataBuffer == NULL) { 327 | return nil; 328 | } 329 | 330 | return [NSData dataWithBytes:(const void *)dataBuffer length:(NSUInteger)dataSize]; 331 | } 332 | 333 | 334 | - (NSData*)dataNoCopyForColumn:(NSString*)columnName { 335 | return [self dataNoCopyForColumnIndex:[self columnIndexForName:columnName]]; 336 | } 337 | 338 | - (NSData*)dataNoCopyForColumnIndex:(int)columnIdx { 339 | 340 | if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) { 341 | return nil; 342 | } 343 | 344 | const char *dataBuffer = sqlite3_column_blob([_statement statement], columnIdx); 345 | int dataSize = sqlite3_column_bytes([_statement statement], columnIdx); 346 | 347 | NSData *data = [NSData dataWithBytesNoCopy:(void *)dataBuffer length:(NSUInteger)dataSize freeWhenDone:NO]; 348 | 349 | return data; 350 | } 351 | 352 | 353 | - (BOOL)columnIndexIsNull:(int)columnIdx { 354 | return sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL; 355 | } 356 | 357 | - (BOOL)columnIsNull:(NSString*)columnName { 358 | return [self columnIndexIsNull:[self columnIndexForName:columnName]]; 359 | } 360 | 361 | - (const unsigned char *)UTF8StringForColumnIndex:(int)columnIdx { 362 | 363 | if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) { 364 | return nil; 365 | } 366 | 367 | return sqlite3_column_text([_statement statement], columnIdx); 368 | } 369 | 370 | - (const unsigned char *)UTF8StringForColumnName:(NSString*)columnName { 371 | return [self UTF8StringForColumnIndex:[self columnIndexForName:columnName]]; 372 | } 373 | 374 | - (id)objectForColumnIndex:(int)columnIdx { 375 | int columnType = sqlite3_column_type([_statement statement], columnIdx); 376 | 377 | id returnValue = nil; 378 | 379 | if (columnType == SQLITE_INTEGER) { 380 | returnValue = [NSNumber numberWithLongLong:[self longLongIntForColumnIndex:columnIdx]]; 381 | } 382 | else if (columnType == SQLITE_FLOAT) { 383 | returnValue = [NSNumber numberWithDouble:[self doubleForColumnIndex:columnIdx]]; 384 | } 385 | else if (columnType == SQLITE_BLOB) { 386 | returnValue = [self dataForColumnIndex:columnIdx]; 387 | } 388 | else { 389 | //default to a string for everything else 390 | returnValue = [self stringForColumnIndex:columnIdx]; 391 | } 392 | 393 | if (returnValue == nil) { 394 | returnValue = [NSNull null]; 395 | } 396 | 397 | return returnValue; 398 | } 399 | 400 | - (id)objectForColumnName:(NSString*)columnName { 401 | return [self objectForColumnIndex:[self columnIndexForName:columnName]]; 402 | } 403 | 404 | // returns autoreleased NSString containing the name of the column in the result set 405 | - (NSString*)columnNameForIndex:(int)columnIdx { 406 | return [NSString stringWithUTF8String: sqlite3_column_name([_statement statement], columnIdx)]; 407 | } 408 | 409 | - (void)setParentDB:(FMDatabase *)newDb { 410 | _parentDB = newDb; 411 | } 412 | 413 | - (id)objectAtIndexedSubscript:(int)columnIdx { 414 | return [self objectForColumnIndex:columnIdx]; 415 | } 416 | 417 | - (id)objectForKeyedSubscript:(NSString *)columnName { 418 | return [self objectForColumnName:columnName]; 419 | } 420 | 421 | 422 | @end 423 | -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMDB.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDB.h -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMDatabase.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabase.h -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseAdditions.h -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabasePool.h -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseQueue.h -------------------------------------------------------------------------------- /Pods/Headers/Private/FMDB/FMResultSet.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMResultSet.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMDB.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDB.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMDatabase.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabase.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMDatabaseAdditions.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseAdditions.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMDatabasePool.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabasePool.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMDatabaseQueue.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMDatabaseQueue.h -------------------------------------------------------------------------------- /Pods/Headers/Public/FMDB/FMResultSet.h: -------------------------------------------------------------------------------- 1 | ../../../FMDB/src/fmdb/FMResultSet.h -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FMDB (2.6.2): 3 | - FMDB/standard (= 2.6.2) 4 | - FMDB/standard (2.6.2) 5 | 6 | DEPENDENCIES: 7 | - FMDB 8 | 9 | SPEC CHECKSUMS: 10 | FMDB: 854a0341b4726e53276f2a8996f06f1b80f9259a 11 | 12 | COCOAPODS: 0.39.0 13 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | archiveVersion 6 | 1 7 | classes 8 | 9 | objectVersion 10 | 46 11 | objects 12 | 13 | 037C0CA694176A3C0915F62C9D20B3E6 14 | 15 | children 16 | 17 | B3D1D13E0C6553800746CB8FD61CF946 18 | 19 | isa 20 | PBXGroup 21 | name 22 | Targets Support Files 23 | sourceTree 24 | <group> 25 | 26 | 050B66E154969A68944942A22BD9B314 27 | 28 | buildActionMask 29 | 2147483647 30 | files 31 | 32 | DCBE5599D5184BC384DF2C2B60FAE896 33 | 174C2322239A2DF7CEA77E62C1D5E5BD 34 | 2FD535761BCF7EF1B7B77D4A765AD7C6 35 | BA078C2D90AE723D992054A66EC7EB0E 36 | 3D0F69C4CA35EB6A1F686BA88B19B4F6 37 | 8805B7571D8D9CD7841BE503BAEB8D80 38 | 39 | isa 40 | PBXSourcesBuildPhase 41 | runOnlyForDeploymentPostprocessing 42 | 0 43 | 44 | 052A17875CB827423D627183396CEB60 45 | 46 | buildSettings 47 | 48 | ALWAYS_SEARCH_USER_PATHS 49 | NO 50 | CLANG_CXX_LANGUAGE_STANDARD 51 | gnu++0x 52 | CLANG_CXX_LIBRARY 53 | libc++ 54 | CLANG_ENABLE_MODULES 55 | YES 56 | CLANG_ENABLE_OBJC_ARC 57 | YES 58 | CLANG_WARN_BOOL_CONVERSION 59 | YES 60 | CLANG_WARN_CONSTANT_CONVERSION 61 | YES 62 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 63 | YES 64 | CLANG_WARN_EMPTY_BODY 65 | YES 66 | CLANG_WARN_ENUM_CONVERSION 67 | YES 68 | CLANG_WARN_INT_CONVERSION 69 | YES 70 | CLANG_WARN_OBJC_ROOT_CLASS 71 | YES 72 | CLANG_WARN_UNREACHABLE_CODE 73 | YES 74 | CLANG_WARN__DUPLICATE_METHOD_MATCH 75 | YES 76 | COPY_PHASE_STRIP 77 | YES 78 | ENABLE_NS_ASSERTIONS 79 | NO 80 | GCC_C_LANGUAGE_STANDARD 81 | gnu99 82 | GCC_PREPROCESSOR_DEFINITIONS 83 | 84 | RELEASE=1 85 | 86 | GCC_WARN_64_TO_32_BIT_CONVERSION 87 | YES 88 | GCC_WARN_ABOUT_RETURN_TYPE 89 | YES 90 | GCC_WARN_UNDECLARED_SELECTOR 91 | YES 92 | GCC_WARN_UNINITIALIZED_AUTOS 93 | YES 94 | GCC_WARN_UNUSED_FUNCTION 95 | YES 96 | GCC_WARN_UNUSED_VARIABLE 97 | YES 98 | IPHONEOS_DEPLOYMENT_TARGET 99 | 7.0 100 | STRIP_INSTALLED_PRODUCT 101 | NO 102 | SYMROOT 103 | ${SRCROOT}/../build 104 | VALIDATE_PRODUCT 105 | YES 106 | 107 | isa 108 | XCBuildConfiguration 109 | name 110 | Release 111 | 112 | 0B3C39CF2CF1742494C17C860038E431 113 | 114 | buildActionMask 115 | 2147483647 116 | files 117 | 118 | A4524A1DF4BD3DEC5A5B5B1513654A4D 119 | 120 | isa 121 | PBXSourcesBuildPhase 122 | runOnlyForDeploymentPostprocessing 123 | 0 124 | 125 | 0F8A8E0D6FAEBF758E0B4D620335F094 126 | 127 | fileRef 128 | 1AF3AEDDA16DD8E28B59FF0788FDDC03 129 | isa 130 | PBXBuildFile 131 | settings 132 | 133 | ATTRIBUTES 134 | 135 | Public 136 | 137 | 138 | 139 | 10834806BD7B412BC24F347361FA2C8E 140 | 141 | includeInIndex 142 | 1 143 | isa 144 | PBXFileReference 145 | lastKnownFileType 146 | text.plist.xml 147 | path 148 | Pods-acknowledgements.plist 149 | sourceTree 150 | <group> 151 | 152 | 174C2322239A2DF7CEA77E62C1D5E5BD 153 | 154 | fileRef 155 | 3BCC0EED53ED8D7C1931178E0E4269B4 156 | isa 157 | PBXBuildFile 158 | settings 159 | 160 | COMPILER_FLAGS 161 | -DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks 162 | 163 | 164 | 1AF3AEDDA16DD8E28B59FF0788FDDC03 165 | 166 | includeInIndex 167 | 1 168 | isa 169 | PBXFileReference 170 | lastKnownFileType 171 | sourcecode.c.h 172 | name 173 | FMDatabasePool.h 174 | path 175 | src/fmdb/FMDatabasePool.h 176 | sourceTree 177 | <group> 178 | 179 | 1B9FA7A5421F72B261CD8F8DC49B18F2 180 | 181 | buildConfigurationList 182 | 8ACB97BD5EDEF44FCE62B074055B42CF 183 | buildPhases 184 | 185 | 0B3C39CF2CF1742494C17C860038E431 186 | 34558EC58B779C2BD9FAF81ECAF0F61D 187 | 188 | buildRules 189 | 190 | dependencies 191 | 192 | 9F76F4C5878AB30C873059B11B19AD2F 193 | 194 | isa 195 | PBXNativeTarget 196 | name 197 | Pods 198 | productName 199 | Pods 200 | productReference 201 | E0EAEEFA8AD36A2BF2DC2B73C68F5890 202 | productType 203 | com.apple.product-type.library.static 204 | 205 | 272643F56613CA0D336AE3DBF19DC404 206 | 207 | includeInIndex 208 | 1 209 | isa 210 | PBXFileReference 211 | lastKnownFileType 212 | sourcecode.c.objc 213 | path 214 | Pods-dummy.m 215 | sourceTree 216 | <group> 217 | 218 | 2D8E8EC45A3A1A1D94AE762CB5028504 219 | 220 | buildConfigurations 221 | 222 | B37F0F91F85060E28F1DAAB522DC7EC1 223 | 052A17875CB827423D627183396CEB60 224 | 225 | defaultConfigurationIsVisible 226 | 0 227 | defaultConfigurationName 228 | Release 229 | isa 230 | XCConfigurationList 231 | 232 | 2FD535761BCF7EF1B7B77D4A765AD7C6 233 | 234 | fileRef 235 | 400AFB42920EB39709666D3F1A73D6C2 236 | isa 237 | PBXBuildFile 238 | settings 239 | 240 | COMPILER_FLAGS 241 | -DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks 242 | 243 | 244 | 313531CEDA0294311D87B4F4C3F073F4 245 | 246 | fileRef 247 | 91893D40185E0EFA40FC217BE44A7C0D 248 | isa 249 | PBXBuildFile 250 | settings 251 | 252 | ATTRIBUTES 253 | 254 | Public 255 | 256 | 257 | 258 | 33F15B71183AD666DFC49D907F769ACF 259 | 260 | includeInIndex 261 | 1 262 | isa 263 | PBXFileReference 264 | lastKnownFileType 265 | sourcecode.c.h 266 | name 267 | FMDatabaseQueue.h 268 | path 269 | src/fmdb/FMDatabaseQueue.h 270 | sourceTree 271 | <group> 272 | 273 | 34558EC58B779C2BD9FAF81ECAF0F61D 274 | 275 | buildActionMask 276 | 2147483647 277 | files 278 | 279 | 36BE2FD561C6F5F18543FC3ED0E2B4CC 280 | 281 | isa 282 | PBXFrameworksBuildPhase 283 | runOnlyForDeploymentPostprocessing 284 | 0 285 | 286 | 36BE2FD561C6F5F18543FC3ED0E2B4CC 287 | 288 | fileRef 289 | 3E4E89230EF59BC255123B67864ACF77 290 | isa 291 | PBXBuildFile 292 | 293 | 37DB56D75062CC75FCB0966E1C6E8A8E 294 | 295 | includeInIndex 296 | 1 297 | isa 298 | PBXFileReference 299 | lastKnownFileType 300 | text 301 | path 302 | Pods-acknowledgements.markdown 303 | sourceTree 304 | <group> 305 | 306 | 3AC899FD215914230EB9D8B57AD910D0 307 | 308 | buildConfigurations 309 | 310 | 8E22345807C46884D17DD8C2728A6201 311 | 641F071BD177C0FD805ECAF1D202F7CB 312 | 313 | defaultConfigurationIsVisible 314 | 0 315 | defaultConfigurationName 316 | Release 317 | isa 318 | XCConfigurationList 319 | 320 | 3BCC0EED53ED8D7C1931178E0E4269B4 321 | 322 | includeInIndex 323 | 1 324 | isa 325 | PBXFileReference 326 | lastKnownFileType 327 | sourcecode.c.objc 328 | name 329 | FMDatabaseAdditions.m 330 | path 331 | src/fmdb/FMDatabaseAdditions.m 332 | sourceTree 333 | <group> 334 | 335 | 3D0F69C4CA35EB6A1F686BA88B19B4F6 336 | 337 | fileRef 338 | 6D76813CB39ACC402A9EE3DC12B4E682 339 | isa 340 | PBXBuildFile 341 | 342 | 3E4E89230EF59BC255123B67864ACF77 343 | 344 | isa 345 | PBXFileReference 346 | lastKnownFileType 347 | wrapper.framework 348 | name 349 | Foundation.framework 350 | path 351 | Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.0.sdk/System/Library/Frameworks/Foundation.framework 352 | sourceTree 353 | DEVELOPER_DIR 354 | 355 | 3FF6CC2D423559E28AE3F55AFFA4CA33 356 | 357 | explicitFileType 358 | archive.ar 359 | includeInIndex 360 | 0 361 | isa 362 | PBXFileReference 363 | name 364 | libFMDB.a 365 | path 366 | libFMDB.a 367 | sourceTree 368 | BUILT_PRODUCTS_DIR 369 | 370 | 400AFB42920EB39709666D3F1A73D6C2 371 | 372 | includeInIndex 373 | 1 374 | isa 375 | PBXFileReference 376 | lastKnownFileType 377 | sourcecode.c.objc 378 | name 379 | FMDatabasePool.m 380 | path 381 | src/fmdb/FMDatabasePool.m 382 | sourceTree 383 | <group> 384 | 385 | 4B2C40130EB9B22C5280B6EF7E9E52BA 386 | 387 | baseConfigurationReference 388 | 4E762F23EC34ED4A6FF3312D84E33A40 389 | buildSettings 390 | 391 | ENABLE_STRICT_OBJC_MSGSEND 392 | YES 393 | IPHONEOS_DEPLOYMENT_TARGET 394 | 7.0 395 | MACH_O_TYPE 396 | staticlib 397 | MTL_ENABLE_DEBUG_INFO 398 | YES 399 | OTHER_LDFLAGS 400 | 401 | OTHER_LIBTOOLFLAGS 402 | 403 | PODS_ROOT 404 | $(SRCROOT) 405 | PRODUCT_NAME 406 | $(TARGET_NAME) 407 | SDKROOT 408 | iphoneos 409 | SKIP_INSTALL 410 | YES 411 | 412 | isa 413 | XCBuildConfiguration 414 | name 415 | Debug 416 | 417 | 4E762F23EC34ED4A6FF3312D84E33A40 418 | 419 | includeInIndex 420 | 1 421 | isa 422 | PBXFileReference 423 | lastKnownFileType 424 | text.xcconfig 425 | path 426 | Pods.debug.xcconfig 427 | sourceTree 428 | <group> 429 | 430 | 587B76A3E381AF7C3EFFDF6754D39288 431 | 432 | fileRef 433 | 3E4E89230EF59BC255123B67864ACF77 434 | isa 435 | PBXBuildFile 436 | 437 | 638E465E4B27490B0FB423614C3ADD11 438 | 439 | includeInIndex 440 | 1 441 | isa 442 | PBXFileReference 443 | lastKnownFileType 444 | sourcecode.c.h 445 | name 446 | FMDatabase.h 447 | path 448 | src/fmdb/FMDatabase.h 449 | sourceTree 450 | <group> 451 | 452 | 641F071BD177C0FD805ECAF1D202F7CB 453 | 454 | baseConfigurationReference 455 | B2AC8D08AB9E95E701EC049C53414AEB 456 | buildSettings 457 | 458 | ENABLE_STRICT_OBJC_MSGSEND 459 | YES 460 | GCC_PREFIX_HEADER 461 | Target Support Files/FMDB/FMDB-prefix.pch 462 | IPHONEOS_DEPLOYMENT_TARGET 463 | 7.0 464 | MTL_ENABLE_DEBUG_INFO 465 | NO 466 | OTHER_LDFLAGS 467 | 468 | OTHER_LIBTOOLFLAGS 469 | 470 | PRIVATE_HEADERS_FOLDER_PATH 471 | 472 | PRODUCT_NAME 473 | $(TARGET_NAME) 474 | PUBLIC_HEADERS_FOLDER_PATH 475 | 476 | SDKROOT 477 | iphoneos 478 | SKIP_INSTALL 479 | YES 480 | 481 | isa 482 | XCBuildConfiguration 483 | name 484 | Release 485 | 486 | 6911BECA35E7518D864239B7E898EEF3 487 | 488 | includeInIndex 489 | 1 490 | isa 491 | PBXFileReference 492 | lastKnownFileType 493 | text.script.sh 494 | path 495 | Pods-frameworks.sh 496 | sourceTree 497 | <group> 498 | 499 | 69CC8B63F837EA7B053AB8BA07253A25 500 | 501 | includeInIndex 502 | 1 503 | isa 504 | PBXFileReference 505 | lastKnownFileType 506 | sourcecode.c.h 507 | name 508 | FMResultSet.h 509 | path 510 | src/fmdb/FMResultSet.h 511 | sourceTree 512 | <group> 513 | 514 | 6A65CEB166911CC900621A37BC272B1F 515 | 516 | children 517 | 518 | B2AC8D08AB9E95E701EC049C53414AEB 519 | 6D76813CB39ACC402A9EE3DC12B4E682 520 | A1448204AE8E2DC37C8C36438BED7AD8 521 | 522 | isa 523 | PBXGroup 524 | name 525 | Support Files 526 | path 527 | ../Target Support Files/FMDB 528 | sourceTree 529 | <group> 530 | 531 | 6D76813CB39ACC402A9EE3DC12B4E682 532 | 533 | includeInIndex 534 | 1 535 | isa 536 | PBXFileReference 537 | lastKnownFileType 538 | sourcecode.c.objc 539 | path 540 | FMDB-dummy.m 541 | sourceTree 542 | <group> 543 | 544 | 71B69D4A7150AC2F65A57B7D04F092D4 545 | 546 | includeInIndex 547 | 1 548 | isa 549 | PBXFileReference 550 | lastKnownFileType 551 | sourcecode.c.objc 552 | name 553 | FMResultSet.m 554 | path 555 | src/fmdb/FMResultSet.m 556 | sourceTree 557 | <group> 558 | 559 | 7DB346D0F39D3F0E887471402A8071AB 560 | 561 | children 562 | 563 | BA6428E9F66FD5A23C0A2E06ED26CD2F 564 | BC3CA7F9E30CC8F7E2DD044DD34432FC 565 | BFB8C92E749ED180124155E2270474D2 566 | CDF1344E9E92C8417899CE037474665F 567 | 037C0CA694176A3C0915F62C9D20B3E6 568 | 569 | isa 570 | PBXGroup 571 | sourceTree 572 | <group> 573 | 574 | 84AF63084FFE4472EFC6131BD113B13D 575 | 576 | buildActionMask 577 | 2147483647 578 | files 579 | 580 | 587B76A3E381AF7C3EFFDF6754D39288 581 | 582 | isa 583 | PBXFrameworksBuildPhase 584 | runOnlyForDeploymentPostprocessing 585 | 0 586 | 587 | 8805B7571D8D9CD7841BE503BAEB8D80 588 | 589 | fileRef 590 | 71B69D4A7150AC2F65A57B7D04F092D4 591 | isa 592 | PBXBuildFile 593 | settings 594 | 595 | COMPILER_FLAGS 596 | -DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks 597 | 598 | 599 | 8ACB97BD5EDEF44FCE62B074055B42CF 600 | 601 | buildConfigurations 602 | 603 | 4B2C40130EB9B22C5280B6EF7E9E52BA 604 | E082381D4370CFE535166B973637724E 605 | 606 | defaultConfigurationIsVisible 607 | 0 608 | defaultConfigurationName 609 | Release 610 | isa 611 | XCConfigurationList 612 | 613 | 8B2D82357BE4C2A10AB2CD4724B8E654 614 | 615 | buildActionMask 616 | 2147483647 617 | files 618 | 619 | D0D5FFE53407F16C9CD3D0ECF43ACE93 620 | B418C9BDCF8C6BAC2E3942F157BB6D4C 621 | 0F8A8E0D6FAEBF758E0B4D620335F094 622 | D0C5FF5485EAA2CDA03E9796B407697A 623 | 313531CEDA0294311D87B4F4C3F073F4 624 | F977B243321331B58666E9284634101A 625 | 626 | isa 627 | PBXHeadersBuildPhase 628 | runOnlyForDeploymentPostprocessing 629 | 0 630 | 631 | 8E22345807C46884D17DD8C2728A6201 632 | 633 | baseConfigurationReference 634 | B2AC8D08AB9E95E701EC049C53414AEB 635 | buildSettings 636 | 637 | ENABLE_STRICT_OBJC_MSGSEND 638 | YES 639 | GCC_PREFIX_HEADER 640 | Target Support Files/FMDB/FMDB-prefix.pch 641 | IPHONEOS_DEPLOYMENT_TARGET 642 | 7.0 643 | MTL_ENABLE_DEBUG_INFO 644 | YES 645 | OTHER_LDFLAGS 646 | 647 | OTHER_LIBTOOLFLAGS 648 | 649 | PRIVATE_HEADERS_FOLDER_PATH 650 | 651 | PRODUCT_NAME 652 | $(TARGET_NAME) 653 | PUBLIC_HEADERS_FOLDER_PATH 654 | 655 | SDKROOT 656 | iphoneos 657 | SKIP_INSTALL 658 | YES 659 | 660 | isa 661 | XCBuildConfiguration 662 | name 663 | Debug 664 | 665 | 91893D40185E0EFA40FC217BE44A7C0D 666 | 667 | includeInIndex 668 | 1 669 | isa 670 | PBXFileReference 671 | lastKnownFileType 672 | sourcecode.c.h 673 | name 674 | FMDB.h 675 | path 676 | src/fmdb/FMDB.h 677 | sourceTree 678 | <group> 679 | 680 | 98C98CDFB3F20F2925F6CD1F141BB14F 681 | 682 | includeInIndex 683 | 1 684 | isa 685 | PBXFileReference 686 | lastKnownFileType 687 | text.xcconfig 688 | path 689 | Pods.release.xcconfig 690 | sourceTree 691 | <group> 692 | 693 | 9F12FB4A63E20F601CFB2E64A65B57C1 694 | 695 | buildConfigurationList 696 | 3AC899FD215914230EB9D8B57AD910D0 697 | buildPhases 698 | 699 | 050B66E154969A68944942A22BD9B314 700 | 84AF63084FFE4472EFC6131BD113B13D 701 | 8B2D82357BE4C2A10AB2CD4724B8E654 702 | 703 | buildRules 704 | 705 | dependencies 706 | 707 | isa 708 | PBXNativeTarget 709 | name 710 | FMDB 711 | productName 712 | FMDB 713 | productReference 714 | 3FF6CC2D423559E28AE3F55AFFA4CA33 715 | productType 716 | com.apple.product-type.library.static 717 | 718 | 9F76F4C5878AB30C873059B11B19AD2F 719 | 720 | isa 721 | PBXTargetDependency 722 | name 723 | FMDB 724 | target 725 | 9F12FB4A63E20F601CFB2E64A65B57C1 726 | targetProxy 727 | A06AB1643FA0EA023EF72341CB59BE89 728 | 729 | A06AB1643FA0EA023EF72341CB59BE89 730 | 731 | containerPortal 732 | D41D8CD98F00B204E9800998ECF8427E 733 | isa 734 | PBXContainerItemProxy 735 | proxyType 736 | 1 737 | remoteGlobalIDString 738 | 9F12FB4A63E20F601CFB2E64A65B57C1 739 | remoteInfo 740 | FMDB 741 | 742 | A1448204AE8E2DC37C8C36438BED7AD8 743 | 744 | includeInIndex 745 | 1 746 | isa 747 | PBXFileReference 748 | lastKnownFileType 749 | sourcecode.c.h 750 | path 751 | FMDB-prefix.pch 752 | sourceTree 753 | <group> 754 | 755 | A1A36D34413696BE466E2CA0AFF194DA 756 | 757 | includeInIndex 758 | 1 759 | isa 760 | PBXFileReference 761 | lastKnownFileType 762 | text.script.sh 763 | path 764 | Pods-resources.sh 765 | sourceTree 766 | <group> 767 | 768 | A4524A1DF4BD3DEC5A5B5B1513654A4D 769 | 770 | fileRef 771 | 272643F56613CA0D336AE3DBF19DC404 772 | isa 773 | PBXBuildFile 774 | 775 | B2AC8D08AB9E95E701EC049C53414AEB 776 | 777 | includeInIndex 778 | 1 779 | isa 780 | PBXFileReference 781 | lastKnownFileType 782 | text.xcconfig 783 | path 784 | FMDB.xcconfig 785 | sourceTree 786 | <group> 787 | 788 | B37F0F91F85060E28F1DAAB522DC7EC1 789 | 790 | buildSettings 791 | 792 | ALWAYS_SEARCH_USER_PATHS 793 | NO 794 | CLANG_CXX_LANGUAGE_STANDARD 795 | gnu++0x 796 | CLANG_CXX_LIBRARY 797 | libc++ 798 | CLANG_ENABLE_MODULES 799 | YES 800 | CLANG_ENABLE_OBJC_ARC 801 | YES 802 | CLANG_WARN_BOOL_CONVERSION 803 | YES 804 | CLANG_WARN_CONSTANT_CONVERSION 805 | YES 806 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE 807 | YES 808 | CLANG_WARN_EMPTY_BODY 809 | YES 810 | CLANG_WARN_ENUM_CONVERSION 811 | YES 812 | CLANG_WARN_INT_CONVERSION 813 | YES 814 | CLANG_WARN_OBJC_ROOT_CLASS 815 | YES 816 | CLANG_WARN_UNREACHABLE_CODE 817 | YES 818 | CLANG_WARN__DUPLICATE_METHOD_MATCH 819 | YES 820 | COPY_PHASE_STRIP 821 | NO 822 | GCC_C_LANGUAGE_STANDARD 823 | gnu99 824 | GCC_DYNAMIC_NO_PIC 825 | NO 826 | GCC_OPTIMIZATION_LEVEL 827 | 0 828 | GCC_PREPROCESSOR_DEFINITIONS 829 | 830 | DEBUG=1 831 | $(inherited) 832 | 833 | GCC_SYMBOLS_PRIVATE_EXTERN 834 | NO 835 | GCC_WARN_64_TO_32_BIT_CONVERSION 836 | YES 837 | GCC_WARN_ABOUT_RETURN_TYPE 838 | YES 839 | GCC_WARN_UNDECLARED_SELECTOR 840 | YES 841 | GCC_WARN_UNINITIALIZED_AUTOS 842 | YES 843 | GCC_WARN_UNUSED_FUNCTION 844 | YES 845 | GCC_WARN_UNUSED_VARIABLE 846 | YES 847 | IPHONEOS_DEPLOYMENT_TARGET 848 | 7.0 849 | ONLY_ACTIVE_ARCH 850 | YES 851 | STRIP_INSTALLED_PRODUCT 852 | NO 853 | SYMROOT 854 | ${SRCROOT}/../build 855 | 856 | isa 857 | XCBuildConfiguration 858 | name 859 | Debug 860 | 861 | B3D1D13E0C6553800746CB8FD61CF946 862 | 863 | children 864 | 865 | 37DB56D75062CC75FCB0966E1C6E8A8E 866 | 10834806BD7B412BC24F347361FA2C8E 867 | 272643F56613CA0D336AE3DBF19DC404 868 | 6911BECA35E7518D864239B7E898EEF3 869 | A1A36D34413696BE466E2CA0AFF194DA 870 | 4E762F23EC34ED4A6FF3312D84E33A40 871 | 98C98CDFB3F20F2925F6CD1F141BB14F 872 | 873 | isa 874 | PBXGroup 875 | name 876 | Pods 877 | path 878 | Target Support Files/Pods 879 | sourceTree 880 | <group> 881 | 882 | B418C9BDCF8C6BAC2E3942F157BB6D4C 883 | 884 | fileRef 885 | D2DD52CB174E1DC79111C38E770F6FC8 886 | isa 887 | PBXBuildFile 888 | settings 889 | 890 | ATTRIBUTES 891 | 892 | Public 893 | 894 | 895 | 896 | BA078C2D90AE723D992054A66EC7EB0E 897 | 898 | fileRef 899 | C11A8F38580C7A7FF38ACB6A3B412884 900 | isa 901 | PBXBuildFile 902 | settings 903 | 904 | COMPILER_FLAGS 905 | -DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks 906 | 907 | 908 | BA6428E9F66FD5A23C0A2E06ED26CD2F 909 | 910 | includeInIndex 911 | 1 912 | isa 913 | PBXFileReference 914 | lastKnownFileType 915 | text 916 | name 917 | Podfile 918 | path 919 | ../Podfile 920 | sourceTree 921 | SOURCE_ROOT 922 | xcLanguageSpecificationIdentifier 923 | xcode.lang.ruby 924 | 925 | BC3CA7F9E30CC8F7E2DD044DD34432FC 926 | 927 | children 928 | 929 | BF6342C8B29F4CEEA088EFF7AB4DE362 930 | 931 | isa 932 | PBXGroup 933 | name 934 | Frameworks 935 | sourceTree 936 | <group> 937 | 938 | BF6342C8B29F4CEEA088EFF7AB4DE362 939 | 940 | children 941 | 942 | 3E4E89230EF59BC255123B67864ACF77 943 | 944 | isa 945 | PBXGroup 946 | name 947 | iOS 948 | sourceTree 949 | <group> 950 | 951 | BFB8C92E749ED180124155E2270474D2 952 | 953 | children 954 | 955 | DEA37EDFE575D4B41E183255F5C2B8C8 956 | 957 | isa 958 | PBXGroup 959 | name 960 | Pods 961 | sourceTree 962 | <group> 963 | 964 | C11A8F38580C7A7FF38ACB6A3B412884 965 | 966 | includeInIndex 967 | 1 968 | isa 969 | PBXFileReference 970 | lastKnownFileType 971 | sourcecode.c.objc 972 | name 973 | FMDatabaseQueue.m 974 | path 975 | src/fmdb/FMDatabaseQueue.m 976 | sourceTree 977 | <group> 978 | 979 | C89A6930D6DE6039F840782BFE7A2DFB 980 | 981 | children 982 | 983 | 638E465E4B27490B0FB423614C3ADD11 984 | DC7C30F9E55829B027C4913D1F19D68C 985 | D2DD52CB174E1DC79111C38E770F6FC8 986 | 3BCC0EED53ED8D7C1931178E0E4269B4 987 | 1AF3AEDDA16DD8E28B59FF0788FDDC03 988 | 400AFB42920EB39709666D3F1A73D6C2 989 | 33F15B71183AD666DFC49D907F769ACF 990 | C11A8F38580C7A7FF38ACB6A3B412884 991 | 91893D40185E0EFA40FC217BE44A7C0D 992 | 69CC8B63F837EA7B053AB8BA07253A25 993 | 71B69D4A7150AC2F65A57B7D04F092D4 994 | 995 | isa 996 | PBXGroup 997 | name 998 | standard 999 | sourceTree 1000 | <group> 1001 | 1002 | CDF1344E9E92C8417899CE037474665F 1003 | 1004 | children 1005 | 1006 | 3FF6CC2D423559E28AE3F55AFFA4CA33 1007 | E0EAEEFA8AD36A2BF2DC2B73C68F5890 1008 | 1009 | isa 1010 | PBXGroup 1011 | name 1012 | Products 1013 | sourceTree 1014 | <group> 1015 | 1016 | D0C5FF5485EAA2CDA03E9796B407697A 1017 | 1018 | fileRef 1019 | 33F15B71183AD666DFC49D907F769ACF 1020 | isa 1021 | PBXBuildFile 1022 | settings 1023 | 1024 | ATTRIBUTES 1025 | 1026 | Public 1027 | 1028 | 1029 | 1030 | D0D5FFE53407F16C9CD3D0ECF43ACE93 1031 | 1032 | fileRef 1033 | 638E465E4B27490B0FB423614C3ADD11 1034 | isa 1035 | PBXBuildFile 1036 | settings 1037 | 1038 | ATTRIBUTES 1039 | 1040 | Public 1041 | 1042 | 1043 | 1044 | D2DD52CB174E1DC79111C38E770F6FC8 1045 | 1046 | includeInIndex 1047 | 1 1048 | isa 1049 | PBXFileReference 1050 | lastKnownFileType 1051 | sourcecode.c.h 1052 | name 1053 | FMDatabaseAdditions.h 1054 | path 1055 | src/fmdb/FMDatabaseAdditions.h 1056 | sourceTree 1057 | <group> 1058 | 1059 | D41D8CD98F00B204E9800998ECF8427E 1060 | 1061 | attributes 1062 | 1063 | LastSwiftUpdateCheck 1064 | 0700 1065 | LastUpgradeCheck 1066 | 0700 1067 | 1068 | buildConfigurationList 1069 | 2D8E8EC45A3A1A1D94AE762CB5028504 1070 | compatibilityVersion 1071 | Xcode 3.2 1072 | developmentRegion 1073 | English 1074 | hasScannedForEncodings 1075 | 0 1076 | isa 1077 | PBXProject 1078 | knownRegions 1079 | 1080 | en 1081 | 1082 | mainGroup 1083 | 7DB346D0F39D3F0E887471402A8071AB 1084 | productRefGroup 1085 | CDF1344E9E92C8417899CE037474665F 1086 | projectDirPath 1087 | 1088 | projectReferences 1089 | 1090 | projectRoot 1091 | 1092 | targets 1093 | 1094 | 9F12FB4A63E20F601CFB2E64A65B57C1 1095 | 1B9FA7A5421F72B261CD8F8DC49B18F2 1096 | 1097 | 1098 | DC7C30F9E55829B027C4913D1F19D68C 1099 | 1100 | includeInIndex 1101 | 1 1102 | isa 1103 | PBXFileReference 1104 | lastKnownFileType 1105 | sourcecode.c.objc 1106 | name 1107 | FMDatabase.m 1108 | path 1109 | src/fmdb/FMDatabase.m 1110 | sourceTree 1111 | <group> 1112 | 1113 | DCBE5599D5184BC384DF2C2B60FAE896 1114 | 1115 | fileRef 1116 | DC7C30F9E55829B027C4913D1F19D68C 1117 | isa 1118 | PBXBuildFile 1119 | settings 1120 | 1121 | COMPILER_FLAGS 1122 | -DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks 1123 | 1124 | 1125 | DEA37EDFE575D4B41E183255F5C2B8C8 1126 | 1127 | children 1128 | 1129 | C89A6930D6DE6039F840782BFE7A2DFB 1130 | 6A65CEB166911CC900621A37BC272B1F 1131 | 1132 | isa 1133 | PBXGroup 1134 | name 1135 | FMDB 1136 | path 1137 | FMDB 1138 | sourceTree 1139 | <group> 1140 | 1141 | E082381D4370CFE535166B973637724E 1142 | 1143 | baseConfigurationReference 1144 | 98C98CDFB3F20F2925F6CD1F141BB14F 1145 | buildSettings 1146 | 1147 | ENABLE_STRICT_OBJC_MSGSEND 1148 | YES 1149 | IPHONEOS_DEPLOYMENT_TARGET 1150 | 7.0 1151 | MACH_O_TYPE 1152 | staticlib 1153 | MTL_ENABLE_DEBUG_INFO 1154 | NO 1155 | OTHER_LDFLAGS 1156 | 1157 | OTHER_LIBTOOLFLAGS 1158 | 1159 | PODS_ROOT 1160 | $(SRCROOT) 1161 | PRODUCT_NAME 1162 | $(TARGET_NAME) 1163 | SDKROOT 1164 | iphoneos 1165 | SKIP_INSTALL 1166 | YES 1167 | 1168 | isa 1169 | XCBuildConfiguration 1170 | name 1171 | Release 1172 | 1173 | E0EAEEFA8AD36A2BF2DC2B73C68F5890 1174 | 1175 | explicitFileType 1176 | archive.ar 1177 | includeInIndex 1178 | 0 1179 | isa 1180 | PBXFileReference 1181 | name 1182 | libPods.a 1183 | path 1184 | libPods.a 1185 | sourceTree 1186 | BUILT_PRODUCTS_DIR 1187 | 1188 | F977B243321331B58666E9284634101A 1189 | 1190 | fileRef 1191 | 69CC8B63F837EA7B053AB8BA07253A25 1192 | isa 1193 | PBXBuildFile 1194 | settings 1195 | 1196 | ATTRIBUTES 1197 | 1198 | Public 1199 | 1200 | 1201 | 1202 | 1203 | rootObject 1204 | D41D8CD98F00B204E9800998ECF8427E 1205 | 1206 | 1207 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/StriEver.xcuserdatad/xcschemes/FMDB.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/StriEver.xcuserdatad/xcschemes/Pods.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/StriEver.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | FMDB.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods.xcscheme 13 | 14 | isShown 15 | 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 1B9FA7A5421F72B261CD8F8DC49B18F2 21 | 22 | primary 23 | 24 | 25 | 9F12FB4A63E20F601CFB2E64A65B57C1 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FMDB/FMDB-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FMDB : NSObject 3 | @end 4 | @implementation PodsDummy_FMDB 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FMDB/FMDB-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FMDB/FMDB.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FMDB" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 3 | OTHER_LDFLAGS = -l"sqlite3" 4 | PODS_ROOT = ${SRCROOT} 5 | SKIP_INSTALL = YES -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FMDB 5 | 6 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 7 | by sending an email to gus@flyingmeat.com. 8 | 9 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 10 | might consider purchasing a drink of their choosing if FMDB has been useful to 11 | you. 12 | 13 | Finally, and shortly, this is the MIT License. 14 | 15 | Copyright (c) 2008-2014 Flying Meat Inc. 16 | 17 | Permission is hereby granted, free of charge, to any person obtaining a copy 18 | of this software and associated documentation files (the "Software"), to deal 19 | in the Software without restriction, including without limitation the rights 20 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | copies of the Software, and to permit persons to whom the Software is 22 | furnished to do so, subject to the following conditions: 23 | 24 | The above copyright notice and this permission notice shall be included in 25 | all copies or substantial portions of the Software. 26 | 27 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 33 | THE SOFTWARE. 34 | Generated by CocoaPods - http://cocoapods.org 35 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know 18 | by sending an email to gus@flyingmeat.com. 19 | 20 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you 21 | might consider purchasing a drink of their choosing if FMDB has been useful to 22 | you. 23 | 24 | Finally, and shortly, this is the MIT License. 25 | 26 | Copyright (c) 2008-2014 Flying Meat Inc. 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy 29 | of this software and associated documentation files (the "Software"), to deal 30 | in the Software without restriction, including without limitation the rights 31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 | copies of the Software, and to permit persons to whom the Software is 33 | furnished to do so, subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in 36 | all copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 44 | THE SOFTWARE. 45 | Title 46 | FMDB 47 | Type 48 | PSGroupSpecifier 49 | 50 | 51 | FooterText 52 | Generated by CocoaPods - http://cocoapods.org 53 | Title 54 | 55 | Type 56 | PSGroupSpecifier 57 | 58 | 59 | StringsTable 60 | Acknowledgements 61 | Title 62 | Acknowledgements 63 | 64 | 65 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods : NSObject 3 | @end 4 | @implementation PodsDummy_Pods 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | realpath() { 12 | DIRECTORY="$(cd "${1%/*}" && pwd)" 13 | FILENAME="${1##*/}" 14 | echo "$DIRECTORY/$FILENAME" 15 | } 16 | 17 | install_resource() 18 | { 19 | case $1 in 20 | *.storyboard) 21 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 22 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 23 | ;; 24 | *.xib) 25 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" 26 | ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" 27 | ;; 28 | *.framework) 29 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 30 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 31 | echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 32 | rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 33 | ;; 34 | *.xcdatamodel) 35 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" 36 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" 37 | ;; 38 | *.xcdatamodeld) 39 | echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" 40 | xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" 41 | ;; 42 | *.xcmappingmodel) 43 | echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" 44 | xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" 45 | ;; 46 | *.xcassets) 47 | ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") 48 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 49 | ;; 50 | /*) 51 | echo "$1" 52 | echo "$1" >> "$RESOURCES_TO_COPY" 53 | ;; 54 | *) 55 | echo "${PODS_ROOT}/$1" 56 | echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" 57 | ;; 58 | esac 59 | } 60 | 61 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 62 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 63 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 64 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 65 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 66 | fi 67 | rm -f "$RESOURCES_TO_COPY" 68 | 69 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 70 | then 71 | case "${TARGETED_DEVICE_FAMILY}" in 72 | 1,2) 73 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 74 | ;; 75 | 1) 76 | TARGET_DEVICE_ARGS="--target-device iphone" 77 | ;; 78 | 2) 79 | TARGET_DEVICE_ARGS="--target-device ipad" 80 | ;; 81 | *) 82 | TARGET_DEVICE_ARGS="--target-device mac" 83 | ;; 84 | esac 85 | 86 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 87 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 88 | while read line; do 89 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 90 | XCASSET_FILES+=("$line") 91 | fi 92 | done <<<"$OTHER_XCASSETS" 93 | 94 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 95 | fi 96 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods.debug.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/FMDB" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"FMDB" -l"sqlite3" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods/Pods.release.xcconfig: -------------------------------------------------------------------------------- 1 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 2 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FMDB" 3 | OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/FMDB" 4 | OTHER_LDFLAGS = $(inherited) -ObjC -l"FMDB" -l"sqlite3" 5 | PODS_ROOT = ${SRCROOT}/Pods -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # STSTDBTool 2 | -------------------------------------------------------------------------------- /STDBTest.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4982C4895588F2E399C8284A /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 238E9C469271F96CD0C83D1A /* libPods.a */; }; 11 | D30A26F11D97679800DD1DFD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D30A26F01D97679800DD1DFD /* main.m */; }; 12 | D30A26F41D97679800DD1DFD /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D30A26F31D97679800DD1DFD /* AppDelegate.m */; }; 13 | D30A26F71D97679900DD1DFD /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D30A26F61D97679900DD1DFD /* ViewController.m */; }; 14 | D30A26FA1D97679900DD1DFD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D30A26F81D97679900DD1DFD /* Main.storyboard */; }; 15 | D30A26FC1D97679900DD1DFD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D30A26FB1D97679900DD1DFD /* Assets.xcassets */; }; 16 | D30A26FF1D97679900DD1DFD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D30A26FD1D97679900DD1DFD /* LaunchScreen.storyboard */; }; 17 | D30A270B1D97695500DD1DFD /* STDBTool.m in Sources */ = {isa = PBXBuildFile; fileRef = D30A27091D97695500DD1DFD /* STDBTool.m */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 238E9C469271F96CD0C83D1A /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 51A4AB29D545BB213B3F55F7 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; 23 | 6B56250FD9451BDB53921088 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; 24 | D30A26EC1D97679800DD1DFD /* STDBTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = STDBTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 25 | D30A26F01D97679800DD1DFD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 26 | D30A26F21D97679800DD1DFD /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 27 | D30A26F31D97679800DD1DFD /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 28 | D30A26F51D97679800DD1DFD /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 29 | D30A26F61D97679900DD1DFD /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 30 | D30A26F91D97679900DD1DFD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 31 | D30A26FB1D97679900DD1DFD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 32 | D30A26FE1D97679900DD1DFD /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 33 | D30A27001D97679900DD1DFD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | D30A27071D97695500DD1DFD /* DBDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DBDefine.h; sourceTree = ""; }; 35 | D30A27081D97695500DD1DFD /* STDBTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = STDBTool.h; sourceTree = ""; }; 36 | D30A27091D97695500DD1DFD /* STDBTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = STDBTool.m; sourceTree = ""; }; 37 | D30A270A1D97695500DD1DFD /* Table.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Table.h; sourceTree = ""; }; 38 | /* End PBXFileReference section */ 39 | 40 | /* Begin PBXFrameworksBuildPhase section */ 41 | D30A26E91D97679800DD1DFD /* Frameworks */ = { 42 | isa = PBXFrameworksBuildPhase; 43 | buildActionMask = 2147483647; 44 | files = ( 45 | 4982C4895588F2E399C8284A /* libPods.a in Frameworks */, 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | 6E08F780B84DE6650C05126F /* Pods */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | 6B56250FD9451BDB53921088 /* Pods.debug.xcconfig */, 56 | 51A4AB29D545BB213B3F55F7 /* Pods.release.xcconfig */, 57 | ); 58 | name = Pods; 59 | sourceTree = ""; 60 | }; 61 | D30A26E31D97679800DD1DFD = { 62 | isa = PBXGroup; 63 | children = ( 64 | D30A27061D97695500DD1DFD /* STDB */, 65 | D30A26EE1D97679800DD1DFD /* STDBTest */, 66 | D30A26ED1D97679800DD1DFD /* Products */, 67 | 6E08F780B84DE6650C05126F /* Pods */, 68 | F285F2B97DDFCEEF118A910D /* Frameworks */, 69 | ); 70 | sourceTree = ""; 71 | }; 72 | D30A26ED1D97679800DD1DFD /* Products */ = { 73 | isa = PBXGroup; 74 | children = ( 75 | D30A26EC1D97679800DD1DFD /* STDBTest.app */, 76 | ); 77 | name = Products; 78 | sourceTree = ""; 79 | }; 80 | D30A26EE1D97679800DD1DFD /* STDBTest */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | D30A26F21D97679800DD1DFD /* AppDelegate.h */, 84 | D30A26F31D97679800DD1DFD /* AppDelegate.m */, 85 | D30A26F51D97679800DD1DFD /* ViewController.h */, 86 | D30A26F61D97679900DD1DFD /* ViewController.m */, 87 | D30A26F81D97679900DD1DFD /* Main.storyboard */, 88 | D30A26FB1D97679900DD1DFD /* Assets.xcassets */, 89 | D30A26FD1D97679900DD1DFD /* LaunchScreen.storyboard */, 90 | D30A27001D97679900DD1DFD /* Info.plist */, 91 | D30A26EF1D97679800DD1DFD /* Supporting Files */, 92 | ); 93 | path = STDBTest; 94 | sourceTree = ""; 95 | }; 96 | D30A26EF1D97679800DD1DFD /* Supporting Files */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | D30A26F01D97679800DD1DFD /* main.m */, 100 | ); 101 | name = "Supporting Files"; 102 | sourceTree = ""; 103 | }; 104 | D30A27061D97695500DD1DFD /* STDB */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | D30A270A1D97695500DD1DFD /* Table.h */, 108 | D30A27071D97695500DD1DFD /* DBDefine.h */, 109 | D30A27081D97695500DD1DFD /* STDBTool.h */, 110 | D30A27091D97695500DD1DFD /* STDBTool.m */, 111 | ); 112 | name = STDB; 113 | path = STDBTest/STDB; 114 | sourceTree = ""; 115 | }; 116 | F285F2B97DDFCEEF118A910D /* Frameworks */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | 238E9C469271F96CD0C83D1A /* libPods.a */, 120 | ); 121 | name = Frameworks; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | D30A26EB1D97679800DD1DFD /* STDBTest */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = D30A27031D97679900DD1DFD /* Build configuration list for PBXNativeTarget "STDBTest" */; 130 | buildPhases = ( 131 | 45B30AFFA87144F7851F6895 /* Check Pods Manifest.lock */, 132 | D30A26E81D97679800DD1DFD /* Sources */, 133 | D30A26E91D97679800DD1DFD /* Frameworks */, 134 | D30A26EA1D97679800DD1DFD /* Resources */, 135 | F7F3B10C7DB8E9D72C9C8DD3 /* Embed Pods Frameworks */, 136 | 38899404BB6A0E108EC79A18 /* Copy Pods Resources */, 137 | ); 138 | buildRules = ( 139 | ); 140 | dependencies = ( 141 | ); 142 | name = STDBTest; 143 | productName = STDBTest; 144 | productReference = D30A26EC1D97679800DD1DFD /* STDBTest.app */; 145 | productType = "com.apple.product-type.application"; 146 | }; 147 | /* End PBXNativeTarget section */ 148 | 149 | /* Begin PBXProject section */ 150 | D30A26E41D97679800DD1DFD /* Project object */ = { 151 | isa = PBXProject; 152 | attributes = { 153 | LastUpgradeCheck = 0800; 154 | ORGANIZATIONNAME = StriEver; 155 | TargetAttributes = { 156 | D30A26EB1D97679800DD1DFD = { 157 | CreatedOnToolsVersion = 8.0; 158 | DevelopmentTeam = G49DMHKN44; 159 | ProvisioningStyle = Automatic; 160 | }; 161 | }; 162 | }; 163 | buildConfigurationList = D30A26E71D97679800DD1DFD /* Build configuration list for PBXProject "STDBTest" */; 164 | compatibilityVersion = "Xcode 3.2"; 165 | developmentRegion = English; 166 | hasScannedForEncodings = 0; 167 | knownRegions = ( 168 | en, 169 | Base, 170 | ); 171 | mainGroup = D30A26E31D97679800DD1DFD; 172 | productRefGroup = D30A26ED1D97679800DD1DFD /* Products */; 173 | projectDirPath = ""; 174 | projectRoot = ""; 175 | targets = ( 176 | D30A26EB1D97679800DD1DFD /* STDBTest */, 177 | ); 178 | }; 179 | /* End PBXProject section */ 180 | 181 | /* Begin PBXResourcesBuildPhase section */ 182 | D30A26EA1D97679800DD1DFD /* Resources */ = { 183 | isa = PBXResourcesBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | D30A26FF1D97679900DD1DFD /* LaunchScreen.storyboard in Resources */, 187 | D30A26FC1D97679900DD1DFD /* Assets.xcassets in Resources */, 188 | D30A26FA1D97679900DD1DFD /* Main.storyboard in Resources */, 189 | ); 190 | runOnlyForDeploymentPostprocessing = 0; 191 | }; 192 | /* End PBXResourcesBuildPhase section */ 193 | 194 | /* Begin PBXShellScriptBuildPhase section */ 195 | 38899404BB6A0E108EC79A18 /* Copy Pods Resources */ = { 196 | isa = PBXShellScriptBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | ); 200 | inputPaths = ( 201 | ); 202 | name = "Copy Pods Resources"; 203 | outputPaths = ( 204 | ); 205 | runOnlyForDeploymentPostprocessing = 0; 206 | shellPath = /bin/sh; 207 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; 208 | showEnvVarsInLog = 0; 209 | }; 210 | 45B30AFFA87144F7851F6895 /* Check Pods Manifest.lock */ = { 211 | isa = PBXShellScriptBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputPaths = ( 216 | ); 217 | name = "Check Pods Manifest.lock"; 218 | outputPaths = ( 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | shellPath = /bin/sh; 222 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 223 | showEnvVarsInLog = 0; 224 | }; 225 | F7F3B10C7DB8E9D72C9C8DD3 /* Embed Pods Frameworks */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputPaths = ( 231 | ); 232 | name = "Embed Pods Frameworks"; 233 | outputPaths = ( 234 | ); 235 | runOnlyForDeploymentPostprocessing = 0; 236 | shellPath = /bin/sh; 237 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-frameworks.sh\"\n"; 238 | showEnvVarsInLog = 0; 239 | }; 240 | /* End PBXShellScriptBuildPhase section */ 241 | 242 | /* Begin PBXSourcesBuildPhase section */ 243 | D30A26E81D97679800DD1DFD /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | D30A270B1D97695500DD1DFD /* STDBTool.m in Sources */, 248 | D30A26F71D97679900DD1DFD /* ViewController.m in Sources */, 249 | D30A26F41D97679800DD1DFD /* AppDelegate.m in Sources */, 250 | D30A26F11D97679800DD1DFD /* main.m in Sources */, 251 | ); 252 | runOnlyForDeploymentPostprocessing = 0; 253 | }; 254 | /* End PBXSourcesBuildPhase section */ 255 | 256 | /* Begin PBXVariantGroup section */ 257 | D30A26F81D97679900DD1DFD /* Main.storyboard */ = { 258 | isa = PBXVariantGroup; 259 | children = ( 260 | D30A26F91D97679900DD1DFD /* Base */, 261 | ); 262 | name = Main.storyboard; 263 | sourceTree = ""; 264 | }; 265 | D30A26FD1D97679900DD1DFD /* LaunchScreen.storyboard */ = { 266 | isa = PBXVariantGroup; 267 | children = ( 268 | D30A26FE1D97679900DD1DFD /* Base */, 269 | ); 270 | name = LaunchScreen.storyboard; 271 | sourceTree = ""; 272 | }; 273 | /* End PBXVariantGroup section */ 274 | 275 | /* Begin XCBuildConfiguration section */ 276 | D30A27011D97679900DD1DFD /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ALWAYS_SEARCH_USER_PATHS = NO; 280 | CLANG_ANALYZER_NONNULL = YES; 281 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 282 | CLANG_CXX_LIBRARY = "libc++"; 283 | CLANG_ENABLE_MODULES = YES; 284 | CLANG_ENABLE_OBJC_ARC = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 288 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 289 | CLANG_WARN_EMPTY_BODY = YES; 290 | CLANG_WARN_ENUM_CONVERSION = YES; 291 | CLANG_WARN_INFINITE_RECURSION = YES; 292 | CLANG_WARN_INT_CONVERSION = YES; 293 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 294 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 295 | CLANG_WARN_UNREACHABLE_CODE = YES; 296 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 297 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 298 | COPY_PHASE_STRIP = NO; 299 | DEBUG_INFORMATION_FORMAT = dwarf; 300 | ENABLE_STRICT_OBJC_MSGSEND = YES; 301 | ENABLE_TESTABILITY = YES; 302 | GCC_C_LANGUAGE_STANDARD = gnu99; 303 | GCC_DYNAMIC_NO_PIC = NO; 304 | GCC_NO_COMMON_BLOCKS = YES; 305 | GCC_OPTIMIZATION_LEVEL = 0; 306 | GCC_PREPROCESSOR_DEFINITIONS = ( 307 | "DEBUG=1", 308 | "$(inherited)", 309 | ); 310 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 311 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 312 | GCC_WARN_UNDECLARED_SELECTOR = YES; 313 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 314 | GCC_WARN_UNUSED_FUNCTION = YES; 315 | GCC_WARN_UNUSED_VARIABLE = YES; 316 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 317 | MTL_ENABLE_DEBUG_INFO = YES; 318 | ONLY_ACTIVE_ARCH = YES; 319 | SDKROOT = iphoneos; 320 | }; 321 | name = Debug; 322 | }; 323 | D30A27021D97679900DD1DFD /* Release */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | ALWAYS_SEARCH_USER_PATHS = NO; 327 | CLANG_ANALYZER_NONNULL = YES; 328 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 329 | CLANG_CXX_LIBRARY = "libc++"; 330 | CLANG_ENABLE_MODULES = YES; 331 | CLANG_ENABLE_OBJC_ARC = YES; 332 | CLANG_WARN_BOOL_CONVERSION = YES; 333 | CLANG_WARN_CONSTANT_CONVERSION = YES; 334 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 335 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 336 | CLANG_WARN_EMPTY_BODY = YES; 337 | CLANG_WARN_ENUM_CONVERSION = YES; 338 | CLANG_WARN_INFINITE_RECURSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 341 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 342 | CLANG_WARN_UNREACHABLE_CODE = YES; 343 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 344 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 345 | COPY_PHASE_STRIP = NO; 346 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 347 | ENABLE_NS_ASSERTIONS = NO; 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_NO_COMMON_BLOCKS = YES; 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 358 | MTL_ENABLE_DEBUG_INFO = NO; 359 | SDKROOT = iphoneos; 360 | VALIDATE_PRODUCT = YES; 361 | }; 362 | name = Release; 363 | }; 364 | D30A27041D97679900DD1DFD /* Debug */ = { 365 | isa = XCBuildConfiguration; 366 | baseConfigurationReference = 6B56250FD9451BDB53921088 /* Pods.debug.xcconfig */; 367 | buildSettings = { 368 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 369 | CODE_SIGN_IDENTITY = "iPhone Developer: ming zong (XE5EV4Y65Q)"; 370 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 371 | DEVELOPMENT_TEAM = G49DMHKN44; 372 | INFOPLIST_FILE = STDBTest/Info.plist; 373 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 375 | PRODUCT_BUNDLE_IDENTIFIER = com.testigancao.STDBTest; 376 | PRODUCT_NAME = "$(TARGET_NAME)"; 377 | PROVISIONING_PROFILE = ""; 378 | PROVISIONING_PROFILE_SPECIFIER = ""; 379 | }; 380 | name = Debug; 381 | }; 382 | D30A27051D97679900DD1DFD /* Release */ = { 383 | isa = XCBuildConfiguration; 384 | baseConfigurationReference = 51A4AB29D545BB213B3F55F7 /* Pods.release.xcconfig */; 385 | buildSettings = { 386 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 387 | CODE_SIGN_IDENTITY = "iPhone Developer: ming zong (XE5EV4Y65Q)"; 388 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 389 | DEVELOPMENT_TEAM = G49DMHKN44; 390 | INFOPLIST_FILE = STDBTest/Info.plist; 391 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 393 | PRODUCT_BUNDLE_IDENTIFIER = com.testigancao.STDBTest; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | PROVISIONING_PROFILE = ""; 396 | PROVISIONING_PROFILE_SPECIFIER = ""; 397 | }; 398 | name = Release; 399 | }; 400 | /* End XCBuildConfiguration section */ 401 | 402 | /* Begin XCConfigurationList section */ 403 | D30A26E71D97679800DD1DFD /* Build configuration list for PBXProject "STDBTest" */ = { 404 | isa = XCConfigurationList; 405 | buildConfigurations = ( 406 | D30A27011D97679900DD1DFD /* Debug */, 407 | D30A27021D97679900DD1DFD /* Release */, 408 | ); 409 | defaultConfigurationIsVisible = 0; 410 | defaultConfigurationName = Release; 411 | }; 412 | D30A27031D97679900DD1DFD /* Build configuration list for PBXNativeTarget "STDBTest" */ = { 413 | isa = XCConfigurationList; 414 | buildConfigurations = ( 415 | D30A27041D97679900DD1DFD /* Debug */, 416 | D30A27051D97679900DD1DFD /* Release */, 417 | ); 418 | defaultConfigurationIsVisible = 0; 419 | defaultConfigurationName = Release; 420 | }; 421 | /* End XCConfigurationList section */ 422 | }; 423 | rootObject = D30A26E41D97679800DD1DFD /* Project object */; 424 | } 425 | -------------------------------------------------------------------------------- /STDBTest.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /STDBTest.xcodeproj/xcuserdata/StriEver.xcuserdatad/xcschemes/STDBTest.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /STDBTest.xcodeproj/xcuserdata/StriEver.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | STDBTest.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D30A26EB1D97679800DD1DFD 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /STDBTest.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /STDBTest.xcworkspace/xcuserdata/StriEver.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /STDBTest/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // STDBTest 4 | // 5 | // Created by StriEver on 16/9/25. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /STDBTest/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // STDBTest 4 | // 5 | // Created by StriEver on 16/9/25. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | // NSFileManager * fmManger = [NSFileManager defaultManager]; 21 | // NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 22 | // NSString * dbPath = [NSString stringWithFormat:@"%@/BookData",[paths count] > 0 ? paths.firstObject : nil]; 23 | // dbPath = [dbPath stringByAppendingPathComponent:@"st_reader.db"]; 24 | // if (![fmManger fileExistsAtPath:dbPath]) { 25 | // [fmManger createFileAtPath:dbPath contents:nil attributes:nil]; 26 | // } 27 | return YES; 28 | } 29 | 30 | 31 | - (void)applicationWillResignActive:(UIApplication *)application { 32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 34 | } 35 | 36 | 37 | - (void)applicationDidEnterBackground:(UIApplication *)application { 38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 40 | } 41 | 42 | 43 | - (void)applicationWillEnterForeground:(UIApplication *)application { 44 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 45 | } 46 | 47 | 48 | - (void)applicationDidBecomeActive:(UIApplication *)application { 49 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 50 | } 51 | 52 | 53 | - (void)applicationWillTerminate:(UIApplication *)application { 54 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 55 | } 56 | 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /STDBTest/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /STDBTest/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /STDBTest/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /STDBTest/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /STDBTest/STDB/DBDefine.h: -------------------------------------------------------------------------------- 1 | // 2 | // DBDefine.h 3 | // STReader 4 | // 5 | // Created by StriEver on 16/8/15. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #ifndef DBDefine_h 10 | #define DBDefine_h 11 | #define ST_DB_NAME @"st_reader.db" 12 | #define ST_DB_NEWVERSION 2.1 13 | 14 | //存储全部书籍 15 | #define ST_TB_NAME_BOOKINFO @"bookInfoTable" 16 | #define ST_DB_CFG_TAB @"readerCfg" 17 | #define ST_DB_BOOK_PROGRESS @"bookChapterProgressInfo" 18 | 19 | #endif /* DBDefine_h */ 20 | 21 | -------------------------------------------------------------------------------- /STDBTest/STDB/STDBTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // STDBTool.h 3 | // STReader 4 | // 5 | // Created by StriEver on 16/8/15. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "Table.h" 12 | @class FMResultSet; 13 | typedef enum ST_DB_ActionType 14 | { 15 | ST_DB_SELECT = 0,//查询操作 16 | ST_DB_INSERT, //插入操作 17 | ST_DB_UPDATE, //更新操作 18 | ST_DB_DELETE, //删除操作 19 | ST_DB_ADDUPDATE //更新或者插入操作 20 | } ST_DB_ActionType; 21 | @interface STDBTool : NSObject 22 | @property(nonatomic,strong) FMDatabaseQueue *dbQueue; 23 | @property(nonatomic,strong) FMDatabaseQueue *dbQueue2; 24 | @property(nonatomic,strong) FMDatabaseQueue *dbQueue3; 25 | + (STDBTool *)shareInstance; 26 | 27 | /** 28 | * @brief 执行单个sql语句 不需要使用事务处理 根据类型确定是否返回记录集 29 | * 30 | * @param sqlStr sql语句 select、update或者insert into语句 31 | * @param actionType 表示操作的类型,ST_DB_SELECT:查询;ST_DB_INSERT:插入;ST_DB_UPDATE:更新;ST_DB_DELETE:删除; 32 | * @param block 返回执行结果 33 | */ 34 | -(void)executeSQL:(NSString *)sqlStr actionType:(ST_DB_ActionType)actionType withBlock:(void(^)(BOOL bRet, FMResultSet *rs, NSString *msg))block; 35 | 36 | /** 37 | * @brief 执行单个sql语句 不需要使用事务处理 根据类型确定是否返回记录集 使用dbQueue3,用于直接调用(不是封装在其他方法中) 38 | * 39 | * @param sqlStr sql语句 select、update或者insert into语句 40 | * @param actionType 表示操作的类型,ST_DB_SELECT:查询;ST_DB_INSERT:插入;ST_DB_UPDATE:更新;ST_DB_DELETE:删除; 41 | * @param block 返回执行结果 42 | */ 43 | - (void)execcuteQueue3Sql:(NSString *)sqlStr actionType:(ST_DB_ActionType)actionType withBlock:(void(^)(BOOL bRet, FMResultSet *rs, NSString *msg))block; 44 | 45 | 46 | /** 47 | * @brief 根据查询结果 确定是更新还是新增操作,只需要知道是否操作成功,不关心结果集 只处理一 48 | 个查询更新,不需要事务处理 49 | * 50 | * @param sqlList sql语句数组,sqlList[0]查询select语句 sqList[1]update更新语句 sqlList[2] insert into 插入语句 51 | * @param block 返回执行结果block 52 | */ 53 | - (void)executeRelevanceSql:(NSArray *)sqlList withBlock:(void(^)(BOOL ret,NSString * errMsg))block; 54 | 55 | /** 56 | * @brief sqlList 是一个二维数组,每一个成员包含三个sql语句,分别是查询,更新,插入,并且 57 | 据查询结果返回是执行更新 还是 插入操 作。使用dbQueue2 用于直接调用。批量处理,使用事务 58 | * 59 | * @param sqlList sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:update语句;sqlArr[i][2]:insert into语句 60 | * @param block 返回执行结果的block 61 | */ 62 | - (void)executeDbQueue2RelevanceTransactionSqlList:(NSArray *)sqlList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block; 63 | 64 | /* 65 | * @brief sql语句数组中每个成员有2条语句,第一条是select语句,第二 66 | 条是insert into语句, 67 | 根据第一个sql的执行结果确定执行第二条语句是否执行。 68 | 根据查询结果确定是否新增,批量处理,不需要返回记录集 69 | 使用dbQueue2,用于程序中直接调用(非封装在其他方法中) 70 | * 71 | * @param sqlArray sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:insert into语句 72 | * 73 | * @param block 返回执行结果的block 74 | */ 75 | -(void)executeInsertTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block; 76 | 77 | 78 | /* 79 | * @brief sql语句数组中每个成员有2条语句,第一条是select语句,第二条是update语句, 80 | * 根据第一个sql的执行结果确定执行第二条语句是否执行。 81 | * 根据查询结果确定是否更新,批量处理,不需要返回记录集 82 | * 使用dbQueue2,用于程序中直接调用(非封装在其他方法中) 83 | * 84 | * @param sqlArray sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:update语句 85 | * 86 | * @param block 返回执行结果的block 87 | */ 88 | -(void)executeUpdateTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block; 89 | 90 | 91 | 92 | /* 93 | * @brief 批量处理更新或者新增sql语句,并且不需要返回记录集,使用事务处理 94 | * 95 | * @param sqlStrList sql语句数组update或者insert into语句 96 | * 97 | * @param block 返回执行结果的block 98 | */ 99 | -(void)executeTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block; 100 | 101 | 102 | /* 103 | * @brief 批量处理更新或者新增sql语句,并且不需要返回记录集 使用dbQueue2 防止嵌套 死循环 104 | * 105 | * @param sqlStrArr sql语句数组update或者insert into语句 106 | * 107 | * @param block 返回执行结果的block 108 | */ 109 | -(void)executeDbQueue2TransactionSqlList:(NSArray *)sqlStrArr withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block; 110 | /** 111 | * @brief 批量处理更新或者新增sql语句,不需要返回记录集 无事务处理 112 | * 113 | * @param sqlStrList sql语句数组update或者insert into语句 114 | * @param db FMDatabase数据库对象 115 | * @param block 返回执行结果的block 116 | */ 117 | 118 | - (void)executeSQLList:(NSArray *)sqlStrList db:(FMDatabase *)db withBlock:(void(^)(BOOL bRet, NSString *msg))block; 119 | 120 | /** 121 | * @brief 批量处理更新或者新增sql语句,不需要返回记录集 无事务处理 122 | * 123 | * @param sqlStrList sql语句数组update或者insert into语句 124 | * @param block 返回执行结果的block 125 | */ 126 | - (void)executeSQLList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg))block; 127 | @end 128 | -------------------------------------------------------------------------------- /STDBTest/STDB/STDBTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // STDBTool.m 3 | // STReader 4 | // 5 | // Created by StriEver on 16/8/15. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import "STDBTool.h" 10 | #import "DBDefine.h" 11 | #import 12 | @implementation STDBTool 13 | static STDBTool *sharedManager=nil; 14 | + (STDBTool *)shareInstance{ 15 | static dispatch_once_t onceToken; 16 | dispatch_once(&onceToken, ^{ 17 | sharedManager = [[STDBTool alloc]init]; 18 | }); 19 | return sharedManager; 20 | } 21 | - (instancetype)init{ 22 | if (self = [super init]) { 23 | NSFileManager * fmManger = [NSFileManager defaultManager]; 24 | NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 25 | NSString * dbPath = [NSString stringWithFormat:@"%@/BookData.db",[paths count] > 0 ? paths.firstObject : nil]; 26 | // dbPath = [dbPath stringByAppendingPathComponent:ST_DB_NAME]; 27 | if (![fmManger fileExistsAtPath:dbPath]) { 28 | [fmManger createFileAtPath:dbPath contents:nil attributes:nil]; 29 | } 30 | self.dbQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath]; 31 | self.dbQueue2 = [FMDatabaseQueue databaseQueueWithPath:dbPath]; 32 | self.dbQueue3 = [FMDatabaseQueue databaseQueueWithPath:dbPath]; 33 | [self updateDbVersion:ST_DB_NEWVERSION]; 34 | } 35 | return self; 36 | } 37 | //更新数据库 38 | - (void)updateDbVersion:(NSInteger)newVersion{ 39 | //执行数据库更新 40 | [_dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback) { 41 | [self getCurrentDbVersion:db withBlock:^(BOOL bRet, int version) { 42 | if (bRet && (newVersion > version || newVersion == 0) ) { 43 | //如果本地数据库版本需要升级 44 | [self executeSQLList:[self setSqliArray] db:db withBlock:^(BOOL bRet, NSString *msg) { 45 | if (bRet) { 46 | //设置数据库版本号 47 | [self setNewDbVersion:newVersion db:db withBlock:^(BOOL bRet) { 48 | if (bRet) 49 | { 50 | NSLog(@"set new db version successfully!"); 51 | } 52 | }]; 53 | } 54 | }]; 55 | } 56 | }]; 57 | }]; 58 | 59 | } 60 | - (void)getCurrentDbVersion:(FMDatabase *)db withBlock:(void(^)(BOOL bRet,int version))block{ 61 | NSString * sql = [NSString stringWithFormat:@"PRAGMA user_version"]; 62 | FMResultSet * rs = [db executeQuery:sql]; 63 | int nVersion = 0; 64 | while ([rs next]) { 65 | nVersion = [rs intForColumn:@"user_version"]; 66 | } 67 | [rs close]; 68 | if ([db hadError]) { 69 | NSLog(@"get db version Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 70 | block(NO,-1); 71 | return; 72 | } 73 | block(YES,nVersion); 74 | } 75 | -(void)setNewDbVersion:(NSInteger)newVersion withBlock:(void(^)(BOOL bRet))block 76 | { 77 | [_dbQueue inDatabase:^(FMDatabase *db) { 78 | 79 | NSString *sql = [NSString stringWithFormat:@"PRAGMA user_version = %ld",(long)newVersion]; 80 | 81 | BOOL ret = [db executeUpdate:sql]; 82 | 83 | if ([db hadError]) 84 | { 85 | NSLog(@"get db version Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 86 | } 87 | 88 | block(ret); 89 | }]; 90 | } 91 | 92 | -(void)setNewDbVersion:(NSInteger)newVersion db:(FMDatabase *)db withBlock:(void(^)(BOOL bRet))block 93 | { 94 | NSString *sql = [NSString stringWithFormat:@"PRAGMA user_version = %ld",(long)newVersion]; 95 | 96 | BOOL ret = [db executeUpdate:sql]; 97 | 98 | if ([db hadError]) 99 | { 100 | NSLog(@"get db version Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 101 | } 102 | 103 | block(ret); 104 | } 105 | 106 | 107 | /** 108 | * @brief 执行单个sql语句 不需要使用事务处理 根据类型确定是否返回记录集 109 | * 110 | * @param sqlStr sql语句 select、update或者insert into语句 111 | * @param actionType 表示操作的类型,ST_DB_SELECT:查询;ST_DB_INSERT:插入;ST_DB_UPDATE:更新;ST_DB_DELETE:删除; 112 | * @param block 返回执行结果 113 | */ 114 | -(void)executeSQL:(NSString *)sqlStr actionType:(ST_DB_ActionType)actionType withBlock:(void(^)(BOOL bRet, FMResultSet *rs, NSString *msg))block{ 115 | [_dbQueue inDatabase:^(FMDatabase *db) { 116 | if (actionType == ST_DB_SELECT) { 117 | //查询语句 需要返回记录集 118 | FMResultSet * rs = [db executeQuery:sqlStr]; 119 | if ([db hadError]) { 120 | block(NO,rs,[db lastErrorMessage]); 121 | NSLog(@"executeSQL error %d: %@",[db lastErrorCode],[db lastErrorMessage]); 122 | }else{ 123 | block(YES,rs,nil); 124 | } 125 | }else{ 126 | //更新操作 只关心操作是否执行成功,不关心记录集 返回布尔值 无执行结果 127 | BOOL ret = [db executeUpdate:sqlStr]; 128 | if ([db hadError]) { 129 | block(NO,nil,[db lastErrorMessage]); 130 | NSLog(@"executeSQL error %d: %@",[db lastErrorCode],[db lastErrorMessage]); 131 | }else{ 132 | block(ret,nil,nil); 133 | } 134 | } 135 | }]; 136 | } 137 | /** 138 | * @brief 执行单个sql语句 不需要使用事务处理 根据类型确定是否返回记录集 使用dbQueue3,用于直接调用(不是封装在其他方法中) 139 | * 140 | * @param sqlStr sql语句 select、update或者insert into语句 141 | * @param actionType 表示操作的类型,ST_DB_SELECT:查询;ST_DB_INSERT:插入;ST_DB_UPDATE:更新;ST_DB_DELETE:删除; 142 | * @param block 返回执行结果 143 | */ 144 | - (void)execcuteQueue3Sql:(NSString *)sqlStr actionType:(ST_DB_ActionType)actionType withBlock:(void(^)(BOOL bRet, FMResultSet *rs, NSString *msg))block{ 145 | [_dbQueue3 inDatabase:^(FMDatabase *db) { 146 | if (actionType == ST_DB_SELECT) { 147 | FMResultSet * rs = [db executeQuery:sqlStr]; 148 | if ([db hadError]) { 149 | block(NO,nil,[db lastErrorMessage]); 150 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 151 | }else{ 152 | block(YES,rs,nil); 153 | } 154 | }else{ 155 | BOOL ret = [db executeUpdate:sqlStr]; 156 | if ([db hadError]) { 157 | block(NO,nil,[db lastErrorMessage]); 158 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 159 | }else{ 160 | block(ret,nil,nil); 161 | } 162 | } 163 | }]; 164 | } 165 | 166 | /** 167 | * @brief 根据查询结果 确定是更新还是新增操作,只需要知道是否操作成功,不关心结果集 只处理一个查询更新,不需要事务处理 168 | * 169 | * @param sqlList sql语句数组,sqlList[0]查询select语句 sqList[1]update更新语句 sqlList[2] insert into 插入语句 170 | * @param block 返回执行结果block 171 | */ 172 | - (void)executeRelevanceSql:(NSArray *)sqlList withBlock:(void(^)(BOOL ret,NSString * errMsg))block{ 173 | __block BOOL ret; 174 | [_dbQueue inDatabase:^(FMDatabase *db) { 175 | FMResultSet * rs = [db executeQuery:sqlList[0]]; 176 | if ([db hadError]) { 177 | block(NO,[db lastErrorMessage]); 178 | NSLog(@"da_error_%@",[db lastErrorMessage]); 179 | } 180 | int nCount = 0; 181 | if ([rs next]) { 182 | //获取查询数据的个数 183 | nCount = [rs intForColumnIndex:0]; 184 | } 185 | [rs close]; 186 | 187 | NSString * nextSqlString = nil; 188 | if (nCount > 0) { 189 | //查询到了结果 执行update操作 190 | nextSqlString = sqlList[1]; 191 | }else{ 192 | //查询无结果 执行 insert into 操作 193 | nextSqlString = sqlList[2]; 194 | } 195 | 196 | ret = [db executeUpdate:nextSqlString]; 197 | if ([db hadError]) { 198 | block(NO,[db lastErrorMessage]); 199 | NSLog(@"da_error_%@",[db lastErrorMessage]); 200 | }else{ 201 | block(ret, nil); 202 | } 203 | }]; 204 | 205 | } 206 | /** 207 | * @brief sqlList 是一个二维数组,每一个成员包含三个sql语句,分别是查询,更新,插入,并且根据查询结果返回是执行更新 还是 插入操 208 | 作。使用dbQueue2 用于直接调用。批量处理,使用事务 209 | * 210 | * @param sqlList sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:update语句;sqlArr[i][2]:insert into语句 211 | * @param block 返回执行结果的block 212 | */ 213 | - (void)executeDbQueue2RelevanceTransactionSqlList:(NSArray *)sqlList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block{ 214 | __block BOOL ret = NO; 215 | [_dbQueue2 inTransaction:^(FMDatabase *db, BOOL *rollback) { 216 | for (NSArray * singleSqlList in sqlList ) { 217 | FMResultSet * rs = [db executeQuery:singleSqlList[0]]; 218 | if ([db hadError]) { 219 | block(NO,[db lastErrorMessage],rollback); 220 | NSLog(@"da_error_%@",[db lastErrorMessage]); 221 | }else{ 222 | int nCount = 0; 223 | while ([rs next]){ 224 | nCount = [rs intForColumnIndex:0]; 225 | } 226 | [rs close]; 227 | 228 | NSString * nextSqlString = nil; 229 | if (nCount > 0){ 230 | //执行更新 231 | nextSqlString = singleSqlList[1]; 232 | } 233 | else{ 234 | //执行插入 235 | nextSqlString = singleSqlList[2]; 236 | } 237 | 238 | ret = [db executeUpdate:nextSqlString]; 239 | if ([db hadError]) 240 | { 241 | block(NO, [db lastErrorMessage], rollback); 242 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 243 | } 244 | } 245 | } 246 | block(ret, nil, rollback); 247 | }]; 248 | } 249 | 250 | /* 251 | * @brief sql语句数组中每个成员有2条语句,第一条是select语句,第二条是insert into语句, 252 | * 根据第一个sql的执行结果确定执行第二条语句是否执行。 253 | * 根据查询结果确定是否新增,批量处理,不需要返回记录集 254 | * 使用dbQueue2,用于程序中直接调用(非封装在其他方法中) 255 | * 256 | * @param sqlArray sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:insert into语句 257 | * 258 | * @param block 返回执行结果的block 259 | */ 260 | -(void)executeInsertTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block 261 | { 262 | __block BOOL ret = NO; 263 | NSLog(@"开始啦---"); 264 | [_dbQueue2 inTransaction:^(FMDatabase *db, BOOL *rollback){ 265 | 266 | for (NSArray *sqlArray in sqlStrList){ 267 | FMResultSet *rs = [db executeQuery:[sqlArray objectAtIndex:0]]; 268 | if ([db hadError]){ 269 | block(NO, [db lastErrorMessage], rollback); 270 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 271 | } 272 | 273 | int nCount = 0; 274 | while ([rs next]){ 275 | nCount = [rs intForColumnIndex:0]; 276 | } 277 | [rs close]; 278 | 279 | if (nCount <= 0){ 280 | ret = [db executeUpdate:[sqlArray objectAtIndex:1]]; 281 | if ([db hadError]) 282 | { 283 | block(NO, [db lastErrorMessage], rollback); 284 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 285 | } 286 | } 287 | } 288 | block(ret, nil, rollback); 289 | }]; 290 | } 291 | 292 | /* 293 | * @brief sql语句数组中每个成员有2条语句,第一条是select语句,第二条是update语句, 294 | * 根据第一个sql的执行结果确定执行第二条语句是否执行。 295 | * 根据查询结果确定是否更新,批量处理,不需要返回记录集 296 | * 使用dbQueue2,用于程序中直接调用(非封装在其他方法中) 297 | * 298 | * @param sqlArray sql语句数组,sqlArr[i][0]:查询语句;sqlArr[i][1]:update语句 299 | * 300 | * @param block 返回执行结果的block 301 | */ 302 | -(void)executeUpdateTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block 303 | { 304 | __block BOOL ret = NO; 305 | [_dbQueue2 inTransaction:^(FMDatabase *db, BOOL *rollback){ 306 | 307 | for (NSArray *sqlArray in sqlStrList){ 308 | FMResultSet *rs = [db executeQuery:[sqlArray objectAtIndex:0]]; 309 | if ([db hadError]){ 310 | block(NO, [db lastErrorMessage], rollback); 311 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 312 | } 313 | 314 | int nCount = 0; 315 | while ([rs next]){ 316 | nCount = [[rs objectForColumnName:@"numbers"] intValue]; 317 | } 318 | [rs close]; 319 | 320 | if (nCount > 0){ 321 | ret = [db executeUpdate:[sqlArray objectAtIndex:1]]; 322 | if ([db hadError]){ 323 | block(NO, [db lastErrorMessage], rollback); 324 | NSLog(@"executeSql Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 325 | } 326 | } 327 | } 328 | block(ret, nil, rollback); 329 | }]; 330 | } 331 | 332 | /* 333 | * @brief 批量处理更新或者新增sql语句,并且不需要返回记录集,使用事务处理 334 | * 335 | * @param sqlStrList sql语句数组update或者insert into语句 336 | * 337 | * @param block 返回执行结果的block 338 | */ 339 | -(void)executeTransactionSqlList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block 340 | { 341 | __block BOOL bRet = NO; 342 | [_dbQueue inTransaction:^(FMDatabase *db, BOOL *rollback){ 343 | 344 | for (NSString *sqlStr in sqlStrList) 345 | { 346 | bRet = [db executeUpdate:sqlStr]; 347 | if ([db hadError]) 348 | { 349 | block(bRet, [db lastErrorMessage], rollback); 350 | NSLog(@"executeSQLList Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 351 | break; 352 | } 353 | } 354 | block(bRet, nil, rollback); 355 | }]; 356 | } 357 | 358 | /* 359 | * @brief 批量处理更新或者新增sql语句,并且不需要返回记录集 使用dbQueue2 防止嵌套 死循环 360 | * 361 | * @param sqlStrArr sql语句数组update或者insert into语句 362 | * 363 | * @param block 返回执行结果的block 364 | */ 365 | -(void)executeDbQueue2TransactionSqlList:(NSArray *)sqlStrArr withBlock:(void(^)(BOOL bRet, NSString *msg, BOOL *bRollback))block 366 | { 367 | __block BOOL bRet = NO; 368 | NSLog(@"开始插入啦---"); 369 | [_dbQueue2 inTransaction:^(FMDatabase *db, BOOL *rollback){ 370 | 371 | for (NSString *sqlStr in sqlStrArr) 372 | { 373 | bRet = [db executeUpdate:sqlStr]; 374 | if ([db hadError]) 375 | { 376 | block(bRet, [db lastErrorMessage], rollback); 377 | NSLog(@"executeSQLList Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 378 | break; 379 | } 380 | } 381 | block(bRet, nil, rollback); 382 | }]; 383 | } 384 | 385 | /** 386 | * @brief 批量处理更新或者新增sql语句,不需要返回记录集 无事务处理 387 | * 388 | * @param sqlStrList sql语句数组update或者insert into语句 389 | * @param db FMDatabase数据库对象 390 | * @param block 返回执行结果的block 391 | */ 392 | - (void)executeSQLList:(NSArray *)sqlStrList db:(FMDatabase *)db withBlock:(void(^)(BOOL bRet, NSString *msg))block{ 393 | __block BOOL bRet = NO; 394 | for (NSString * sqlString in sqlStrList) { 395 | bRet = [db executeUpdate:sqlString]; 396 | if ([db hadError]) { 397 | block(bRet,[db lastErrorMessage]); 398 | NSLog(@"executeSQLList Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 399 | break; 400 | } 401 | } 402 | block(bRet,nil); 403 | 404 | } 405 | 406 | 407 | /** 408 | * @brief 批量处理更新或者新增sql语句,不需要返回记录集 无事务处理 409 | * 410 | * @param sqlStrList sql语句数组update或者insert into语句 411 | * @param block 返回执行结果的block 412 | */ 413 | - (void)executeSQLList:(NSArray *)sqlStrList withBlock:(void(^)(BOOL bRet, NSString *msg))block{ 414 | __block BOOL bRet = NO; 415 | [_dbQueue inDatabase:^(FMDatabase *db) { 416 | for (NSString * sql in sqlStrList) { 417 | bRet = [db executeUpdate:sql]; 418 | if ([db hadError]) { 419 | block(bRet,[db lastErrorMessage]); 420 | NSLog(@"executeSQLList Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); 421 | break; 422 | } 423 | } 424 | }]; 425 | block(bRet,nil); 426 | } 427 | //插入创建表数组 428 | - (NSArray *)setSqliArray{ 429 | NSMutableArray * sqlList = @[].mutableCopy; 430 | [sqlList addObject:ST_TB_CREATE_BOOKINFO]; 431 | [sqlList addObject:ST_DB_CREATE_BOOKCHAPTERINFO]; 432 | [sqlList addObject:ST_TB_CREATE_CFG]; 433 | return sqlList; 434 | } 435 | - (void)clearDb{ 436 | 437 | } 438 | @end 439 | -------------------------------------------------------------------------------- /STDBTest/STDB/Table.h: -------------------------------------------------------------------------------- 1 | // 2 | // Table.h 3 | // STReader 4 | // 5 | // Created by StriEver on 16/8/19. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #ifndef Table_h 10 | #define Table_h 11 | #import "DBDefine.h" 12 | #define ST_DB_CREATE_BOOKCHAPTERINFO @"CREATE TABLE IF NOT EXISTS bookChapterProgressInfo (bookId INTEGER primary key, bookName tetx,Chapter integer,SecChapter integer,currentPageIdx integer)" 13 | 14 | #define ST_TB_CREATE_CFG @"CREATE TABLE IF NOT EXISTS readerCfg (cfgId text , state INTEGER ,fontSize Single)" 15 | 16 | #define ST_TB_CREATE_BOOKINFO @"CREATE TABLE IF NOT EXISTS bookInfoTable (bookId text primary key,file_version text,hot_sort text,pic text,name text,path text,time double)" 17 | #endif /* Table_h */ 18 | -------------------------------------------------------------------------------- /STDBTest/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // STDBTest 4 | // 5 | // Created by StriEver on 16/9/25. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /STDBTest/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // STDBTest 4 | // 5 | // Created by StriEver on 16/9/25. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "STDBTool.h" 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | 20 | // dispatch_queue_t queue1 = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_SERIAL); 21 | // dispatch_queue_t queue2 = dispatch_queue_create("com.dispatch.seria2", DISPATCH_QUEUE_SERIAL); 22 | // dispatch_sync(queue1, ^{ 23 | // NSLog(@"执行1%@",[NSThread currentThread]); 24 | // dispatch_sync(queue2, ^{ 25 | // NSLog(@"执行2%@",[NSThread currentThread]); 26 | //   }); 27 | //  }); 28 | // Do any additional setup after loading the view, typically from a nib. 29 | [STDBTool shareInstance]; 30 | //[self useTransactionInsertData]; 31 | [self insertData]; 32 | 33 | 34 | } 35 | //使用事务插入1000000数据 36 | - (void)useTransactionInsertData{ 37 | NSMutableArray * sqlList = @[].mutableCopy; 38 | for (int i = 0 ;i < 100;i ++) { 39 | NSString * sql = [NSString stringWithFormat:@"INSERT INTO %@ (bookId,file_version,hot_sort,pic,name,path,time) VALUES (%d,'%@','%@','%@','%@','%@',%f)",ST_TB_NAME_BOOKINFO,i,@"2",@"2.0.1",@"pic",@"网络小说",@"path",[[NSDate date]timeIntervalSince1970]]; 40 | [sqlList addObject:sql]; 41 | } 42 | NSLog(@"开始插入数据%@",[NSDate date]); 43 | [[STDBTool shareInstance]executeTransactionSqlList:sqlList withBlock:^(BOOL bRet, NSString *msg, BOOL *bRollback) { 44 | NSLog(@"插入数据成功%@",[NSDate date]); 45 | }]; 46 | } 47 | - (void)insertData{ 48 | NSMutableArray * sqlList = @[].mutableCopy; 49 | for (int i = 1000000 ;i < 2000000;i ++) { 50 | NSString * sql = [NSString stringWithFormat:@"INSERT INTO %@ (bookId,file_version,hot_sort,pic,name,path,time) VALUES (%d,'%@','%@','%@','%@','%@',%f)",ST_TB_NAME_BOOKINFO,i,@"2",@"2.0.1",@"pic",@"网络小说",@"path",[[NSDate date]timeIntervalSince1970]]; 51 | [sqlList addObject:sql]; 52 | } 53 | NSLog(@"无事务处理开始插入数据%@",[NSDate date]); 54 | [[STDBTool shareInstance]executeSQLList:sqlList withBlock:^(BOOL bRet, NSString *msg) { 55 | NSLog(@"无事务处理插入完成数据%@",[NSDate date]); 56 | }];; 57 | } 58 | 59 | - (void)didReceiveMemoryWarning { 60 | [super didReceiveMemoryWarning]; 61 | // Dispose of any resources that can be recreated. 62 | } 63 | 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /STDBTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // STDBTest 4 | // 5 | // Created by StriEver on 16/9/25. 6 | // Copyright © 2016年 StriEver. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /podfile: -------------------------------------------------------------------------------- 1 | platform :ios, '7.0' 2 | inhibit_all_warnings! 3 | pod 'FMDB' 4 | --------------------------------------------------------------------------------