123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- //
- // 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"
- @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;
- }
- #if SQLITE_VERSION_NUMBER >= 3007017
- - (uint32_t)applicationID {
-
- uint32_t r = 0;
-
- FMResultSet *rs = [self executeQuery:@"pragma application_id"];
-
- if ([rs next]) {
- r = (uint32_t)[rs longLongIntForColumnIndex:0];
- }
-
- [rs close];
-
- return r;
- }
- - (void)setApplicationID:(uint32_t)appID {
- NSString *query = [NSString stringWithFormat:@"pragma application_id=%d", appID];
- FMResultSet *rs = [self executeQuery:query];
- [rs next];
- [rs close];
- }
- #if TARGET_OS_MAC && !TARGET_OS_IPHONE
- - (NSString*)applicationIDString {
- NSString *s = NSFileTypeForHFSTypeCode([self applicationID]);
-
- assert([s length] == 6);
-
- s = [s substringWithRange:NSMakeRange(1, 4)];
-
-
- return s;
-
- }
- - (void)setApplicationIDString:(NSString*)s {
-
- if ([s length] != 4) {
- NSLog(@"setApplicationIDString: string passed is not exactly 4 chars long. (was %ld)", [s length]);
- }
-
- [self setApplicationID:NSHFSTypeCodeFromFileType([NSString stringWithFormat:@"'%@'", s])];
- }
- #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
|