From 26fa4fe52624cea3ec2403b2381f1212e4d4247f Mon Sep 17 00:00:00 2001 From: Fahim Farook Date: Fri, 13 Jun 2014 15:30:40 +0800 Subject: [PATCH] Added String extension to handle substring operations, Completed code to determine column data type --- SQLiteDB.swift | 178 ++++++++++++++++++++----------------------------- 1 file changed, 73 insertions(+), 105 deletions(-) diff --git a/SQLiteDB.swift b/SQLiteDB.swift index 7c1a9ad..4dc9092 100644 --- a/SQLiteDB.swift +++ b/SQLiteDB.swift @@ -9,6 +9,31 @@ import Foundation import UIKit +extension String { + func positionOf(sub:String)->Int { + var pos = -1 + let range = self.rangeOfString(sub) + pos = distance(self.startIndex, range.startIndex) + return pos + } + + func subStringFrom(pos:Int)->String { + var substr = "" + let start = advance(self.startIndex, pos) + let range = start...self.endIndex + substr = self[range] + return substr + } + + func subStringTo(pos:Int)->String { + var substr = "" + let end = advance(self.startIndex, pos-1) + let range = self.startIndex...end + substr = self[range] + return substr + } +} + class SQLiteDB { let DB_NAME:CString = "data.db" var db:COpaquePointer = nil @@ -146,7 +171,7 @@ class SQLiteDB { var fetchColumnInfo = true var columnCount:CInt = 0 var columnNames = String[]() - var columnTypes = String[]() + var columnTypes = CInt[]() result = sqlite3_step(stmt) while result == SQLITE_ROW { // Should we get column info? @@ -179,8 +204,7 @@ class SQLiteDB { // SQL escape string func esc(str: String)->String { var cstr:CString = str.bridgeToObjectiveC().cString() -// var ptr:CMutablePointer = &cstr -// cstr = sqlite3_vmprintf("%Q", CVaListPointer(fromUnsafePointer: ptr)) +// cstr = sqlite3_vmprintf("%Q", CVaListPointer(fromUnsafePointer: &cstr)) return "" } @@ -210,9 +234,51 @@ class SQLiteDB { } // Get column type - func getColumnType(index:CInt, stmt:COpaquePointer)->String { - var type = "" - + func getColumnType(index:CInt, stmt:COpaquePointer)->CInt { + var type:CInt = 0 + // Column types - http://www.sqlite.org/datatype3.html (section 2.2 table column 1) + let blobTypes = ["BINARY", "BLOB", "VARBINARY"] + let charTypes = ["CHAR", "CHARACTER", "CLOB", "NATIONAL VARYING CHARACTER", "NATIVE CHARACTER", "NCHAR", "NVARCHAR", "TEXT", "VARCHAR", "VARIANT", "VARYING CHARACTER"] + let dateTypes = ["DATE", "DATETIME", "TIME", "TIMESTAMP"] + let intTypes = ["BIGINT", "BIT", "BOOL", "BOOLEAN", "INT", "INT2", "INT8", "INTEGER", "MEDIUMINT", "SMALLINT", "TINYINT"] + let nullTypes = ["NULL"] + let realTypes = ["DECIMAL", "DOUBLE", "DOUBLE PRECISION", "FLOAT", "NUMERIC", "REAL"] + // Determine type of column - http://www.sqlite.org/c3ref/c_blob.html + let buf:CString? = sqlite3_column_decltype(stmt, index) + println("SQLiteDB - Got column type: \(buf)") + if (buf) { + var tmp = String.fromCString(buf!).uppercaseString + // Remove brackets + let pos = tmp.positionOf("(") + if pos > 0 { + tmp = tmp.subStringTo(pos) + } + // Remove unsigned? + // Remove spaces + // Is the data type in any of the pre-set values? + println("SQLiteDB - Cleaned up column type: \(tmp)") + if contains(intTypes, tmp) { + return SQLITE_INTEGER + } + if contains(realTypes, tmp) { + return SQLITE_FLOAT + } + if contains(charTypes, tmp) { + return SQLITE_TEXT + } + if contains(blobTypes, tmp) { + return SQLITE_BLOB + } + if contains(nullTypes, tmp) { + return SQLITE_NULL + } + if contains(dateTypes, tmp) { + return SQLITE_NULL + 1 + } + return SQLITE_TEXT + } else { + type = sqlite3_column_type(stmt, index) + } return type } @@ -224,102 +290,4 @@ class SQLiteDB { value = String.fromCString(cstr) return value } -} - -/* --(id)columnValueAtIndex:(int)column withColumnType:(int)columnType inStatement:(sqlite3_stmt *)statement { - if (columnType == SQLITE_INTEGER) { - return @(sqlite3_column_int(statement, column)); - } - if (columnType == SQLITE_FLOAT) { - return [[NSDecimalNumber alloc] initWithDouble:sqlite3_column_double(statement, column)]; - } - if (columnType == SQLITE_TEXT) { - const char *text = (const char *)sqlite3_column_text(statement, column); - if (text != NULL) { - return @(text); - } - } - if (columnType == SQLITE_BLOB) { - return [NSData dataWithBytes:sqlite3_column_blob(statement, column) length:sqlite3_column_bytes(statement, column)]; - } - if (columnType == SQLITE_DATE) { - const char *text = (const char *)sqlite3_column_text(statement, column); - if (text != NULL) { - NSString *buf = @(text); - NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"-:"]; - if ([buf rangeOfCharacterFromSet:set].location != NSNotFound) { - time_t t; - struct tm tm; - strptime([buf cStringUsingEncoding:NSUTF8StringEncoding], "%Y-%m-%d %H:%M:%S", &tm); - tm.tm_isdst = -1; - t = mktime(&tm); - return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]]; - } - } - return [[NSDecimalNumber alloc] initWithDouble:sqlite3_column_double(statement, column)]; - } - return [NSNull null]; -} - - --(NSString *)esc:(NSString *)str { - if (!str || [str length] == 0) { - return @""; - } - return @(sqlite3_mprintf("%Q", [str cStringUsingEncoding:NSUTF8StringEncoding])); -} - --(NSArray *)query:(NSString *)sql { - return [self query:sql asObject:[NSMutableDictionary class]]; -} - - --(SEL)selectorForSettingColumnName:(NSString *)column { - return NSSelectorFromString([NSString stringWithFormat:@"set%@:", [NSString capitalizeFirstCharacterInString:column]]); -} - --(int)columnTypeAtIndex:(int)column inStatement:(sqlite3_stmt *)statement { - // Declared data types - http://www.sqlite.org/datatype3.html (section 2.2 table column 1) - const NSSet *blobTypes = [NSSet setWithObjects:@"BINARY", @"BLOB", @"VARBINARY", nil]; - const NSSet *charTypes = [NSSet setWithObjects:@"CHAR", @"CHARACTER", @"CLOB", @"NATIONAL VARYING CHARACTER", @"NATIVE CHARACTER", @"NCHAR", @"NVARCHAR", @"TEXT", @"VARCHAR", @"VARIANT", @"VARYING CHARACTER", nil]; - const NSSet *dateTypes = [NSSet setWithObjects:@"DATE", @"DATETIME", @"TIME", @"TIMESTAMP", nil]; - const NSSet *intTypes = [NSSet setWithObjects:@"BIGINT", @"BIT", @"BOOL", @"BOOLEAN", @"INT", @"INT2", @"INT8", @"INTEGER", @"MEDIUMINT", @"SMALLINT", @"TINYINT", nil]; - const NSSet *nullTypes = [NSSet setWithObjects:@"NULL", nil]; - const NSSet *realTypes = [NSSet setWithObjects:@"DECIMAL", @"DOUBLE", @"DOUBLE PRECISION", @"FLOAT", @"NUMERIC", @"REAL", nil]; - // Determine data type of the column - http://www.sqlite.org/c3ref/c_blob.html - const char *columnType = (const char *)sqlite3_column_decltype(statement, column); - if (columnType != NULL) { - NSString *dataType = [@(columnType) uppercaseString]; - NSRange end = [dataType rangeOfString:@"("]; - if (end.location != NSNotFound) { - dataType = [dataType substringWithRange:NSMakeRange(0, end.location)]; - } - if ([dataType hasPrefix:@"UNSIGNED"]) { - dataType = [dataType substringWithRange:NSMakeRange(0, 8)]; - } - dataType = [dataType stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; - if ([intTypes containsObject:dataType]) { - return SQLITE_INTEGER; - } - if ([realTypes containsObject:dataType]) { - return SQLITE_FLOAT; - } - if ([charTypes containsObject:dataType]) { - return SQLITE_TEXT; - } - if ([blobTypes containsObject:dataType]) { - return SQLITE_BLOB; - } - if ([nullTypes containsObject:dataType]) { - return SQLITE_NULL; - } - if ([dateTypes containsObject:dataType]) { - return SQLITE_DATE; - } - return SQLITE_TEXT; - } - return sqlite3_column_type(statement, column); -} - -*/ +} \ No newline at end of file