├── 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 | [](https://www.versioneye.com/objective-c/fmdb/2.3)
19 | [](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 |
--------------------------------------------------------------------------------