From cb00d18102f8c3f88e8a15bb4d9fb7825cf29a59 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 15 Jul 2012 10:15:11 +0000 Subject: Add a new order by class. --- .../QueryKit/QueryKit.xcodeproj/project.pbxproj | 30 +++++- Frameworks/QueryKit/Source/QKQuery.h | 13 ++- Frameworks/QueryKit/Source/QKQuery.m | 101 ++++++++++----------- Frameworks/QueryKit/Source/QKQueryConstruct.h | 55 +++++++++++ Frameworks/QueryKit/Source/QKQueryConstruct.m | 60 ++++++++++++ .../QueryKit/Source/QKQueryGenericParameter.h | 16 +--- .../QueryKit/Source/QKQueryGenericParameter.m | 16 +--- Frameworks/QueryKit/Source/QKQueryOrderBy.h | 60 ++++++++++++ Frameworks/QueryKit/Source/QKQueryOrderBy.m | 81 +++++++++++++++++ .../QueryKit/Source/QKQueryStringAdditions.m | 4 +- Frameworks/QueryKit/Source/QueryKit.h | 1 + .../QueryKit/Tests/QKSelectQueryOrderByTests.m | 28 +++--- Frameworks/QueryKit/Tests/QKUpdateQueryTests.m | 2 + 13 files changed, 362 insertions(+), 105 deletions(-) create mode 100644 Frameworks/QueryKit/Source/QKQueryConstruct.h create mode 100644 Frameworks/QueryKit/Source/QKQueryConstruct.m create mode 100644 Frameworks/QueryKit/Source/QKQueryOrderBy.h create mode 100644 Frameworks/QueryKit/Source/QKQueryOrderBy.m diff --git a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj index decc195b..acdf559c 100644 --- a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj +++ b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj @@ -32,6 +32,10 @@ 17E595F214F3058F0054EE08 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17E595F114F3058F0054EE08 /* Foundation.framework */; }; 17E596A814F308160054EE08 /* QKSelectQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E5969814F307B70054EE08 /* QKSelectQueryTests.m */; }; 17E596A914F308250054EE08 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17E595F114F3058F0054EE08 /* Foundation.framework */; }; + 17F48BA815B27F6400C6455B /* QKQueryOrderBy.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F48BA615B27F6400C6455B /* QKQueryOrderBy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17F48BA915B27F6500C6455B /* QKQueryOrderBy.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F48BA715B27F6400C6455B /* QKQueryOrderBy.m */; }; + 17F48BC315B289C100C6455B /* QKQueryConstruct.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F48BC115B289C100C6455B /* QKQueryConstruct.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17F48BC415B289C100C6455B /* QKQueryConstruct.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F48BC215B289C100C6455B /* QKQueryConstruct.m */; }; 17F620BE14F961C1003E7290 /* QueryKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DC2EF5B0486A6940098B216 /* QueryKit.framework */; }; /* End PBXBuildFile section */ @@ -78,6 +82,10 @@ 17E5969814F307B70054EE08 /* QKSelectQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKSelectQueryTests.m; sourceTree = ""; }; 17E5969E14F307CE0054EE08 /* Tests.octest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.octest; sourceTree = BUILT_PRODUCTS_DIR; }; 17E5969F14F307CE0054EE08 /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Tests-Info.plist"; path = "Resources/Tests-Info.plist"; sourceTree = ""; }; + 17F48BA615B27F6400C6455B /* QKQueryOrderBy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryOrderBy.h; sourceTree = ""; }; + 17F48BA715B27F6400C6455B /* QKQueryOrderBy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQueryOrderBy.m; sourceTree = ""; }; + 17F48BC115B289C100C6455B /* QKQueryConstruct.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryConstruct.h; sourceTree = ""; }; + 17F48BC215B289C100C6455B /* QKQueryConstruct.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQueryConstruct.m; sourceTree = ""; }; 32DBCF5E0370ADEE00C91783 /* QueryKit-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "QueryKit-Prefix.pch"; path = "Source/QueryKit-Prefix.pch"; sourceTree = ""; }; 8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Resources/Info.plist; sourceTree = ""; }; 8DC2EF5B0486A6940098B216 /* QueryKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = QueryKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -161,12 +169,13 @@ 1719E47A151E8C87003F98C5 /* Model */ = { isa = PBXGroup; children = ( + 17F48BC515B28A4D00C6455B /* Common */, + 17F48BA615B27F6400C6455B /* QKQueryOrderBy.h */, + 17F48BA715B27F6400C6455B /* QKQueryOrderBy.m */, 17E5951914F301DF0054EE08 /* QKQueryParameter.h */, 17E5951A14F301DF0054EE08 /* QKQueryParameter.m */, 1719E47B151E8CA7003F98C5 /* QKQueryUpdateParameter.h */, 1719E47C151E8CA7003F98C5 /* QKQueryUpdateParameter.m */, - 1757801C15A9A14400CDF67A /* QKQueryGenericParameter.h */, - 1757801D15A9A14400CDF67A /* QKQueryGenericParameter.m */, ); name = Model; sourceTree = ""; @@ -221,7 +230,6 @@ 17577FC315A99AA500CDF67A /* Other */ = { isa = PBXGroup; children = ( - 17577FC415A99AC000CDF67A /* QKQueryConstants.h */, 1726979315AEE939009586E1 /* QKQueryStringAdditions.h */, 1726979415AEE939009586E1 /* QKQueryStringAdditions.m */, ); @@ -234,6 +242,7 @@ 17E5951B14F301DF0054EE08 /* QKQueryTypes.h */, 17E5951814F301DF0054EE08 /* QKQueryOperators.h */, 1726976515AC3DD2009586E1 /* QKQueryDatabases.h */, + 17577FC415A99AC000CDF67A /* QKQueryConstants.h */, ); name = Constants; sourceTree = ""; @@ -250,6 +259,17 @@ path = Tests; sourceTree = ""; }; + 17F48BC515B28A4D00C6455B /* Common */ = { + isa = PBXGroup; + children = ( + 17F48BC115B289C100C6455B /* QKQueryConstruct.h */, + 17F48BC215B289C100C6455B /* QKQueryConstruct.m */, + 1757801C15A9A14400CDF67A /* QKQueryGenericParameter.h */, + 1757801D15A9A14400CDF67A /* QKQueryGenericParameter.m */, + ); + name = Common; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -268,6 +288,8 @@ 1757801E15A9A14400CDF67A /* QKQueryGenericParameter.h in Headers */, 1726976715AC3DD2009586E1 /* QKQueryDatabases.h in Headers */, 1726979515AEE939009586E1 /* QKQueryStringAdditions.h in Headers */, + 17F48BA815B27F6400C6455B /* QKQueryOrderBy.h in Headers */, + 17F48BC315B289C100C6455B /* QKQueryConstruct.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -387,6 +409,8 @@ 1719E47E151E8CA7003F98C5 /* QKQueryUpdateParameter.m in Sources */, 1757801F15A9A14400CDF67A /* QKQueryGenericParameter.m in Sources */, 1726979615AEE939009586E1 /* QKQueryStringAdditions.m in Sources */, + 17F48BA915B27F6500C6455B /* QKQueryOrderBy.m in Sources */, + 17F48BC415B289C100C6455B /* QKQueryConstruct.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Frameworks/QueryKit/Source/QKQuery.h b/Frameworks/QueryKit/Source/QKQuery.h index 117da9b3..9eb0a621 100644 --- a/Frameworks/QueryKit/Source/QKQuery.h +++ b/Frameworks/QueryKit/Source/QKQuery.h @@ -31,8 +31,10 @@ #import "QKQueryTypes.h" #import "QKQueryDatabases.h" #import "QKQueryOperators.h" -#import "QKQueryParameter.h" -#import "QKQueryUpdateParameter.h" + +@class QKQueryOrderBy; +@class QKQueryParameter; +@class QKQueryUpdateParameter; /** * @class QKQuery QKQuery.h @@ -59,7 +61,6 @@ QKQueryDatabase _queryDatabase; BOOL _useQuotedIdentifiers; - BOOL _orderDescending; } /** @@ -100,7 +101,7 @@ /** * @property _useQuotedIdentifiers Indicates whether or not the query's fields should be quoted. */ -@property(readwrite, assign, getter=useQuotedIdentifiers) BOOL _useQuotedIdentifiers; +@property(readwrite, assign, getter=useQuotedIdentifiers, setter=setUseQuotedIdentifiers:) BOOL _useQuotedIdentifiers; /** * @property _groupByFields The group by fields of the query. @@ -129,8 +130,6 @@ - (NSString *)query; - (void)clear; -- (void)setUseQuotedIdentifiers:(BOOL)quote; - - (void)addField:(NSString *)field; - (void)addFields:(NSArray *)fields; @@ -143,7 +142,7 @@ - (void)groupByField:(NSString *)field; - (void)groupByFields:(NSArray *)fields; +- (void)orderBy:(QKQueryOrderBy *)orderBy; - (void)orderByField:(NSString *)field descending:(BOOL)descending; -- (void)orderByFields:(NSArray *)fields descending:(BOOL)descending; @end diff --git a/Frameworks/QueryKit/Source/QKQuery.m b/Frameworks/QueryKit/Source/QKQuery.m index 3834bd82..01dfa1fc 100644 --- a/Frameworks/QueryKit/Source/QKQuery.m +++ b/Frameworks/QueryKit/Source/QKQuery.m @@ -29,8 +29,12 @@ // OTHER DEALINGS IN THE SOFTWARE. #import "QKQuery.h" +#import "QKQueryTypes.h" +#import "QKQueryOrderBy.h" #import "QKQueryUtilities.h" #import "QKQueryConstants.h" +#import "QKQueryParameter.h" +#import "QKQueryUpdateParameter.h" #import "QKQueryGenericParameter.h" static NSString *QKNoQueryTypeException = @"QKNoQueryType"; @@ -39,6 +43,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; @interface QKQuery () - (void)_validateRequiements; +- (void)_configureQuoteIdentifiers; - (NSString *)_buildQuery; - (NSString *)_buildFieldList; @@ -117,7 +122,6 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; // Default to MySQL [self setQueryDatabase:QKDatabaseMySQL]; - _orderDescending = NO; _identifierQuote = EMPTY_STRING; _groupByFields = [[NSMutableArray alloc] init]; @@ -164,29 +168,6 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; if (_query) [_query release], _query = [[NSMutableString alloc] init]; } -#pragma mark - -#pragma mark Accessors - -/** - * Sets whether to quote identifiers in the query. - * - * @param quote A BOOL indicating whether quoting should be used. - */ -- (void)setUseQuotedIdentifiers:(BOOL)quote -{ - _useQuotedIdentifiers = quote; - - for (QKQueryParameter *param in _parameters) - { - [param setUseQuotedIdentifier:_useQuotedIdentifiers]; - } - - for (QKQueryUpdateParameter *param in _updateParameters) - { - [param setUseQuotedIdentifier:_useQuotedIdentifiers]; - } -} - #pragma mark - #pragma mark Fields @@ -295,30 +276,26 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; #pragma mark Ordering /** - * Adds the supplied field to the query's ORDER BY clause. + * Adds the supplied order by instance to this query. * - * @param field The field to ORDER BY. - * @param descending Indicates whether the ORDER BY should be descending. + * @param orderBy The order by instance to add. */ -- (void)orderByField:(NSString *)field descending:(BOOL)descending +- (void)orderBy:(QKQueryOrderBy *)orderBy { - _orderDescending = descending; - - [self _addString:field toArray:_orderByFields]; + if ([orderBy orderByField] && [[orderBy orderByField] length] > 0) { + [_orderByFields addObject:orderBy]; + } } /** - * Convenience method for adding more than one field to the query's ORDER BY clause. + * Convenience method for adding a field to ORDER BY. * - * @param fields An array of fields to ORDER BY. + * @param field The field to ORDER BY. * @param descending Indicates whether the ORDER BY should be descending. */ -- (void)orderByFields:(NSArray *)fields descending:(BOOL)descending +- (void)orderByField:(NSString *)field descending:(BOOL)descending { - for (NSString *field in fields) - { - [self orderByField:field descending:descending]; - } + [self orderBy:[QKQueryOrderBy orderByField:field descending:descending]]; } #pragma mark - @@ -338,6 +315,32 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; } } +/** + * Configures the query's parameters, update parameters and order by field's quote identifier settings. + */ +- (void)_configureQuoteIdentifiers +{ + _identifierQuote = [QKQueryUtilities identifierQuoteCharacterForDatabase:_queryDatabase]; + + for (QKQueryParameter *param in _parameters) + { + [param setIdentifierQuote:_identifierQuote]; + [param setUseQuotedIdentifier:_useQuotedIdentifiers]; + } + + for (QKQueryOrderBy *orderBy in _orderByFields) + { + [orderBy setIdentifierQuote:_identifierQuote]; + [orderBy setUseQuotedIdentifier:_useQuotedIdentifiers]; + } + + for (QKQueryUpdateParameter *param in _updateParameters) + { + [param setIdentifierQuote:_identifierQuote]; + [param setUseQuotedIdentifier:_useQuotedIdentifiers]; + } +} + /** * Builds the actual query. * @@ -352,18 +355,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; BOOL isUpdate = _queryType == QKUpdateQuery; BOOL isDelete = _queryType == QKDeleteQuery; - if ([self useQuotedIdentifiers]) { - _identifierQuote = [QKQueryUtilities identifierQuoteCharacterForDatabase:_queryDatabase]; - - for (QKQueryParameter *param in _parameters) - { - [param setIdentifierQuote:_identifierQuote]; - } - - for (QKQueryUpdateParameter *param in _updateParameters) - { - [param setIdentifierQuote:_identifierQuote]; - } + if (_useQuotedIdentifiers) { + [self _configureQuoteIdentifiers]; } NSString *fields = [self _buildFieldList]; @@ -495,17 +488,15 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; [orderBy appendString:@"ORDER BY "]; - for (NSString *field in _orderByFields) + for (NSString *orderByField in _orderByFields) { - [orderBy appendFormat:@"%1$@%2$@%1$@, ", _identifierQuote, field]; + [orderBy appendFormat:@"%@, ", orderByField]; } if ([orderBy hasSuffix:@", "]) { [orderBy setString:[orderBy substringToIndex:([orderBy length] - 2)]]; } - - [orderBy appendString:_orderDescending ? @" DESC" : @" ASC"]; - + return orderBy; } diff --git a/Frameworks/QueryKit/Source/QKQueryConstruct.h b/Frameworks/QueryKit/Source/QKQueryConstruct.h new file mode 100644 index 00000000..be3ab220 --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryConstruct.h @@ -0,0 +1,55 @@ +// +// $Id$ +// +// QKQueryConstruct.h +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on July 15, 2012 +// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +/** + * @class QKQueryConstruct QKQueryConstruct.h + * + * @author Stuart Connolly http://stuconnolly.com/ + * + * Acts as a base of all SQL constructs and provides various common properties. + */ +@interface QKQueryConstruct : NSObject +{ + BOOL _useQuotedIdentifier; + + NSString *_identiferQuote; +} + +/** + * @property _identifierQuote The quoute character to use for identifiers. + */ +@property(readwrite, retain, getter=identifierQuote, setter=setIdentifierQuote:) NSString *_identiferQuote; + +/** + * @property _useQuotedIdentifier Indicates whether or not identifiers should be quoted. + */ +@property(readwrite, assign, getter=useQuotedIdentifier, setter=setUseQuotedIdentifier:) BOOL _useQuotedIdentifier; + +@end diff --git a/Frameworks/QueryKit/Source/QKQueryConstruct.m b/Frameworks/QueryKit/Source/QKQueryConstruct.m new file mode 100644 index 00000000..db432add --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryConstruct.m @@ -0,0 +1,60 @@ +// +// $Id$ +// +// QKQueryConstruct.m +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on July 15, 2012 +// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#import "QKQueryConstruct.h" + +@implementation QKQueryConstruct + +@synthesize _useQuotedIdentifier; +@synthesize _identiferQuote; + +#pragma mark - +#pragma mark Initialisation + +- (id)init +{ + if ((self = [super init])) { + [self setUseQuotedIdentifier:YES]; + [self setIdentifierQuote:EMPTY_STRING]; + } + + return self; +} + +#pragma mark - + +- (void)dealloc +{ + if (_identiferQuote) [_identiferQuote release], _identiferQuote = nil; + + [super dealloc]; +} + +@end diff --git a/Frameworks/QueryKit/Source/QKQueryGenericParameter.h b/Frameworks/QueryKit/Source/QKQueryGenericParameter.h index 562689f5..1c782b6a 100644 --- a/Frameworks/QueryKit/Source/QKQueryGenericParameter.h +++ b/Frameworks/QueryKit/Source/QKQueryGenericParameter.h @@ -28,13 +28,13 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. -@interface QKQueryGenericParameter : NSObject +#import "QKQueryConstruct.h" + +@interface QKQueryGenericParameter : QKQueryConstruct { id _value; - BOOL _useQuotedIdentifier; NSString *_field; - NSString *_identiferQuote; } /** @@ -42,16 +42,6 @@ */ @property(readwrite, retain, getter=field, setter=setField:) NSString *_field; -/** - * @property _identifierQuote - */ -@property(readwrite, retain, getter=identifierQuote, setter=setIdentifierQuote:) NSString *_identiferQuote; - -/** - * @property _useQuotedIdentifier Indicates whether or not this parameters field should be quoted. - */ -@property(readwrite, assign, getter=useQuotedIdentifier, setter=setUseQuotedIdentifier:) BOOL _useQuotedIdentifier; - /** *@property _value The value component of the parameter. */ diff --git a/Frameworks/QueryKit/Source/QKQueryGenericParameter.m b/Frameworks/QueryKit/Source/QKQueryGenericParameter.m index efaf10d3..57fe58c7 100644 --- a/Frameworks/QueryKit/Source/QKQueryGenericParameter.m +++ b/Frameworks/QueryKit/Source/QKQueryGenericParameter.m @@ -28,28 +28,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. +#import "QKQueryConstruct.h" #import "QKQueryGenericParameter.h" @implementation QKQueryGenericParameter @synthesize _field; -@synthesize _useQuotedIdentifier; -@synthesize _identiferQuote; @synthesize _value; -#pragma mark - -#pragma mark Initialisation - -- (id)init -{ - if ((self = [super init])) { - [self setUseQuotedIdentifier:YES]; - [self setIdentifierQuote:EMPTY_STRING]; - } - - return self; -} - #pragma mark - - (void)dealloc diff --git a/Frameworks/QueryKit/Source/QKQueryOrderBy.h b/Frameworks/QueryKit/Source/QKQueryOrderBy.h new file mode 100644 index 00000000..aa7a80e7 --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryOrderBy.h @@ -0,0 +1,60 @@ +// +// $Id$ +// +// QKQueryOrderBy.h +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on July 15, 2012 +// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#import "QKQueryConstruct.h" + +/** + * @class QKQueryOrderBy QKQueryOrderBy.h + * + * @author Stuart Connolly http://stuconnolly.com/ + * + * QueryKit SELECT query ORDER BY class. + */ +@interface QKQueryOrderBy : QKQueryConstruct +{ + NSString *_orderByField; + BOOL _orderByDescending; +} + +/** + * @property _orderByField + */ +@property(readwrite, retain, getter=orderByField, setter=setOrderByField:) NSString *_orderByField; + +/** + * @property _orderByDescending + */ +@property(readwrite, assign, getter=orderByDescending, setter=setOrderByDescending:) BOOL _orderByDescending; + ++ (QKQueryOrderBy *)orderByField:(NSString *)field descending:(BOOL)descending; + +- (id)initWithField:(NSString *)field descending:(BOOL)descending; + +@end diff --git a/Frameworks/QueryKit/Source/QKQueryOrderBy.m b/Frameworks/QueryKit/Source/QKQueryOrderBy.m new file mode 100644 index 00000000..36b43248 --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryOrderBy.m @@ -0,0 +1,81 @@ +// +// $Id$ +// +// QKQueryOrderBy.m +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on July 15, 2012 +// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +#import "QKQueryOrderBy.h" + +@implementation QKQueryOrderBy + +@synthesize _orderByField; +@synthesize _orderByDescending; + +#pragma mark - +#pragma mark Initialisation + ++ (QKQueryOrderBy *)orderByField:(NSString *)field descending:(BOOL)descending +{ + return [[[QKQueryOrderBy alloc] initWithField:field descending:descending] autorelease]; +} + +- (id)init +{ + return [self initWithField:nil descending:NO]; +} + +- (id)initWithField:(NSString *)field descending:(BOOL)descending +{ + if ((self = [super init])) { + [self setOrderByField:field]; + [self setOrderByDescending:descending]; + } + + return self; +} + +#pragma mark - + +- (NSString *)description +{ + if (!_orderByField || [_orderByField length] == 0) return EMPTY_STRING; + + NSString *field = [_orderByField stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + return [NSString stringWithFormat:@"%1$@%2$@%1$@ %3$@", [self useQuotedIdentifier] ? _identiferQuote : EMPTY_STRING, field, _orderByDescending ? @"DESC" : @"ASC"]; +} + +#pragma mark - + +- (void)dealloc +{ + if (_orderByField) [_orderByField release], _orderByField = nil; + + [super dealloc]; +} + +@end diff --git a/Frameworks/QueryKit/Source/QKQueryStringAdditions.m b/Frameworks/QueryKit/Source/QKQueryStringAdditions.m index 7c87e458..d2167041 100644 --- a/Frameworks/QueryKit/Source/QKQueryStringAdditions.m +++ b/Frameworks/QueryKit/Source/QKQueryStringAdditions.m @@ -35,7 +35,9 @@ /** * Returns the string quoted with supplied character. * - * @return The quoted string + * @param character The character (as a string) to use. + * + * @return The quoted string. */ - (NSString *)quotedStringWithCharacter:(NSString *)character { diff --git a/Frameworks/QueryKit/Source/QueryKit.h b/Frameworks/QueryKit/Source/QueryKit.h index 624ba08b..0ae6b406 100644 --- a/Frameworks/QueryKit/Source/QueryKit.h +++ b/Frameworks/QueryKit/Source/QueryKit.h @@ -30,6 +30,7 @@ #import #import +#import #import #import #import diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m index 4ea01e4a..5f5c7356 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m +++ b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m @@ -55,10 +55,10 @@ - (void)testSelectQueryOrderByAscendingIsCorrect { [_query orderByField:QKTestFieldOne descending:NO]; - + NSString *query = [NSString stringWithFormat:@"ORDER BY `%@` ASC", QKTestFieldOne]; - STAssertTrue([[_query query] hasSuffix:query], @"select query order by"); + STAssertTrue([[_query query] hasSuffix:query], @""); } - (void)testSelectQueryOrderByAscendingWithoutQuotesIsCorrect @@ -73,9 +73,10 @@ - (void)testSelectQueryOrderByMultipleFieldsAscendingIsCorrect { - [_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:NO]; - - NSString *query = [NSString stringWithFormat:@"ORDER BY `%@`, `%@` ASC", QKTestFieldOne, QKTestFieldTwo]; + [_query orderByField:QKTestFieldOne descending:NO]; + [_query orderByField:QKTestFieldTwo descending:NO]; + + NSString *query = [NSString stringWithFormat:@"ORDER BY `%@` ASC, `%@` ASC", QKTestFieldOne, QKTestFieldTwo]; STAssertTrue([[_query query] hasSuffix:query], @"select query order by multiple fields ascending when quoted"); } @@ -83,9 +84,11 @@ - (void)testSelectQueryOrderByMultipleFieldsAscendingWithoutQuotesIsCorrect { [_query setUseQuotedIdentifiers:NO]; - [_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:NO]; - NSString *query = [NSString stringWithFormat:@"ORDER BY %@, %@ ASC", QKTestFieldOne, QKTestFieldTwo]; + [_query orderByField:QKTestFieldOne descending:NO]; + [_query orderByField:QKTestFieldTwo descending:NO]; + + NSString *query = [NSString stringWithFormat:@"ORDER BY %@ ASC, %@ ASC", QKTestFieldOne, QKTestFieldTwo]; STAssertTrue([[_query query] hasSuffix:query], @"select query order by multiple fields ascending without quotes"); } @@ -111,9 +114,10 @@ - (void)testSelectQueryOrderByMultipleFieldsDescendingIsCorrect { - [_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:YES]; + [_query orderByField:QKTestFieldOne descending:YES]; + [_query orderByField:QKTestFieldTwo descending:YES]; - NSString *query = [NSString stringWithFormat:@"ORDER BY `%@`, `%@` DESC", QKTestFieldOne, QKTestFieldTwo]; + NSString *query = [NSString stringWithFormat:@"ORDER BY `%@` DESC, `%@` DESC", QKTestFieldOne, QKTestFieldTwo]; STAssertTrue([[_query query] hasSuffix:query], @"select query order by multiple fields descending"); } @@ -121,9 +125,11 @@ - (void)testSelectQueryOrderByMultipleFieldsDescendingWithoutQuotesIsCorrect { [_query setUseQuotedIdentifiers:NO]; - [_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:YES]; - NSString *query = [NSString stringWithFormat:@"ORDER BY %@, %@ DESC", QKTestFieldOne, QKTestFieldTwo]; + [_query orderByField:QKTestFieldOne descending:YES]; + [_query orderByField:QKTestFieldTwo descending:YES]; + + NSString *query = [NSString stringWithFormat:@"ORDER BY %@ DESC, %@ DESC", QKTestFieldOne, QKTestFieldTwo]; STAssertTrue([[_query query] hasSuffix:query], @"select query order by multiple fields descending without quotes"); } diff --git a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m index 65c31dae..cd1fb848 100644 --- a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m +++ b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m @@ -78,6 +78,8 @@ { NSString *query = [NSString stringWithFormat:@"WHERE `%@` %@ %@", QKTestFieldOne, [QKQueryUtilities stringRepresentationOfQueryOperator:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]]; + NSLog(@"%@", [_query query]); + STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"update query constraint"); } -- cgit v1.2.3