1

I'm looking for a quick way to debug my SQLite queries in an iOS app. I have something like this:

NSString *sql = [NSString stringWithString: @"SELECT * FROM table WHERE foo = ? AND bar = ?"]; 
NSArray *params = [NSArray arrayWithObjects: @"baz", @"bat", nil];
NSLog(@"%@ %@", sql, params);

I'd like to know if there is a one or two-liner to replace the question marks with the params to make the output more readable. I'm not looking for something that outputs valid sql but rather something easier to read than my current NSLog.

1 Answer 1

1
@interface NSString (SQLQueryDebugging)
- (NSString *)stringBySubstitutingParameters:(NSArray *)params forInstancesOfPlaceholder:(NSString *)placeholder;
@end

@implementation NSString (SQLQueryDebugging)

- (NSString *)stringBySubstitutingParameters:(NSArray *)params forInstancesOfPlaceholder:(NSString *)placeholder
{
    NSString *composedQuery = self;
    NSRange substitutionRange = [composedQuery rangeOfString:placeholder];
    NSInteger parameterIndex = 0;
    while(substitutionRange.length != 0)
    {
        NSString *currentParam = [params objectAtIndex:parameterIndex];
        composedQuery = [composedQuery stringByReplacingCharactersInRange:substitutionRange withString:currentParam];
        ++parameterIndex;
        NSInteger lastSubstitutionIndex = substitutionRange.location + [currentParam length];
        NSRange searchRange = NSMakeRange(lastSubstitutionIndex, [composedQuery length] - lastSubstitutionIndex);
        substitutionRange = [composedQuery rangeOfString:placeholder options:0 range:searchRange];
    }

    return composedQuery;
}

Drop that in somewhere, then you can get what you want with:

NSString *completeSQL = [sql stringBySubstitutingParameters:params forInstancesOfPlaceholder:@"?"];
Sign up to request clarification or add additional context in comments.

2 Comments

As a beginning Objective-C developer I haven't had the chance to really use Categories for much. This is a great example! I had to modify it a little bit to add a check for when currentParam is an NSNumber. Since this always expects a string, it will crash. Other than that, it's a perfect one-liner! Thanks!
Glad this worked for you. I thought about the case where you might have non-string parameters and almost suggested that you use [currentParam description] instead of currentParam where appropriate. Glad you figured it out on your own :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.