aboutsummaryrefslogtreecommitdiffstats
path: root/Frameworks/QueryKit
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2012-01-22 12:19:21 +0000
committerstuconnolly <stuart02@gmail.com>2012-01-22 12:19:21 +0000
commit1d7ed99d602bf9c7aa4ea40a9a2ab6458864e51f (patch)
tree6c08ad29618ea02caf302180706d010c90cd57e0 /Frameworks/QueryKit
parente23ba5155a53c43a106ac9646f51321ccc7d86f4 (diff)
downloadsequelpro-1d7ed99d602bf9c7aa4ea40a9a2ab6458864e51f.tar.gz
sequelpro-1d7ed99d602bf9c7aa4ea40a9a2ab6458864e51f.tar.bz2
sequelpro-1d7ed99d602bf9c7aa4ea40a9a2ab6458864e51f.zip
Bring outlinew view branch up to date with trunk (r3375:3468).
Diffstat (limited to 'Frameworks/QueryKit')
-rw-r--r--Frameworks/QueryKit/QKQuery.h110
-rw-r--r--Frameworks/QueryKit/QKQuery.m438
-rw-r--r--Frameworks/QueryKit/QKQueryOperators.h56
-rw-r--r--Frameworks/QueryKit/QKQueryParameter.h70
-rw-r--r--Frameworks/QueryKit/QKQueryParameter.m86
-rw-r--r--Frameworks/QueryKit/QKQueryTypes.h45
-rw-r--r--Frameworks/QueryKit/QKQueryUtilities.h46
-rw-r--r--Frameworks/QueryKit/QKQueryUtilities.m96
-rw-r--r--Frameworks/QueryKit/QueryKit.h37
9 files changed, 984 insertions, 0 deletions
diff --git a/Frameworks/QueryKit/QKQuery.h b/Frameworks/QueryKit/QKQuery.h
new file mode 100644
index 00000000..b3670808
--- /dev/null
+++ b/Frameworks/QueryKit/QKQuery.h
@@ -0,0 +1,110 @@
+//
+// $Id$
+//
+// QKQuery.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQueryTypes.h"
+#import "QKQueryOperators.h"
+#import "QKQueryParameter.h"
+
+/**
+ * @class QKQuery QKQuery.h
+ *
+ * @author Stuart Connolly http://stuconnolly.com/
+ *
+ * Main QueryKit query class.
+ */
+@interface QKQuery : NSObject
+{
+ NSString *_database;
+ NSString *_table;
+
+ NSMutableString *_query;
+ NSMutableArray *_parameters;
+ NSMutableArray *_fields;
+ NSMutableArray *_groupByFields;
+ NSMutableArray *_orderByFields;
+
+ QKQueryType _queryType;
+
+ BOOL _quoteFields;
+ BOOL _orderDescending;
+}
+
+/**
+ * @property _database The database the query is to be run against (optional).
+ */
+@property (readwrite, retain, getter=database, setter=setDatabase:) NSString *_database;
+
+/**
+ * @property _table The table the query is to be run against.
+ */
+@property (readwrite, retain, getter=table, setter=setTable:) NSString *_table;
+
+/**
+ * @property _parameters The parameters (constraints) of the query.
+ */
+@property (readwrite, retain, getter=parameters, setter=setParameters:) NSMutableArray *_parameters;
+
+/**
+ * @property _fields The fields of the query.
+ */
+@property (readwrite, retain, getter=fields, setter=setFields:) NSMutableArray *_fields;
+
+/**
+ * @property _queryType The type of query to be built.
+ */
+@property (readwrite, assign, getter=queryType, setter=setQueryType:) QKQueryType _queryType;
+
+/**
+ * @property _quoteFields Indicates whether or not the query's fields should be quoted.
+ */
+@property (readwrite, assign, getter=quoteFields, setter=setQuoteFields:) BOOL _quoteFields;
+
++ (QKQuery *)queryTable:(NSString *)table;
++ (QKQuery *)selectQueryFromTable:(NSString *)table;
+
+- (id)initWithTable:(NSString *)table;
+
+- (NSString *)query;
+
+- (void)addField:(NSString *)field;
+- (void)addFields:(NSArray *)fields;
+
+- (void)addParameter:(QKQueryParameter *)parameter;
+- (void)addParameter:(NSString *)field operator:(QKQueryOperator)operator value:(id)value;
+
+- (void)groupByField:(NSString *)field;
+- (void)groupByFields:(NSArray *)fields;
+
+- (void)orderByField:(NSString *)field descending:(BOOL)descending;
+- (void)orderByFields:(NSArray *)fields descending:(BOOL)descending;
+
+@end
diff --git a/Frameworks/QueryKit/QKQuery.m b/Frameworks/QueryKit/QKQuery.m
new file mode 100644
index 00000000..31755b6d
--- /dev/null
+++ b/Frameworks/QueryKit/QKQuery.m
@@ -0,0 +1,438 @@
+//
+// $Id$
+//
+// QKQuery.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQuery.h"
+
+static NSString *QKNoQueryTypeException = @"QKNoQueryType";
+static NSString *QKNoQueryTableException = @"QKNoQueryTable";
+
+@interface QKQuery ()
+
+- (void)_validateRequiements;
+
+- (NSString *)_buildQuery;
+- (NSString *)_buildFieldList;
+- (NSString *)_buildConstraints;
+- (NSString *)_buildGroupByClause;
+- (NSString *)_buildOrderByClause;
+
+- (BOOL)_addString:(NSString *)string toArray:(NSMutableArray *)array;
+
+@end
+
+@implementation QKQuery
+
+@synthesize _database;
+@synthesize _table;
+@synthesize _parameters;
+@synthesize _queryType;
+@synthesize _fields;
+@synthesize _quoteFields;
+
+#pragma mark -
+#pragma mark Initialization
+
++ (QKQuery *)queryTable:(NSString *)table
+{
+ return [[[QKQuery alloc] initWithTable:table] autorelease];
+}
+
++ (QKQuery *)selectQueryFromTable:(NSString *)table
+{
+ QKQuery *query = [[[QKQuery alloc] initWithTable:table] autorelease];
+
+ [query setQueryType:QKSelectQuery];
+
+ return query;
+}
+
+- (id)initWithTable:(NSString *)table
+{
+ if ((self = [super init])) {
+ [self setTable:table];
+ [self setFields:[[NSMutableArray alloc] init]];
+ [self setParameters:[[NSMutableArray alloc] init]];
+ [self setQueryType:-1];
+ [self setQuoteFields:NO];
+
+ _orderDescending = NO;
+
+ _groupByFields = [[NSMutableArray alloc] init];
+ _orderByFields = [[NSMutableArray alloc] init];
+
+ _query = [[NSMutableString alloc] init];
+ }
+
+ return self;
+}
+
+#pragma mark -
+#pragma mark Public API
+
+- (NSString *)query
+{
+ return _query ? [self _buildQuery] : @"";
+}
+
+#pragma mark -
+#pragma mark Fields
+
+/**
+ * Shortcut for adding a new field to this query.
+ */
+- (void)addField:(NSString *)field
+{
+ [self _addString:field toArray:_fields];
+}
+
+/**
+ * Convenience method for adding more than one field.
+ *
+ * @param The array (of strings) of fields to add.
+ */
+- (void)addFields:(NSArray *)fields
+{
+ for (NSString *field in fields)
+ {
+ [self addField:field];
+ }
+}
+
+#pragma mark -
+#pragma mark Parameters
+
+/**
+ * Adds the supplied parameter.
+ *
+ * @param parameter The parameter to add.
+ */
+- (void)addParameter:(QKQueryParameter *)parameter
+{
+ if ([parameter field] && ([[parameter field] length] > 0) && ((NSInteger)[parameter operator] > -1) && [parameter value]) {
+ [_parameters addObject:parameter];
+ }
+}
+
+/**
+ * Convenience method for adding a new parameter.
+ */
+- (void)addParameter:(NSString *)field operator:(QKQueryOperator)operator value:(id)value
+{
+ [self addParameter:[QKQueryParameter queryParamWithField:field operator:operator value:value]];
+}
+
+#pragma mark -
+#pragma mark Grouping
+
+/**
+ * Adds the supplied field to the query's GROUP BY clause.
+ */
+- (void)groupByField:(NSString *)field
+{
+ [self _addString:field toArray:_groupByFields];
+}
+
+/**
+ * Convenience method for adding more than one field to the query's GROUP BY clause.
+ */
+- (void)groupByFields:(NSArray *)fields
+{
+ for (NSString *field in fields)
+ {
+ [self groupByField:field];
+ }
+}
+
+#pragma mark -
+#pragma mark Ordering
+
+/**
+ * Adds the supplied field to the query's ORDER BY clause.
+ */
+- (void)orderByField:(NSString *)field descending:(BOOL)descending
+{
+ _orderDescending = descending;
+
+ [self _addString:field toArray:_orderByFields];
+}
+
+/**
+ * Convenience method for adding more than one field to the query's ORDER BY clause.
+ */
+- (void)orderByFields:(NSArray *)fields descending:(BOOL)descending
+{
+ for (NSString *field in fields)
+ {
+ [self orderByField:field descending:descending];
+ }
+}
+
+#pragma mark -
+#pragma mark Private API
+
+/**
+ * Validates that everything necessary to build the query has been set.
+ */
+- (void)_validateRequiements
+{
+ if (_queryType == -1) {
+ [NSException raise:QKNoQueryTypeException format:@"Attempt to build query with no query type specified."];
+ }
+
+ if (!_table || [_table length] == 0) {
+ [NSException raise:QKNoQueryTableException format:@"Attempt to build query with no query table specified."];
+ }
+}
+
+/**
+ * Builds the actual query.
+ */
+- (NSString *)_buildQuery
+{
+ [self _validateRequiements];
+
+ BOOL isSelect = (_queryType == QKSelectQuery);
+ BOOL isInsert = (_queryType == QKInsertQuery);
+ BOOL isUpdate = (_queryType == QKUpdateQuery);
+ BOOL isDelete = (_queryType == QKDeleteQuery);
+
+ NSString *fields = [self _buildFieldList];
+
+ if (isSelect) {
+ [_query appendFormat:@"SELECT %@ FROM ", fields];
+ }
+ else if (isInsert) {
+ [_query appendString:@"INSERT INTO "];
+ }
+ else if (isUpdate) {
+ [_query appendString:@"UPDATE "];
+ }
+ else if (isDelete) {
+ [_query appendString:@"DELETE FROM "];
+ }
+
+ if (_database && [_database length] > 0) {
+ [_query appendFormat:@"%@.", _database];
+ }
+
+ [_query appendString:_table];
+
+ if ([_parameters count] > 0) {
+ [_query appendString:@" WHERE "];
+ [_query appendString:[self _buildConstraints]];
+ }
+
+ if (isSelect) {
+ NSString *groupBy = [self _buildGroupByClause];
+ NSString *orderBy = [self _buildOrderByClause];
+
+ if ([groupBy length] > 0) {
+ [_query appendFormat:@" %@", groupBy];
+ }
+
+ if ([orderBy length] > 0) {
+ [_query appendFormat:@" %@", orderBy];
+ }
+ }
+
+ return _query;
+}
+
+/**
+ * Builds the string representation of the query's field list.
+ */
+- (NSString *)_buildFieldList
+{
+ NSMutableString *fields = [NSMutableString string];
+
+ if ([_fields count] == 0) {
+ [fields appendString:@"*"];
+
+ return fields;
+ }
+
+ for (NSString *field in _fields)
+ {
+ field = [field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+
+ if ([field length] == 0) continue;
+
+ if (_quoteFields) {
+ [fields appendString:@"`"];
+ }
+
+ [fields appendString:field];
+
+ if (_quoteFields) {
+ [fields appendString:@"`"];
+ }
+
+ [fields appendString:@", "];
+ }
+
+ if ([fields hasSuffix:@", "]) {
+ [fields setString:[fields substringToIndex:([fields length] - 2)]];
+ }
+
+ return fields;
+}
+
+/**
+ * Builds the string representation of the query's constraints.
+ */
+- (NSString *)_buildConstraints
+{
+ NSMutableString *constraints = [NSMutableString string];
+
+ if ([_parameters count] == 0) return constraints;
+
+ for (QKQueryParameter *param in _parameters)
+ {
+ [constraints appendFormat:@"%@ ", param];
+
+ [constraints appendString:@" AND "];
+ }
+
+ if ([constraints hasSuffix:@" AND "]) {
+ [constraints setString:[constraints substringToIndex:([constraints length] - 5)]];
+ }
+
+ return constraints;
+}
+
+/**
+ * Builds the string representation of the query's GROUP BY clause.
+ *
+ * @return The GROUP BY clause
+ */
+- (NSString *)_buildGroupByClause
+{
+ NSMutableString *groupBy = [NSMutableString string];
+
+ if ([_groupByFields count] == 0) return groupBy;
+
+ [groupBy appendString:@"GROUP BY "];
+
+ for (NSString *field in _groupByFields)
+ {
+ [groupBy appendString:field];
+ [groupBy appendString:@", "];
+ }
+
+ if ([groupBy hasSuffix:@", "]) {
+ [groupBy setString:[groupBy substringToIndex:([groupBy length] - 2)]];
+ }
+
+ return groupBy;
+}
+
+/**
+ * Builds the string representation of the query's ORDER BY clause.
+ *
+ * @return The ORDER BY clause
+ */
+- (NSString *)_buildOrderByClause
+{
+ NSMutableString *orderBy = [NSMutableString string];
+
+ if ([_orderByFields count] == 0) return orderBy;
+
+ [orderBy appendString:@"ORDER BY "];
+
+ for (NSString *field in _orderByFields)
+ {
+ [orderBy appendString:field];
+ [orderBy appendString:@", "];
+ }
+
+ if ([orderBy hasSuffix:@", "]) {
+ [orderBy setString:[orderBy substringToIndex:([orderBy length] - 2)]];
+ }
+
+ if (_orderDescending) {
+ [orderBy appendString:@" DESC"];
+ }
+
+ return orderBy;
+}
+
+/**
+ * Adds the supplied string to the supplied array, but only if the length is greater than zero.
+ *
+ * @param string The string to add to the array
+ * @param array The array to add the string to
+ *
+ * @return A BOOL indicating whether or not the string was added.
+ */
+- (BOOL)_addString:(NSString *)string toArray:(NSMutableArray *)array
+{
+ BOOL result = NO;
+
+ if (!string || !array) return result;
+
+ string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+
+ if ([string length] > 0) {
+ [array addObject:string];
+
+ result = YES;
+ }
+
+ return result;
+}
+
+#pragma mark -
+
+/**
+ * Same as calling -query.
+ */
+- (NSString *)description
+{
+ return [self query];
+}
+
+#pragma mark -
+
+- (void)dealloc
+{
+ if (_table) [_table release], _table = nil;
+ if (_database) [_database release], _database = nil;
+ if (_query) [_query release], _query = nil;
+ if (_parameters) [_parameters release], _parameters = nil;
+ if (_fields) [_fields release], _fields = nil;
+ if (_groupByFields) [_groupByFields release], _groupByFields = nil;
+ if (_orderByFields) [_orderByFields release], _orderByFields = nil;
+
+ [super dealloc];
+}
+
+@end
diff --git a/Frameworks/QueryKit/QKQueryOperators.h b/Frameworks/QueryKit/QKQueryOperators.h
new file mode 100644
index 00000000..247496fd
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryOperators.h
@@ -0,0 +1,56 @@
+//
+// $Id$
+//
+// QKQueryOperators.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+/**
+ * @enum QKQueryOperator
+ *
+ * Used to specify the operator to use for a specific query parameter.
+ *
+ * Note that this is by no means a complete list of available operators, only the most commonly used ones.
+ * Other operators can be added as and when they are required.
+ */
+typedef enum
+{
+ QKEqualityOperator,
+ QKNotEqualOperator,
+ QKLikeOperator,
+ QKNotLikeOperator,
+ QKInOperator,
+ QKNotInOperator,
+ QKIsNullOperator,
+ QKIsNotNullOperator,
+ QKGreaterThanOperator,
+ QKLessThanOperator,
+ QKGreaterThanOrEqualOperator,
+ QKLessThanOrEqualOperator
+}
+QKQueryOperator;
diff --git a/Frameworks/QueryKit/QKQueryParameter.h b/Frameworks/QueryKit/QKQueryParameter.h
new file mode 100644
index 00000000..3a24eb8d
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryParameter.h
@@ -0,0 +1,70 @@
+//
+// $Id$
+//
+// QKQueryParameter.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQueryOperators.h"
+
+/**
+ * @class QKQueryParameter QKQueryParameter.h
+ *
+ * @author Stuart Connolly http://stuconnolly.com/
+ *
+ * QueryKit query parameter class.
+ */
+@interface QKQueryParameter : NSObject
+{
+ NSString *_field;
+
+ QKQueryOperator _operator;
+
+ id _value;
+}
+
+/**
+ * @property _field The field component of the parameter.
+ */
+@property (readwrite, retain, getter=field, setter=setField:) NSString *_field;
+
+/**
+ * @property _operator The operator component of the parameter.
+ */
+@property (readwrite, assign, getter=operator, setter=setOperator:) QKQueryOperator _operator;
+
+/**
+ *@property _value The value component of the parameter.
+ */
+@property (readwrite, retain, getter=value, setter=setValue:) id _value;
+
++ (QKQueryParameter *)queryParamWithField:(NSString *)field operator:(QKQueryOperator)op value:(id)value;
+
+- (id)initParamWithField:(NSString *)field operator:(QKQueryOperator)op value:(id)value;
+
+@end
diff --git a/Frameworks/QueryKit/QKQueryParameter.m b/Frameworks/QueryKit/QKQueryParameter.m
new file mode 100644
index 00000000..bc9efa2f
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryParameter.m
@@ -0,0 +1,86 @@
+//
+// $Id$
+//
+// QKQueryParameter.m
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQueryParameter.h"
+#import "QKQueryUtilities.h"
+
+@implementation QKQueryParameter
+
+@synthesize _field;
+@synthesize _operator;
+@synthesize _value;
+
+#pragma mark -
+#pragma mark Initialisation
+
++ (QKQueryParameter *)queryParamWithField:(NSString *)field operator:(QKQueryOperator)op value:(id)value
+{
+ return [[[QKQueryParameter alloc] initParamWithField:field operator:op value:value] autorelease];
+}
+
+- (id)initParamWithField:(NSString *)field operator:(QKQueryOperator)op value:(id)value
+{
+ if ((self = [super init])) {
+ [self setField:field];
+ [self setOperator:op];
+ [self setValue:value];
+ }
+
+ return self;
+}
+
+#pragma mark -
+
+- (NSString *)description
+{
+ NSMutableString *string = [NSMutableString string];
+
+ NSString *field = [_field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
+
+ [string appendString:field];
+ [string appendFormat:@" %@ ", [QKQueryUtilities operatorRepresentationForType:_operator]];
+ [string appendFormat:(![_value isKindOfClass:[NSNumber class]]) ? @"'%@'" : @"%@", [_value description]];
+
+ return string;
+}
+
+#pragma mark -
+
+- (void)dealloc
+{
+ if (_field) [_field release], _field = nil;
+ if (_value) [_value release], _value = nil;
+
+ [super dealloc];
+}
+
+@end
diff --git a/Frameworks/QueryKit/QKQueryTypes.h b/Frameworks/QueryKit/QKQueryTypes.h
new file mode 100644
index 00000000..1e9e7403
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryTypes.h
@@ -0,0 +1,45 @@
+//
+// $Id$
+//
+// QKQueryTypes.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+/**
+ * @enum QKQueryType
+ *
+ * Used to specify the type of query to be constructed.
+ */
+typedef enum
+{
+ QKSelectQuery,
+ QKUpdateQuery,
+ QKInsertQuery,
+ QKDeleteQuery,
+}
+QKQueryType;
diff --git a/Frameworks/QueryKit/QKQueryUtilities.h b/Frameworks/QueryKit/QKQueryUtilities.h
new file mode 100644
index 00000000..352c5533
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryUtilities.h
@@ -0,0 +1,46 @@
+//
+// $Id$
+//
+// QKQueryUtilities.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQueryOperators.h"
+
+/**
+ * @class QKQueryUtilities QKQueryUtilities.h
+ *
+ * @author Stuart Connolly http://stuconnolly.com/
+ *
+ * QueryKit utilities class.
+ */
+@interface QKQueryUtilities : NSObject
+
++ (NSString *)operatorRepresentationForType:(QKQueryOperator)operator;
+
+@end
diff --git a/Frameworks/QueryKit/QKQueryUtilities.m b/Frameworks/QueryKit/QKQueryUtilities.m
new file mode 100644
index 00000000..5e4eb4ab
--- /dev/null
+++ b/Frameworks/QueryKit/QKQueryUtilities.m
@@ -0,0 +1,96 @@
+//
+// $Id$
+//
+// QKQueryUtilities.m
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "QKQueryUtilities.h"
+
+static NSString *QKUnrecognisedQueryOperatorException = @"QKUnrecognisedQueryOperator";
+
+@implementation QKQueryUtilities
+
+/**
+ * Returns a string representation of the supplied operator type.
+ *
+ * @param operator The operator
+ *
+ * @return A string represenation of the operator.
+ */
++ (NSString *)operatorRepresentationForType:(QKQueryOperator)operator
+{
+ NSString *opString = nil;
+
+ switch (operator)
+ {
+ case QKEqualityOperator:
+ opString = @"=";
+ break;
+ case QKNotEqualOperator:
+ opString = @"!=";
+ break;
+ case QKLikeOperator:
+ opString = @"LIKE";
+ break;
+ case QKNotLikeOperator:
+ opString = @"NOT LIKE";
+ break;
+ case QKInOperator:
+ opString = @"IN";
+ break;
+ case QKNotInOperator:
+ opString = @"NOT IN";
+ break;
+ case QKIsNullOperator:
+ opString = @"IS NULL";
+ break;
+ case QKIsNotNullOperator:
+ opString = @"IS NOT NULL";
+ break;
+ case QKGreaterThanOperator:
+ opString = @">";
+ break;
+ case QKLessThanOperator:
+ opString = @"<";
+ break;
+ case QKGreaterThanOrEqualOperator:
+ opString = @">=";
+ break;
+ case QKLessThanOrEqualOperator:
+ opString = @"<=";
+ break;
+ default:
+ [NSException raise:QKUnrecognisedQueryOperatorException format:@"Unrecognised query operator type: %d", operator];
+ break;
+ }
+
+ return opString;
+}
+
+@end
diff --git a/Frameworks/QueryKit/QueryKit.h b/Frameworks/QueryKit/QueryKit.h
new file mode 100644
index 00000000..04c072de
--- /dev/null
+++ b/Frameworks/QueryKit/QueryKit.h
@@ -0,0 +1,37 @@
+//
+// $Id$
+//
+// QueryKit.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on September 4, 2011
+// Copyright (c) 2011 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.
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import <QueryKit/QKQuery.h>
+#import <QueryKit/QKQueryTypes.h>
+#import <QueryKit/QKQueryOperators.h>
+#import <QueryKit/QKQueryParameter.h>
+#import <QueryKit/QKQueryUtilities.h>