diff options
Diffstat (limited to 'Frameworks')
19 files changed, 1156 insertions, 123 deletions
diff --git a/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter b/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter Binary files differindex 16c81c40..6b9802a9 100755 --- a/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter +++ b/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter diff --git a/Frameworks/Growl.framework/Versions/A/Growl b/Frameworks/Growl.framework/Versions/A/Growl Binary files differindex 55db3246..ee84bef2 100755 --- a/Frameworks/Growl.framework/Versions/A/Growl +++ b/Frameworks/Growl.framework/Versions/A/Growl diff --git a/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h b/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h index d4adefd4..e7213dbe 100644 --- a/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h +++ b/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge-Carbon.h @@ -2,7 +2,7 @@ // GrowlApplicationBridge-Carbon.h // Growl // -// Created by Mac-arena the Bored Zo on Wed Jun 18 2004. +// Created by Peter Hosey on Wed Jun 18 2004. // Based on GrowlApplicationBridge.h by Evan Schoenberg. // This source code is in the public domain. You may freely link it into any // program. diff --git a/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h b/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h index 1e39f8d6..8afda27e 100644 --- a/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h +++ b/Frameworks/Growl.framework/Versions/A/Headers/GrowlApplicationBridge.h @@ -45,9 +45,9 @@ * @method isGrowlInstalled * @abstract Detects whether Growl is installed. * @discussion Determines if the Growl prefpane and its helper app are installed. - * @result Returns YES if Growl is installed, NO otherwise. + * @result this method will forever return YES */ -+ (BOOL) isGrowlInstalled; ++ (BOOL) isGrowlInstalled __attribute__((deprecated)); /*! * @method isGrowlRunning diff --git a/Frameworks/Growl.framework/Versions/A/Resources/Info.plist b/Frameworks/Growl.framework/Versions/A/Resources/Info.plist index 82b32dbb..fa23da2d 100644 --- a/Frameworks/Growl.framework/Versions/A/Resources/Info.plist +++ b/Frameworks/Growl.framework/Versions/A/Resources/Info.plist @@ -2,6 +2,8 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> + <key>BuildMachineOSBuild</key> + <string>11C74</string> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> @@ -13,11 +15,25 @@ <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> - <string>1.2</string> + <string>1.2.3</string> <key>CFBundleSignature</key> <string>GRRR</string> <key>CFBundleVersion</key> - <string>1.2</string> + <string>1.2.3</string> + <key>DTCompiler</key> + <string>4.0</string> + <key>DTPlatformBuild</key> + <string>10M2518</string> + <key>DTPlatformVersion</key> + <string>PG</string> + <key>DTSDKBuild</key> + <string>9L31a</string> + <key>DTSDKName</key> + <string>macosx10.5</string> + <key>DTXcode</key> + <string>0400</string> + <key>DTXcodeBuild</key> + <string>10M2518</string> <key>NSPrincipalClass</key> <string>GrowlApplicationBridge</string> </dict> diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m index cf66a102..2c4f424d 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPConnection.m @@ -54,7 +54,7 @@ static BOOL sTruncateLongFieldInLogs = YES; */ @interface MCPConnection (PrivateAPI) -- (void)_getServerVersionString; +- (void)_updateConnectionVariables; - (BOOL)_isCurrentHostReachable; - (void)_setupKeepalivePingTimer; @@ -460,6 +460,7 @@ static BOOL sTruncateLongFieldInLogs = YES; theRet = mysql_real_connect(mConnection, theHost, theLogin, thePass, NULL, (unsigned int)connectionPort, theSocket, mConnectionFlags); thePass = NULL; + // If the connection failed, record the error state and return if (theRet != mConnection) { [self unlockConnection]; [self setLastErrorMessage:nil]; @@ -469,21 +470,20 @@ static BOOL sTruncateLongFieldInLogs = YES; return mConnected = NO; } + // Set and reset connection flags mConnected = YES; userTriggeredDisconnect = NO; connectionStartTime = mach_absolute_time(); lastKeepAliveTime = 0; automaticReconnectAttempts = 0; pingFailureCount = 0; - const char *mysqlStringEncoding = mysql_character_set_name(mConnection); - [encoding release]; - encoding = [[NSString alloc] initWithUTF8String:mysqlStringEncoding]; - stringEncoding = [MCPConnection encodingForMySQLEncoding:mysqlStringEncoding]; - encodingUsesLatin1Transport = NO; - [self setLastErrorMessage:nil]; connectionThreadId = mConnection->thread_id; + [self setLastErrorMessage:nil]; + [self unlockConnection]; - [self timeZone]; // Getting the timezone used by the server. + + // Update connection variables - server version, time zone, and connection encoding + [self _updateConnectionVariables]; // Only attempt to set the max allowed packet if we have a connection // The fetches may fail, in which case the class default (which should match @@ -761,7 +761,23 @@ static BOOL sTruncateLongFieldInLogs = YES; if (!mConnected) return NO; BOOL connectionVerified = FALSE; - + + // If the connection is currently locked, it's probably in use - no need to check + // the connection. + if ([connectionLock condition] == MCPConnectionBusy) { + + // However if a ping thread is active, might be a background ping - wait for it + // to complete, then check the connection. + if (pingThreadActive) { + while (pingThreadActive) { + usleep(10000); + } + return [self checkConnection]; + } + + return YES; + } + // Check whether the connection is still operational via a wrapped version of MySQL ping. connectionVerified = [self pingConnectionUsingLoopDelay:400]; @@ -1036,14 +1052,8 @@ void pingThreadCleanup(void *pingDetails) */ - (NSString *)serverVersionString { - if (mConnected) { - if (serverVersionString == nil) { - [self _getServerVersionString]; - } - - if (serverVersionString) { - return [NSString stringWithString:serverVersionString]; - } + if (serverVersionString) { + return [NSString stringWithString:serverVersionString]; } return nil; @@ -1055,14 +1065,8 @@ void pingThreadCleanup(void *pingDetails) - (NSInteger)serverMajorVersion { - if (mConnected) { - if (serverVersionString == nil) { - [self _getServerVersionString]; - } - - if (serverVersionString != nil) { - return [[[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:0] integerValue]; - } + if (serverVersionString != nil) { + return [[[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:0] integerValue]; } return -1; @@ -1073,15 +1077,8 @@ void pingThreadCleanup(void *pingDetails) */ - (NSInteger)serverMinorVersion { - - if (mConnected) { - if (serverVersionString == nil) { - [self _getServerVersionString]; - } - - if(serverVersionString != nil) { - return [[[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:1] integerValue]; - } + if (serverVersionString != nil) { + return [[[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:1] integerValue]; } return -1; @@ -1092,15 +1089,9 @@ void pingThreadCleanup(void *pingDetails) */ - (NSInteger)serverReleaseVersion { - if (mConnected) { - if (serverVersionString == nil) { - [self _getServerVersionString]; - } - - if (serverVersionString != nil) { - NSString *s = [[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:2]; - return [[[s componentsSeparatedByString:@"-"] objectAtIndex:0] integerValue]; - } + if (serverVersionString != nil) { + NSString *s = [[serverVersionString componentsSeparatedByString:@"."] objectAtIndex:2]; + return [[[s componentsSeparatedByString:@"-"] objectAtIndex:0] integerValue]; } return -1; @@ -1343,7 +1334,8 @@ void pingThreadCleanup(void *pingDetails) } /** - * The method used by !{initToHost:withLogin:password:usingPort:} and !{initToSocket:withLogin:password:}. Same information and use of the parameters: + * Trigger a connection to a server using the supplied details. Any details supplied are + * stored for automatic reconnection attempts. * * - login is the user name * - pass is the password corresponding to the user name @@ -1352,70 +1344,40 @@ void pingThreadCleanup(void *pingDetails) * - socket is the path to the socket (for the localhost) * * The socket is used if the host is set to !{@"localhost"}, to an empty or a !{nil} string - * For the moment the implementation might not be safe if you have a nil pointer to one of the NSString* variables (underestand: I don't know what the result will be). */ - (BOOL)connectWithLogin:(NSString *)login password:(NSString *)pass host:(NSString *)host port:(NSUInteger)port socket:(NSString *)aSocket { - const char *theLogin = [self cStringFromString:login]; - const char *theHost = [self cStringFromString:host]; - const char *thePass = [self cStringFromString:pass]; - const char *theSocket = [self cStringFromString:aSocket]; - void *theRet; - - // Disconnect if it was already connected - if (mConnected) { - [self disconnect]; - mConnection = mysql_init(NULL); - if (mConnection == NULL) return NO; - } - - if (mConnection != NULL) { - // Ensure the custom timeout option is set - mysql_options(mConnection, MYSQL_OPT_CONNECT_TIMEOUT, (const void *)&connectionTimeout); + // Reset any stored connection settings + if (connectionHost) [connectionHost release], connectionHost = nil; + if (connectionLogin) [connectionLogin release], connectionLogin = nil; + if (connectionPassword) [connectionPassword release], connectionPassword = nil; + if (connectionSocket) [connectionSocket release], connectionSocket = nil; - // ensure that automatic reconnection is explicitly disabled - now handled manually. - my_bool falseBool = FALSE; - mysql_options(mConnection, MYSQL_OPT_RECONNECT, &falseBool); + // Determine whether a socket connection should be made + if (!host || ![host length] || [host isEqualToString:@"localhost"]) { + if (!aSocket || ![aSocket length]) { + aSocket = [self findSocketPath]; + if (!aSocket) aSocket = @""; + } + connectionSocket = [[NSString alloc] initWithString:aSocket]; + connectionPort = 0; - // Set the connection encoding to utf8 - mysql_options(mConnection, MYSQL_SET_CHARSET_NAME, [encoding UTF8String]); + // Otherwise, use host and port details + } else { + connectionHost = [[NSString alloc] initWithString:host]; + connectionPort = port; } - if ([host isEqualToString:@""]) { - theHost = NULL; - } - - if (theSocket == NULL) { - theSocket = kMCPConnectionDefaultSocket; - } + // Store the username + connectionLogin = [[NSString alloc] initWithString:(login?login:@"")]; - // Apply SSL if appropriate - if (useSSL) { - mysql_ssl_set(mConnection, - sslKeyFilePath ? [sslKeyFilePath UTF8String] : NULL, - sslCertificatePath ? [sslCertificatePath UTF8String] : NULL, - sslCACertificatePath ? [sslCACertificatePath UTF8String] : NULL, - NULL, - kMCPSSLCipherList); - } - - theRet = mysql_real_connect(mConnection, theHost, theLogin, thePass, NULL, (unsigned int)port, theSocket, mConnectionFlags); - if (theRet != mConnection) { - return mConnected = NO; - } - - mConnected = YES; - const char *mysqlStringEncoding = mysql_character_set_name(mConnection); - [encoding release]; - encoding = [[NSString alloc] initWithUTF8String:mysqlStringEncoding]; - stringEncoding = [MCPConnection encodingForMySQLEncoding:mysqlStringEncoding]; - encodingUsesLatin1Transport = NO; - - // Getting the timezone used by the server. - [self timeZone]; - - return mConnected; + // Store the password if supplied. It is more secure to allow MCPConnection to ask the + // delegate to retrieve details - see delegate method keychainPasswordForConnection:) + if (pass) connectionPassword = [[NSString alloc] initWithString:pass]; + + // Trigger a connection and return the resulting status + return [self connect]; } /** @@ -2856,6 +2818,7 @@ void pingThreadCleanup(void *pingDetails) @"/opt/local/var/run/mysqld/mysqld.sock", // Darwinports MySQL @"/opt/local/var/run/mysql4/mysqld.sock", // Darwinports MySQL 4 @"/opt/local/var/run/mysql5/mysqld.sock", // Darwinports MySQL 5 + @"/usr/local/zend/mysql/tmp/mysql.sock", // Zend Server CE (see Issue #1251) @"/var/run/mysqld/mysqld.sock", // As used on Debian/Gentoo @"/var/tmp/mysql.sock", // As used on FreeBSD @"/var/lib/mysql/mysql.sock", // As used by Fedora @@ -3032,15 +2995,12 @@ void pingThreadCleanup(void *pingDetails) [theSessionTZ dataSeek:0ULL]; theRow = [theSessionTZ fetchRowAsArray]; theTZName = [theRow objectAtIndex:1]; - - if ( [theTZName isKindOfClass:[NSData class]] ) { - // MySQL 4.1.14 returns the mysql variables as NSData - theTZName = [self stringWithText:theTZName]; - } } if (theTZName) { // Old versions of the server does not support there own time zone ? theTZ = [NSTimeZone timeZoneWithName:theTZName]; + if (!theTZ) theTZ = [NSTimeZone timeZoneWithAbbreviation:theTZName]; + if (!theTZ) theTZ = [NSTimeZone defaultTimeZone]; } else { // By default set the time zone to the local one.. // Try to get the name using the previously available variable: @@ -3052,6 +3012,8 @@ void pingThreadCleanup(void *pingDetails) if (theTZName) { // Finally we found one ... theTZ = [NSTimeZone timeZoneWithName:theTZName]; + if (!theTZ) theTZ = [NSTimeZone timeZoneWithAbbreviation:theTZName]; + if (!theTZ) theTZ = [NSTimeZone defaultTimeZone]; } else { theTZ = [NSTimeZone defaultTimeZone]; //theTZ = [NSTimeZone systemTimeZone]; @@ -3328,19 +3290,81 @@ void pingThreadCleanup(void *pingDetails) @implementation MCPConnection (PrivateAPI) /** - * Get the server's version string + * Retrieve connection variables and use them to update local variables - incuding + * server version string, server time zone, and the current connection encoding. */ -- (void)_getServerVersionString +- (void)_updateConnectionVariables { - if (mConnected) { - MCPResult *theResult = [self queryString:@"SHOW VARIABLES LIKE 'version'"]; - [theResult setReturnDataAsStrings:YES]; - - if ([theResult numOfRows]) { - [theResult dataSeek:0]; - serverVersionString = [[NSString stringWithString:[[theResult fetchRowAsArray] objectAtIndex:1]] retain]; + if (!mConnected) return; + + // Retrieve all the variables from the server + MCPResult *theResult = [self queryString:@"SHOW VARIABLES"]; + [theResult setReturnDataAsStrings:YES]; + if (![theResult numOfRows]) return; + + // Step through the rows, converting into an NSDictionary + NSMutableDictionary *variables = [NSMutableDictionary new]; + NSArray *variableRow = nil; + while ((variableRow = [theResult fetchRowAsArray])) { + [variables setObject:[variableRow objectAtIndex:1] forKey:[variableRow objectAtIndex:0]]; + } + + // Get the version string + if (serverVersionString) [serverVersionString release], serverVersionString = nil; + if ([variables objectForKey:@"version"]) { + serverVersionString = [[NSString alloc] initWithString:[variables objectForKey:@"version"]]; + } + + // Get the timezone + NSString *serverTimeZoneName = nil; + NSTimeZone *serverTimeZone = nil; + if ([variables objectForKey:@"time_zone"] && ![[variables objectForKey:@"time_zone"] isNSNull]) { + if ([[variables objectForKey:@"time_zone"] isEqualToString:@"SYSTEM"]) { + if ([variables objectForKey:@"system_time_zone"]) { + serverTimeZoneName = [variables objectForKey:@"system_time_zone"]; + } + } else { + serverTimeZoneName = [variables objectForKey:@"time_zone"]; } + } else if ([variables objectForKey:@"timezone"] && ![[variables objectForKey:@"timezone"] isNSNull]) { + serverTimeZoneName = [variables objectForKey:@"timezone"]; } + if (!serverTimeZoneName) { + serverTimeZone = [NSTimeZone defaultTimeZone]; + NSLog(@"The time zone was not defined on the server, fallen back to default time zone: %@", serverTimeZone); + } else { + serverTimeZone = [NSTimeZone timeZoneWithName:serverTimeZoneName]; + if (!serverTimeZone) + serverTimeZone = [NSTimeZone timeZoneWithAbbreviation:serverTimeZoneName]; + if (!serverTimeZone) { + serverTimeZone = [NSTimeZone defaultTimeZone]; + NSLog(@"The time zone defined on the server (%@) was not recognised, fallen back to default time zone: %@", serverTimeZoneName, serverTimeZone); + } + } + + if (mTimeZone) [mTimeZone release], mTimeZone = nil; + mTimeZone = [serverTimeZone retain]; + + // Get the connection encoding + NSString *serverEncoding = @"latin1"; + if ([variables objectForKey:@"character_set_results"]) { + serverEncoding = [variables objectForKey:@"character_set_results"]; + } else if ([variables objectForKey:@"character_set"]) { + serverEncoding = [variables objectForKey:@"character_set"]; + } + if (encoding) [encoding release]; + encoding = [[NSString alloc] initWithString:serverEncoding]; + stringEncoding = [MCPConnection encodingForMySQLEncoding:[self cStringFromString:encoding]]; + encodingUsesLatin1Transport = NO; + + // Check the interactive timeout - if it's below five minutes, increase it to ten to imprive timeout/keepalive behaviour + if ([variables objectForKey:@"interactive_timeout"]) { + if ([[variables objectForKey:@"interactive_timeout"] integerValue] < 300) { + [self queryString:@"SET interactive_timeout=600"]; + } + } + + [variables release]; } /** diff --git a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m index 84793e44..f112a02d 100644 --- a/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m +++ b/Frameworks/MCPKit/MCPFoundationKit/MCPResult.m @@ -746,7 +746,7 @@ const OUR_CHARSET our_charsets60[] = NSMutableDictionary *fieldStructure = [NSMutableDictionary dictionaryWithCapacity:39]; /* Original column position */ - [fieldStructure setObject:[NSNumber numberWithInteger:i] forKey:@"datacolumnindex"]; + [fieldStructure setObject:[NSString stringWithFormat:@"%llu", (unsigned long long)i] forKey:@"datacolumnindex"]; /* Name of column */ [fieldStructure setObject:[self stringWithCString:theField[i].name] forKey:@"name"]; diff --git a/Frameworks/PSMTabBar/PSMTabDragAssistant.m b/Frameworks/PSMTabBar/PSMTabDragAssistant.m index 5d5b7fcc..21e014da 100644 --- a/Frameworks/PSMTabBar/PSMTabDragAssistant.m +++ b/Frameworks/PSMTabBar/PSMTabDragAssistant.m @@ -337,6 +337,7 @@ static PSMTabDragAssistant *sharedDragAssistant = nil; if ([[[self sourceTabBar] tabView] numberOfTabViewItems] == 1 && [self sourceTabBar] == control && [[[self sourceTabBar] delegate] respondsToSelector:@selector(tabView:newTabBarForDraggedTabViewItem:atPoint:)]) { [[[self sourceTabBar] window] setAlphaValue:0.0f]; + [[[self sourceTabBar] window] setIgnoresMouseEvents:YES]; if ([_sourceTabBar tearOffStyle] == PSMTabBarTearOffAlphaWindow) { [[_draggedView window] setAlphaValue:kPSMTabDragWindowAlpha]; diff --git a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h index d7ab9a56..599bc492 100644 --- a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h +++ b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.h @@ -26,6 +26,8 @@ #import "PSMTabStyle.h" @interface PSMSequelProTabStyle : NSObject <PSMTabStyle> { + SInt32 systemVersion; + NSImage *sequelProCloseButton; NSImage *sequelProCloseButtonDown; NSImage *sequelProCloseButtonOver; diff --git a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m index ece10a76..05c4ada2 100644 --- a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m +++ b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m @@ -46,6 +46,9 @@ - (id) init { if ( (self = [super init]) ) { + systemVersion = 0; + Gestalt(gestaltSystemVersion, &systemVersion); + sequelProCloseButton = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose"]]; sequelProCloseButtonDown = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose_Pressed"]]; sequelProCloseButtonOver = [[NSImage alloc] initByReferencingFile:[[PSMTabBarControl bundle] pathForImageResource:@"SequelProTabClose_Rollover"]]; @@ -405,12 +408,15 @@ [[NSGraphicsContext currentContext] setShouldAntialias:NO]; float backgroundCalibratedWhite = 0.495f; + if (systemVersion >= 0x1070) backgroundCalibratedWhite = 0.55f; + float lineCalibratedWhite = [[NSColor darkGrayColor] whiteComponent]; float shadowAlpha = 0.4f; // When the window is in the background, tone down the colours if (![[tabBar window] isMainWindow] || ![NSApp isActive]) { backgroundCalibratedWhite = 0.73f; + if (systemVersion >= 0x1070) backgroundCalibratedWhite = 0.79f; lineCalibratedWhite = 0.49f; shadowAlpha = 0.3f; } @@ -502,19 +508,19 @@ if ([[tabBar window] isMainWindow] && [NSApp isActive]) { lineColor = [NSColor darkGrayColor]; if ([cell state] == NSOnState) { - fillColor = [NSColor colorWithCalibratedWhite:0.59f alpha:1.0f]; + fillColor = [NSColor colorWithCalibratedWhite:(systemVersion >= 0x1070)?0.63f:0.59f alpha:1.0f]; shadowColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.7f]; } else { - fillColor = [NSColor colorWithCalibratedWhite:0.495f alpha:1.0f]; + fillColor = [NSColor colorWithCalibratedWhite:(systemVersion >= 0x1070)?0.55f:0.495f alpha:1.0f]; shadowColor = [NSColor colorWithCalibratedWhite:0.0f alpha:1.0f]; } } else { lineColor = [NSColor colorWithCalibratedWhite:0.49f alpha:1.0f]; if ([cell state] == NSOnState) { - fillColor = [NSColor colorWithCalibratedWhite:0.81f alpha:1.0f]; + fillColor = [NSColor colorWithCalibratedWhite:(systemVersion >= 0x1070)?0.85f:0.81f alpha:1.0f]; shadowColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.4f]; } else { - fillColor = [NSColor colorWithCalibratedWhite:0.73f alpha:1.0f]; + fillColor = [NSColor colorWithCalibratedWhite:(systemVersion >= 0x1070)?0.79f:0.73f alpha:1.0f]; shadowColor = [NSColor colorWithCalibratedWhite:0.0f alpha:0.7f]; } } 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> |