| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, |
| software distributed under the License is distributed on an |
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| KIND, either express or implied. See the License for the |
| specific language governing permissions and limitations |
| under the License. |
| */ |
| |
| #import "CMISQueryStatement.h" |
| |
| static NSDateFormatter *cmisQueryStatementTimeStampFormatter; |
| |
| @interface CMISQueryStatement () |
| |
| @property (nonatomic, strong) NSString* statement; |
| @property (nonatomic, strong) NSMutableDictionary *parametersDictionary; |
| |
| @end |
| |
| @implementation CMISQueryStatement |
| |
| - (id)initWithStatement:(NSString*)statement { |
| self = [super init]; |
| if (self) { |
| self.statement = statement; |
| self.parametersDictionary = [NSMutableDictionary dictionary]; |
| } |
| |
| return self; |
| } |
| |
| - (void)setTypeAtIndex:(NSUInteger)parameterIndex type:(NSString*)type { |
| if (type && type.length > 0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeString:type withSurroundingQuotes:NO]; |
| } |
| } |
| |
| - (void)setPropertyAtIndex:(NSUInteger)parameterIndex property:(NSString*)property { |
| if (property && property.length > 0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeString:property withSurroundingQuotes:NO]; |
| } |
| } |
| |
| - (void)setNumberAtIndex:(NSUInteger)parameterIndex number:(NSNumber*)number { |
| if (number) { |
| self.parametersDictionary[@(parameterIndex)] = number; |
| } |
| } |
| |
| - (void)setStringAtIndex:(NSUInteger)parameterIndex string:(NSString*)string { |
| if (string && string.length > 0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeString:string withSurroundingQuotes:YES]; |
| } |
| } |
| |
| - (void)setStringLikeAtIndex:(NSUInteger)parameterIndex string:(NSString*)string { |
| if (string && string.length > 0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeLike:string]; |
| } |
| } |
| |
| - (void)setStringContainsAtIndex:(NSUInteger)parameterIndex string:(NSString*)string { |
| if (string && string.length > 0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeContains:string]; |
| } |
| } |
| |
| - (void)setStringArrayAtIndex:(NSUInteger)parameterIndex stringArray:(NSArray*)stringArray { |
| NSMutableString *paramStr = [NSMutableString string]; |
| for (NSString *value in stringArray) { |
| if ([value isKindOfClass:NSString.class] && value.length > 0) { |
| [paramStr appendFormat:@"%@, ", [CMISQueryStatement escapeString:value withSurroundingQuotes:YES]]; |
| } |
| } |
| if (paramStr.length > 2) { |
| self.parametersDictionary[@(parameterIndex)] = [paramStr substringToIndex:paramStr.length-2]; |
| } else { |
| self.parametersDictionary[@(parameterIndex)] = [NSString string]; // Empty list |
| } |
| } |
| |
| - (void)setUrlAtIndex:(NSUInteger)parameterIndex url:(NSURL*)url { |
| if (url) { |
| NSError *error; |
| NSString *urlString = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error]; |
| if (!error && urlString && urlString.length >0) { |
| self.parametersDictionary[@(parameterIndex)] = [CMISQueryStatement escapeString:urlString withSurroundingQuotes:YES]; |
| } |
| } |
| } |
| |
| - (void)setBooleanAtIndex:(NSUInteger)parameterIndex boolean:(BOOL)boolean { |
| self.parametersDictionary[@(parameterIndex)] = boolean ? @"TRUE" : @"FALSE"; |
| } |
| |
| - (void)setDateTimeAtIndex:(NSUInteger)parameterIndex date:(NSDate*)date { |
| if (date) { |
| self.parametersDictionary[@(parameterIndex)] = [NSString stringWithFormat:@"TIMESTAMP '%@'", [CMISQueryStatement convert:date]]; |
| } |
| } |
| |
| |
| - (NSString*)queryString { |
| BOOL inStr = false; |
| NSUInteger parameterIndex = 0; |
| |
| NSMutableString *retStr = [NSMutableString string]; |
| |
| for (NSUInteger i = 0; i < self.statement.length; i++) { |
| unichar c = [self.statement characterAtIndex:i]; |
| |
| if (c == '\'') { |
| if (inStr && [retStr characterAtIndex:i - 1] == '\\') { |
| inStr = true; |
| } else { |
| inStr = !inStr; |
| } |
| [retStr appendString:[NSString stringWithCharacters:&c length:1]]; |
| } else if (c == '?' && !inStr) { |
| parameterIndex++; |
| NSObject *parameter = self.parametersDictionary[@(parameterIndex)]; |
| NSString *paramValue = nil; |
| if ([parameter isKindOfClass:NSString.class]) { |
| paramValue = (NSString*)parameter; |
| } else if ([parameter isKindOfClass:NSNumber.class]) { |
| paramValue = [(NSNumber*)parameter stringValue]; |
| } |
| if (paramValue) { |
| // Replace placeholder |
| [retStr appendString:paramValue]; |
| } |
| } else { |
| [retStr appendString:[NSString stringWithCharacters:&c length:1]]; |
| } |
| } |
| |
| return retStr; |
| } |
| |
| #pragma mark - Escaping methods |
| |
| + (NSString*)escapeString:(NSString*)string withSurroundingQuotes:(BOOL)quotes { |
| NSMutableString *escapedString = [NSMutableString string]; |
| [escapedString appendString:quotes ? @"'" : @"" ]; |
| for (NSUInteger i = 0; i < string.length; i++) { |
| unichar c = [string characterAtIndex:i]; |
| |
| if (c == '\'' || c == '\\') { |
| [escapedString appendString:@"\\"]; |
| } |
| |
| [escapedString appendString:[NSString stringWithCharacters:&c length:1]]; |
| } |
| |
| if (quotes) { |
| [escapedString appendString:@"\'"]; |
| } |
| |
| return escapedString; |
| } |
| |
| + (NSString*)escapeLike:(NSString*)string { |
| NSMutableString *escapedString = [NSMutableString stringWithString:@"'"]; |
| for (NSUInteger i = 0; i < string.length; i++) { |
| unichar c = [string characterAtIndex:i]; |
| |
| if (c == '\'') { |
| [escapedString appendString:@"\\"]; |
| } else if (c == '\\') { |
| if (i + 1 < string.length && ([string characterAtIndex:(i + 1)] == '%' || [string characterAtIndex:(i + 1)] == '_')) { |
| // no additional back slash |
| } else { |
| [escapedString appendString:@"\\"]; |
| } |
| } |
| |
| [escapedString appendString:[NSString stringWithCharacters:&c length:1]]; |
| } |
| |
| [escapedString appendString:@"\'"]; |
| return escapedString; |
| } |
| |
| + (NSString*)escapeContains:(NSString*)string { |
| NSMutableString *escapedString = [NSMutableString stringWithString:@"'"]; |
| for (NSUInteger i = 0; i < string.length; i++) { |
| unichar c = [string characterAtIndex:i]; |
| |
| if (c == '\\') { |
| [escapedString appendString:@"\\"]; |
| } else if (c == '\'' || c == '\"') { |
| [escapedString appendString:@"\\\\\\"]; |
| } |
| |
| [escapedString appendString:[NSString stringWithCharacters:&c length:1]]; |
| } |
| |
| [escapedString appendString:@"\'"]; |
| return escapedString; |
| } |
| |
| + (NSString*)convert:(NSDate*)date { |
| if (!cmisQueryStatementTimeStampFormatter) { |
| cmisQueryStatementTimeStampFormatter = [[NSDateFormatter alloc] init]; |
| cmisQueryStatementTimeStampFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"; |
| cmisQueryStatementTimeStampFormatter.calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; |
| cmisQueryStatementTimeStampFormatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"]; |
| } |
| |
| return [cmisQueryStatementTimeStampFormatter stringFromDate:date]; |
| } |
| |
| @end |