aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2012-07-14 10:26:44 +0000
committerstuconnolly <stuart02@gmail.com>2012-07-14 10:26:44 +0000
commit6c1a1acdb2e030b08ccd08dc6eea70b3657ebb4c (patch)
treea2b9c82ab3db6f149ee6a67affd94ecda30a5b9b
parenta2d65d3fa1e58d91d47260cdbbbeae7c99aa04f8 (diff)
downloadsequelpro-6c1a1acdb2e030b08ccd08dc6eea70b3657ebb4c.tar.gz
sequelpro-6c1a1acdb2e030b08ccd08dc6eea70b3657ebb4c.tar.bz2
sequelpro-6c1a1acdb2e030b08ccd08dc6eea70b3657ebb4c.zip
Bunch of improvements including uderlying database system support.
-rw-r--r--Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj8
-rw-r--r--Frameworks/QueryKit/Source/QKQuery.h31
-rw-r--r--Frameworks/QueryKit/Source/QKQuery.m116
-rw-r--r--Frameworks/QueryKit/Source/QKQueryConstants.h1
-rw-r--r--Frameworks/QueryKit/Source/QKQueryDatabases.h1
-rw-r--r--Frameworks/QueryKit/Source/QKQueryGenericParameter.h13
-rw-r--r--Frameworks/QueryKit/Source/QKQueryGenericParameter.m6
-rw-r--r--Frameworks/QueryKit/Source/QKQueryParameter.m4
-rw-r--r--Frameworks/QueryKit/Source/QKQueryStringAdditions.h35
-rw-r--r--Frameworks/QueryKit/Source/QKQueryStringAdditions.m47
-rw-r--r--Frameworks/QueryKit/Source/QKQueryUpdateParameter.m2
-rw-r--r--Frameworks/QueryKit/Source/QKQueryUtilities.h4
-rw-r--r--Frameworks/QueryKit/Source/QKQueryUtilities.m25
-rw-r--r--Frameworks/QueryKit/Source/QueryKit-Prefix.pch2
-rw-r--r--Frameworks/QueryKit/Tests/QKQueryTests.m11
-rw-r--r--Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m4
-rw-r--r--Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m8
-rw-r--r--Frameworks/QueryKit/Tests/QKSelectQueryTests.m10
-rw-r--r--Frameworks/QueryKit/Tests/QKTestConstants.h2
-rw-r--r--Frameworks/QueryKit/Tests/QKUpdateQueryTests.m10
20 files changed, 287 insertions, 53 deletions
diff --git a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj
index d84389e0..decc195b 100644
--- a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj
+++ b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj
@@ -14,6 +14,8 @@
1719E4BD151F51F1003F98C5 /* QKUpdateQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1719E4BA151F51EA003F98C5 /* QKUpdateQueryTests.m */; };
1726972915AAF6CE009586E1 /* QKQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1726972815AAF6CE009586E1 /* QKQueryTests.m */; };
1726976715AC3DD2009586E1 /* QKQueryDatabases.h in Headers */ = {isa = PBXBuildFile; fileRef = 1726976515AC3DD2009586E1 /* QKQueryDatabases.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 1726979515AEE939009586E1 /* QKQueryStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1726979315AEE939009586E1 /* QKQueryStringAdditions.h */; };
+ 1726979615AEE939009586E1 /* QKQueryStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1726979415AEE939009586E1 /* QKQueryStringAdditions.m */; };
17577F6715A98FEA00CDF67A /* QKTestConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 17577F6615A98FEA00CDF67A /* QKTestConstants.m */; };
17577FC615A99AC000CDF67A /* QKQueryConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 17577FC415A99AC000CDF67A /* QKQueryConstants.h */; settings = {ATTRIBUTES = (Public, ); }; };
1757801E15A9A14400CDF67A /* QKQueryGenericParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1757801C15A9A14400CDF67A /* QKQueryGenericParameter.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -55,6 +57,8 @@
1726972715AAF6CE009586E1 /* QKQueryTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryTests.h; sourceTree = "<group>"; };
1726972815AAF6CE009586E1 /* QKQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQueryTests.m; sourceTree = "<group>"; };
1726976515AC3DD2009586E1 /* QKQueryDatabases.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryDatabases.h; sourceTree = "<group>"; };
+ 1726979315AEE939009586E1 /* QKQueryStringAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryStringAdditions.h; sourceTree = "<group>"; };
+ 1726979415AEE939009586E1 /* QKQueryStringAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQueryStringAdditions.m; sourceTree = "<group>"; };
17577F6515A98FEA00CDF67A /* QKTestConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKTestConstants.h; sourceTree = "<group>"; };
17577F6615A98FEA00CDF67A /* QKTestConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKTestConstants.m; sourceTree = "<group>"; };
17577FC415A99AC000CDF67A /* QKQueryConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryConstants.h; sourceTree = "<group>"; };
@@ -218,6 +222,8 @@
isa = PBXGroup;
children = (
17577FC415A99AC000CDF67A /* QKQueryConstants.h */,
+ 1726979315AEE939009586E1 /* QKQueryStringAdditions.h */,
+ 1726979415AEE939009586E1 /* QKQueryStringAdditions.m */,
);
name = Other;
sourceTree = "<group>";
@@ -261,6 +267,7 @@
17577FC615A99AC000CDF67A /* QKQueryConstants.h in Headers */,
1757801E15A9A14400CDF67A /* QKQueryGenericParameter.h in Headers */,
1726976715AC3DD2009586E1 /* QKQueryDatabases.h in Headers */,
+ 1726979515AEE939009586E1 /* QKQueryStringAdditions.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -379,6 +386,7 @@
17E5952614F301DF0054EE08 /* QKQueryUtilities.m in Sources */,
1719E47E151E8CA7003F98C5 /* QKQueryUpdateParameter.m in Sources */,
1757801F15A9A14400CDF67A /* QKQueryGenericParameter.m in Sources */,
+ 1726979615AEE939009586E1 /* QKQueryStringAdditions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Frameworks/QueryKit/Source/QKQuery.h b/Frameworks/QueryKit/Source/QKQuery.h
index e3b7f148..117da9b3 100644
--- a/Frameworks/QueryKit/Source/QKQuery.h
+++ b/Frameworks/QueryKit/Source/QKQuery.h
@@ -29,6 +29,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#import "QKQueryTypes.h"
+#import "QKQueryDatabases.h"
#import "QKQueryOperators.h"
#import "QKQueryParameter.h"
#import "QKQueryUpdateParameter.h"
@@ -44,6 +45,7 @@
{
NSString *_database;
NSString *_table;
+ NSString *_identifierQuote;
NSMutableString *_query;
@@ -54,8 +56,9 @@
NSMutableArray *_orderByFields;
QKQueryType _queryType;
+ QKQueryDatabase _queryDatabase;
- BOOL _useQuotes;
+ BOOL _useQuotedIdentifiers;
BOOL _orderDescending;
}
@@ -90,23 +93,43 @@
@property(readwrite, assign, getter=queryType, setter=setQueryType:) QKQueryType _queryType;
/**
- * @property _useQuotes Indicates whether or not the query's fields should be quoted.
+ * @property _queryDatabase The underlying database system this query will be run against.
*/
-@property(readwrite, assign, getter=useQuotes) BOOL _useQuotes;
+@property(readwrite, assign, getter=queryDatabase, setter=setQueryDatabase:) QKQueryDatabase _queryDatabase;
+/**
+ * @property _useQuotedIdentifiers Indicates whether or not the query's fields should be quoted.
+ */
+@property(readwrite, assign, getter=useQuotedIdentifiers) BOOL _useQuotedIdentifiers;
+
+/**
+ * @property _groupByFields The group by fields of the query.
+ */
@property(readonly, getter=groupByFields) NSMutableArray *_groupByFields;
+/**
+ * @property _orderByFields The order by fields of the query.
+ */
@property(readonly, getter=orderByFields) NSMutableArray *_orderByFields;
+/**
+ * @property _identifierQuote The character to use when quoting identifiers.
+ */
+@property(readonly, getter=identifierQuote) NSString *_identifierQuote;
+
+ (QKQuery *)queryTable:(NSString *)table;
++ (QKQuery *)queryTable:(NSString *)table database:(NSString *)database;
+
+ (QKQuery *)selectQueryFromTable:(NSString *)table;
++ (QKQuery *)selectQueryFromTable:(NSString *)table database:(NSString *)database;
- (id)initWithTable:(NSString *)table;
+- (id)initWithTable:(NSString *)table database:(NSString *)database;
- (NSString *)query;
- (void)clear;
-- (void)setUseQuotes:(BOOL)quote;
+- (void)setUseQuotedIdentifiers:(BOOL)quote;
- (void)addField:(NSString *)field;
- (void)addFields:(NSArray *)fields;
diff --git a/Frameworks/QueryKit/Source/QKQuery.m b/Frameworks/QueryKit/Source/QKQuery.m
index c60f3162..08499b8d 100644
--- a/Frameworks/QueryKit/Source/QKQuery.m
+++ b/Frameworks/QueryKit/Source/QKQuery.m
@@ -29,6 +29,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#import "QKQuery.h"
+#import "QKQueryUtilities.h"
#import "QKQueryConstants.h"
#import "QKQueryGenericParameter.h"
@@ -55,11 +56,13 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
@synthesize _database;
@synthesize _table;
+@synthesize _identifierQuote;
@synthesize _parameters;
@synthesize _queryType;
+@synthesize _queryDatabase;
@synthesize _fields;
@synthesize _updateParameters;
-@synthesize _useQuotes;
+@synthesize _useQuotedIdentifiers;
@synthesize _groupByFields;
@synthesize _orderByFields;
@@ -68,29 +71,54 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
+ (QKQuery *)queryTable:(NSString *)table
{
- return [[[QKQuery alloc] initWithTable:table] autorelease];
+ return [QKQuery queryTable:table database:nil];
+}
+
++ (QKQuery *)queryTable:(NSString *)table database:(NSString *)database
+{
+ return [[[QKQuery alloc] initWithTable:table database:database] autorelease];
}
+ (QKQuery *)selectQueryFromTable:(NSString *)table
+{
+ return [QKQuery selectQueryFromTable:table database:nil];
+}
+
++ (QKQuery *)selectQueryFromTable:(NSString *)table database:(NSString *)database
{
- QKQuery *query = [[[QKQuery alloc] initWithTable:table] autorelease];
+ QKQuery *query = [[[QKQuery alloc] initWithTable:table database:database] autorelease];
[query setQueryType:QKSelectQuery];
return query;
}
+- (id)init
+{
+ return [self initWithTable:nil];
+}
+
- (id)initWithTable:(NSString *)table
{
+ return [self initWithTable:table database:nil];
+}
+
+- (id)initWithTable:(NSString *)table database:(NSString *)database
+{
if ((self = [super init])) {
[self setTable:table];
+ [self setDatabase:database];
[self setFields:[[NSMutableArray alloc] init]];
[self setUpdateParameters:[[NSMutableArray alloc] init]];
[self setParameters:[[NSMutableArray alloc] init]];
[self setQueryType:QKUnknownQuery];
- [self setUseQuotes:YES];
+ [self setUseQuotedIdentifiers:YES];
+
+ // Default to MySQL
+ [self setQueryDatabase:QKDatabaseMySQL];
_orderDescending = NO;
+ _identifierQuote = EMPTY_STRING;
_groupByFields = [[NSMutableArray alloc] init];
_orderByFields = [[NSMutableArray alloc] init];
@@ -111,7 +139,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
*/
- (NSString *)query
{
- return _query ? [self _buildQuery] : @"";
+ return _query ? [self _buildQuery] : EMPTY_STRING;
}
/**
@@ -121,31 +149,41 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
{
[self setTable:nil];
[self setDatabase:nil];
- [self setUseQuotes:YES];
+ [self setUseQuotedIdentifiers:YES];
[self setQueryType:QKUnknownQuery];
+ [self setQueryDatabase:QKDatabaseUnknown];
[_fields removeAllObjects];
[_parameters removeAllObjects];
[_updateParameters removeAllObjects];
[_groupByFields removeAllObjects];
[_orderByFields removeAllObjects];
+
+ _identifierQuote = EMPTY_STRING;
+
+ if (_query) [_query release], _query = [[NSMutableString alloc] init];
}
#pragma mark -
#pragma mark Accessors
-- (void)setUseQuotes:(BOOL)quote
+/**
+ * Sets whether to quote identifiers in the query.
+ *
+ * @param quote A BOOL indicating whether quoting should be used.
+ */
+- (void)setUseQuotedIdentifiers:(BOOL)quote
{
- _useQuotes = quote;
+ _useQuotedIdentifiers = quote;
for (QKQueryParameter *param in _parameters)
{
- [param setUseQuotes:_useQuotes];
+ [param setUseQuotedIdentifier:_useQuotedIdentifiers];
}
for (QKQueryUpdateParameter *param in _updateParameters)
{
- [param setUseQuotes:_useQuotes];
+ [param setUseQuotedIdentifier:_useQuotedIdentifiers];
}
}
@@ -154,6 +192,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Shortcut for adding a new field to this query.
+ *
+ * @param field The field to add.
*/
- (void)addField:(NSString *)field
{
@@ -163,7 +203,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Convenience method for adding more than one field.
*
- * @param The array (of strings) of fields to add.
+ * @param fields The array (of strings) of fields to add.
*/
- (void)addFields:(NSArray *)fields
{
@@ -190,6 +230,9 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Convenience method for adding a new parameter.
+ *
+ * @param field
+ * @param value
*/
- (void)addParameter:(NSString *)field operator:(QKQueryOperator)operator value:(id)value
{
@@ -213,6 +256,9 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Convenience method for adding a new update parameter.
+ *
+ * @param field
+ * @param value
*/
- (void)addFieldToUpdate:(NSString *)field toValue:(id)value
{
@@ -224,6 +270,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Adds the supplied field to the query's GROUP BY clause.
+ *
+ * @param field
*/
- (void)groupByField:(NSString *)field
{
@@ -232,6 +280,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Convenience method for adding more than one field to the query's GROUP BY clause.
+ *
+ * @param fields
*/
- (void)groupByFields:(NSArray *)fields
{
@@ -246,6 +296,9 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Adds the supplied field to the query's ORDER BY clause.
+ *
+ * @param field
+ * @param descending
*/
- (void)orderByField:(NSString *)field descending:(BOOL)descending
{
@@ -256,6 +309,9 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Convenience method for adding more than one field to the query's ORDER BY clause.
+ *
+ * @param fields
+ * @param descending
*/
- (void)orderByFields:(NSArray *)fields descending:(BOOL)descending
{
@@ -284,6 +340,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the actual query.
+ *
+ * @return The built SQL query.
*/
- (NSString *)_buildQuery
{
@@ -294,6 +352,20 @@ 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];
+ }
+ }
+
NSString *fields = [self _buildFieldList];
if (isSelect) {
@@ -310,10 +382,10 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
}
if (_database && [_database length] > 0) {
- [_query appendFormat:@"%@%@%@.", _useQuotes ? QUERY_QUOTE : EMPTY_STRING, _database, _useQuotes ? QUERY_QUOTE : EMPTY_STRING];
+ [_query appendFormat:@"%1$@%2$@%1$@.", _identifierQuote, _database];
}
- [_query appendFormat:@"%@%@%@", _useQuotes ? QUERY_QUOTE : EMPTY_STRING, _table, _useQuotes ? QUERY_QUOTE : EMPTY_STRING];
+ [_query appendFormat:@"%1$@%2$@%1$@", _identifierQuote, _table];
if (isUpdate) {
[_query appendFormat:@" %@", [self _buildUpdateClause]];
@@ -332,6 +404,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the string representation of the query's field list.
+ *
+ * @return The field list as SQL.
*/
- (NSString *)_buildFieldList
{
@@ -349,7 +423,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
if ([field length] == 0) continue;
- [fields appendFormat:@"%@%@%@, ", _useQuotes ? QUERY_QUOTE : EMPTY_STRING, field, _useQuotes ? QUERY_QUOTE : EMPTY_STRING];
+ [fields appendFormat:@"%1$@%2$@%1$@, ", _identifierQuote, field];
}
if ([fields hasSuffix:@", "]) {
@@ -361,6 +435,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the string representation of the query's constraints.
+ *
+ * @return The query constraints as SQL.
*/
- (NSString *)_buildConstraints
{
@@ -384,7 +460,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the string representation of the query's GROUP BY clause.
*
- * @return The GROUP BY clause
+ * @return The GROUP BY SQL clause.
*/
- (NSString *)_buildGroupByClause
{
@@ -396,7 +472,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
for (NSString *field in _groupByFields)
{
- [groupBy appendFormat:@"%@%@%@, ", _useQuotes ? QUERY_QUOTE : EMPTY_STRING, field, _useQuotes ? QUERY_QUOTE : EMPTY_STRING];
+ [groupBy appendFormat:@"%1$@%2$@%1$@, ", _identifierQuote, field];
}
if ([groupBy hasSuffix:@", "]) {
@@ -409,7 +485,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the string representation of the query's ORDER BY clause.
*
- * @return The ORDER BY clause
+ * @return The ORDER BY SQL clause.
*/
- (NSString *)_buildOrderByClause
{
@@ -421,7 +497,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
for (NSString *field in _orderByFields)
{
- [orderBy appendFormat:@"%@%@%@, ", _useQuotes ? QUERY_QUOTE : EMPTY_STRING, field, _useQuotes ? QUERY_QUOTE : EMPTY_STRING];
+ [orderBy appendFormat:@"%1$@%2$@%1$@, ", _identifierQuote, field];
}
if ([orderBy hasSuffix:@", "]) {
@@ -436,7 +512,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Builds the string representation of the query's UPDATE parameters.
*
- * @return The fields to be updated
+ * @return The fields to update section of the SQL query.
*/
- (NSString *)_buildUpdateClause
{
@@ -510,6 +586,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable";
/**
* Same as calling -query.
+ *
+ * @return the query that was built.
*/
- (NSString *)description
{
diff --git a/Frameworks/QueryKit/Source/QKQueryConstants.h b/Frameworks/QueryKit/Source/QKQueryConstants.h
index 9d843169..57c7a55b 100644
--- a/Frameworks/QueryKit/Source/QKQueryConstants.h
+++ b/Frameworks/QueryKit/Source/QKQueryConstants.h
@@ -28,5 +28,4 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
-#define QUERY_QUOTE @"`"
#define EMPTY_STRING @""
diff --git a/Frameworks/QueryKit/Source/QKQueryDatabases.h b/Frameworks/QueryKit/Source/QKQueryDatabases.h
index 16843b2a..cdb76221 100644
--- a/Frameworks/QueryKit/Source/QKQueryDatabases.h
+++ b/Frameworks/QueryKit/Source/QKQueryDatabases.h
@@ -35,6 +35,7 @@
*/
typedef enum
{
+ QKDatabaseUnknown = -1,
QKDatabaseMySQL,
QKDatabasePostgreSQL
}
diff --git a/Frameworks/QueryKit/Source/QKQueryGenericParameter.h b/Frameworks/QueryKit/Source/QKQueryGenericParameter.h
index 63e9b529..562689f5 100644
--- a/Frameworks/QueryKit/Source/QKQueryGenericParameter.h
+++ b/Frameworks/QueryKit/Source/QKQueryGenericParameter.h
@@ -31,8 +31,10 @@
@interface QKQueryGenericParameter : NSObject
{
id _value;
+ BOOL _useQuotedIdentifier;
+
NSString *_field;
- BOOL _useQuotes;
+ NSString *_identiferQuote;
}
/**
@@ -41,9 +43,14 @@
@property(readwrite, retain, getter=field, setter=setField:) NSString *_field;
/**
- * @property _quoteField Indicates whether or not this parameters field should be quoted.
+ * @property _identifierQuote
*/
-@property(readwrite, assign, getter=useQuotes, setter=setUseQuotes:) BOOL _useQuotes;
+@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 8648dc0a..efaf10d3 100644
--- a/Frameworks/QueryKit/Source/QKQueryGenericParameter.m
+++ b/Frameworks/QueryKit/Source/QKQueryGenericParameter.m
@@ -33,7 +33,8 @@
@implementation QKQueryGenericParameter
@synthesize _field;
-@synthesize _useQuotes;
+@synthesize _useQuotedIdentifier;
+@synthesize _identiferQuote;
@synthesize _value;
#pragma mark -
@@ -42,7 +43,8 @@
- (id)init
{
if ((self = [super init])) {
- [self setUseQuotes:YES];
+ [self setUseQuotedIdentifier:YES];
+ [self setIdentifierQuote:EMPTY_STRING];
}
return self;
diff --git a/Frameworks/QueryKit/Source/QKQueryParameter.m b/Frameworks/QueryKit/Source/QKQueryParameter.m
index c4f9cc29..87035d00 100644
--- a/Frameworks/QueryKit/Source/QKQueryParameter.m
+++ b/Frameworks/QueryKit/Source/QKQueryParameter.m
@@ -63,8 +63,8 @@
NSString *field = [_field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- [string appendFormat:@"%@%@%@", [self useQuotes] ? QUERY_QUOTE : EMPTY_STRING, field, [self useQuotes] ? QUERY_QUOTE : EMPTY_STRING];
- [string appendFormat:@" %@ ", [QKQueryUtilities operatorRepresentationForType:_operator]];
+ [string appendFormat:@"%1$@%2$@%1$@", [self useQuotedIdentifier] ? _identiferQuote : EMPTY_STRING, field];
+ [string appendFormat:@" %@ ", [QKQueryUtilities stringRepresentationOfQueryOperator:_operator]];
[string appendFormat:![_value isKindOfClass:[NSNumber class]] ? @"'%@'" : @"%@", [_value description]];
return string;
diff --git a/Frameworks/QueryKit/Source/QKQueryStringAdditions.h b/Frameworks/QueryKit/Source/QKQueryStringAdditions.h
new file mode 100644
index 00000000..3a0b8e89
--- /dev/null
+++ b/Frameworks/QueryKit/Source/QKQueryStringAdditions.h
@@ -0,0 +1,35 @@
+//
+// $Id$
+//
+// QKQueryStringAdditions.h
+// QueryKit
+//
+// Created by Stuart Connolly (stuconnolly.com) on July 12, 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.
+
+@interface NSString (QKQueryStringAdditions)
+
+- (NSString *)quotedStringWithCharacter:(NSString *)character;
+
+@end
diff --git a/Frameworks/QueryKit/Source/QKQueryStringAdditions.m b/Frameworks/QueryKit/Source/QKQueryStringAdditions.m
new file mode 100644
index 00000000..7c87e458
--- /dev/null
+++ b/Frameworks/QueryKit/Source/QKQueryStringAdditions.m
@@ -0,0 +1,47 @@
+//
+// $Id$
+//
+// QKQueryStringAdditions.m
+// QueryKit
+//
+// Created by Stuart Connolly (stuconnolly.com) on July 12, 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 "QKQueryStringAdditions.h"
+
+@implementation NSString (QKQueryStringAdditions)
+
+/**
+ * Returns the string quoted with supplied character.
+ *
+ * @return The quoted string
+ */
+- (NSString *)quotedStringWithCharacter:(NSString *)character
+{
+ NSString *escapedVersion = [NSString stringWithFormat:@"%@%@", character, character];
+
+ return [NSString stringWithFormat: @"%@%@%@", character, [self stringByReplacingOccurrencesOfString:character withString:escapedVersion], character];
+}
+
+@end
diff --git a/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m
index 8df3aba5..3c271e99 100644
--- a/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m
+++ b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m
@@ -59,7 +59,7 @@
NSString *field = [_field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
- [string appendFormat:@"%@%@%@", [self useQuotes] ? QUERY_QUOTE : EMPTY_STRING, field, [self useQuotes] ? QUERY_QUOTE : EMPTY_STRING];
+ [string appendFormat:@"%1$@%2$@%1$@", [self useQuotedIdentifier] ? _identiferQuote : EMPTY_STRING, field];
[string appendString:@" = "];
[string appendFormat:(![_value isKindOfClass:[NSNumber class]]) ? @"'%@'" : @"%@", [_value description]];
diff --git a/Frameworks/QueryKit/Source/QKQueryUtilities.h b/Frameworks/QueryKit/Source/QKQueryUtilities.h
index 228385f8..7aa6124a 100644
--- a/Frameworks/QueryKit/Source/QKQueryUtilities.h
+++ b/Frameworks/QueryKit/Source/QKQueryUtilities.h
@@ -29,6 +29,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#import "QKQueryOperators.h"
+#import "QKQueryDatabases.h"
/**
* @class QKQueryUtilities QKQueryUtilities.h
@@ -39,6 +40,7 @@
*/
@interface QKQueryUtilities : NSObject
-+ (NSString *)operatorRepresentationForType:(QKQueryOperator)operator;
++ (NSString *)identifierQuoteCharacterForDatabase:(QKQueryDatabase)database;
++ (NSString *)stringRepresentationOfQueryOperator:(QKQueryOperator)operator;
@end
diff --git a/Frameworks/QueryKit/Source/QKQueryUtilities.m b/Frameworks/QueryKit/Source/QKQueryUtilities.m
index 8519eb20..06396ddc 100644
--- a/Frameworks/QueryKit/Source/QKQueryUtilities.m
+++ b/Frameworks/QueryKit/Source/QKQueryUtilities.m
@@ -35,13 +35,34 @@ static NSString *QKUnrecognisedQueryOperatorException = @"QKUnrecognisedQueryOpe
@implementation QKQueryUtilities
/**
- * Returns a string representation of the supplied operator type.
+ * Returns the identifier quote character for the supplied database.
+ *
+ * @param database The database to return the character for
+ *
+ * @return The character as a string.
+ */
++ (NSString *)identifierQuoteCharacterForDatabase:(QKQueryDatabase)database
+{
+ NSString *character = EMPTY_STRING;
+
+ if (database == QKDatabaseMySQL) {
+ character = @"`";
+ }
+ else if (database == QKDatabasePostgreSQL) {
+ character = @"""";
+ }
+
+ return character;
+}
+
+/**
+ * Returns a string representation of the supplied operator.
*
* @param operator The operator
*
* @return A string represenation of the operator.
*/
-+ (NSString *)operatorRepresentationForType:(QKQueryOperator)operator
++ (NSString *)stringRepresentationOfQueryOperator:(QKQueryOperator)operator
{
NSString *opString = nil;
diff --git a/Frameworks/QueryKit/Source/QueryKit-Prefix.pch b/Frameworks/QueryKit/Source/QueryKit-Prefix.pch
index 5e15c359..d5c5da40 100644
--- a/Frameworks/QueryKit/Source/QueryKit-Prefix.pch
+++ b/Frameworks/QueryKit/Source/QueryKit-Prefix.pch
@@ -30,4 +30,6 @@
#ifdef __OBJC__
#import <Foundation/Foundation.h>
+
+ #import "QKQueryConstants.h"
#endif
diff --git a/Frameworks/QueryKit/Tests/QKQueryTests.m b/Frameworks/QueryKit/Tests/QKQueryTests.m
index 63b0ec73..35212cff 100644
--- a/Frameworks/QueryKit/Tests/QKQueryTests.m
+++ b/Frameworks/QueryKit/Tests/QKQueryTests.m
@@ -40,7 +40,8 @@
{
_query = [QKQuery selectQueryFromTable:QKTestTableName];
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
+ [_query setQueryDatabase:QKDatabaseMySQL];
[_query setDatabase:QKTestDatabaseName];
@@ -63,13 +64,17 @@
STAssertNil([_query table], @"query table");
STAssertNil([_query database], @"query database");
- STAssertTrue([_query useQuotes], @"query use quotes");
- STAssertTrue([_query queryType] == QKUnknownQuery, @"query type");
+
+ STAssertTrue([_query useQuotedIdentifiers], @"query use quoted identifiers");
+ STAssertTrue([[_query identifierQuote] isEqualToString:EMPTY_STRING], @"query identifier quote");
STAssertTrue([[_query fields] count] == 0, @"query fields");
STAssertTrue([[_query parameters] count] == 0, @"query parameters");
STAssertTrue([[_query updateParameters] count] == 0, @"query update parameters");
STAssertTrue([[_query groupByFields] count] == 0, @"query group by fields");
STAssertTrue([[_query orderByFields] count] == 0, @"query order by fields");
+
+ STAssertEquals([_query queryType], QKUnknownQuery, @"query type");
+ STAssertEquals([_query queryDatabase], QKDatabaseUnknown, @"query database");
}
@end
diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m
index e9edbea1..c0ee4681 100644
--- a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m
+++ b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m
@@ -63,7 +63,7 @@
- (void)testSelectQueryGroupByWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query groupByField:QKTestFieldOne];
NSString *query = [NSString stringWithFormat:@"GROUP BY %@", QKTestFieldOne];
@@ -82,7 +82,7 @@
- (void)testSelectQueryGroupByMultipleFieldsWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query groupByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil]];
NSString *query = [NSString stringWithFormat:@"GROUP BY %@, %@", QKTestFieldOne, QKTestFieldTwo];
diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m
index cb1a472f..4ea01e4a 100644
--- a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m
+++ b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m
@@ -63,7 +63,7 @@
- (void)testSelectQueryOrderByAscendingWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query orderByField:QKTestFieldOne descending:NO];
NSString *query = [NSString stringWithFormat:@"ORDER BY %@ ASC", QKTestFieldOne];
@@ -82,7 +82,7 @@
- (void)testSelectQueryOrderByMultipleFieldsAscendingWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:NO];
NSString *query = [NSString stringWithFormat:@"ORDER BY %@, %@ ASC", QKTestFieldOne, QKTestFieldTwo];
@@ -101,7 +101,7 @@
- (void)testSelectQueryOrderByDescendingWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query orderByField:QKTestFieldOne descending:YES];
NSString *query = [NSString stringWithFormat:@"ORDER BY %@ DESC", QKTestFieldOne];
@@ -120,7 +120,7 @@
- (void)testSelectQueryOrderByMultipleFieldsDescendingWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
[_query orderByFields:[NSArray arrayWithObjects:QKTestFieldOne, QKTestFieldTwo, nil] descending:YES];
NSString *query = [NSString stringWithFormat:@"ORDER BY %@, %@ DESC", QKTestFieldOne, QKTestFieldTwo];
diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryTests.m
index 75cf7ed2..dc31d353 100644
--- a/Frameworks/QueryKit/Tests/QKSelectQueryTests.m
+++ b/Frameworks/QueryKit/Tests/QKSelectQueryTests.m
@@ -65,7 +65,7 @@
- (void)testSelectQueryFieldWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
NSString *query = [NSString stringWithFormat:@"SELECT %@", QKTestFieldOne];
@@ -81,7 +81,7 @@
- (void)testSelectQueryMultipleFieldsWithoutQuotesAreCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
NSString *query = [NSString stringWithFormat:@"SELECT %@, %@, %@, %@", QKTestFieldOne, QKTestFieldTwo, QKTestFieldThree, QKTestFieldFour];
@@ -90,16 +90,16 @@
- (void)testSelectQueryConstraintsAreCorrect
{
- NSString *query = [NSString stringWithFormat:@"WHERE `%@` %@ %@", QKTestFieldOne, [QKQueryUtilities operatorRepresentationForType:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
+ NSString *query = [NSString stringWithFormat:@"WHERE `%@` %@ %@", QKTestFieldOne, [QKQueryUtilities stringRepresentationOfQueryOperator:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"select query constraint");
}
- (void)testSelectQueryConstraintsWithoutQuotesAreCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
- NSString *query = [NSString stringWithFormat:@"WHERE %@ %@ %@", QKTestFieldOne, [QKQueryUtilities operatorRepresentationForType:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
+ NSString *query = [NSString stringWithFormat:@"WHERE %@ %@ %@", QKTestFieldOne, [QKQueryUtilities stringRepresentationOfQueryOperator:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"select query constraint without quotes");
}
diff --git a/Frameworks/QueryKit/Tests/QKTestConstants.h b/Frameworks/QueryKit/Tests/QKTestConstants.h
index 10e3fa7e..7c200d3e 100644
--- a/Frameworks/QueryKit/Tests/QKTestConstants.h
+++ b/Frameworks/QueryKit/Tests/QKTestConstants.h
@@ -28,6 +28,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
+#define EMPTY_STRING @""
+
extern NSString *QKTestDatabaseName;
extern NSString *QKTestTableName;
diff --git a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m
index 6a24881d..65c31dae 100644
--- a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m
+++ b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m
@@ -65,25 +65,27 @@
- (void)testUpdateQueryFieldsWithoutQuotesAreCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
NSString *query = [NSString stringWithFormat:@"UPDATE %@ SET %@ = '%@', %@ = '%@'", QKTestTableName, QKTestFieldOne, QKTestUpdateValueOne, QKTestFieldTwo, QKTestUpdateValueTwo];
+ NSLog(@"%@", [_query query]);
+
STAssertTrue([[_query query] hasPrefix:query], @"update query fields without quotes");
}
- (void)testUpdateQueryConstraintIsCorrect
{
- NSString *query = [NSString stringWithFormat:@"WHERE `%@` %@ %@", QKTestFieldOne, [QKQueryUtilities operatorRepresentationForType:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
+ NSString *query = [NSString stringWithFormat:@"WHERE `%@` %@ %@", QKTestFieldOne, [QKQueryUtilities stringRepresentationOfQueryOperator:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"update query constraint");
}
- (void)testUpdateQueryConstraintWithoutQuotesIsCorrect
{
- [_query setUseQuotes:NO];
+ [_query setUseQuotedIdentifiers:NO];
- NSString *query = [NSString stringWithFormat:@"WHERE %@ %@ %@", QKTestFieldOne, [QKQueryUtilities operatorRepresentationForType:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
+ NSString *query = [NSString stringWithFormat:@"WHERE %@ %@ %@", QKTestFieldOne, [QKQueryUtilities stringRepresentationOfQueryOperator:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]];
STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"update query constraint without quotes");
}