diff options
author | stuconnolly <stuart02@gmail.com> | 2012-04-16 20:16:52 +0000 |
---|---|---|
committer | stuconnolly <stuart02@gmail.com> | 2012-04-16 20:16:52 +0000 |
commit | 4cad6f0e6e4fb497b480256c2abe3de34ebf225c (patch) | |
tree | b66d6a72a1537cf98624acf3c685f1a4d916fd86 /Frameworks | |
parent | 0d3b69f964a8d9d93ca794d457b461463f1ec95d (diff) | |
download | sequelpro-4cad6f0e6e4fb497b480256c2abe3de34ebf225c.tar.gz sequelpro-4cad6f0e6e4fb497b480256c2abe3de34ebf225c.tar.bz2 sequelpro-4cad6f0e6e4fb497b480256c2abe3de34ebf225c.zip |
Bring outline view branch up to date with trunk.
Diffstat (limited to 'Frameworks')
47 files changed, 819 insertions, 479 deletions
diff --git a/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter b/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter Binary files differindex 6b9802a9..67f472ab 100755 --- a/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter +++ b/Frameworks/FeedbackReporter.framework/Versions/A/FeedbackReporter diff --git a/Frameworks/PSMTabBar/PSMRolloverButton.m b/Frameworks/PSMTabBar/PSMRolloverButton.m index 988abbb2..eebbd68e 100644 --- a/Frameworks/PSMTabBar/PSMRolloverButton.m +++ b/Frameworks/PSMTabBar/PSMRolloverButton.m @@ -24,6 +24,8 @@ [self resetCursorRects]; _myTrackingRectTag = -1; + _rolloverImage = nil; + _usualImage = nil; } - (void)dealloc @@ -31,6 +33,8 @@ [[NSNotificationCenter defaultCenter] removeObserver:self]; [self removeTrackingRect]; + [_rolloverImage release]; + [_usualImage release]; [super dealloc]; } diff --git a/Frameworks/PSMTabBar/PSMTabBarControl.h b/Frameworks/PSMTabBar/PSMTabBarControl.h index 481bb3b8..d2cbc534 100644 --- a/Frameworks/PSMTabBar/PSMTabBarControl.h +++ b/Frameworks/PSMTabBar/PSMTabBarControl.h @@ -16,6 +16,7 @@ #define PSMTabDragDidBeginNotification @"PSMTabDragDidBeginNotification" #define kPSMTabBarControlHeight 22 +#define kPSMTabBarControlHeightCollapsed 1 // internal cell border #define MARGIN_X 6 #define MARGIN_Y 3 @@ -205,6 +206,7 @@ enum { - (void)hideTabBar:(BOOL)hide animate:(BOOL)animate; - (BOOL)isTabBarHidden; - (BOOL)isAnimating; +- (void)destroyAnimations; // internal bindings methods also used by the tab drag assistant - (void)bindPropertiesForCell:(PSMTabBarCell *)cell andTabViewItem:(NSTabViewItem *)item; diff --git a/Frameworks/PSMTabBar/PSMTabBarControl.m b/Frameworks/PSMTabBar/PSMTabBarControl.m index a38c50b0..2a92a2b1 100644 --- a/Frameworks/PSMTabBar/PSMTabBarControl.m +++ b/Frameworks/PSMTabBar/PSMTabBarControl.m @@ -202,17 +202,8 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; - - //stop any animations that may be running - [_animationTimer invalidate]; - [_animationTimer release]; _animationTimer = nil; - - [_showHideAnimationTimer invalidate]; - [_showHideAnimationTimer release]; _showHideAnimationTimer = nil; - //Also unwind the spring, if it's wound. - [_springTimer invalidate]; - [_springTimer release]; _springTimer = nil; + [self destroyAnimations]; //unbind all the items to prevent crashing //not sure if this is necessary or not @@ -796,7 +787,7 @@ - (void)hideTabBar:(BOOL)hide animate:(BOOL)animate { - if (!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide) || (_currentStep != kPSMIsNotBeingResized)) { + if (!_awakenedFromNib || (_isHidden && hide) || (!_isHidden && !hide)) { return; } @@ -830,55 +821,35 @@ partnerOriginalSize = [[self window] frame].size.height; partnerOriginalOrigin = [[self window] frame].origin.y; } - + + // Determine the target sizes + if (_isHidden) { + myTargetSize = kPSMTabBarControlHeightCollapsed; + } else { + myTargetSize = kPSMTabBarControlHeight; + } + if (partnerView) { + partnerTargetSize = partnerOriginalSize + myOriginalSize - myTargetSize; + // above or below me? - if ((myOriginalOrigin - 22) > partnerOriginalOrigin) { - // partner is below me - if (_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin + 21; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize + 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin - 21; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin; - partnerTargetSize = partnerOriginalSize - 21; - } + if ((myOriginalOrigin - kPSMTabBarControlHeight) > partnerOriginalOrigin) { + + // partner is below me, keeps its origin + partnerTargetOrigin = partnerOriginalOrigin; + myTargetOrigin = myOriginalOrigin + myOriginalSize - myTargetSize; } else { - // partner is above me - if (_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin - 21; - partnerTargetSize = partnerOriginalSize + 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin + 21; - partnerTargetSize = partnerOriginalSize - 21; - } + + // partner is above me, I keep my origin + myTargetOrigin = myOriginalOrigin; + partnerTargetOrigin = partnerOriginalOrigin + myOriginalSize - myTargetSize; } } else { + // for window movement - if (_isHidden) { - // I'm shrinking - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize - 21; - partnerTargetOrigin = partnerOriginalOrigin + 21; - partnerTargetSize = partnerOriginalSize - 21; - } else { - // I'm growing - myTargetOrigin = myOriginalOrigin; - myTargetSize = myOriginalSize + 21; - partnerTargetOrigin = partnerOriginalOrigin - 21; - partnerTargetSize = partnerOriginalSize + 21; - } + myTargetOrigin = myOriginalOrigin; + partnerTargetOrigin = partnerOriginalOrigin + myOriginalSize - myTargetSize; + partnerTargetSize = partnerOriginalSize - myOriginalSize + myTargetSize; } } else /* vertical */ { // current (original) values @@ -1046,6 +1017,21 @@ partnerView = view; } +- (void)destroyAnimations +{ + // Stop any animations that may be running + + [_animationTimer invalidate]; + [_animationTimer release]; _animationTimer = nil; + + [_showHideAnimationTimer invalidate]; + [_showHideAnimationTimer release]; _showHideAnimationTimer = nil; + + // Also unwind the spring, if it's wound. + [_springTimer invalidate]; + [_springTimer release]; _springTimer = nil; +} + #pragma mark - #pragma mark Drawing @@ -1368,7 +1354,7 @@ - (void)mouseDragged:(NSEvent *)theEvent { - if ([self lastMouseDownEvent] == nil) { + if (![self lastMouseDownEvent]) { return; } @@ -1426,6 +1412,10 @@ - (void)mouseUp:(NSEvent *)theEvent { + if (![self lastMouseDownEvent]) { + return; + } + if (_resizing) { _resizing = NO; [[NSCursor arrowCursor] set]; @@ -1474,6 +1464,9 @@ _closeClicked = NO; } + + // Clear the last mouse down event to prevent drag issues + [self setLastMouseDownEvent:nil]; } - (NSMenu *)menuForEvent:(NSEvent *)event diff --git a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m index 05c4ada2..b0a96ccd 100644 --- a/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m +++ b/Frameworks/PSMTabBar/Styles/PSMSequelProTabStyle.m @@ -364,7 +364,7 @@ } [self drawBackgroundInRect:rect]; - + // no tab view == not connected if (![bar tabView]) { NSRect labelRect = rect; @@ -530,7 +530,7 @@ NSRect aRect = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width, cellFrame.size.height); // If the tab bar is hidden, don't draw the top pixel - if ([tabBar isTabBarHidden]) { + if ([tabBar isTabBarHidden] && [tabBar frame].size.height == kPSMTabBarControlHeightCollapsed) { aRect.origin.y++; aRect.size.height--; } @@ -655,21 +655,10 @@ { NSRect cellFrame = [cell frame]; CGFloat insetLabelWidth = 0; - BOOL tabBarIsRightOfSelectedTab = NO; - - // Determine if the selected tab is right of this tab - for (PSMTabBarCell *aCell in [tabBar cells]) { - if (aCell == cell) break; - if ([aCell state] == NSOnState) { - tabBarIsRightOfSelectedTab = YES; - break; - } - } - + // close button if ([cell hasCloseButton] && ![cell isCloseButtonSuppressed] && [cell isHighlighted]) { - NSSize closeButtonSize = NSZeroSize; NSRect closeButtonRect = [cell closeButtonRectForFrame:cellFrame]; NSImage * closeButton = nil; @@ -677,9 +666,7 @@ if ([cell closeButtonOver]) closeButton = [cell isEdited] ? sequelProCloseDirtyButtonOver : sequelProCloseButtonOver; if ([cell closeButtonPressed]) closeButton = [cell isEdited] ? sequelProCloseDirtyButtonDown : sequelProCloseButtonDown; - - closeButtonSize = [closeButton size]; - + if ([controlView isFlipped]) { closeButtonRect.origin.y += closeButtonRect.size.height; } diff --git a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj index 89c50725..8b5221ae 100644 --- a/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj +++ b/Frameworks/QueryKit/QueryKit.xcodeproj/project.pbxproj @@ -9,6 +9,9 @@ /* Begin PBXBuildFile section */ 1713ECB014F96A5C0013C4F0 /* QKSelectQueryOrderByTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1713ECAF14F96A5C0013C4F0 /* QKSelectQueryOrderByTests.m */; }; 1713ECD814F970BB0013C4F0 /* QKSelectQueryGroupByTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1713ECD714F970BB0013C4F0 /* QKSelectQueryGroupByTests.m */; }; + 1719E47D151E8CA7003F98C5 /* QKQueryUpdateParameter.h in Headers */ = {isa = PBXBuildFile; fileRef = 1719E47B151E8CA7003F98C5 /* QKQueryUpdateParameter.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1719E47E151E8CA7003F98C5 /* QKQueryUpdateParameter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1719E47C151E8CA7003F98C5 /* QKQueryUpdateParameter.m */; }; + 1719E4BD151F51F1003F98C5 /* QKUpdateQueryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1719E4BA151F51EA003F98C5 /* QKUpdateQueryTests.m */; }; 17E5951F14F301DF0054EE08 /* QKQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 17E5951614F301DF0054EE08 /* QKQuery.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17E5952014F301DF0054EE08 /* QKQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E5951714F301DF0054EE08 /* QKQuery.m */; }; 17E5952114F301DF0054EE08 /* QKQueryOperators.h in Headers */ = {isa = PBXBuildFile; fileRef = 17E5951814F301DF0054EE08 /* QKQueryOperators.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -39,6 +42,10 @@ 1713ECAF14F96A5C0013C4F0 /* QKSelectQueryOrderByTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKSelectQueryOrderByTests.m; sourceTree = "<group>"; }; 1713ECD614F970BB0013C4F0 /* QKSelectQueryGroupByTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKSelectQueryGroupByTests.h; sourceTree = "<group>"; }; 1713ECD714F970BB0013C4F0 /* QKSelectQueryGroupByTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKSelectQueryGroupByTests.m; sourceTree = "<group>"; }; + 1719E47B151E8CA7003F98C5 /* QKQueryUpdateParameter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryUpdateParameter.h; sourceTree = "<group>"; }; + 1719E47C151E8CA7003F98C5 /* QKQueryUpdateParameter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQueryUpdateParameter.m; sourceTree = "<group>"; }; + 1719E4B9151F51EA003F98C5 /* QKUpdateQueryTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKUpdateQueryTests.h; sourceTree = "<group>"; }; + 1719E4BA151F51EA003F98C5 /* QKUpdateQueryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKUpdateQueryTests.m; sourceTree = "<group>"; }; 17E5951614F301DF0054EE08 /* QKQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQuery.h; sourceTree = "<group>"; }; 17E5951714F301DF0054EE08 /* QKQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = QKQuery.m; sourceTree = "<group>"; }; 17E5951814F301DF0054EE08 /* QKQueryOperators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = QKQueryOperators.h; sourceTree = "<group>"; }; @@ -124,15 +131,25 @@ 17E5951E14F301DF0054EE08 /* QueryKit.h */, 17E5951614F301DF0054EE08 /* QKQuery.h */, 17E5951714F301DF0054EE08 /* QKQuery.m */, - 17E5951914F301DF0054EE08 /* QKQueryParameter.h */, - 17E5951A14F301DF0054EE08 /* QKQueryParameter.m */, 17E5951C14F301DF0054EE08 /* QKQueryUtilities.h */, 17E5951D14F301DF0054EE08 /* QKQueryUtilities.m */, + 1719E47A151E8C87003F98C5 /* Model */, 17E5952814F301F40054EE08 /* Constants */, ); path = Source; sourceTree = "<group>"; }; + 1719E47A151E8C87003F98C5 /* Model */ = { + isa = PBXGroup; + children = ( + 17E5951914F301DF0054EE08 /* QKQueryParameter.h */, + 17E5951A14F301DF0054EE08 /* QKQueryParameter.m */, + 1719E47B151E8CA7003F98C5 /* QKQueryUpdateParameter.h */, + 1719E47C151E8CA7003F98C5 /* QKQueryUpdateParameter.m */, + ); + name = Model; + sourceTree = "<group>"; + }; 17322A7214FA645300F0CF9B /* SELECT Tests */ = { isa = PBXGroup; children = ( @@ -149,6 +166,8 @@ 17322A7414FA646000F0CF9B /* UPDATE Tests */ = { isa = PBXGroup; children = ( + 1719E4B9151F51EA003F98C5 /* QKUpdateQueryTests.h */, + 1719E4BA151F51EA003F98C5 /* QKUpdateQueryTests.m */, ); name = "UPDATE Tests"; sourceTree = "<group>"; @@ -200,6 +219,7 @@ 17E5952414F301DF0054EE08 /* QKQueryTypes.h in Headers */, 17E5952514F301DF0054EE08 /* QKQueryUtilities.h in Headers */, 17E5952714F301DF0054EE08 /* QueryKit.h in Headers */, + 1719E47D151E8CA7003F98C5 /* QKQueryUpdateParameter.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -311,6 +331,7 @@ 17E596A814F308160054EE08 /* QKSelectQueryTests.m in Sources */, 1713ECB014F96A5C0013C4F0 /* QKSelectQueryOrderByTests.m in Sources */, 1713ECD814F970BB0013C4F0 /* QKSelectQueryGroupByTests.m in Sources */, + 1719E4BD151F51F1003F98C5 /* QKUpdateQueryTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -321,6 +342,7 @@ 17E5952014F301DF0054EE08 /* QKQuery.m in Sources */, 17E5952314F301DF0054EE08 /* QKQueryParameter.m in Sources */, 17E5952614F301DF0054EE08 /* QKQueryUtilities.m in Sources */, + 1719E47E151E8CA7003F98C5 /* QKQueryUpdateParameter.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -338,7 +360,11 @@ 17E5952D14F302740054EE08 /* Distribution */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = ( + i386, + ppc, + x86_64, + ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Source/QueryKit-Prefix.pch"; @@ -348,8 +374,8 @@ INFOPLIST_FILE = Resources/Info.plist; INFOPLIST_PREFIX_HEADER = ""; PREBINDING = NO; - SDKROOT = macosx10.6; - VALID_ARCHS = "i386 x86_64"; + SDKROOT = macosx10.5; + VALID_ARCHS = "i386 ppc x86_64"; }; name = Distribution; }; @@ -518,18 +544,12 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = ( - i386, - x86_64, - ppc, - ); DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; FRAMEWORK_VERSION = A; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Source/QueryKit-Prefix.pch"; - GCC_SYMBOLS_PRIVATE_EXTERN = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = YES; @@ -554,8 +574,6 @@ INFOPLIST_FILE = Resources/Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; PRODUCT_NAME = QueryKit; - SDKROOT = macosx10.5; - VALID_ARCHS = "ppc i386 x86_64"; WRAPPER_EXTENSION = framework; }; name = Release; @@ -563,7 +581,11 @@ 1DEB91B208733DA50010E9CD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = ( + i386, + ppc, + x86_64, + ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_OPTIMIZATION_LEVEL = 0; GCC_PRECOMPILE_PREFIX_HEADER = YES; @@ -575,15 +597,19 @@ INFOPLIST_PREFIX_HEADER = ""; ONLY_ACTIVE_ARCH = YES; PREBINDING = NO; - SDKROOT = macosx10.6; - VALID_ARCHS = "i386 x86_64"; + SDKROOT = macosx10.5; + VALID_ARCHS = "i386 ppc x86_64"; }; name = Debug; }; 1DEB91B308733DA50010E9CD /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + ARCHS = ( + i386, + ppc, + x86_64, + ); GCC_C_LANGUAGE_STANDARD = gnu99; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Source/QueryKit-Prefix.pch"; @@ -593,8 +619,8 @@ INFOPLIST_FILE = Resources/Info.plist; INFOPLIST_PREFIX_HEADER = ""; PREBINDING = NO; - SDKROOT = macosx10.6; - VALID_ARCHS = "i386 x86_64"; + SDKROOT = macosx10.5; + VALID_ARCHS = "i386 ppc x86_64"; }; name = Release; }; diff --git a/Frameworks/QueryKit/Source/QKQuery.h b/Frameworks/QueryKit/Source/QKQuery.h index b45dc556..c0f925bb 100644 --- a/Frameworks/QueryKit/Source/QKQuery.h +++ b/Frameworks/QueryKit/Source/QKQuery.h @@ -2,7 +2,7 @@ // $Id: QKQuery.h 3421 2011-09-10 22:58:45Z stuart02 $ // // QKQuery.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,12 +27,11 @@ // 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" +#import "QKQueryUpdateParameter.h" /** * @class QKQuery QKQuery.h @@ -47,8 +46,10 @@ NSString *_table; NSMutableString *_query; + NSMutableArray *_parameters; NSMutableArray *_fields; + NSMutableArray *_updateParameters; NSMutableArray *_groupByFields; NSMutableArray *_orderByFields; @@ -79,6 +80,11 @@ @property (readwrite, retain, getter=fields, setter=setFields:) NSMutableArray *_fields; /** + * @property _updateFields The fields of an UPDATE query. + */ +@property (readwrite, retain, getter=updateParameters, setter=setUpdateParameters:) NSMutableArray *_updateParameters; + +/** * @property _queryType The type of query to be built. */ @property (readwrite, assign, getter=queryType, setter=setQueryType:) QKQueryType _queryType; @@ -94,6 +100,7 @@ - (id)initWithTable:(NSString *)table; - (NSString *)query; +- (void)clear; - (void)addField:(NSString *)field; - (void)addFields:(NSArray *)fields; @@ -101,6 +108,9 @@ - (void)addParameter:(QKQueryParameter *)parameter; - (void)addParameter:(NSString *)field operator:(QKQueryOperator)operator value:(id)value; +- (void)addFieldToUpdate:(QKQueryUpdateParameter *)parameter; +- (void)addFieldToUpdate:(NSString *)field toValue:(id)value; + - (void)groupByField:(NSString *)field; - (void)groupByFields:(NSArray *)fields; diff --git a/Frameworks/QueryKit/Source/QKQuery.m b/Frameworks/QueryKit/Source/QKQuery.m index 21053203..4be29ae2 100644 --- a/Frameworks/QueryKit/Source/QKQuery.m +++ b/Frameworks/QueryKit/Source/QKQuery.m @@ -2,7 +2,7 @@ // $Id: QKQuery.m 3432 2011-09-27 00:21:35Z stuart02 $ // // QKQuery.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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" @@ -44,6 +42,8 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; - (NSString *)_buildConstraints; - (NSString *)_buildGroupByClause; - (NSString *)_buildOrderByClause; +- (NSString *)_buildUpdateClause; +- (NSString *)_buildSelectOptions; - (BOOL)_addString:(NSString *)string toArray:(NSMutableArray *)array; @@ -56,6 +56,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; @synthesize _parameters; @synthesize _queryType; @synthesize _fields; +@synthesize _updateParameters; @synthesize _quoteFields; #pragma mark - @@ -80,6 +81,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; if ((self = [super init])) { [self setTable:table]; [self setFields:[[NSMutableArray alloc] init]]; + [self setUpdateParameters:[[NSMutableArray alloc] init]]; [self setParameters:[[NSMutableArray alloc] init]]; [self setQueryType:(QKQueryType)-1]; [self setQuoteFields:NO]; @@ -98,11 +100,32 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; #pragma mark - #pragma mark Public API +/** + * Requests that the query be built. + * + * @return The generated query. + */ - (NSString *)query { return _query ? [self _buildQuery] : @""; } +/** + * Clears anything this instance should know about the query it's building. + */ +- (void)clear +{ + [self setTable:nil]; + [self setDatabase:nil]; + [self setQueryType:(QKQueryType)-1]; + + [_fields removeAllObjects]; + [_parameters removeAllObjects]; + [_updateParameters removeAllObjects]; + [_groupByFields removeAllObjects]; + [_orderByFields removeAllObjects]; +} + #pragma mark - #pragma mark Fields @@ -151,6 +174,29 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; } #pragma mark - +#pragma mark Update Parameters + +/** + * Adds the supplied update parameter. + * + * @param parameter The parameter to add. + */ +- (void)addFieldToUpdate:(QKQueryUpdateParameter *)parameter +{ + if ([parameter field] && ([[parameter field] length] > 0) && [parameter value]) { + [_updateParameters addObject:parameter]; + } +} + +/** + * Convenience method for adding a new update parameter. + */ +- (void)addFieldToUpdate:(NSString *)field toValue:(id)value +{ + [self addFieldToUpdate:[QKQueryUpdateParameter queryUpdateParamWithField:field value:value]]; +} + +#pragma mark - #pragma mark Grouping /** @@ -220,10 +266,10 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; { [self _validateRequiements]; - BOOL isSelect = (_queryType == QKSelectQuery); - BOOL isInsert = (_queryType == QKInsertQuery); - BOOL isUpdate = (_queryType == QKUpdateQuery); - BOOL isDelete = (_queryType == QKDeleteQuery); + BOOL isSelect = _queryType == QKSelectQuery; + BOOL isInsert = _queryType == QKInsertQuery; + BOOL isUpdate = _queryType == QKUpdateQuery; + BOOL isDelete = _queryType == QKDeleteQuery; NSString *fields = [self _buildFieldList]; @@ -246,22 +292,16 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; [_query appendString:_table]; + if (isUpdate) { + [_query appendFormat:@" %@", [self _buildUpdateClause]]; + } + if ([_parameters count] > 0) { - [_query appendString:@" WHERE "]; - [_query appendString:[self _buildConstraints]]; + [_query appendFormat:@" WHERE %@", [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]; - } + [_query appendString:[self _buildSelectOptions]]; } return _query; @@ -317,7 +357,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; for (QKQueryParameter *param in _parameters) { - [constraints appendFormat:@"%@ ", param]; + [constraints appendFormat:@"%@", param]; [constraints appendString:@" AND "]; } @@ -384,6 +424,54 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; } /** + * Builds the string representation of the query's UPDATE parameters. + * + * @return The fields to be updated + */ +- (NSString *)_buildUpdateClause +{ + NSMutableString *update = [NSMutableString string]; + + if ([_updateParameters count] == 0) return update; + + [update appendString:@"SET "]; + + for (QKQueryUpdateParameter *param in _updateParameters) + { + [update appendFormat:@"%@, ", param]; + } + + if ([update hasSuffix:@", "]) { + [update setString:[update substringToIndex:([update length] - 2)]]; + } + + return update; +} + +/** + * Builds any SELECT specific query constraints, namely ORDER BY or GROUP BY clauses. + * + * @return The query clauses (if any). + */ +- (NSString *)_buildSelectOptions +{ + NSMutableString *string = [NSMutableString string]; + + NSString *groupBy = [self _buildGroupByClause]; + NSString *orderBy = [self _buildOrderByClause]; + + if ([groupBy length] > 0) { + [string appendFormat:@" %@", groupBy]; + } + + if ([orderBy length] > 0) { + [string appendFormat:@" %@", orderBy]; + } + + return string; +} + +/** * 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 @@ -427,6 +515,7 @@ static NSString *QKNoQueryTableException = @"QKNoQueryTable"; if (_query) [_query release], _query = nil; if (_parameters) [_parameters release], _parameters = nil; if (_fields) [_fields release], _fields = nil; + if (_updateParameters) [_updateParameters release], _updateParameters = nil; if (_groupByFields) [_groupByFields release], _groupByFields = nil; if (_orderByFields) [_orderByFields release], _orderByFields = nil; diff --git a/Frameworks/QueryKit/Source/QKQueryOperators.h b/Frameworks/QueryKit/Source/QKQueryOperators.h index 32e64563..0c7565e0 100644 --- a/Frameworks/QueryKit/Source/QKQueryOperators.h +++ b/Frameworks/QueryKit/Source/QKQueryOperators.h @@ -2,7 +2,7 @@ // $Id: QKQueryOperators.h 3423 2011-09-12 16:50:15Z stuart02 $ // // QKQueryOperators.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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 diff --git a/Frameworks/QueryKit/Source/QKQueryParameter.h b/Frameworks/QueryKit/Source/QKQueryParameter.h index 78c5739f..18f87929 100644 --- a/Frameworks/QueryKit/Source/QKQueryParameter.h +++ b/Frameworks/QueryKit/Source/QKQueryParameter.h @@ -2,7 +2,7 @@ // $Id: QKQueryParameter.h 3421 2011-09-10 22:58:45Z stuart02 $ // // QKQueryParameter.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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" diff --git a/Frameworks/QueryKit/Source/QKQueryParameter.m b/Frameworks/QueryKit/Source/QKQueryParameter.m index 7f6064e6..c95bf585 100644 --- a/Frameworks/QueryKit/Source/QKQueryParameter.m +++ b/Frameworks/QueryKit/Source/QKQueryParameter.m @@ -2,7 +2,7 @@ // $Id: QKQueryParameter.m 3432 2011-09-27 00:21:35Z stuart02 $ // // QKQueryParameter.m -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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" diff --git a/Frameworks/QueryKit/Source/QKQueryTypes.h b/Frameworks/QueryKit/Source/QKQueryTypes.h index 4ab338ec..96978ce2 100644 --- a/Frameworks/QueryKit/Source/QKQueryTypes.h +++ b/Frameworks/QueryKit/Source/QKQueryTypes.h @@ -2,7 +2,7 @@ // $Id: QKQueryTypes.h 3423 2011-09-12 16:50:15Z stuart02 $ // // QKQueryTypes.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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 diff --git a/Frameworks/QueryKit/Source/QKQueryUpdateParameter.h b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.h new file mode 100644 index 00000000..5231d272 --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.h @@ -0,0 +1,59 @@ +// +// $Id$ +// +// QKQueryUpdateParameter.h +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on March 24, 2012 +// Copyright (c) 2012 Stuart Connolly. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. + +/** + * @class QKQueryUpdateParameter QKQueryUpdateParameter.h + * + * @author Stuart Connolly http://stuconnolly.com/ + * + * QueryKit update query parameter class. + */ +@interface QKQueryUpdateParameter : NSObject +{ + NSString *_field; + + id _value; +} + +/** + * @property _field The field component of the parameter. + */ +@property (readwrite, retain, getter=field, setter=setField:) NSString *_field; + +/** + *@property _value The value component of the parameter. + */ +@property (readwrite, retain, getter=value, setter=setValue:) id _value; + ++ (QKQueryUpdateParameter *)queryUpdateParamWithField:(NSString *)field value:(id)value; + +- (id)initUpdateParamWithField:(NSString *)field value:(id)value; + +@end diff --git a/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m new file mode 100644 index 00000000..febbfa44 --- /dev/null +++ b/Frameworks/QueryKit/Source/QKQueryUpdateParameter.m @@ -0,0 +1,81 @@ +// +// $Id$ +// +// QKQueryUpdateParameter.m +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on March 24, 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 "QKQueryUpdateParameter.h" + +@implementation QKQueryUpdateParameter + +@synthesize _field; +@synthesize _value; + +#pragma mark - +#pragma mark Initialisation + ++ (QKQueryUpdateParameter *)queryUpdateParamWithField:(NSString *)field value:(id)value +{ + return [[[QKQueryUpdateParameter alloc] initUpdateParamWithField:field value:value] autorelease]; +} + +- (id)initUpdateParamWithField:(NSString *)field value:(id)value +{ + if ((self = [super init])) { + [self setField:field]; + [self setValue:value]; + } + + return self; +} + +#pragma mark - + +- (NSString *)description +{ + NSMutableString *string = [NSMutableString string]; + + NSString *field = [_field stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + + [string appendString:field]; + [string appendString:@" = "]; + [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/Source/QKQueryUtilities.h b/Frameworks/QueryKit/Source/QKQueryUtilities.h index 9049b191..228385f8 100644 --- a/Frameworks/QueryKit/Source/QKQueryUtilities.h +++ b/Frameworks/QueryKit/Source/QKQueryUtilities.h @@ -2,7 +2,7 @@ // $Id: QKQueryUtilities.h 3421 2011-09-10 22:58:45Z stuart02 $ // // QKQueryUtilities.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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" diff --git a/Frameworks/QueryKit/Source/QKQueryUtilities.m b/Frameworks/QueryKit/Source/QKQueryUtilities.m index dde1bd77..8519eb20 100644 --- a/Frameworks/QueryKit/Source/QKQueryUtilities.m +++ b/Frameworks/QueryKit/Source/QKQueryUtilities.m @@ -2,7 +2,7 @@ // $Id: QKQueryUtilities.m 3421 2011-09-10 22:58:45Z stuart02 $ // // QKQueryUtilities.m -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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" diff --git a/Frameworks/QueryKit/Source/QueryKit.h b/Frameworks/QueryKit/Source/QueryKit.h index f8570025..2b62a7b5 100644 --- a/Frameworks/QueryKit/Source/QueryKit.h +++ b/Frameworks/QueryKit/Source/QueryKit.h @@ -2,7 +2,7 @@ // $Id: QueryKit.h 3431 2011-09-26 22:26:24Z stuart02 $ // // QueryKit.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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> diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.h b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.h index 56907b36..1be5345b 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.h +++ b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.h @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryGroupByTests.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on February 25, 2012 // Copyright (c) 2012 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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/QueryKit.h> #import <SenTestingKit/SenTestingKit.h> diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m index 9bbe75a2..0a8277e0 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m +++ b/Frameworks/QueryKit/Tests/QKSelectQueryGroupByTests.m @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryGroupByTests.m -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on February 25, 2012 // Copyright (c) 2012 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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 "QKSelectQueryGroupByTests.h" diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.h b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.h index c457491a..1ced6503 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.h +++ b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.h @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryOrderByTests.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on February 25, 2012 // Copyright (c) 2012 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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/QueryKit.h> #import <SenTestingKit/SenTestingKit.h> diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m index 84bd5ddb..ac70f0fe 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m +++ b/Frameworks/QueryKit/Tests/QKSelectQueryOrderByTests.m @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryOrderByTests.m -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on February 25, 2012 // Copyright (c) 2012 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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 "QKSelectQueryOrderByTests.h" diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryTests.h b/Frameworks/QueryKit/Tests/QKSelectQueryTests.h index df9e3272..80ea92e2 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryTests.h +++ b/Frameworks/QueryKit/Tests/QKSelectQueryTests.h @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryTests.h -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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/QueryKit.h> #import <SenTestingKit/SenTestingKit.h> diff --git a/Frameworks/QueryKit/Tests/QKSelectQueryTests.m b/Frameworks/QueryKit/Tests/QKSelectQueryTests.m index 620dbadd..cb2d3599 100644 --- a/Frameworks/QueryKit/Tests/QKSelectQueryTests.m +++ b/Frameworks/QueryKit/Tests/QKSelectQueryTests.m @@ -2,7 +2,7 @@ // $Id$ // // QKSelectQueryTests.m -// sequel-pro +// QueryKit // // Created by Stuart Connolly (stuconnolly.com) on September 4, 2011 // Copyright (c) 2011 Stuart Connolly. All rights reserved. @@ -27,8 +27,6 @@ // 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 "QKSelectQueryTests.h" diff --git a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.h b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.h new file mode 100644 index 00000000..b4230c1f --- /dev/null +++ b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.h @@ -0,0 +1,39 @@ +// +// $Id$ +// +// QKUpdateQueryTests.h +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on March 25, 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 <QueryKit/QueryKit.h> +#import <SenTestingKit/SenTestingKit.h> + +@interface QKUpdateQueryTests : SenTestCase +{ + QKQuery *_query; +} + +@end diff --git a/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m new file mode 100644 index 00000000..fa3bb766 --- /dev/null +++ b/Frameworks/QueryKit/Tests/QKUpdateQueryTests.m @@ -0,0 +1,82 @@ +// +// $Id$ +// +// QKUpdateQueryTests.m +// QueryKit +// +// Created by Stuart Connolly (stuconnolly.com) on March 25, 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 "QKUpdateQueryTests.h" + +static NSString *QKTestTableName = @"test_table"; + +static NSString *QKTestFieldOne = @"test_field1"; +static NSString *QKTestFieldTwo = @"test_field2"; + +static NSString *QKTestUpdateValueOne = @"update_one"; +static NSString *QKTestUpdateValueTwo = @"update_two"; + +static NSUInteger QKTestParameterOne = 10; + +@implementation QKUpdateQueryTests + +#pragma mark - +#pragma mark Setup & tear down + +- (void)setUp +{ + _query = [QKQuery queryTable:QKTestTableName]; + + [_query setQueryType:QKUpdateQuery]; + + [_query addFieldToUpdate:QKTestFieldOne toValue:QKTestUpdateValueOne]; + [_query addFieldToUpdate:QKTestFieldTwo toValue:QKTestUpdateValueTwo]; + + [_query addParameter:QKTestFieldOne operator:QKEqualityOperator value:[NSNumber numberWithUnsignedInteger:QKTestParameterOne]]; +} + +#pragma mark - +#pragma mark Tests + +- (void)testUpdateQueryTypeIsCorrect +{ + STAssertTrue([[_query query] hasPrefix:@"UPDATE"], @"query type"); +} + +- (void)testUpdateQueryFieldsAreCorrect +{ + NSString *query = [NSString stringWithFormat:@"UPDATE %@ SET %@ = '%@', %@ = '%@'", QKTestTableName, QKTestFieldOne, QKTestUpdateValueOne, QKTestFieldTwo, QKTestUpdateValueTwo]; + + STAssertTrue([[_query query] hasPrefix:query], @"query fields"); +} + +- (void)testUpdateQueryConstraintsAreCorrect +{ + NSString *query = [NSString stringWithFormat:@"WHERE %@ %@ %@", QKTestFieldOne, [QKQueryUtilities operatorRepresentationForType:QKEqualityOperator], [NSNumber numberWithUnsignedInteger:QKTestParameterOne]]; + + STAssertTrue(([[_query query] rangeOfString:query].location != NSNotFound), @"query constraints"); +} + +@end diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_alloc.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_alloc.h index 93b7438a..9e2ef541 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_alloc.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_alloc.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Data structures for mysys/my_alloc.c (root memory allocator) @@ -23,6 +23,10 @@ #define ALLOC_MAX_BLOCK_TO_DROP 4096 #define ALLOC_MAX_BLOCK_USAGE_BEFORE_DROP 10 +#ifdef __cplusplus +extern "C" { +#endif + typedef struct st_used_mem { /* struct for once_alloc (block) */ struct st_used_mem *next; /* Next block in use */ @@ -48,4 +52,9 @@ typedef struct st_mem_root void (*error_handler)(void); } MEM_ROOT; + +#ifdef __cplusplus +} +#endif + #endif diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_list.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_list.h index 775b5658..294be663 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_list.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/my_list.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _list_h_ #define _list_h_ @@ -37,7 +37,7 @@ extern int list_walk(LIST *,list_walk_action action,unsigned char * argument); #define list_rest(a) ((a)->next) #define list_push(a,b) (a)=list_cons((b),(a)) -#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old) ; my_free((unsigned char *) old,MYF(MY_FAE)); } +#define list_pop(A) {LIST *old=(A); (A)=list_delete(old,old); my_free(old); } #ifdef __cplusplus } diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql.h index da477278..cff8c647 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql.h @@ -1,5 +1,4 @@ -/* - Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -12,18 +11,16 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This file defines the client API to MySQL and also the ABI of the dynamically linked libmysqlclient. - The ABI should never be changed in a released product of MySQL + The ABI should never be changed in a released product of MySQL, thus you need to take great care when changing the file. In case - the file is changed so the ABI is broken, you must also - update the SHAREDLIB_MAJOR_VERSION in configure.in . - + the file is changed so the ABI is broken, you must also update + the SHARED_LIB_MAJOR_VERSION in cmake/mysql_version.cmake */ #ifndef _mysql_h @@ -83,16 +80,14 @@ extern char *mysql_unix_port; #define CLIENT_NET_READ_TIMEOUT 365*24*3600 /* Timeout on read */ #define CLIENT_NET_WRITE_TIMEOUT 365*24*3600 /* Timeout on write */ -#ifdef __NETWARE__ -#pragma pack(push, 8) /* 8 byte alignment */ -#endif - #define IS_PRI_KEY(n) ((n) & PRI_KEY_FLAG) #define IS_NOT_NULL(n) ((n) & NOT_NULL_FLAG) #define IS_BLOB(n) ((n) & BLOB_FLAG) -#define IS_NUM(t) ((t) <= MYSQL_TYPE_INT24 || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) -#define IS_NUM_FIELD(f) ((f)->flags & NUM_FLAG) -#define INTERNAL_NUM_FIELD(f) (((f)->type <= MYSQL_TYPE_INT24 && ((f)->type != MYSQL_TYPE_TIMESTAMP || (f)->length == 14 || (f)->length == 8)) || (f)->type == MYSQL_TYPE_YEAR) +/** + Returns true if the value is a number which does not need quotes for + the sql_lex.cc parser to parse correctly. +*/ +#define IS_NUM(t) (((t) <= MYSQL_TYPE_INT24 && (t) != MYSQL_TYPE_TIMESTAMP) || (t) == MYSQL_TYPE_YEAR || (t) == MYSQL_TYPE_NEWDECIMAL) #define IS_LONGDATA(t) ((t) >= MYSQL_TYPE_TINY_BLOB && (t) <= MYSQL_TYPE_STRING) @@ -171,9 +166,15 @@ enum mysql_option MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION, MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH, MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT, - MYSQL_OPT_SSL_VERIFY_SERVER_CERT + MYSQL_OPT_SSL_VERIFY_SERVER_CERT, MYSQL_PLUGIN_DIR, MYSQL_DEFAULT_AUTH }; +/** + @todo remove the "extension", move st_mysql_options completely + out of mysql.h +*/ +struct st_mysql_options_extention; + struct st_mysql_options { unsigned int connect_timeout, read_timeout, write_timeout; unsigned int port, protocol; @@ -190,24 +191,10 @@ struct st_mysql_options { unsigned long max_allowed_packet; my_bool use_ssl; /* if to use SSL or not */ my_bool compress,named_pipe; - /* - On connect, find out the replication role of the server, and - establish connections to all the peers - */ - my_bool rpl_probe; - /* - Each call to mysql_real_query() will parse it to tell if it is a read - or a write, and direct it to the slave or the master - */ - my_bool rpl_parse; - /* - If set, never read from a master, only from slave, when doing - a read that is replication-aware - */ - my_bool no_master_reads; -#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY) - my_bool separate_thread; -#endif + my_bool unused1; + my_bool unused2; + my_bool unused3; + my_bool unused4; enum mysql_option methods_to_use; char *client_ip; /* Refuse client connecting to server if it uses old (pre-4.1.1) protocol */ @@ -221,7 +208,7 @@ struct st_mysql_options { void (*local_infile_end)(void *); int (*local_infile_error)(void *, char *, unsigned int); void *local_infile_userdata; - void *extension; + struct st_mysql_options_extention *extension; }; enum mysql_status @@ -235,15 +222,6 @@ enum mysql_protocol_type MYSQL_PROTOCOL_DEFAULT, MYSQL_PROTOCOL_TCP, MYSQL_PROTOCOL_SOCKET, MYSQL_PROTOCOL_PIPE, MYSQL_PROTOCOL_MEMORY }; -/* - There are three types of queries - the ones that have to go to - the master, the ones that go to a slave, and the adminstrative - type which must happen on the pivot connectioin -*/ -enum mysql_rpl_type -{ - MYSQL_RPL_MASTER, MYSQL_RPL_SLAVE, MYSQL_RPL_ADMIN -}; typedef struct character_set { @@ -288,21 +266,8 @@ typedef struct st_mysql /* session-wide random string */ char scramble[SCRAMBLE_LENGTH+1]; - - /* - Set if this is the original connection, not a master or a slave we have - added though mysql_rpl_probe() or mysql_set_master()/ mysql_add_slave() - */ - my_bool rpl_pivot; - /* - Pointers to the master, and the next slave connections, points to - itself if lone connection. - */ - struct st_mysql* master, *next_slave; - - struct st_mysql* last_used_slave; /* needed for round-robin slave pick */ - /* needed for send/read/store/use result to work correctly with replication */ - struct st_mysql* last_used_con; + my_bool unused1; + void *unused2, *unused3, *unused4, *unused5; LIST *stmts; /* list of all statements */ const struct st_mysql_methods *methods; @@ -336,35 +301,12 @@ typedef struct st_mysql_res { void *extension; } MYSQL_RES; -#define MAX_MYSQL_MANAGER_ERR 256 -#define MAX_MYSQL_MANAGER_MSG 256 - -#define MANAGER_OK 200 -#define MANAGER_INFO 250 -#define MANAGER_ACCESS 401 -#define MANAGER_CLIENT_ERR 450 -#define MANAGER_INTERNAL_ERR 500 #if !defined(MYSQL_SERVER) && !defined(MYSQL_CLIENT) #define MYSQL_CLIENT #endif -typedef struct st_mysql_manager -{ - NET net; - char *host, *user, *passwd; - char *net_buf, *net_buf_pos, *net_data_end; - unsigned int port; - int cmd_status; - int last_errno; - int net_buf_size; - my_bool free_me; - my_bool eof; - char last_error[MAX_MYSQL_MANAGER_ERR]; - void *extension; -} MYSQL_MANAGER; - typedef struct st_mysql_parameters { unsigned long *p_max_allowed_packet; @@ -457,16 +399,6 @@ int STDCALL mysql_real_query(MYSQL *mysql, const char *q, MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); -/* perform query on master */ -my_bool STDCALL mysql_master_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, - unsigned long length); -/* perform query on slave */ -my_bool STDCALL mysql_slave_query(MYSQL *mysql, const char *q, - unsigned long length); -my_bool STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, - unsigned long length); void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *charset); @@ -488,37 +420,6 @@ mysql_set_local_infile_handler(MYSQL *mysql, void mysql_set_local_infile_default(MYSQL *mysql); - -/* - enable/disable parsing of all queries to decide if they go on master or - slave -*/ -void STDCALL mysql_enable_rpl_parse(MYSQL* mysql); -void STDCALL mysql_disable_rpl_parse(MYSQL* mysql); -/* get the value of the parse flag */ -int STDCALL mysql_rpl_parse_enabled(MYSQL* mysql); - -/* enable/disable reads from master */ -void STDCALL mysql_enable_reads_from_master(MYSQL* mysql); -void STDCALL mysql_disable_reads_from_master(MYSQL* mysql); -/* get the value of the master read flag */ -my_bool STDCALL mysql_reads_from_master_enabled(MYSQL* mysql); - -enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len); - -/* discover the master and its slaves */ -my_bool STDCALL mysql_rpl_probe(MYSQL* mysql); - -/* set the master, close/free the old one, if it is not a pivot */ -int STDCALL mysql_set_master(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); -int STDCALL mysql_add_slave(MYSQL* mysql, const char* host, - unsigned int port, - const char* user, - const char* passwd); - int STDCALL mysql_shutdown(MYSQL *mysql, enum mysql_enum_shutdown_level shutdown_level); @@ -565,18 +466,6 @@ void STDCALL mysql_debug(const char *debug); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); my_bool STDCALL mysql_embedded(void); -MYSQL_MANAGER* STDCALL mysql_manager_init(MYSQL_MANAGER* con); -MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con, - const char* host, - const char* user, - const char* passwd, - unsigned int port); -void STDCALL mysql_manager_close(MYSQL_MANAGER* con); -int STDCALL mysql_manager_command(MYSQL_MANAGER* con, - const char* cmd, int cmd_len); -int STDCALL mysql_manager_fetch_line(MYSQL_MANAGER* con, - char* res_buf, - int res_buf_size); my_bool STDCALL mysql_read_query_result(MYSQL *mysql); @@ -684,6 +573,8 @@ typedef struct st_mysql_bind } MYSQL_BIND; +struct st_mysql_stmt_extension; + /* statement handler */ typedef struct st_mysql_stmt { @@ -729,7 +620,7 @@ typedef struct st_mysql_stmt metadata fields when doing mysql_stmt_store_result. */ my_bool update_max_length; - void *extension; + struct st_mysql_stmt_extension *extension; } MYSQL_STMT; enum enum_stmt_attr_type @@ -755,38 +646,6 @@ enum enum_stmt_attr_type }; -typedef struct st_mysql_methods -{ - my_bool (*read_query_result)(MYSQL *mysql); - my_bool (*advanced_command)(MYSQL *mysql, - enum enum_server_command command, - const unsigned char *header, - unsigned long header_length, - const unsigned char *arg, - unsigned long arg_length, - my_bool skip_check, - MYSQL_STMT *stmt); - MYSQL_DATA *(*read_rows)(MYSQL *mysql,MYSQL_FIELD *mysql_fields, - unsigned int fields); - MYSQL_RES * (*use_result)(MYSQL *mysql); - void (*fetch_lengths)(unsigned long *to, - MYSQL_ROW column, unsigned int field_count); - void (*flush_use_result)(MYSQL *mysql); -#if !defined(MYSQL_SERVER) || defined(EMBEDDED_LIBRARY) - MYSQL_FIELD * (*list_fields)(MYSQL *mysql); - my_bool (*read_prepare_result)(MYSQL *mysql, MYSQL_STMT *stmt); - int (*stmt_execute)(MYSQL_STMT *stmt); - int (*read_binary_rows)(MYSQL_STMT *stmt); - int (*unbuffered_fetch)(MYSQL *mysql, char **row); - void (*free_embedded_thd)(MYSQL *mysql); - const char *(*read_statistics)(MYSQL *mysql); - my_bool (*next_result)(MYSQL *mysql); - int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd); - int (*read_rows_from_cursor)(MYSQL_STMT *stmt); -#endif -} MYSQL_METHODS; - - MYSQL_STMT * STDCALL mysql_stmt_init(MYSQL *mysql); int STDCALL mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, unsigned long length); @@ -831,6 +690,7 @@ my_bool STDCALL mysql_rollback(MYSQL * mysql); my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode); my_bool STDCALL mysql_more_results(MYSQL *mysql); int STDCALL mysql_next_result(MYSQL *mysql); +int STDCALL mysql_stmt_next_result(MYSQL_STMT *stmt); void STDCALL mysql_close(MYSQL *sock); @@ -845,26 +705,9 @@ MYSQL * STDCALL mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd); int STDCALL mysql_create_db(MYSQL *mysql, const char *DB); int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); -#define mysql_reload(mysql) mysql_refresh((mysql),REFRESH_GRANT) #endif #define HAVE_MYSQL_REAL_CONNECT -/* - The following functions are mainly exported because of mysqlbinlog; - They are not for general usage -*/ - -#define simple_command(mysql, command, arg, length, skip_check) \ - (*(mysql)->methods->advanced_command)(mysql, command, 0, \ - 0, arg, length, skip_check, NULL) -#define stmt_command(mysql, command, arg, length, stmt) \ - (*(mysql)->methods->advanced_command)(mysql, command, 0, \ - 0, arg, length, 1, stmt) - -#ifdef __NETWARE__ -#pragma pack(pop) /* restore alignment */ -#endif - #ifdef __cplusplus } #endif diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_com.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_com.h index 357519d5..f2345be6 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_com.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_com.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* ** Common definition between mysql server & client @@ -27,10 +27,20 @@ #define NAME_LEN (NAME_CHAR_LEN*SYSTEM_CHARSET_MBMAXLEN) #define USERNAME_LENGTH (USERNAME_CHAR_LENGTH*SYSTEM_CHARSET_MBMAXLEN) +#define MYSQL_AUTODETECT_CHARSET_NAME "auto" + #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 /* + Maximum length of comments +*/ +#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */ +#define TABLE_COMMENT_MAXLEN 2048 +#define COLUMN_COMMENT_MAXLEN 1024 +#define INDEX_COMMENT_MAXLEN 1024 + +/* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain username and hostname parts of the user identifier with trailing zero in MySQL standard format: @@ -104,6 +114,10 @@ enum enum_server_command #define FIELD_IN_PART_FUNC_FLAG (1 << 19)/* Field part of partition func */ #define FIELD_IN_ADD_INDEX (1<< 20) /* Intern: Field used in ADD INDEX */ #define FIELD_IS_RENAMED (1<< 21) /* Intern: Field is being renamed */ +#define FIELD_FLAGS_STORAGE_MEDIA 22 /* Field storage media, bit 22-23, + reserved by MySQL Cluster */ +#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25, + reserved by MySQL Cluster */ #define REFRESH_GRANT 1 /* Refresh grant tables */ #define REFRESH_LOG 2 /* Start on new log file */ @@ -115,6 +129,12 @@ enum enum_server_command thread */ #define REFRESH_MASTER 128 /* Remove all bin logs in the index and truncate the index */ +#define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */ +#define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */ +#define REFRESH_BINARY_LOG 1024 /* Flush the binary log */ +#define REFRESH_RELAY_LOG 2048 /* Flush the relay log */ +#define REFRESH_GENERAL_LOG 4096 /* Flush the general log */ +#define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */ /* The following can't be set with mysql_refresh() */ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */ @@ -144,10 +164,19 @@ enum enum_server_command #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ +#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */ + +#define CLIENT_PLUGIN_AUTH (1UL << 19) /* Client supports plugin authentication */ #define CLIENT_SSL_VERIFY_SERVER_CERT (1UL << 30) #define CLIENT_REMEMBER_OPTIONS (1UL << 31) +#ifdef HAVE_COMPRESS +#define CAN_CLIENT_COMPRESS CLIENT_COMPRESS +#else +#define CAN_CLIENT_COMPRESS 0 +#endif + /* Gather all possible capabilites (flags) supported by the server */ #define CLIENT_ALL_FLAGS (CLIENT_LONG_PASSWORD | \ CLIENT_FOUND_ROWS | \ @@ -167,8 +196,10 @@ enum enum_server_command CLIENT_SECURE_CONNECTION | \ CLIENT_MULTI_STATEMENTS | \ CLIENT_MULTI_RESULTS | \ + CLIENT_PS_MULTI_RESULTS | \ CLIENT_SSL_VERIFY_SERVER_CERT | \ - CLIENT_REMEMBER_OPTIONS) + CLIENT_REMEMBER_OPTIONS | \ + CLIENT_PLUGIN_AUTH) /* Switch off the flags that are optional and depending on build flags @@ -179,7 +210,14 @@ enum enum_server_command & ~CLIENT_COMPRESS) \ & ~CLIENT_SSL_VERIFY_SERVER_CERT) -#define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ +/** + Is raised when a multi-statement transaction + has been started, either explicitly, by means + of BEGIN or COMMIT AND CHAIN, or + implicitly, by the first transactional + statement, when autocommit=off. +*/ +#define SERVER_STATUS_IN_TRANS 1 #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define SERVER_QUERY_NO_GOOD_INDEX_USED 16 @@ -203,6 +241,12 @@ enum enum_server_command number of result set columns. */ #define SERVER_STATUS_METADATA_CHANGED 1024 +#define SERVER_QUERY_WAS_SLOW 2048 + +/** + To mark ResultSet containing output parameter values. +*/ +#define SERVER_PS_OUT_PARAMS 4096 /** Server status flags that must be cleared when starting @@ -215,7 +259,11 @@ enum enum_server_command #define SERVER_STATUS_CLEAR_SET (SERVER_QUERY_NO_GOOD_INDEX_USED| \ SERVER_QUERY_NO_INDEX_USED|\ SERVER_MORE_RESULTS_EXISTS|\ - SERVER_STATUS_METADATA_CHANGED) + SERVER_STATUS_METADATA_CHANGED |\ + SERVER_QUERY_WAS_SLOW |\ + SERVER_STATUS_DB_DROPPED |\ + SERVER_STATUS_CURSOR_EXISTS|\ + SERVER_STATUS_LAST_ROW_SENT) #define MYSQL_ERRMSG_SIZE 512 #define NET_READ_TIMEOUT 30 /* Timeout on read */ @@ -254,24 +302,23 @@ typedef struct st_net { unsigned int *return_status; unsigned char reading_or_writing; char save_char; - my_bool unused0; /* Please remove with the next incompatible ABI change. */ - my_bool unused; /* Please remove with the next incompatible ABI change */ - my_bool compress; my_bool unused1; /* Please remove with the next incompatible ABI change. */ + my_bool unused2; /* Please remove with the next incompatible ABI change */ + my_bool compress; + my_bool unused3; /* Please remove with the next incompatible ABI change. */ /* Pointer to query object in query cache, do not equal NULL (0) for queries in cache that have not stored its results yet */ #endif /* - 'query_cache_query' should be accessed only via query cache - functions and methods to maintain proper locking. + Unused, please remove with the next incompatible ABI change. */ - unsigned char *query_cache_query; + unsigned char *unused; unsigned int last_errno; unsigned char error; - my_bool unused2; /* Please remove with the next incompatible ABI change. */ - my_bool return_errno; + my_bool unused4; /* Please remove with the next incompatible ABI change. */ + my_bool unused5; /* Please remove with the next incompatible ABI change. */ /** Client library error message buffer. Actually belongs to struct MYSQL. */ char last_error[MYSQL_ERRMSG_SIZE]; /** Client library sqlstate buffer. Set along with the error message. */ @@ -419,10 +466,6 @@ void my_net_set_write_timeout(NET *net, uint timeout); void my_net_set_read_timeout(NET *net, uint timeout); #endif -/* - The following function is not meant for normal usage - Currently it's used internally by manager.c -*/ struct sockaddr; int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, unsigned int timeout); @@ -492,14 +535,14 @@ void create_random_string(char *to, unsigned int length, struct rand_struct *ran void hash_password(unsigned long *to, const char *password, unsigned int password_len); void make_scrambled_password_323(char *to, const char *password); void scramble_323(char *to, const char *message, const char *password); -my_bool check_scramble_323(const char *, const char *message, +my_bool check_scramble_323(const unsigned char *reply, const char *message, unsigned long *salt); void get_salt_from_password_323(unsigned long *res, const char *password); void make_password_from_salt_323(char *to, const unsigned long *salt); void make_scrambled_password(char *to, const char *password); void scramble(char *to, const char *message, const char *password); -my_bool check_scramble(const char *reply, const char *message, +my_bool check_scramble(const unsigned char *reply, const char *message, const unsigned char *hash_stage2); void get_salt_from_password(unsigned char *res, const char *password); void make_password_from_salt(char *to, const unsigned char *hash_stage2); @@ -529,4 +572,5 @@ uchar *net_store_length(uchar *pkg, ulonglong length); #define MYSQL_STMT_HEADER 4 #define MYSQL_LONG_DATA_HEADER 6 +#define NOT_FIXED_DEC 31 #endif diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_embed.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_embed.h deleted file mode 100644 index e3318864..00000000 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_embed.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/* Defines that are unique to the embedded version of MySQL */ - -#ifdef EMBEDDED_LIBRARY - -/* Things we don't need in the embedded version of MySQL */ -/* TODO HF add #undef HAVE_VIO if we don't want client in embedded library */ - -#undef HAVE_OPENSSL -#undef HAVE_SMEM /* No shared memory */ -#undef HAVE_NDBCLUSTER_DB /* No NDB cluster */ - -#define DONT_USE_RAID - -#endif /* EMBEDDED_LIBRARY */ diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_version.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_version.h index dc8c5b3f..2822e22d 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_version.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/mysql_version.h @@ -9,16 +9,16 @@ #include <custom_conf.h> #else #define PROTOCOL_VERSION 10 -#define MYSQL_SERVER_VERSION "5.1.61" -#define MYSQL_BASE_VERSION "mysqld-5.1" +#define MYSQL_SERVER_VERSION "5.5.22" +#define MYSQL_BASE_VERSION "mysqld-5.5" #define MYSQL_SERVER_SUFFIX_DEF "" #define FRM_VER 6 -#define MYSQL_VERSION_ID 50161 +#define MYSQL_VERSION_ID 50522 #define MYSQL_PORT 3306 #define MYSQL_PORT_DEFAULT 0 #define MYSQL_UNIX_ADDR "/tmp/mysql.sock" #define MYSQL_CONFIG_NAME "my" -#define MYSQL_COMPILATION_COMMENT "Source distribution" +#define MYSQL_COMPILATION_COMMENT "MySQL Community Server (GPL)" /* mysqld compile time options */ #endif /* _CUSTOMCONFIG_ */ diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/typelib.h b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/typelib.h index 46106d1b..00dbafea 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/typelib.h +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/include/typelib.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,11 +29,26 @@ typedef struct st_typelib { /* Different types saved here */ extern my_ulonglong find_typeset(char *x, TYPELIB *typelib,int *error_position); extern int find_type_or_exit(const char *x, TYPELIB *typelib, const char *option); -extern int find_type(char *x, const TYPELIB *typelib, unsigned int full_name); +#define FIND_TYPE_BASIC 0 +/** makes @c find_type() require the whole name, no prefix */ +#define FIND_TYPE_NO_PREFIX (1 << 0) +/** always implicitely on, so unused, but old code may pass it */ +#define FIND_TYPE_NO_OVERWRITE (1 << 1) +/** makes @c find_type() accept a number */ +#define FIND_TYPE_ALLOW_NUMBER (1 << 2) +/** makes @c find_type() treat ',' as terminator */ +#define FIND_TYPE_COMMA_TERM (1 << 3) + +extern int find_type(const char *x, const TYPELIB *typelib, unsigned int flags); extern void make_type(char *to,unsigned int nr,TYPELIB *typelib); extern const char *get_type(TYPELIB *typelib,unsigned int nr); extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from); extern TYPELIB sql_protocol_typelib; +my_ulonglong find_set_from_flags(const TYPELIB *lib, unsigned int default_name, + my_ulonglong cur_set, my_ulonglong default_set, + const char *str, unsigned int length, + char **err_pos, unsigned int *err_len); + #endif /* _typelib_h */ diff --git a/Frameworks/SPMySQLFramework/MySQL Client Libraries/lib/libmysqlclient.a b/Frameworks/SPMySQLFramework/MySQL Client Libraries/lib/libmysqlclient.a Binary files differindex 5b7d405a..ab6be1a6 100644 --- a/Frameworks/SPMySQLFramework/MySQL Client Libraries/lib/libmysqlclient.a +++ b/Frameworks/SPMySQLFramework/MySQL Client Libraries/lib/libmysqlclient.a diff --git a/Frameworks/SPMySQLFramework/Resources/Info.plist b/Frameworks/SPMySQLFramework/Resources/Info.plist index 392b428f..84b64d04 100644 --- a/Frameworks/SPMySQLFramework/Resources/Info.plist +++ b/Frameworks/SPMySQLFramework/Resources/Info.plist @@ -5,15 +5,11 @@ <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleExecutable</key> - <string>${EXECUTABLE_NAME}</string> - <key>CFBundleIconFile</key> - <string></string> + <string>SPMySQL</string> <key>CFBundleIdentifier</key> - <string>com.yourcompany.${PRODUCT_NAME:rfc1034Identifier}</string> + <string>com.sequelpro.spmysql</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> - <key>CFBundleName</key> - <string>${PRODUCT_NAME}</string> <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> @@ -22,7 +18,5 @@ <string>SPDT</string> <key>CFBundleVersion</key> <string>1</string> - <key>NSPrincipalClass</key> - <string></string> </dict> </plist> diff --git a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj index 2f8d300c..076e112a 100644 --- a/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj +++ b/Frameworks/SPMySQLFramework/SPMySQLFramework.xcodeproj/project.pbxproj @@ -15,7 +15,6 @@ 584292A014C34B36000F8438 /* my_list.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929514C34B36000F8438 /* my_list.h */; settings = {ATTRIBUTES = (); }; }; 584292A114C34B36000F8438 /* mysql.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929614C34B36000F8438 /* mysql.h */; }; 584292A214C34B36000F8438 /* mysql_com.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929714C34B36000F8438 /* mysql_com.h */; }; - 584292A314C34B36000F8438 /* mysql_embed.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929814C34B36000F8438 /* mysql_embed.h */; }; 584292A414C34B36000F8438 /* mysql_time.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929914C34B36000F8438 /* mysql_time.h */; }; 584292A514C34B36000F8438 /* mysql_version.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929A14C34B36000F8438 /* mysql_version.h */; }; 584292A614C34B36000F8438 /* typelib.h in Headers */ = {isa = PBXBuildFile; fileRef = 5842929B14C34B36000F8438 /* typelib.h */; }; @@ -49,7 +48,7 @@ 5884165614D2306A0078027F /* SPMySQLResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 5884165414D2306A0078027F /* SPMySQLResult.m */; }; 58C006C814E0B18A00AC489A /* SPMySQLUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C006C714E0B18A00AC489A /* SPMySQLUtilities.h */; }; 58C008CD14E2AC7D00AC489A /* SPMySQLConnectionProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C008CC14E2AC7D00AC489A /* SPMySQLConnectionProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 58C009D514E31D3800AC489A /* SPMySQLStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C009D314E31D3800AC489A /* SPMySQLStringAdditions.h */; }; + 58C009D514E31D3800AC489A /* SPMySQLStringAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C009D314E31D3800AC489A /* SPMySQLStringAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58C009D614E31D3800AC489A /* SPMySQLStringAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C009D414E31D3800AC489A /* SPMySQLStringAdditions.m */; }; 58C00AA914E4869C00AC489A /* Max Packet Size.h in Headers */ = {isa = PBXBuildFile; fileRef = 58C00AA714E4869C00AC489A /* Max Packet Size.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58C00AAA14E4869C00AC489A /* Max Packet Size.m in Sources */ = {isa = PBXBuildFile; fileRef = 58C00AA814E4869C00AC489A /* Max Packet Size.m */; }; @@ -82,7 +81,6 @@ 5842929514C34B36000F8438 /* my_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = my_list.h; sourceTree = "<group>"; }; 5842929614C34B36000F8438 /* mysql.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mysql.h; sourceTree = "<group>"; }; 5842929714C34B36000F8438 /* mysql_com.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mysql_com.h; sourceTree = "<group>"; }; - 5842929814C34B36000F8438 /* mysql_embed.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mysql_embed.h; sourceTree = "<group>"; }; 5842929914C34B36000F8438 /* mysql_time.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mysql_time.h; sourceTree = "<group>"; }; 5842929A14C34B36000F8438 /* mysql_version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mysql_version.h; sourceTree = "<group>"; }; 5842929B14C34B36000F8438 /* typelib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typelib.h; sourceTree = "<group>"; }; @@ -279,7 +277,6 @@ 5842929514C34B36000F8438 /* my_list.h */, 5842929614C34B36000F8438 /* mysql.h */, 5842929714C34B36000F8438 /* mysql_com.h */, - 5842929814C34B36000F8438 /* mysql_embed.h */, 5842929914C34B36000F8438 /* mysql_time.h */, 5842929A14C34B36000F8438 /* mysql_version.h */, 5842929B14C34B36000F8438 /* typelib.h */, @@ -377,7 +374,6 @@ 584292A014C34B36000F8438 /* my_list.h in Headers */, 584292A114C34B36000F8438 /* mysql.h in Headers */, 584292A214C34B36000F8438 /* mysql_com.h in Headers */, - 584292A314C34B36000F8438 /* mysql_embed.h in Headers */, 584292A414C34B36000F8438 /* mysql_time.h in Headers */, 584292A514C34B36000F8438 /* mysql_version.h in Headers */, 584292A614C34B36000F8438 /* typelib.h in Headers */, @@ -516,6 +512,7 @@ GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = Source/SPMySQLFramework_Prefix.pch; + GENERATE_PKGINFO_FILE = YES; INFOPLIST_FILE = Resources/Info.plist; INSTALL_PATH = "@executable_path/../Frameworks"; LD_DYLIB_INSTALL_NAME = "$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(EXECUTABLE_PATH)"; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQL.h b/Frameworks/SPMySQLFramework/Source/SPMySQL.h index 3c4c78f8..bfdacf3e 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQL.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQL.h @@ -37,7 +37,11 @@ #import "SPMySQLConstants.h" // Required category additions +#ifndef SP_REFACTOR #import "SPMySQLStringAdditions.h" +#else +#import <SPMySQL/SPMySQL.h> +#endif // MySQL Connection Delegate and Proxy protocols #import "SPMySQLConnectionDelegate.h" diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m index a95e060e..2065c998 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Databases & Tables.m @@ -32,6 +32,7 @@ #import "Databases & Tables.h" #import "SPMySQL Private APIs.h" +#import "SPMySQLStringAdditions.h" @implementation SPMySQLConnection (Databases_and_Tables) diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.h index cf132fcf..9fa930c5 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.h @@ -33,4 +33,12 @@ @interface SPMySQLConnection (Delegate_and_Proxy) +// Connection delegage +- (void)setDelegate:(NSObject <SPMySQLConnectionDelegate> *)aDelegate; +- (NSObject <SPMySQLConnectionDelegate> *)delegate; + +// Connection proxy +- (void)setProxy:(NSObject <SPMySQLConnectionProxy> *)aProxy; +- (NSObject <SPMySQLConnectionProxy> *)proxy; + @end diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m index 3ac013cc..59e78c35 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Delegate & Proxy.m @@ -39,8 +39,8 @@ #pragma mark Connection delegate /** - * Override the synthesized delegate setter, to allow optimisations to oft-made - * checks by precacheing availability. + * Set the delegate of the connection object, precaching availability of + * oft-called methods to allow optimisation. */ - (void)setDelegate:(NSObject <SPMySQLConnectionDelegate> *)aDelegate { @@ -51,12 +51,22 @@ delegateSupportsConnectionLost = [delegate respondsToSelector:@selector(connectionLost:)]; } +/** + * Return the current instance delegate. + */ +- (NSObject <SPMySQLConnectionDelegate> *)delegate +{ + return delegate; +} + #pragma mark - #pragma mark Connection proxy /** - * Override the synthesized proxy setter, to record the initial state and to - * set the state change selector. + * Set the connection proxy, used by the class to set up a connection pre-requisite, and + * monitored for state changes. This allows the MySQL connection to be routed over + * another helper class providing a port or socket. This method also records the initial + * state and sets the state change selector. */ - (void)setProxy:(NSObject <SPMySQLConnectionProxy> *)aProxy { @@ -64,7 +74,15 @@ previousProxyState = [aProxy state]; [proxy setConnectionStateChangeSelector:@selector(_proxyStateChange:) delegate:self]; -} +} + +/** + * Return the current instance proxy. + */ +- (NSObject <SPMySQLConnectionProxy> *)proxy +{ + return proxy; +} @end diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Encoding.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Encoding.m index 8f684f29..d11c75b2 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Encoding.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Encoding.m @@ -32,6 +32,7 @@ #import "Encoding.h" +#import "SPMySQLStringAdditions.h" @implementation SPMySQLConnection (Encoding) diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m index 9b54029c..5df71e96 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m @@ -330,10 +330,22 @@ NSString *theErrorMessage = [self _stringForCString:mysql_error(mySQLConnection)]; NSUInteger theErrorID = mysql_errno(mySQLConnection); + // Update the connection's stored insert ID if available + if (mySQLConnection->insert_id) { + lastQueryInsertID = mySQLConnection->insert_id; + } + // If the query was cancelled, override the error state if (lastQueryWasCancelled) { theErrorMessage = NSLocalizedString(@"Query cancelled.", @"Query cancelled error"); theErrorID = 1317; + + // If the query was cancelled on a MySQL <5 server, check the connection to allow reconnects + // after query kills. This is also handled within the class for internal cancellations, but + // as other external classes may also cancel the query. + if (![self serverVersionIsGreaterThanOrEqualTo:5 minorVersion:0 releaseVersion:0]) { + [self checkConnection]; + } } // Unlock the connection if appropriate - if not a streaming result type. diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h index 8f3b7f9f..8ed01ec6 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.h @@ -131,9 +131,6 @@ #pragma mark - #pragma mark Synthesized properties -@property (readwrite, assign, nonatomic) NSObject <SPMySQLConnectionDelegate> *delegate; -@property (readwrite, assign, nonatomic) NSObject <SPMySQLConnectionProxy> *proxy; - @property (readwrite, retain) NSString *host; @property (readwrite, retain) NSString *username; @property (readwrite, retain) NSString *password; diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m index 6308a3f5..800157ca 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m @@ -54,8 +54,6 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS #pragma mark - #pragma mark Synthesized properties -@synthesize delegate; -@synthesize proxy; @synthesize host; @synthesize username; @synthesize password; @@ -124,6 +122,7 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS previousEncodingUsesLatin1Transport = NO; // Initialise default delegate settings + delegate = nil; delegateSupportsWillQueryString = NO; delegateSupportsConnectionLost = NO; delegateQueryLogging = YES; @@ -435,10 +434,15 @@ const char *SPMySQLSSLPermissibleCiphers = "DHE-RSA-AES256-SHA:AES256-SHA:DHE-RS isReconnecting = NO; [reconnectionPool release]; return NO; + + // By default attempt a reconnect, returning if it fails. If it succeeds, continue + // on to the end of the function to restore details if appropriate. default: isReconnecting = NO; - [reconnectionPool release]; - return [self reconnect]; + if (![self reconnect]) { + [reconnectionPool release]; + return NO; + } } } diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m index 8ba55134..1fa4b829 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLFastStreamingResult.m @@ -398,6 +398,11 @@ typedef struct st_spmysqlstreamingrowdata { [parentConnection _unlockConnection]; connectionUnlocked = YES; + // If the connection query may have been cancelled with a query kill, double-check connection + if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) { + [parentConnection checkConnection]; + } + dataDownloaded = YES; [downloadPool drain]; } diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Convenience Methods.m b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Convenience Methods.m index 2b049264..4d18db18 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Convenience Methods.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLResult Categories/Convenience Methods.m @@ -65,7 +65,7 @@ // Instead of empty arrays, return nil if there are no rows. if (![rowsToReturn count]) return nil; - return rowsToReturn; + return [rowsToReturn autorelease]; } @end diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResult.m b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResult.m index b19e5356..51a17611 100644 --- a/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResult.m +++ b/Frameworks/SPMySQLFramework/Source/SPMySQLStreamingResult.m @@ -170,6 +170,12 @@ dataDownloaded = YES; [parentConnection _unlockConnection]; connectionUnlocked = YES; + + // If the connection query may have been cancelled with a query kill, double-check connection + if ([parentConnection lastQueryWasCancelled] && [parentConnection serverMajorVersion] < 5) { + [parentConnection checkConnection]; + } + return nil; } diff --git a/Frameworks/SPMySQLFramework/build-mysql-client.sh b/Frameworks/SPMySQLFramework/build-mysql-client.sh index 45e3c465..158d9393 100755 --- a/Frameworks/SPMySQLFramework/build-mysql-client.sh +++ b/Frameworks/SPMySQLFramework/build-mysql-client.sh @@ -27,10 +27,10 @@ # Builds the MySQL client libraries for distrubution in Sequel Pro's MySQL framework. # -# Paramters: -s -- The path to the MySQL source directory. -# -q -- Quiet. Don't output any compiler messages. -# -c -- Clean the source after build completes. -# -d -- Debug. Output the build statements. +# Parameters: -s -- The path to the MySQL source directory. +# -q -- Quiet. Don't output any compiler messages. +# -c -- Clean the source instead of building it. +# -d -- Debug. Output the build statements. QUIET='NO' DEBUG='NO' @@ -40,8 +40,11 @@ CLEAN='NO' export CFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk -arch ppc -arch i386 -arch x86_64 -O3 -fno-omit-frame-pointer -fno-exceptions -mmacosx-version-min=10.5' export CXXFLAGS='-isysroot /Developer/SDKs/MacOSX10.5.sdk -arch ppc -arch i386 -arch x86_64 -O3 -fno-omit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -mmacosx-version-min=10.5' -CONFIGURE_OPTIONS='--without-server --enable-thread-safe-client --disable-dependency-tracking --enable-local-infile --with-ssl --enable-assembler --with-mysqld-ldflags=-all-static' -BINARY_DISTRIBUTION_SCRIPT='scripts/make_binary_distribution' +CONFIGURE_OPTIONS='-DBUILD_CONFIG=mysql_release -DENABLED_LOCAL_INFILE=1 -DWITH_SSL=bundled -DWITH_MYSQLD_LDFLAGS="-all-static --disable-shared"' +OUTPUT_DIR='SPMySQLFiles.build' + +set -A INCLUDE_HEADERS 'my_alloc.h' 'my_list.h' 'mysql_com.h' 'mysql_time.h' 'mysql_version.h' 'mysql.h' 'typelib.h' +ESC=`printf '\033'` usage() { @@ -50,32 +53,28 @@ Usage: $(basename $0): -s <mysql_source_path> [-q -c -d] Where: -s -- Path to the MySQL source directory -q -- Be quiet during the build. Suppress all compiler messages - -c -- Clean the source directory after the build completes + -c -- Clean the source directory instead of building -d -- Debug. Output all the build commands !EOF } +# Test for cmake +cmake --version > /dev/null 2>&1 +if [ ! $? -eq 0 ] +then + echo "$ESC[1;31mIn addition to the standard OS X build tools, '$ESC[0;1mcmake$ESC[1;31m' is required to compile the MySQL source. $ESC[0;1mcmake$ESC[1;31m is found at $ESC[0mcmake.org$ESC[1;31m, and a binary distribution is available from $ESC[0mhttp://www.cmake.org/cmake/resources/software.mhtml$ESC[1;31m ." + echo "Exiting...$ESC[0m" + exit 1 +fi + if [ $# -eq 0 ] then - echo "Invalid number of arguments. I need the path to the MySQL source directory." + echo "$ESC[1;31mInvalid number of arguments. I need the path to the MySQL source directory.$ESC[0m" echo '' usage exit 1 fi -echo '' -echo "This script builds the MySQL client libraries for distribution in Sequel Pro's MySQL framework." -echo 'They are all built as 3-way binaries (32 bit PPC, 32/64 bit i386).' -echo '' -echo -n 'This may take a while, are you sure you want to continue [y | n]: ' - -read CONTINUE - -if [ "x${CONTINUE}" == 'xn' ] -then - echo 'Aborting...' - exit 0 -fi while getopts ':s:qcd' OPTION do @@ -84,88 +83,156 @@ do q) QUIET='YES';; c) CLEAN='YES';; d) DEBUG='YES';; - *) echo 'Unrecognised option'; usage; exit 1;; + *) echo "$ESC[1;31mUnrecognised option$ESC[0m"; usage; exit 1;; esac done if [ ! -d "$MYSQL_SOURCE_DIR" ] then - echo "MySQL source directory does not exist at path '${MYSQL_SOURCE_DIR}'." - echo 'Exiting...' + echo "$ESC[1;31mMySQL source directory does not exist at path '${MYSQL_SOURCE_DIR}'.$ESC[0m" + echo "$ESC[1;31mExiting...$ESC[0m" exit 1 fi # Change to source directory +if [ "x${DEBUG}" == 'xYES' ] +then + echo "cd ${MYSQL_SOURCE_DIR}" +fi cd "$MYSQL_SOURCE_DIR" -echo 'Configuring MySQL source...' +# Perform a clean if requested +if [ "x${CLEAN}" == 'xYES' ] +then + echo "$ESC[1mCleaning MySQL source and builds...$ESC[0m" + + if [ "x${QUIET}" == 'xYES' ] + then + make clean > /dev/null + if [ -f 'CMakeCache.txt' ]; then rm 'CMakeCache.txt' > /dev/null; fi + if [ -d "$OUTPUT_DIR" ]; then rm -rf "$OUTPUT_DIR" > /dev/null; fi + else + make clean + if [ -f 'CMakeCache.txt' ]; then rm 'CMakeCache.txt'; fi + if [ -d "$OUTPUT_DIR" ]; then rm -rf "$OUTPUT_DIR" > /dev/null; fi + fi + + echo "$ESC[1mCleaning MySQL completed.$ESC[0m" + + exit 0 +fi + +echo '' +echo "This script builds the MySQL client libraries for distribution in Sequel Pro's MySQL framework." +echo 'They are all built as 3-way binaries (32 bit PPC, 32/64 bit i386).' +echo '' +echo -n "$ESC[1mThis may take a while, are you sure you want to continue [y | n]: $ESC[0m" + +read CONTINUE + +if [ "x${CONTINUE}" == 'xn' ] +then + echo "$ESC[31mAborting...$ESC[0m" + exit 0 +fi + + +echo "$ESC[1mConfiguring MySQL source...$ESC[0m" if [ "x${DEBUG}" == 'xYES' ] then - echo "${MYSQL_SOURCE_DIR}/configure" "$CONFIGURE_OPTIONS" + echo "cmake ${CONFIGURE_OPTIONS} ." fi if [ "x${QUIET}" == 'xYES' ] then - ./configure $CONFIGURE_OPTIONS > /dev/null + cmake $CONFIGURE_OPTIONS . > /dev/null else - ./configure $CONFIGURE_OPTIONS + cmake $CONFIGURE_OPTIONS . fi if [ $? -eq 0 ] then - echo 'Configure successfully completed' + echo "$ESC[1mConfigure successfully completed$ESC[0m" else - echo 'Configure failed. Exiting...' + echo "$ESC[1;31mConfigure failed. Exiting...$ESC[0m" exit 1 fi -echo 'Building client libraries...' +if [ "x${DEBUG}" == 'xYES' ] +then + echo "make mysqlclient" +fi + +echo "$ESC[1mBuilding client libraries...$ESC[0m" if [ "x${QUIET}" == 'xYES' ] then - make > /dev/null + make mysqlclient > /dev/null else - make + make mysqlclient fi if [ $? -eq 0 ] then - echo 'Building libraries successfully completed' + echo "$ESC[1mBuilding libraries successfully completed$ESC[0m" else - echo 'Building libraries failed. Exiting...' + echo "$ESC[1;31mBuilding libraries failed. Exiting...$ESC[0m" exit 1 fi -echo 'Building binary distribution...' +echo "$ESC[1mPutting together files for distribution...$ESC[0m" -if [ "x${QUIET}" == 'xYES' ] +# Create the appropriate directories +if [ ! -d "$OUTPUT_DIR" ] then - $BINARY_DISTRIBUTION_SCRIPT > /dev/null -else - $BINARY_DISTRIBUTION_SCRIPT + mkdir "$OUTPUT_DIR" + if [ ! $? -eq 0 ] + then + echo "$ESC[1;31mCould not create $OUTPUT_DIR output directory!$ESC[0m" + exit 1 + fi +fi +if [ ! -d "${OUTPUT_DIR}/lib" ] +then + mkdir "${OUTPUT_DIR}/lib" + if [ ! $? -eq 0 ] + then + echo "$ESC[1;31mCould not create ${OUTPUT_DIR}/lib output directory!$ESC[0m" + exit 1 + fi +fi +if [ ! -d "${OUTPUT_DIR}/include" ] +then + mkdir "${OUTPUT_DIR}/include" + if [ ! $? -eq 0 ] + then + echo "$ESC[1;31mCould not create ${OUTPUT_DIR}/include output directory!$ESC[0m" + exit 1 + fi fi -if [ $? -eq 0 ] +# Copy the library +cp 'libmysql/libmysqlclient.a' "${OUTPUT_DIR}/lib/" +if [ ! $? -eq 0 ] then - echo 'Building binary distribution successfully completed' -else - echo 'Building binary distribution failed. Exiting...' + echo "$ESC[1;31mCould not copy libmysqlclient.a to output directory! (${MYSQL_SOURCE_DIR}/${OUTPUT_DIR}/lib)$ESC[0m" exit 1 fi -if [ "x${CLEAN}" == 'xYES' ] -then - echo 'Cleaning build...' - - if [ "x${QUIET}" == 'xYES' ] +# Copy in the required headers +for eachheader in ${INCLUDE_HEADERS[@]} +do + cp "include/${eachheader}" "${OUTPUT_DIR}/include/" + if [ ! $? -eq 0 ] then - make clean > /dev/null - else - make clean + echo "$ESC[1;31mCould not copy ${eachheader} to output directory! (${MYSQL_SOURCE_DIR}/${OUTPUT_DIR}/include)$ESC[0m" + exit 1 fi -fi +done + -echo 'Building MySQL client libraries successfully completed.' +echo "$ESC[1mBuilding MySQL client libraries successfully completed.$ESC[0m" +echo "$ESC[1mSee ${MYSQL_SOURCE_DIR}/${OUTPUT_DIR}/ for the product.$ESC[0m" exit 0 |