ios demo version

This commit is contained in:
Semyon Babushkin
2017-10-19 14:46:44 +03:00
parent 1b98b320d2
commit 1e9ddbf3a9
145 changed files with 18395 additions and 208 deletions

10
ios/Pods/FMDB/src/fmdb/FMDB.h generated Normal file
View File

@@ -0,0 +1,10 @@
#import <Foundation/Foundation.h>
FOUNDATION_EXPORT double FMDBVersionNumber;
FOUNDATION_EXPORT const unsigned char FMDBVersionString[];
#import "FMDatabase.h"
#import "FMResultSet.h"
#import "FMDatabaseAdditions.h"
#import "FMDatabaseQueue.h"
#import "FMDatabasePool.h"

1162
ios/Pods/FMDB/src/fmdb/FMDatabase.h generated Normal file

File diff suppressed because it is too large Load Diff

1479
ios/Pods/FMDB/src/fmdb/FMDatabase.m generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,278 @@
//
// FMDatabaseAdditions.h
// fmdb
//
// Created by August Mueller on 10/30/05.
// Copyright 2005 Flying Meat Inc.. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "FMDatabase.h"
/** Category of additions for `<FMDatabase>` class.
### See also
- `<FMDatabase>`
*/
@interface FMDatabase (FMDatabaseAdditions)
///----------------------------------------
/// @name Return results of SQL to variable
///----------------------------------------
/** Return `int` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `int` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (int)intForQuery:(NSString*)query, ...;
/** Return `long` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `long` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (long)longForQuery:(NSString*)query, ...;
/** Return `BOOL` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `BOOL` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (BOOL)boolForQuery:(NSString*)query, ...;
/** Return `double` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `double` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (double)doubleForQuery:(NSString*)query, ...;
/** Return `NSString` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `NSString` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (NSString*)stringForQuery:(NSString*)query, ...;
/** Return `NSData` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `NSData` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (NSData*)dataForQuery:(NSString*)query, ...;
/** Return `NSDate` value for query
@param query The SQL query to be performed.
@param ... A list of parameters that will be bound to the `?` placeholders in the SQL query.
@return `NSDate` value.
@note To use this method from Swift, you must include `FMDatabaseAdditionsVariadic.swift` in your project.
*/
- (NSDate*)dateForQuery:(NSString*)query, ...;
// Notice that there's no dataNoCopyForQuery:.
// That would be a bad idea, because we close out the result set, and then what
// happens to the data that we just didn't copy? Who knows, not I.
///--------------------------------
/// @name Schema related operations
///--------------------------------
/** Does table exist in database?
@param tableName The name of the table being looked for.
@return `YES` if table found; `NO` if not found.
*/
- (BOOL)tableExists:(NSString*)tableName;
/** The schema of the database.
This will be the schema for the entire database. For each entity, each row of the result set will include the following fields:
- `type` - The type of entity (e.g. table, index, view, or trigger)
- `name` - The name of the object
- `tbl_name` - The name of the table to which the object references
- `rootpage` - The page number of the root b-tree page for tables and indices
- `sql` - The SQL that created the entity
@return `FMResultSet` of schema; `nil` on error.
@see [SQLite File Format](http://www.sqlite.org/fileformat.html)
*/
- (FMResultSet*)getSchema;
/** The schema of the database.
This will be the schema for a particular table as report by SQLite `PRAGMA`, for example:
PRAGMA table_info('employees')
This will report:
- `cid` - The column ID number
- `name` - The name of the column
- `type` - The data type specified for the column
- `notnull` - whether the field is defined as NOT NULL (i.e. values required)
- `dflt_value` - The default value for the column
- `pk` - Whether the field is part of the primary key of the table
@param tableName The name of the table for whom the schema will be returned.
@return `FMResultSet` of schema; `nil` on error.
@see [table_info](http://www.sqlite.org/pragma.html#pragma_table_info)
*/
- (FMResultSet*)getTableSchema:(NSString*)tableName;
/** Test to see if particular column exists for particular table in database
@param columnName The name of the column.
@param tableName The name of the table.
@return `YES` if column exists in table in question; `NO` otherwise.
*/
- (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName;
/** Test to see if particular column exists for particular table in database
@param columnName The name of the column.
@param tableName The name of the table.
@return `YES` if column exists in table in question; `NO` otherwise.
@see columnExists:inTableWithName:
@warning Deprecated - use `<columnExists:inTableWithName:>` instead.
*/
- (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated));
/** Validate SQL statement
This validates SQL statement by performing `sqlite3_prepare_v2`, but not returning the results, but instead immediately calling `sqlite3_finalize`.
@param sql The SQL statement being validated.
@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.
@return `YES` if validation succeeded without incident; `NO` otherwise.
*/
- (BOOL)validateSQL:(NSString*)sql error:(NSError**)error;
///-----------------------------------
/// @name Application identifier tasks
///-----------------------------------
/** Retrieve application ID
@return The `uint32_t` numeric value of the application ID.
@see setApplicationID:
*/
- (uint32_t)applicationID;
/** Set the application ID
@param appID The `uint32_t` numeric value of the application ID.
@see applicationID
*/
- (void)setApplicationID:(uint32_t)appID;
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
/** Retrieve application ID string
@return The `NSString` value of the application ID.
@see setApplicationIDString:
*/
- (NSString*)applicationIDString;
/** Set the application ID string
@param string The `NSString` value of the application ID.
@see applicationIDString
*/
- (void)setApplicationIDString:(NSString*)string;
#endif
///-----------------------------------
/// @name user version identifier tasks
///-----------------------------------
/** Retrieve user version
@return The `uint32_t` numeric value of the user version.
@see setUserVersion:
*/
- (uint32_t)userVersion;
/** Set the user-version
@param version The `uint32_t` numeric value of the user version.
@see userVersion
*/
- (void)setUserVersion:(uint32_t)version;
@end

View File

@@ -0,0 +1,246 @@
//
// FMDatabaseAdditions.m
// fmdb
//
// Created by August Mueller on 10/30/05.
// Copyright 2005 Flying Meat Inc.. All rights reserved.
//
#import "FMDatabase.h"
#import "FMDatabaseAdditions.h"
#import "TargetConditionals.h"
#if FMDB_SQLITE_STANDALONE
#import <sqlite3/sqlite3.h>
#else
#import <sqlite3.h>
#endif
@interface FMDatabase (PrivateStuff)
- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orDictionary:(NSDictionary *)dictionaryArgs orVAList:(va_list)args;
@end
@implementation FMDatabase (FMDatabaseAdditions)
#define RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(type, sel) \
va_list args; \
va_start(args, query); \
FMResultSet *resultSet = [self executeQuery:query withArgumentsInArray:0x00 orDictionary:0x00 orVAList:args]; \
va_end(args); \
if (![resultSet next]) { return (type)0; } \
type ret = [resultSet sel:0]; \
[resultSet close]; \
[resultSet setParentDB:nil]; \
return ret;
- (NSString*)stringForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSString *, stringForColumnIndex);
}
- (int)intForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(int, intForColumnIndex);
}
- (long)longForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(long, longForColumnIndex);
}
- (BOOL)boolForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(BOOL, boolForColumnIndex);
}
- (double)doubleForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(double, doubleForColumnIndex);
}
- (NSData*)dataForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSData *, dataForColumnIndex);
}
- (NSDate*)dateForQuery:(NSString*)query, ... {
RETURN_RESULT_FOR_QUERY_WITH_SELECTOR(NSDate *, dateForColumnIndex);
}
- (BOOL)tableExists:(NSString*)tableName {
tableName = [tableName lowercaseString];
FMResultSet *rs = [self executeQuery:@"select [sql] from sqlite_master where [type] = 'table' and lower(name) = ?", tableName];
//if at least one next exists, table exists
BOOL returnBool = [rs next];
//close and free object
[rs close];
return returnBool;
}
/*
get table with list of tables: result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING]
check if table exist in database (patch from OZLB)
*/
- (FMResultSet*)getSchema {
//result colums: type[STRING], name[STRING],tbl_name[STRING],rootpage[INTEGER],sql[STRING]
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"];
return rs;
}
/*
get table schema: result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER]
*/
- (FMResultSet*)getTableSchema:(NSString*)tableName {
//result colums: cid[INTEGER], name,type [STRING], notnull[INTEGER], dflt_value[],pk[INTEGER]
FMResultSet *rs = [self executeQuery:[NSString stringWithFormat: @"pragma table_info('%@')", tableName]];
return rs;
}
- (BOOL)columnExists:(NSString*)columnName inTableWithName:(NSString*)tableName {
BOOL returnBool = NO;
tableName = [tableName lowercaseString];
columnName = [columnName lowercaseString];
FMResultSet *rs = [self getTableSchema:tableName];
//check if column is present in table schema
while ([rs next]) {
if ([[[rs stringForColumn:@"name"] lowercaseString] isEqualToString:columnName]) {
returnBool = YES;
break;
}
}
//If this is not done FMDatabase instance stays out of pool
[rs close];
return returnBool;
}
- (uint32_t)applicationID {
#if SQLITE_VERSION_NUMBER >= 3007017
uint32_t r = 0;
FMResultSet *rs = [self executeQuery:@"pragma application_id"];
if ([rs next]) {
r = (uint32_t)[rs longLongIntForColumnIndex:0];
}
[rs close];
return r;
#else
NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
return 0;
#endif
}
- (void)setApplicationID:(uint32_t)appID {
#if SQLITE_VERSION_NUMBER >= 3007017
NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID];
FMResultSet *rs = [self executeQuery:query];
[rs next];
[rs close];
#else
NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
#endif
}
#if TARGET_OS_MAC && !TARGET_OS_IPHONE
- (NSString*)applicationIDString {
#if SQLITE_VERSION_NUMBER >= 3007017
NSString *s = NSFileTypeForHFSTypeCode([self applicationID]);
assert([s length] == 6);
s = [s substringWithRange:NSMakeRange(1, 4)];
return s;
#else
NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
return nil;
#endif
}
- (void)setApplicationIDString:(NSString*)s {
#if SQLITE_VERSION_NUMBER >= 3007017
if ([s length] != 4) {
NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]);
}
[self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])];
#else
NSString *errorMessage = NSLocalizedString(@"Application ID functions require SQLite 3.7.17", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
#endif
}
#endif
- (uint32_t)userVersion {
uint32_t r = 0;
FMResultSet *rs = [self executeQuery:@"pragma user_version"];
if ([rs next]) {
r = (uint32_t)[rs longLongIntForColumnIndex:0];
}
[rs close];
return r;
}
- (void)setUserVersion:(uint32_t)version {
NSString *query = [NSString stringWithFormat:@"pragma user_version = %d", version];
FMResultSet *rs = [self executeQuery:query];
[rs next];
[rs close];
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (BOOL)columnExists:(NSString*)tableName columnName:(NSString*)columnName __attribute__ ((deprecated)) {
return [self columnExists:columnName inTableWithName:tableName];
}
#pragma clang diagnostic pop
- (BOOL)validateSQL:(NSString*)sql error:(NSError**)error {
sqlite3_stmt *pStmt = NULL;
BOOL validationSucceeded = YES;
int rc = sqlite3_prepare_v2(_db, [sql UTF8String], -1, &pStmt, 0);
if (rc != SQLITE_OK) {
validationSucceeded = NO;
if (error) {
*error = [NSError errorWithDomain:NSCocoaErrorDomain
code:[self lastErrorCode]
userInfo:[NSDictionary dictionaryWithObject:[self lastErrorMessage]
forKey:NSLocalizedDescriptionKey]];
}
}
sqlite3_finalize(pStmt);
return validationSucceeded;
}
@end

200
ios/Pods/FMDB/src/fmdb/FMDatabasePool.h generated Normal file
View File

@@ -0,0 +1,200 @@
//
// FMDatabasePool.h
// fmdb
//
// Created by August Mueller on 6/22/11.
// Copyright 2011 Flying Meat Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@class FMDatabase;
/** Pool of `<FMDatabase>` objects.
### See also
- `<FMDatabaseQueue>`
- `<FMDatabase>`
@warning Before using `FMDatabasePool`, please consider using `<FMDatabaseQueue>` instead.
If you really really really know what you're doing and `FMDatabasePool` is what
you really really need (ie, you're using a read only database), OK you can use
it. But just be careful not to deadlock!
For an example on deadlocking, search for:
`ONLY_USE_THE_POOL_IF_YOU_ARE_DOING_READS_OTHERWISE_YOULL_DEADLOCK_USE_FMDATABASEQUEUE_INSTEAD`
in the main.m file.
*/
@interface FMDatabasePool : NSObject {
NSString *_path;
dispatch_queue_t _lockQueue;
NSMutableArray *_databaseInPool;
NSMutableArray *_databaseOutPool;
__unsafe_unretained id _delegate;
NSUInteger _maximumNumberOfDatabasesToCreate;
int _openFlags;
}
/** Database path */
@property (atomic, retain) NSString *path;
/** Delegate object */
@property (atomic, assign) id delegate;
/** Maximum number of databases to create */
@property (atomic, assign) NSUInteger maximumNumberOfDatabasesToCreate;
/** Open flags */
@property (atomic, readonly) int openFlags;
///---------------------
/// @name Initialization
///---------------------
/** Create pool using path.
@param aPath The file path of the database.
@return The `FMDatabasePool` object. `nil` on error.
*/
+ (instancetype)databasePoolWithPath:(NSString*)aPath;
/** Create pool using path and specified flags
@param aPath The file path of the database.
@param openFlags Flags passed to the openWithFlags method of the database
@return The `FMDatabasePool` object. `nil` on error.
*/
+ (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags;
/** Create pool using path.
@param aPath The file path of the database.
@return The `FMDatabasePool` object. `nil` on error.
*/
- (instancetype)initWithPath:(NSString*)aPath;
/** Create pool using path and specified flags.
@param aPath The file path of the database.
@param openFlags Flags passed to the openWithFlags method of the database
@return The `FMDatabasePool` object. `nil` on error.
*/
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags;
///------------------------------------------------
/// @name Keeping track of checked in/out databases
///------------------------------------------------
/** Number of checked-in databases in pool
@returns Number of databases
*/
- (NSUInteger)countOfCheckedInDatabases;
/** Number of checked-out databases in pool
@returns Number of databases
*/
- (NSUInteger)countOfCheckedOutDatabases;
/** Total number of databases in pool
@returns Number of databases
*/
- (NSUInteger)countOfOpenDatabases;
/** Release all databases in pool */
- (void)releaseAllDatabases;
///------------------------------------------
/// @name Perform database operations in pool
///------------------------------------------
/** Synchronously perform database operations in pool.
@param block The code to be run on the `FMDatabasePool` pool.
*/
- (void)inDatabase:(void (^)(FMDatabase *db))block;
/** Synchronously perform database operations in pool using transaction.
@param block The code to be run on the `FMDatabasePool` pool.
*/
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
/** Synchronously perform database operations in pool using deferred transaction.
@param block The code to be run on the `FMDatabasePool` pool.
*/
- (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
/** Synchronously perform database operations in pool using save point.
@param block The code to be run on the `FMDatabasePool` pool.
@return `NSError` object if error; `nil` if successful.
@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.
*/
- (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block;
@end
/** FMDatabasePool delegate category
This is a category that defines the protocol for the FMDatabasePool delegate
*/
@interface NSObject (FMDatabasePoolDelegate)
/** Asks the delegate whether database should be added to the pool.
@param pool The `FMDatabasePool` object.
@param database The `FMDatabase` object.
@return `YES` if it should add database to pool; `NO` if not.
*/
- (BOOL)databasePool:(FMDatabasePool*)pool shouldAddDatabaseToPool:(FMDatabase*)database;
/** Tells the delegate that database was added to the pool.
@param pool The `FMDatabasePool` object.
@param database The `FMDatabase` object.
*/
- (void)databasePool:(FMDatabasePool*)pool didAddDatabase:(FMDatabase*)database;
@end

283
ios/Pods/FMDB/src/fmdb/FMDatabasePool.m generated Normal file
View File

@@ -0,0 +1,283 @@
//
// FMDatabasePool.m
// fmdb
//
// Created by August Mueller on 6/22/11.
// Copyright 2011 Flying Meat Inc. All rights reserved.
//
#if FMDB_SQLITE_STANDALONE
#import <sqlite3/sqlite3.h>
#else
#import <sqlite3.h>
#endif
#import "FMDatabasePool.h"
#import "FMDatabase.h"
@interface FMDatabasePool()
- (void)pushDatabaseBackInPool:(FMDatabase*)db;
- (FMDatabase*)db;
@end
@implementation FMDatabasePool
@synthesize path=_path;
@synthesize delegate=_delegate;
@synthesize maximumNumberOfDatabasesToCreate=_maximumNumberOfDatabasesToCreate;
@synthesize openFlags=_openFlags;
+ (instancetype)databasePoolWithPath:(NSString*)aPath {
return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath]);
}
+ (instancetype)databasePoolWithPath:(NSString*)aPath flags:(int)openFlags {
return FMDBReturnAutoreleased([[self alloc] initWithPath:aPath flags:openFlags]);
}
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags {
self = [super init];
if (self != nil) {
_path = [aPath copy];
_lockQueue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
_databaseInPool = FMDBReturnRetained([NSMutableArray array]);
_databaseOutPool = FMDBReturnRetained([NSMutableArray array]);
_openFlags = openFlags;
}
return self;
}
- (instancetype)initWithPath:(NSString*)aPath
{
// default flags for sqlite3_open
return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE];
}
- (instancetype)init {
return [self initWithPath:nil];
}
- (void)dealloc {
_delegate = 0x00;
FMDBRelease(_path);
FMDBRelease(_databaseInPool);
FMDBRelease(_databaseOutPool);
if (_lockQueue) {
FMDBDispatchQueueRelease(_lockQueue);
_lockQueue = 0x00;
}
#if ! __has_feature(objc_arc)
[super dealloc];
#endif
}
- (void)executeLocked:(void (^)(void))aBlock {
dispatch_sync(_lockQueue, aBlock);
}
- (void)pushDatabaseBackInPool:(FMDatabase*)db {
if (!db) { // db can be null if we set an upper bound on the # of databases to create.
return;
}
[self executeLocked:^() {
if ([self->_databaseInPool containsObject:db]) {
[[NSException exceptionWithName:@"Database already in pool" reason:@"The FMDatabase being put back into the pool is already present in the pool" userInfo:nil] raise];
}
[self->_databaseInPool addObject:db];
[self->_databaseOutPool removeObject:db];
}];
}
- (FMDatabase*)db {
__block FMDatabase *db;
[self executeLocked:^() {
db = [self->_databaseInPool lastObject];
BOOL shouldNotifyDelegate = NO;
if (db) {
[self->_databaseOutPool addObject:db];
[self->_databaseInPool removeLastObject];
}
else {
if (self->_maximumNumberOfDatabasesToCreate) {
NSUInteger currentCount = [self->_databaseOutPool count] + [self->_databaseInPool count];
if (currentCount >= self->_maximumNumberOfDatabasesToCreate) {
NSLog(@"Maximum number of databases (%ld) has already been reached!", (long)currentCount);
return;
}
}
db = [FMDatabase databaseWithPath:self->_path];
shouldNotifyDelegate = YES;
}
//This ensures that the db is opened before returning
#if SQLITE_VERSION_NUMBER >= 3005000
BOOL success = [db openWithFlags:self->_openFlags];
#else
BOOL success = [db open];
#endif
if (success) {
if ([self->_delegate respondsToSelector:@selector(databasePool:shouldAddDatabaseToPool:)] && ![self->_delegate databasePool:self shouldAddDatabaseToPool:db]) {
[db close];
db = 0x00;
}
else {
//It should not get added in the pool twice if lastObject was found
if (![self->_databaseOutPool containsObject:db]) {
[self->_databaseOutPool addObject:db];
if (shouldNotifyDelegate && [self->_delegate respondsToSelector:@selector(databasePool:didAddDatabase:)]) {
[self->_delegate databasePool:self didAddDatabase:db];
}
}
}
}
else {
NSLog(@"Could not open up the database at path %@", self->_path);
db = 0x00;
}
}];
return db;
}
- (NSUInteger)countOfCheckedInDatabases {
__block NSUInteger count;
[self executeLocked:^() {
count = [self->_databaseInPool count];
}];
return count;
}
- (NSUInteger)countOfCheckedOutDatabases {
__block NSUInteger count;
[self executeLocked:^() {
count = [self->_databaseOutPool count];
}];
return count;
}
- (NSUInteger)countOfOpenDatabases {
__block NSUInteger count;
[self executeLocked:^() {
count = [self->_databaseOutPool count] + [self->_databaseInPool count];
}];
return count;
}
- (void)releaseAllDatabases {
[self executeLocked:^() {
[self->_databaseOutPool removeAllObjects];
[self->_databaseInPool removeAllObjects];
}];
}
- (void)inDatabase:(void (^)(FMDatabase *db))block {
FMDatabase *db = [self db];
block(db);
[self pushDatabaseBackInPool:db];
}
- (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
BOOL shouldRollback = NO;
FMDatabase *db = [self db];
if (useDeferred) {
[db beginDeferredTransaction];
}
else {
[db beginTransaction];
}
block(db, &shouldRollback);
if (shouldRollback) {
[db rollback];
}
else {
[db commit];
}
[self pushDatabaseBackInPool:db];
}
- (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
[self beginTransaction:YES withBlock:block];
}
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
[self beginTransaction:NO withBlock:block];
}
- (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
#if SQLITE_VERSION_NUMBER >= 3007000
static unsigned long savePointIdx = 0;
NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
BOOL shouldRollback = NO;
FMDatabase *db = [self db];
NSError *err = 0x00;
if (![db startSavePointWithName:name error:&err]) {
[self pushDatabaseBackInPool:db];
return err;
}
block(db, &shouldRollback);
if (shouldRollback) {
// We need to rollback and release this savepoint to remove it
[db rollbackToSavePointWithName:name error:&err];
}
[db releaseSavePointWithName:name error:&err];
[self pushDatabaseBackInPool:db];
return err;
#else
NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}];
#endif
}
@end

182
ios/Pods/FMDB/src/fmdb/FMDatabaseQueue.h generated Normal file
View File

@@ -0,0 +1,182 @@
//
// FMDatabaseQueue.h
// fmdb
//
// Created by August Mueller on 6/22/11.
// Copyright 2011 Flying Meat Inc. All rights reserved.
//
#import <Foundation/Foundation.h>
@class FMDatabase;
/** To perform queries and updates on multiple threads, you'll want to use `FMDatabaseQueue`.
Using a single instance of `<FMDatabase>` from multiple threads at once is a bad idea. It has always been OK to make a `<FMDatabase>` object *per thread*. Just don't share a single instance across threads, and definitely not across multiple threads at the same time.
Instead, use `FMDatabaseQueue`. Here's how to use it:
First, make your queue.
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
Then use it like so:
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
//…
}
}];
An easy way to wrap things up in a transaction can be done like this:
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
if (whoopsSomethingWrongHappened) {
*rollback = YES;
return;
}
// etc…
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];
`FMDatabaseQueue` will run the blocks on a serialized queue (hence the name of the class). So if you 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.
### See also
- `<FMDatabase>`
@warning Do not instantiate a single `<FMDatabase>` object and use it across multiple threads. Use `FMDatabaseQueue` instead.
@warning The calls to `FMDatabaseQueue`'s methods are blocking. So even though you are passing along blocks, they will **not** be run on another thread.
*/
@interface FMDatabaseQueue : NSObject {
NSString *_path;
dispatch_queue_t _queue;
FMDatabase *_db;
int _openFlags;
}
/** Path of database */
@property (atomic, retain) NSString *path;
/** Open flags */
@property (atomic, readonly) int openFlags;
///----------------------------------------------------
/// @name Initialization, opening, and closing of queue
///----------------------------------------------------
/** Create queue using path.
@param aPath The file path of the database.
@return The `FMDatabaseQueue` object. `nil` on error.
*/
+ (instancetype)databaseQueueWithPath:(NSString*)aPath;
/** Create queue using path and specified flags.
@param aPath The file path of the database.
@param openFlags Flags passed to the openWithFlags method of the database
@return The `FMDatabaseQueue` object. `nil` on error.
*/
+ (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags;
/** Create queue using path.
@param aPath The file path of the database.
@return The `FMDatabaseQueue` object. `nil` on error.
*/
- (instancetype)initWithPath:(NSString*)aPath;
/** Create queue using path and specified flags.
@param aPath The file path of the database.
@param openFlags Flags passed to the openWithFlags method of the database
@return The `FMDatabaseQueue` object. `nil` on error.
*/
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags;
/** Create queue using path and specified flags.
@param aPath The file path of the database.
@param openFlags Flags passed to the openWithFlags method of the database
@param vfsName The name of a custom virtual file system
@return The `FMDatabaseQueue` object. `nil` on error.
*/
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName;
/** Returns the Class of 'FMDatabase' subclass, that will be used to instantiate database object.
Subclasses can override this method to return specified Class of 'FMDatabase' subclass.
@return The Class of 'FMDatabase' subclass, that will be used to instantiate database object.
*/
+ (Class)databaseClass;
/** Close database used by queue. */
- (void)close;
///-----------------------------------------------
/// @name Dispatching database operations to queue
///-----------------------------------------------
/** Synchronously perform database operations on queue.
@param block The code to be run on the queue of `FMDatabaseQueue`
*/
- (void)inDatabase:(void (^)(FMDatabase *db))block;
/** Synchronously perform database operations on queue, using transactions.
@param block The code to be run on the queue of `FMDatabaseQueue`
*/
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
/** Synchronously perform database operations on queue, using deferred transactions.
@param block The code to be run on the queue of `FMDatabaseQueue`
*/
- (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block;
///-----------------------------------------------
/// @name Dispatching database operations to queue
///-----------------------------------------------
/** Synchronously perform database operations using save point.
@param block The code to be run on the queue of `FMDatabaseQueue`
*/
// NOTE: 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's startSavePointWithName:error: instead.
- (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block;
@end

245
ios/Pods/FMDB/src/fmdb/FMDatabaseQueue.m generated Normal file
View File

@@ -0,0 +1,245 @@
//
// FMDatabaseQueue.m
// fmdb
//
// Created by August Mueller on 6/22/11.
// Copyright 2011 Flying Meat Inc. All rights reserved.
//
#import "FMDatabaseQueue.h"
#import "FMDatabase.h"
#if FMDB_SQLITE_STANDALONE
#import <sqlite3/sqlite3.h>
#else
#import <sqlite3.h>
#endif
/*
Note: we call [self retain]; before using dispatch_sync, just incase
FMDatabaseQueue is released on another thread and we're in the middle of doing
something in dispatch_sync
*/
/*
* A key used to associate the FMDatabaseQueue object with the dispatch_queue_t it uses.
* This in turn is used for deadlock detection by seeing if inDatabase: is called on
* the queue's dispatch queue, which should not happen and causes a deadlock.
*/
static const void * const kDispatchQueueSpecificKey = &kDispatchQueueSpecificKey;
@implementation FMDatabaseQueue
@synthesize path = _path;
@synthesize openFlags = _openFlags;
+ (instancetype)databaseQueueWithPath:(NSString*)aPath {
FMDatabaseQueue *q = [[self alloc] initWithPath:aPath];
FMDBAutorelease(q);
return q;
}
+ (instancetype)databaseQueueWithPath:(NSString*)aPath flags:(int)openFlags {
FMDatabaseQueue *q = [[self alloc] initWithPath:aPath flags:openFlags];
FMDBAutorelease(q);
return q;
}
+ (Class)databaseClass {
return [FMDatabase class];
}
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags vfs:(NSString *)vfsName {
self = [super init];
if (self != nil) {
_db = [[[self class] databaseClass] databaseWithPath:aPath];
FMDBRetain(_db);
#if SQLITE_VERSION_NUMBER >= 3005000
BOOL success = [_db openWithFlags:openFlags vfs:vfsName];
#else
BOOL success = [_db open];
#endif
if (!success) {
NSLog(@"Could not create database queue for path %@", aPath);
FMDBRelease(self);
return 0x00;
}
_path = FMDBReturnRetained(aPath);
_queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);
dispatch_queue_set_specific(_queue, kDispatchQueueSpecificKey, (__bridge void *)self, NULL);
_openFlags = openFlags;
}
return self;
}
- (instancetype)initWithPath:(NSString*)aPath flags:(int)openFlags {
return [self initWithPath:aPath flags:openFlags vfs:nil];
}
- (instancetype)initWithPath:(NSString*)aPath {
// default flags for sqlite3_open
return [self initWithPath:aPath flags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE vfs:nil];
}
- (instancetype)init {
return [self initWithPath:nil];
}
- (void)dealloc {
FMDBRelease(_db);
FMDBRelease(_path);
if (_queue) {
FMDBDispatchQueueRelease(_queue);
_queue = 0x00;
}
#if ! __has_feature(objc_arc)
[super dealloc];
#endif
}
- (void)close {
FMDBRetain(self);
dispatch_sync(_queue, ^() {
[self->_db close];
FMDBRelease(_db);
self->_db = 0x00;
});
FMDBRelease(self);
}
- (FMDatabase*)database {
if (!_db) {
_db = FMDBReturnRetained([FMDatabase databaseWithPath:_path]);
#if SQLITE_VERSION_NUMBER >= 3005000
BOOL success = [_db openWithFlags:_openFlags];
#else
BOOL success = [_db open];
#endif
if (!success) {
NSLog(@"FMDatabaseQueue could not reopen database for path %@", _path);
FMDBRelease(_db);
_db = 0x00;
return 0x00;
}
}
return _db;
}
- (void)inDatabase:(void (^)(FMDatabase *db))block {
/* Get the currently executing queue (which should probably be nil, but in theory could be another DB queue
* and then check it against self to make sure we're not about to deadlock. */
FMDatabaseQueue *currentSyncQueue = (__bridge id)dispatch_get_specific(kDispatchQueueSpecificKey);
assert(currentSyncQueue != self && "inDatabase: was called reentrantly on the same queue, which would lead to a deadlock");
FMDBRetain(self);
dispatch_sync(_queue, ^() {
FMDatabase *db = [self database];
block(db);
if ([db hasOpenResultSets]) {
NSLog(@"Warning: there is at least one open result set around after performing [FMDatabaseQueue inDatabase:]");
#if defined(DEBUG) && DEBUG
NSSet *openSetCopy = FMDBReturnAutoreleased([[db valueForKey:@"_openResultSets"] copy]);
for (NSValue *rsInWrappedInATastyValueMeal in openSetCopy) {
FMResultSet *rs = (FMResultSet *)[rsInWrappedInATastyValueMeal pointerValue];
NSLog(@"query: '%@'", [rs query]);
}
#endif
}
});
FMDBRelease(self);
}
- (void)beginTransaction:(BOOL)useDeferred withBlock:(void (^)(FMDatabase *db, BOOL *rollback))block {
FMDBRetain(self);
dispatch_sync(_queue, ^() {
BOOL shouldRollback = NO;
if (useDeferred) {
[[self database] beginDeferredTransaction];
}
else {
[[self database] beginTransaction];
}
block([self database], &shouldRollback);
if (shouldRollback) {
[[self database] rollback];
}
else {
[[self database] commit];
}
});
FMDBRelease(self);
}
- (void)inDeferredTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
[self beginTransaction:YES withBlock:block];
}
- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block {
[self beginTransaction:NO withBlock:block];
}
- (NSError*)inSavePoint:(void (^)(FMDatabase *db, BOOL *rollback))block {
#if SQLITE_VERSION_NUMBER >= 3007000
static unsigned long savePointIdx = 0;
__block NSError *err = 0x00;
FMDBRetain(self);
dispatch_sync(_queue, ^() {
NSString *name = [NSString stringWithFormat:@"savePoint%ld", savePointIdx++];
BOOL shouldRollback = NO;
if ([[self database] startSavePointWithName:name error:&err]) {
block([self database], &shouldRollback);
if (shouldRollback) {
// We need to rollback and release this savepoint to remove it
[[self database] rollbackToSavePointWithName:name error:&err];
}
[[self database] releaseSavePointWithName:name error:&err];
}
});
FMDBRelease(self);
return err;
#else
NSString *errorMessage = NSLocalizedString(@"Save point functions require SQLite 3.7", nil);
if (self.logsErrors) NSLog(@"%@", errorMessage);
return [NSError errorWithDomain:@"FMDatabase" code:0 userInfo:@{NSLocalizedDescriptionKey : errorMessage}];
#endif
}
@end

468
ios/Pods/FMDB/src/fmdb/FMResultSet.h generated Normal file
View File

@@ -0,0 +1,468 @@
#import <Foundation/Foundation.h>
#ifndef __has_feature // Optional.
#define __has_feature(x) 0 // Compatibility with non-clang compilers.
#endif
#ifndef NS_RETURNS_NOT_RETAINED
#if __has_feature(attribute_ns_returns_not_retained)
#define NS_RETURNS_NOT_RETAINED __attribute__((ns_returns_not_retained))
#else
#define NS_RETURNS_NOT_RETAINED
#endif
#endif
@class FMDatabase;
@class FMStatement;
/** Represents the results of executing a query on an `<FMDatabase>`.
### See also
- `<FMDatabase>`
*/
@interface FMResultSet : NSObject {
FMDatabase *_parentDB;
FMStatement *_statement;
NSString *_query;
NSMutableDictionary *_columnNameToIndexMap;
}
///-----------------
/// @name Properties
///-----------------
/** Executed query */
@property (atomic, retain) NSString *query;
/** `NSMutableDictionary` mapping column names to numeric index */
@property (readonly) NSMutableDictionary *columnNameToIndexMap;
/** `FMStatement` used by result set. */
@property (atomic, retain) FMStatement *statement;
///------------------------------------
/// @name Creating and closing database
///------------------------------------
/** Create result set from `<FMStatement>`
@param statement A `<FMStatement>` to be performed
@param aDB A `<FMDatabase>` to be used
@return A `FMResultSet` on success; `nil` on failure
*/
+ (instancetype)resultSetWithStatement:(FMStatement *)statement usingParentDatabase:(FMDatabase*)aDB;
/** Close result set */
- (void)close;
- (void)setParentDB:(FMDatabase *)newDb;
///---------------------------------------
/// @name Iterating through the result set
///---------------------------------------
/** Retrieve next row for result set.
You must always invoke `next` or `nextWithError` before attempting to access the values returned in a query, even if you're only expecting one.
@return `YES` if row successfully retrieved; `NO` if end of result set reached
@see hasAnotherRow
*/
- (BOOL)next;
/** Retrieve next row for result set.
You must always invoke `next` or `nextWithError` before attempting to access the values returned in a query, even if you're only expecting one.
@param outErr A 'NSError' object to receive any error object (if any).
@return 'YES' if row successfully retrieved; 'NO' if end of result set reached
@see hasAnotherRow
*/
- (BOOL)nextWithError:(NSError **)outErr;
/** Did the last call to `<next>` succeed in retrieving another row?
@return `YES` if the last call to `<next>` succeeded in retrieving another record; `NO` if not.
@see next
@warning The `hasAnotherRow` method must follow a call to `<next>`. 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.
*/
- (BOOL)hasAnotherRow;
///---------------------------------------------
/// @name Retrieving information from result set
///---------------------------------------------
/** How many columns in result set
@return Integer value of the number of columns.
*/
- (int)columnCount;
/** Column index for column name
@param columnName `NSString` value of the name of the column.
@return Zero-based index for column.
*/
- (int)columnIndexForName:(NSString*)columnName;
/** Column name for column index
@param columnIdx Zero-based index for column.
@return columnName `NSString` value of the name of the column.
*/
- (NSString*)columnNameForIndex:(int)columnIdx;
/** Result set integer value for column.
@param columnName `NSString` value of the name of the column.
@return `int` value of the result set's column.
*/
- (int)intForColumn:(NSString*)columnName;
/** Result set integer value for column.
@param columnIdx Zero-based index for column.
@return `int` value of the result set's column.
*/
- (int)intForColumnIndex:(int)columnIdx;
/** Result set `long` value for column.
@param columnName `NSString` value of the name of the column.
@return `long` value of the result set's column.
*/
- (long)longForColumn:(NSString*)columnName;
/** Result set long value for column.
@param columnIdx Zero-based index for column.
@return `long` value of the result set's column.
*/
- (long)longForColumnIndex:(int)columnIdx;
/** Result set `long long int` value for column.
@param columnName `NSString` value of the name of the column.
@return `long long int` value of the result set's column.
*/
- (long long int)longLongIntForColumn:(NSString*)columnName;
/** Result set `long long int` value for column.
@param columnIdx Zero-based index for column.
@return `long long int` value of the result set's column.
*/
- (long long int)longLongIntForColumnIndex:(int)columnIdx;
/** Result set `unsigned long long int` value for column.
@param columnName `NSString` value of the name of the column.
@return `unsigned long long int` value of the result set's column.
*/
- (unsigned long long int)unsignedLongLongIntForColumn:(NSString*)columnName;
/** Result set `unsigned long long int` value for column.
@param columnIdx Zero-based index for column.
@return `unsigned long long int` value of the result set's column.
*/
- (unsigned long long int)unsignedLongLongIntForColumnIndex:(int)columnIdx;
/** Result set `BOOL` value for column.
@param columnName `NSString` value of the name of the column.
@return `BOOL` value of the result set's column.
*/
- (BOOL)boolForColumn:(NSString*)columnName;
/** Result set `BOOL` value for column.
@param columnIdx Zero-based index for column.
@return `BOOL` value of the result set's column.
*/
- (BOOL)boolForColumnIndex:(int)columnIdx;
/** Result set `double` value for column.
@param columnName `NSString` value of the name of the column.
@return `double` value of the result set's column.
*/
- (double)doubleForColumn:(NSString*)columnName;
/** Result set `double` value for column.
@param columnIdx Zero-based index for column.
@return `double` value of the result set's column.
*/
- (double)doubleForColumnIndex:(int)columnIdx;
/** Result set `NSString` value for column.
@param columnName `NSString` value of the name of the column.
@return `NSString` value of the result set's column.
*/
- (NSString*)stringForColumn:(NSString*)columnName;
/** Result set `NSString` value for column.
@param columnIdx Zero-based index for column.
@return `NSString` value of the result set's column.
*/
- (NSString*)stringForColumnIndex:(int)columnIdx;
/** Result set `NSDate` value for column.
@param columnName `NSString` value of the name of the column.
@return `NSDate` value of the result set's column.
*/
- (NSDate*)dateForColumn:(NSString*)columnName;
/** Result set `NSDate` value for column.
@param columnIdx Zero-based index for column.
@return `NSDate` value of the result set's column.
*/
- (NSDate*)dateForColumnIndex:(int)columnIdx;
/** Result set `NSData` value for column.
This is useful when storing binary data in table (such as image or the like).
@param columnName `NSString` value of the name of the column.
@return `NSData` value of the result set's column.
*/
- (NSData*)dataForColumn:(NSString*)columnName;
/** Result set `NSData` value for column.
@param columnIdx Zero-based index for column.
@return `NSData` value of the result set's column.
*/
- (NSData*)dataForColumnIndex:(int)columnIdx;
/** Result set `(const unsigned char *)` value for column.
@param columnName `NSString` value of the name of the column.
@return `(const unsigned char *)` value of the result set's column.
*/
- (const unsigned char *)UTF8StringForColumnName:(NSString*)columnName;
/** Result set `(const unsigned char *)` value for column.
@param columnIdx Zero-based index for column.
@return `(const unsigned char *)` value of the result set's column.
*/
- (const unsigned char *)UTF8StringForColumnIndex:(int)columnIdx;
/** Result set object for column.
@param columnName `NSString` value of the name of the column.
@return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object.
@see objectForKeyedSubscript:
*/
- (id)objectForColumnName:(NSString*)columnName;
/** Result set object for column.
@param columnIdx Zero-based index for column.
@return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object.
@see objectAtIndexedSubscript:
*/
- (id)objectForColumnIndex:(int)columnIdx;
/** Result set object for column.
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:
id result = rs[@"employee_name"];
This simplified syntax is equivalent to calling:
id result = [rs objectForKeyedSubscript:@"employee_name"];
which is, it turns out, equivalent to calling:
id result = [rs objectForColumnName:@"employee_name"];
@param columnName `NSString` value of the name of the column.
@return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object.
*/
- (id)objectForKeyedSubscript:(NSString *)columnName;
/** Result set object for column.
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:
id result = rs[0];
This simplified syntax is equivalent to calling:
id result = [rs objectForKeyedSubscript:0];
which is, it turns out, equivalent to calling:
id result = [rs objectForColumnName:0];
@param columnIdx Zero-based index for column.
@return Either `NSNumber`, `NSString`, `NSData`, or `NSNull`. If the column was `NULL`, this returns `[NSNull null]` object.
*/
- (id)objectAtIndexedSubscript:(int)columnIdx;
/** Result set `NSData` value for column.
@param columnName `NSString` value of the name of the column.
@return `NSData` value of the result set's column.
@warning If you are going to use this data after you iterate over the next row, or after you close the
result set, make sure to make a copy of the data first (or just use `<dataForColumn:>`/`<dataForColumnIndex:>`)
If you don't, you're going to be in a world of hurt when you try and use the data.
*/
- (NSData*)dataNoCopyForColumn:(NSString*)columnName NS_RETURNS_NOT_RETAINED;
/** Result set `NSData` value for column.
@param columnIdx Zero-based index for column.
@return `NSData` value of the result set's column.
@warning If you are going to use this data after you iterate over the next row, or after you close the
result set, make sure to make a copy of the data first (or just use `<dataForColumn:>`/`<dataForColumnIndex:>`)
If you don't, you're going to be in a world of hurt when you try and use the data.
*/
- (NSData*)dataNoCopyForColumnIndex:(int)columnIdx NS_RETURNS_NOT_RETAINED;
/** Is the column `NULL`?
@param columnIdx Zero-based index for column.
@return `YES` if column is `NULL`; `NO` if not `NULL`.
*/
- (BOOL)columnIndexIsNull:(int)columnIdx;
/** Is the column `NULL`?
@param columnName `NSString` value of the name of the column.
@return `YES` if column is `NULL`; `NO` if not `NULL`.
*/
- (BOOL)columnIsNull:(NSString*)columnName;
/** Returns a dictionary of the row results mapped to case sensitive keys of the column names.
@returns `NSDictionary` of the row results.
@warning The keys to the dictionary are case sensitive of the column names.
*/
- (NSDictionary*)resultDictionary;
/** Returns a dictionary of the row results
@see resultDictionary
@warning **Deprecated**: Please use `<resultDictionary>` instead. Also, beware that `<resultDictionary>` is case sensitive!
*/
- (NSDictionary*)resultDict __attribute__ ((deprecated));
///-----------------------------
/// @name Key value coding magic
///-----------------------------
/** Performs `setValue` to yield support for key value observing.
@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.
*/
- (void)kvcMagic:(id)object;
@end

422
ios/Pods/FMDB/src/fmdb/FMResultSet.m generated Normal file
View File

@@ -0,0 +1,422 @@
#import "FMResultSet.h"
#import "FMDatabase.h"
#import "unistd.h"
#if FMDB_SQLITE_STANDALONE
#import <sqlite3/sqlite3.h>
#else
#import <sqlite3.h>
#endif
@interface FMDatabase ()
- (void)resultSetDidClose:(FMResultSet *)resultSet;
@end
@implementation FMResultSet
@synthesize query=_query;
@synthesize statement=_statement;
+ (instancetype)resultSetWithStatement:(FMStatement *)statement usingParentDatabase:(FMDatabase*)aDB {
FMResultSet *rs = [[FMResultSet alloc] init];
[rs setStatement:statement];
[rs setParentDB:aDB];
NSParameterAssert(![statement inUse]);
[statement setInUse:YES]; // weak reference
return FMDBReturnAutoreleased(rs);
}
- (void)finalize {
[self close];
[super finalize];
}
- (void)dealloc {
[self close];
FMDBRelease(_query);
_query = nil;
FMDBRelease(_columnNameToIndexMap);
_columnNameToIndexMap = nil;
#if ! __has_feature(objc_arc)
[super dealloc];
#endif
}
- (void)close {
[_statement reset];
FMDBRelease(_statement);
_statement = nil;
// we don't need this anymore... (i think)
//[_parentDB setInUse:NO];
[_parentDB resultSetDidClose:self];
_parentDB = nil;
}
- (int)columnCount {
return sqlite3_column_count([_statement statement]);
}
- (NSMutableDictionary *)columnNameToIndexMap {
if (!_columnNameToIndexMap) {
int columnCount = sqlite3_column_count([_statement statement]);
_columnNameToIndexMap = [[NSMutableDictionary alloc] initWithCapacity:(NSUInteger)columnCount];
int columnIdx = 0;
for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
[_columnNameToIndexMap setObject:[NSNumber numberWithInt:columnIdx]
forKey:[[NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)] lowercaseString]];
}
}
return _columnNameToIndexMap;
}
- (void)kvcMagic:(id)object {
int columnCount = sqlite3_column_count([_statement statement]);
int columnIdx = 0;
for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
const char *c = (const char *)sqlite3_column_text([_statement statement], columnIdx);
// check for a null row
if (c) {
NSString *s = [NSString stringWithUTF8String:c];
[object setValue:s forKey:[NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)]];
}
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-implementations"
- (NSDictionary*)resultDict {
NSUInteger num_cols = (NSUInteger)sqlite3_data_count([_statement statement]);
if (num_cols > 0) {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols];
NSEnumerator *columnNames = [[self columnNameToIndexMap] keyEnumerator];
NSString *columnName = nil;
while ((columnName = [columnNames nextObject])) {
id objectValue = [self objectForColumnName:columnName];
[dict setObject:objectValue forKey:columnName];
}
return FMDBReturnAutoreleased([dict copy]);
}
else {
NSLog(@"Warning: There seem to be no columns in this set.");
}
return nil;
}
#pragma clang diagnostic pop
- (NSDictionary*)resultDictionary {
NSUInteger num_cols = (NSUInteger)sqlite3_data_count([_statement statement]);
if (num_cols > 0) {
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:num_cols];
int columnCount = sqlite3_column_count([_statement statement]);
int columnIdx = 0;
for (columnIdx = 0; columnIdx < columnCount; columnIdx++) {
NSString *columnName = [NSString stringWithUTF8String:sqlite3_column_name([_statement statement], columnIdx)];
id objectValue = [self objectForColumnIndex:columnIdx];
[dict setObject:objectValue forKey:columnName];
}
return dict;
}
else {
NSLog(@"Warning: There seem to be no columns in this set.");
}
return nil;
}
- (BOOL)next {
return [self nextWithError:nil];
}
- (BOOL)nextWithError:(NSError **)outErr {
int rc = sqlite3_step([_statement statement]);
if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) {
NSLog(@"%s:%d Database busy (%@)", __FUNCTION__, __LINE__, [_parentDB databasePath]);
NSLog(@"Database busy");
if (outErr) {
*outErr = [_parentDB lastError];
}
}
else if (SQLITE_DONE == rc || SQLITE_ROW == rc) {
// all is well, let's return.
}
else if (SQLITE_ERROR == rc) {
NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle]));
if (outErr) {
*outErr = [_parentDB lastError];
}
}
else if (SQLITE_MISUSE == rc) {
// uh oh.
NSLog(@"Error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle]));
if (outErr) {
if (_parentDB) {
*outErr = [_parentDB lastError];
}
else {
// If 'next' or 'nextWithError' is called after the result set is closed,
// we need to return the appropriate error.
NSDictionary* errorMessage = [NSDictionary dictionaryWithObject:@"parentDB does not exist" forKey:NSLocalizedDescriptionKey];
*outErr = [NSError errorWithDomain:@"FMDatabase" code:SQLITE_MISUSE userInfo:errorMessage];
}
}
}
else {
// wtf?
NSLog(@"Unknown error calling sqlite3_step (%d: %s) rs", rc, sqlite3_errmsg([_parentDB sqliteHandle]));
if (outErr) {
*outErr = [_parentDB lastError];
}
}
if (rc != SQLITE_ROW) {
[self close];
}
return (rc == SQLITE_ROW);
}
- (BOOL)hasAnotherRow {
return sqlite3_errcode([_parentDB sqliteHandle]) == SQLITE_ROW;
}
- (int)columnIndexForName:(NSString*)columnName {
columnName = [columnName lowercaseString];
NSNumber *n = [[self columnNameToIndexMap] objectForKey:columnName];
if (n) {
return [n intValue];
}
NSLog(@"Warning: I could not find the column named '%@'.", columnName);
return -1;
}
- (int)intForColumn:(NSString*)columnName {
return [self intForColumnIndex:[self columnIndexForName:columnName]];
}
- (int)intForColumnIndex:(int)columnIdx {
return sqlite3_column_int([_statement statement], columnIdx);
}
- (long)longForColumn:(NSString*)columnName {
return [self longForColumnIndex:[self columnIndexForName:columnName]];
}
- (long)longForColumnIndex:(int)columnIdx {
return (long)sqlite3_column_int64([_statement statement], columnIdx);
}
- (long long int)longLongIntForColumn:(NSString*)columnName {
return [self longLongIntForColumnIndex:[self columnIndexForName:columnName]];
}
- (long long int)longLongIntForColumnIndex:(int)columnIdx {
return sqlite3_column_int64([_statement statement], columnIdx);
}
- (unsigned long long int)unsignedLongLongIntForColumn:(NSString*)columnName {
return [self unsignedLongLongIntForColumnIndex:[self columnIndexForName:columnName]];
}
- (unsigned long long int)unsignedLongLongIntForColumnIndex:(int)columnIdx {
return (unsigned long long int)[self longLongIntForColumnIndex:columnIdx];
}
- (BOOL)boolForColumn:(NSString*)columnName {
return [self boolForColumnIndex:[self columnIndexForName:columnName]];
}
- (BOOL)boolForColumnIndex:(int)columnIdx {
return ([self intForColumnIndex:columnIdx] != 0);
}
- (double)doubleForColumn:(NSString*)columnName {
return [self doubleForColumnIndex:[self columnIndexForName:columnName]];
}
- (double)doubleForColumnIndex:(int)columnIdx {
return sqlite3_column_double([_statement statement], columnIdx);
}
- (NSString*)stringForColumnIndex:(int)columnIdx {
if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
return nil;
}
const char *c = (const char *)sqlite3_column_text([_statement statement], columnIdx);
if (!c) {
// null row.
return nil;
}
return [NSString stringWithUTF8String:c];
}
- (NSString*)stringForColumn:(NSString*)columnName {
return [self stringForColumnIndex:[self columnIndexForName:columnName]];
}
- (NSDate*)dateForColumn:(NSString*)columnName {
return [self dateForColumnIndex:[self columnIndexForName:columnName]];
}
- (NSDate*)dateForColumnIndex:(int)columnIdx {
if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
return nil;
}
return [_parentDB hasDateFormatter] ? [_parentDB dateFromString:[self stringForColumnIndex:columnIdx]] : [NSDate dateWithTimeIntervalSince1970:[self doubleForColumnIndex:columnIdx]];
}
- (NSData*)dataForColumn:(NSString*)columnName {
return [self dataForColumnIndex:[self columnIndexForName:columnName]];
}
- (NSData*)dataForColumnIndex:(int)columnIdx {
if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
return nil;
}
const char *dataBuffer = sqlite3_column_blob([_statement statement], columnIdx);
int dataSize = sqlite3_column_bytes([_statement statement], columnIdx);
if (dataBuffer == NULL) {
return nil;
}
return [NSData dataWithBytes:(const void *)dataBuffer length:(NSUInteger)dataSize];
}
- (NSData*)dataNoCopyForColumn:(NSString*)columnName {
return [self dataNoCopyForColumnIndex:[self columnIndexForName:columnName]];
}
- (NSData*)dataNoCopyForColumnIndex:(int)columnIdx {
if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
return nil;
}
const char *dataBuffer = sqlite3_column_blob([_statement statement], columnIdx);
int dataSize = sqlite3_column_bytes([_statement statement], columnIdx);
NSData *data = [NSData dataWithBytesNoCopy:(void *)dataBuffer length:(NSUInteger)dataSize freeWhenDone:NO];
return data;
}
- (BOOL)columnIndexIsNull:(int)columnIdx {
return sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL;
}
- (BOOL)columnIsNull:(NSString*)columnName {
return [self columnIndexIsNull:[self columnIndexForName:columnName]];
}
- (const unsigned char *)UTF8StringForColumnIndex:(int)columnIdx {
if (sqlite3_column_type([_statement statement], columnIdx) == SQLITE_NULL || (columnIdx < 0)) {
return nil;
}
return sqlite3_column_text([_statement statement], columnIdx);
}
- (const unsigned char *)UTF8StringForColumnName:(NSString*)columnName {
return [self UTF8StringForColumnIndex:[self columnIndexForName:columnName]];
}
- (id)objectForColumnIndex:(int)columnIdx {
int columnType = sqlite3_column_type([_statement statement], columnIdx);
id returnValue = nil;
if (columnType == SQLITE_INTEGER) {
returnValue = [NSNumber numberWithLongLong:[self longLongIntForColumnIndex:columnIdx]];
}
else if (columnType == SQLITE_FLOAT) {
returnValue = [NSNumber numberWithDouble:[self doubleForColumnIndex:columnIdx]];
}
else if (columnType == SQLITE_BLOB) {
returnValue = [self dataForColumnIndex:columnIdx];
}
else {
//default to a string for everything else
returnValue = [self stringForColumnIndex:columnIdx];
}
if (returnValue == nil) {
returnValue = [NSNull null];
}
return returnValue;
}
- (id)objectForColumnName:(NSString*)columnName {
return [self objectForColumnIndex:[self columnIndexForName:columnName]];
}
// returns autoreleased NSString containing the name of the column in the result set
- (NSString*)columnNameForIndex:(int)columnIdx {
return [NSString stringWithUTF8String: sqlite3_column_name([_statement statement], columnIdx)];
}
- (void)setParentDB:(FMDatabase *)newDb {
_parentDB = newDb;
}
- (id)objectAtIndexedSubscript:(int)columnIdx {
return [self objectForColumnIndex:columnIdx];
}
- (id)objectForKeyedSubscript:(NSString *)columnName {
return [self objectForColumnName:columnName];
}
@end