Browse Source

Added methods to execute a query or update with an NSString-style format string

Dave DeLong 15 years ago
parent
commit
c8ff945f52
2 changed files with 122 additions and 0 deletions
  1. 2 0
      src/FMDatabase.h
  2. 120 0
      src/FMDatabase.m

+ 2 - 0
src/FMDatabase.h

@@ -48,10 +48,12 @@
 
 - (BOOL)update:(NSString*)sql error:(NSError**)outErr bind:(id)bindArgs, ...;
 - (BOOL)executeUpdate:(NSString*)sql, ...;
+- (BOOL)executeUpdateWithFormat:(NSString *)format, ...;
 - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments;
 - (BOOL)executeUpdate:(NSString*)sql error:(NSError**)outErr withArgumentsInArray:(NSArray*)arrayArgs orVAList:(va_list)args; // you shouldn't ever need to call this.  use the previous two instead.
 
 - (FMResultSet *)executeQuery:(NSString*)sql, ...;
+- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...;
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments;
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orVAList:(va_list)args; // you shouldn't ever need to call this.  use the previous two instead.
 

+ 120 - 0
src/FMDatabase.m

@@ -297,6 +297,100 @@ - (void)bindObject:(id)obj toColumn:(int)idx inStatement:(sqlite3_stmt*)pStmt {
     }
 }
 
+- (void)_extractSQL:(NSString *)sql argumentsList:(va_list)args intoString:(NSMutableString *)cleanedSQL arguments:(NSMutableArray *)arguments {
+	NSUInteger length = [sql length];
+	unichar last = '\0';
+	for (NSUInteger i = 0; i < length; ++i) {
+		id arg = nil;
+		unichar current = [sql characterAtIndex:i];
+		unichar add = current;
+		if (last == '%') {
+			switch (current) {
+				case '@':
+					arg = va_arg(args, id); break;
+				case 'c':
+					arg = [NSNumber numberWithChar:va_arg(args, char)]; break;
+				case 's':
+					arg = [NSString stringWithUTF8String:va_arg(args, char*)]; break;
+				case 'd':
+				case 'D':
+				case 'i':
+					arg = [NSNumber numberWithInt:va_arg(args, int)]; break;
+				case 'u':
+				case 'U':
+					arg = [NSNumber numberWithUnsignedInt:va_arg(args, unsigned int)]; break;
+				case 'h':
+					i++;
+					if (i < length && [sql characterAtIndex:i] == 'i') {
+						arg = [NSNumber numberWithShort:va_arg(args, short)];
+					} else if (i < length && [sql characterAtIndex:i] == 'u') {
+						arg = [NSNumber numberWithUnsignedShort:va_arg(args, unsigned short)];
+					} else {
+						i--;
+					}
+					break;
+				case 'q':
+					i++;
+					if (i < length && [sql characterAtIndex:i] == 'i') {
+						arg = [NSNumber numberWithLongLong:va_arg(args, long long)];
+					} else if (i < length && [sql characterAtIndex:i] == 'u') {
+						arg = [NSNumber numberWithUnsignedLongLong:va_arg(args, unsigned long long)];
+					} else {
+						i--;
+					}
+					break;
+				case 'f':
+					arg = [NSNumber numberWithDouble:va_arg(args, double)]; break;
+				case 'g':
+					arg = [NSNumber numberWithFloat:va_arg(args, float)]; break;
+				case 'l':
+					i++;
+					if (i < length) {
+						unichar next = [sql characterAtIndex:i];
+						if (next == 'l') {
+							i++;
+							if (i < length && [sql characterAtIndex:i] == 'd') {
+								//%lld
+								arg = [NSNumber numberWithLongLong:va_arg(args, long long)];
+							} else if (i < length && [sql characterAtIndex:i] == 'u') {
+								//%llu
+								arg = [NSNumber numberWithUnsignedLongLong:va_arg(args, unsigned long long)];
+							} else {
+								i--;
+							}
+						} else if (next == 'd') {
+							//%ld
+							arg = [NSNumber numberWithLong:va_arg(args, long)];
+						} else if (next == 'u') {
+							//%lu
+							arg = [NSNumber numberWithUnsignedLong:va_arg(args, unsigned long)];
+						} else {
+							i--;
+						}
+					} else {
+						i--;
+					}
+					break;
+				default:
+					// something else that we can't interpret. just pass it on through like normal
+					break;
+			}
+		} else if (current == '%') {
+			// percent sign; skip this character
+			add = '\0';
+		}
+		
+		if (arg != nil) {
+			[cleanedSQL appendString:@"?"];
+			[arguments addObject:arg];
+		} else if (add != '\0') {
+			[cleanedSQL appendFormat:@"%C", add];
+		}
+		last = current;
+	}
+	
+}
+
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray*)arrayArgs orVAList:(va_list)args {
     
     if (inUse) {
@@ -428,6 +522,19 @@ - (FMResultSet *)executeQuery:(NSString*)sql, ... {
     return result;
 }
 
+- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ... {
+	va_list args;
+	va_start(args, format);
+	
+	NSMutableString *sql = [NSMutableString stringWithCapacity:[format length]];
+	NSMutableArray *arguments = [NSMutableArray array];
+	[self _extractSQL:format argumentsList:args intoString:sql arguments:arguments];	
+	
+	va_end(args);
+	
+	return [self executeQuery:sql withArgumentsInArray:arguments];
+}
+
 - (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments {
     return [self executeQuery:sql withArgumentsInArray:arguments orVAList:nil];
 }
@@ -623,6 +730,19 @@ - (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments {
     return [self executeUpdate:sql error:nil withArgumentsInArray:arguments orVAList:nil];
 }
 
+- (BOOL)executeUpdateWithFormat:(NSString*)format, ... {
+	va_list args;
+	va_start(args, format);
+	
+	NSMutableString *sql = [NSMutableString stringWithCapacity:[format length]];
+	NSMutableArray *arguments = [NSMutableArray array];
+	[self _extractSQL:format argumentsList:args intoString:sql arguments:arguments];	
+	
+	va_end(args);
+	
+	return [self executeUpdate:sql withArgumentsInArray:arguments];
+}
+
 - (BOOL)update:(NSString*)sql error:(NSError**)outErr bind:(id)bindArgs, ... {
     va_list args;
     va_start(args, bindArgs);