aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/DMLocalizedNib.m2
-rw-r--r--Source/ImageAndTextCell.m10
-rw-r--r--Source/NSMutableArray-MultipleSort.m2
-rw-r--r--Source/NSNotificationAdditions.h44
-rw-r--r--Source/NSNotificationAdditions.m169
-rw-r--r--Source/NSNotificationCenterThreadingAdditions.h18
-rw-r--r--Source/NSNotificationCenterThreadingAdditions.m52
-rw-r--r--Source/SPArrayAdditions.h36
-rw-r--r--Source/SPBundleHTMLOutputController.m1
-rw-r--r--Source/SPCSVExporter.m21
-rw-r--r--Source/SPCSVParser.m4
-rw-r--r--Source/SPCategoryAdditions.h3
-rw-r--r--Source/SPColorAdditions.m6
-rw-r--r--Source/SPConnectionController.h15
-rw-r--r--Source/SPConnectionController.m1
-rw-r--r--Source/SPConnectionDelegate.h8
-rw-r--r--Source/SPConnectionDelegate.m26
-rw-r--r--Source/SPConnectionHandler.m71
-rw-r--r--Source/SPConstants.h7
-rw-r--r--Source/SPConstants.m19
-rw-r--r--Source/SPCopyTable.m36
-rw-r--r--Source/SPCustomQuery.h13
-rw-r--r--Source/SPCustomQuery.m155
-rw-r--r--Source/SPDBActionCommons.h8
-rw-r--r--Source/SPDataImport.h6
-rw-r--r--Source/SPDataImport.m50
-rw-r--r--Source/SPDatabaseCopy.m3
-rw-r--r--Source/SPDatabaseData.h8
-rw-r--r--Source/SPDatabaseData.m33
-rw-r--r--Source/SPDatabaseDocument.h19
-rw-r--r--Source/SPDatabaseDocument.m259
-rw-r--r--Source/SPDatabaseInfo.m33
-rw-r--r--Source/SPDatabaseRename.m5
-rw-r--r--Source/SPDatabaseStructure.h58
-rw-r--r--Source/SPDatabaseStructure.m653
-rw-r--r--Source/SPDatabaseViewController.m12
-rw-r--r--Source/SPEditorPreferencePane.m16
-rw-r--r--Source/SPExportController.h14
-rw-r--r--Source/SPExportController.m17
-rw-r--r--Source/SPExportFileUtilities.m1
-rw-r--r--Source/SPExportInitializer.m3
-rw-r--r--Source/SPExporter.h6
-rw-r--r--Source/SPExtendedTableInfo.h8
-rw-r--r--Source/SPExtendedTableInfo.m201
-rw-r--r--Source/SPFavoritesController.m3
-rw-r--r--Source/SPFieldEditorController.h1
-rw-r--r--Source/SPFieldEditorController.m7
-rw-r--r--Source/SPFieldMapperController.h39
-rw-r--r--Source/SPFieldMapperController.m13
-rw-r--r--Source/SPGeometryDataView.m18
-rw-r--r--Source/SPIndexesController.h26
-rw-r--r--Source/SPIndexesController.m14
-rw-r--r--Source/SPLogger.m1
-rw-r--r--Source/SPNarrowDownCompletion.h5
-rw-r--r--Source/SPNarrowDownCompletion.m22
-rw-r--r--Source/SPNavigatorController.h5
-rw-r--r--Source/SPNavigatorController.m40
-rw-r--r--Source/SPNotLoaded.m26
-rw-r--r--Source/SPObjectAdditions.h31
-rw-r--r--Source/SPObjectAdditions.m40
-rw-r--r--Source/SPProcessListController.h12
-rw-r--r--Source/SPProcessListController.m25
-rw-r--r--Source/SPQueryController.m4
-rw-r--r--Source/SPQueryFavoriteManager.m12
-rw-r--r--Source/SPSQLExporter.m76
-rw-r--r--Source/SPSSHTunnel.h7
-rw-r--r--Source/SPSSHTunnel.m41
-rw-r--r--Source/SPServerVariablesController.h6
-rw-r--r--Source/SPServerVariablesController.m12
-rw-r--r--Source/SPTableContent.h14
-rw-r--r--Source/SPTableContent.m186
-rw-r--r--Source/SPTableCopy.m7
-rw-r--r--Source/SPTableData.h11
-rw-r--r--Source/SPTableData.m63
-rw-r--r--Source/SPTableRelations.h8
-rw-r--r--Source/SPTableRelations.m18
-rw-r--r--Source/SPTableStructure.h14
-rw-r--r--Source/SPTableStructure.m110
-rw-r--r--Source/SPTableStructureDelegate.m7
-rw-r--r--Source/SPTableTextFieldCell.m2
-rw-r--r--Source/SPTableTriggers.h8
-rw-r--r--Source/SPTableTriggers.m11
-rw-r--r--Source/SPTablesList.h8
-rw-r--r--Source/SPTablesList.m156
-rw-r--r--Source/SPTextView.h7
-rw-r--r--Source/SPTextView.m29
-rw-r--r--Source/SPUserMO.h2
-rw-r--r--Source/SPUserManager.h8
-rw-r--r--Source/SPUserManager.m66
-rw-r--r--Source/SPWindowAdditions.m4
-rw-r--r--Source/SPWindowController.m36
-rw-r--r--Source/SPXMLExporter.m32
-rw-r--r--Source/SPXMLExporterDelegate.m1
93 files changed, 2027 insertions, 1399 deletions
diff --git a/Source/DMLocalizedNib.m b/Source/DMLocalizedNib.m
index 55e51e35..3f56a07d 100644
--- a/Source/DMLocalizedNib.m
+++ b/Source/DMLocalizedNib.m
@@ -136,4 +136,4 @@ static NSMutableDictionary *deliciousNibNames = nil;
[self deliciousDealloc];
}
-@end \ No newline at end of file
+@end
diff --git a/Source/ImageAndTextCell.m b/Source/ImageAndTextCell.m
index eb2f6678..e3c835f0 100644
--- a/Source/ImageAndTextCell.m
+++ b/Source/ImageAndTextCell.m
@@ -53,7 +53,7 @@
imageFrame.size = [image size];
imageFrame.origin = cellFrame.origin;
imageFrame.origin.x += ((1 - MIN(1,INDENT_AMOUNT)) * 3) + (INDENT_AMOUNT * _indentationLevel);
- imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
+ imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2);
return imageFrame;
}
else
@@ -115,9 +115,9 @@
imageFrame.size = imageSize;
if ([view isFlipped])
- imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
+ imageFrame.origin.y += ceilf((cellFrame.size.height + imageFrame.size.height) / 2);
else
- imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
+ imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2);
imageFrame.origin.y -= 1;
@@ -154,9 +154,9 @@
imageFrame.size = imageSize;
if ([controlView isFlipped])
- imageFrame.origin.y += ceil((cellFrame.size.height + imageFrame.size.height) / 2);
+ imageFrame.origin.y += ceilf((cellFrame.size.height + imageFrame.size.height) / 2);
else
- imageFrame.origin.y += ceil((cellFrame.size.height - imageFrame.size.height) / 2);
+ imageFrame.origin.y += ceilf((cellFrame.size.height - imageFrame.size.height) / 2);
[image compositeToPoint:imageFrame.origin operation:NSCompositeSourceOver];
}
diff --git a/Source/NSMutableArray-MultipleSort.m b/Source/NSMutableArray-MultipleSort.m
index 55a55962..e48db16b 100644
--- a/Source/NSMutableArray-MultipleSort.m
+++ b/Source/NSMutableArray-MultipleSort.m
@@ -74,4 +74,4 @@
}
}
}
-@end \ No newline at end of file
+@end
diff --git a/Source/NSNotificationAdditions.h b/Source/NSNotificationAdditions.h
deleted file mode 100644
index 8722ed4f..00000000
--- a/Source/NSNotificationAdditions.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// $Id$
-//
-// NSNotificationAdditions.h
-// sequel-pro
-//
-// Copied from the Colloquy project; original code available from Trac at
-// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.h
-//
-// 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; either version 2 of the License, or
-// (at your option) any later version.
-//
-// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// More info at <http://code.google.com/p/sequel-pro/>
-
-@interface NSNotificationCenter (NSNotificationCenterAdditions)
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThread:(NSNotification *)notification;
-- (void)postNotificationOnMainThread:(NSNotification *)notification waitUntilDone:(BOOL)wait;
-
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object;
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo waitUntilDone:(BOOL)wait;
-#else
-- (void)sequelProPostNotificationOnMainThread:(NSNotification *)notification;
-- (void)sequelProPostNotificationOnMainThread:(NSNotification *)notification waitUntilDone:(BOOL)wait;
-
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object;
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo waitUntilDone:(BOOL)wait;
-#endif
-
-@end
diff --git a/Source/NSNotificationAdditions.m b/Source/NSNotificationAdditions.m
deleted file mode 100644
index 8b64c1f2..00000000
--- a/Source/NSNotificationAdditions.m
+++ /dev/null
@@ -1,169 +0,0 @@
-//
-// $Id$
-//
-// NSNotificationAdditions.m
-// sequel-pro
-//
-// Copied from the Colloquy project; original code available from Trac at
-// http://colloquy.info/project/browser/trunk/Additions/NSNotificationAdditions.m
-//
-// 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; either version 2 of the License, or
-// (at your option) any later version.
-//
-// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// More info at <http://code.google.com/p/sequel-pro/>
-
-#import "NSNotificationAdditions.h"
-#import "pthread.h"
-
-@interface NSNotificationCenter (NSNotificationCenterAdditions_PrivateAPI)
-#ifndef SP_REFACTOR
-+ (void)_postNotification:(NSNotification *)notification;
-+ (void)_postNotificationName:(NSDictionary *)info;
-+ (void)_postNotificationForwarder:(NSDictionary *)info;
-#else
-+ (void)_sequelProPostNotification:(NSNotification *)notification;
-+ (void)_sequelProPostNotificationName:(NSDictionary *)info;
-+ (void)_sequelProPostNotificationForwarder:(NSDictionary *)info;
-#endif
-@end
-
-@implementation NSNotificationCenter (NSNotificationCenterAdditions)
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThread:(NSNotification *)notification
-#else
-- (void)sequelProPostNotificationOnMainThread:(NSNotification *)notification
-#endif
-{
- if (pthread_main_np()) return [self postNotification:notification];
-
-#ifndef SP_REFACTOR
- [self postNotificationOnMainThread:notification waitUntilDone:NO];
-#else
- [self sequelProPostNotificationOnMainThread:notification waitUntilDone:NO];
-#endif
-}
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThread:(NSNotification *)notification waitUntilDone:(BOOL)shouldWaitUntilDone
-#else
-- (void)sequelProPostNotificationOnMainThread:(NSNotification *)notification waitUntilDone:(BOOL)shouldWaitUntilDone
-#endif
-{
- if (pthread_main_np()) return [self postNotification:notification];
-
-#ifndef SP_REFACTOR
- [self performSelectorOnMainThread:@selector(_postNotification:) withObject:notification waitUntilDone:shouldWaitUntilDone];
-#else
- [self performSelectorOnMainThread:@selector(_sequelProPostNotification:) withObject:notification waitUntilDone:shouldWaitUntilDone];
-#endif
-}
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object
-#else
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object
-#endif
-{
- if (pthread_main_np()) return [self postNotificationName:name object:object userInfo:nil];
-
-#ifndef SP_REFACTOR
- [self postNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO];
-#else
- [self sequelProPostNotificationOnMainThreadWithName:name object:object userInfo:nil waitUntilDone:NO];
-#endif
-}
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo
-#else
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo
-#endif
-{
- if(pthread_main_np()) return [self postNotificationName:name object:object userInfo:userInfo];
-
-#ifndef SP_REFACTOR
- [self postNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO];
-#else
- [self sequelProPostNotificationOnMainThreadWithName:name object:object userInfo:userInfo waitUntilDone:NO];
-#endif
-}
-
-#ifndef SP_REFACTOR
-- (void)postNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo waitUntilDone:(BOOL)shouldWaitUntilDone
-#else
-- (void)sequelProPostNotificationOnMainThreadWithName:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo waitUntilDone:(BOOL)shouldWaitUntilDone
-#endif
-{
- if (pthread_main_np()) return [self postNotificationName:name object:object userInfo:userInfo];
-
- NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:3];
-
- if (name) [info setObject:name forKey:@"name"];
- if (object) [info setObject:object forKey:@"object"];
- if (userInfo) [info setObject:userInfo forKey:@"userInfo"];
-
-#ifndef SP_REFACTOR
- [[self class] performSelectorOnMainThread:@selector(_postNotificationName:) withObject:info waitUntilDone:shouldWaitUntilDone];
-#else
- [[self class] performSelectorOnMainThread:@selector(_sequelProPostNotificationName:) withObject:info waitUntilDone:shouldWaitUntilDone];
-#endif
-
- [info release];
-}
-
-@end
-
-@implementation NSNotificationCenter (NSNotificationCenterAdditions_PrivateAPI)
-
-#ifndef SP_REFACTOR
-+ (void)_postNotification:(NSNotification *)notification
-#else
-+ (void)_sequelProPostNotification:(NSNotification *)notification
-#endif
-{
- [[self defaultCenter] postNotification:notification];
-}
-
-#ifndef SP_REFACTOR
-+ (void)_postNotificationName:(NSDictionary *)info
-#else
-+ (void)_sequelProPostNotificationName:(NSDictionary *)info
-#endif
-{
- NSString *name = [info objectForKey:@"name"];
-
- id object = [info objectForKey:@"object"];
-
- NSDictionary *userInfo = [info objectForKey:@"userInfo"];
-
- [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo];
-}
-
-#ifndef SP_REFACTOR
-+ (void)_postNotificationForwarder:(NSDictionary *)info
-#else
-+ (void)_sequelProPostNotificationForwarder:(NSDictionary *)info
-#endif
-{
- NSString *name = [info objectForKey:@"name"];
-
- id object = [info objectForKey:@"object"];
-
- NSDictionary *userInfo = [info objectForKey:@"userInfo"];
-
- [[self defaultCenter] postNotificationName:name object:object userInfo:userInfo];
-}
-
-@end
diff --git a/Source/NSNotificationCenterThreadingAdditions.h b/Source/NSNotificationCenterThreadingAdditions.h
new file mode 100644
index 00000000..b71ad17f
--- /dev/null
+++ b/Source/NSNotificationCenterThreadingAdditions.h
@@ -0,0 +1,18 @@
+//
+// $Id$
+//
+// NSNotificationCenterThreadingAdditions.h
+// Enable NSNotification being sent from threads
+//
+// Copied from the TCMPortMapper project; original code available on
+// Google Code at <http://code.google.com/p/tcmportmapper/source/browse/TCMPortMapper/framework/NSNotificationCenterThreadingAdditions.h>
+//
+// Copyright (c) 2007-2008 TheCodingMonkeys:
+// Martin Pittenauer, Dominik Wagner, <http://codingmonkeys.de>
+// Some rights reserved: <http://opensource.org/licenses/mit-license.php>
+//
+
+@interface NSNotificationCenter (NSNotificationCenterThreadingAdditions)
+- (void)postNotificationOnMainThread:(NSNotification *)aNotification;
+- (void)postNotificationOnMainThreadWithName:(NSString *)aName object:(id)anObject;
+@end
diff --git a/Source/NSNotificationCenterThreadingAdditions.m b/Source/NSNotificationCenterThreadingAdditions.m
new file mode 100644
index 00000000..395275e4
--- /dev/null
+++ b/Source/NSNotificationCenterThreadingAdditions.m
@@ -0,0 +1,52 @@
+//
+// $Id$
+//
+// NSNotificationCenterThreadingAdditions.m
+// Enable NSNotification being sent from threads
+//
+// Copied from the TCMPortMapper project; original code available on
+// Google Code at <http://code.google.com/p/tcmportmapper/source/browse/TCMPortMapper/framework/NSNotificationCenterThreadingAdditions.m>
+//
+// Copyright (c) 2007-2008 TheCodingMonkeys:
+// Martin Pittenauer, Dominik Wagner, <http://codingmonkeys.de>
+// Some rights reserved: <http://opensource.org/licenses/mit-license.php>
+//
+
+#import "NSNotificationCenterThreadingAdditions.h"
+#import <pthread.h>
+
+@implementation NSNotificationCenter (NSNotificationCenterThreadingAdditions)
+
++ (void)_postNotification:(NSNotification *)aNotification {
+ [[self defaultCenter] postNotification:aNotification];
+}
+
++ (void)_postNotificationViaDictionary:(NSDictionary *)anInfoDictionary {
+ NSString *name = [anInfoDictionary objectForKey:@"name"];
+ id object = [anInfoDictionary objectForKey:@"object"];
+ [[self defaultCenter] postNotificationName:name
+ object:object
+ userInfo:nil];
+ [anInfoDictionary release];
+}
+
+
+- (void)postNotificationOnMainThread:(NSNotification *)aNotification {
+ if( pthread_main_np() ) return [self postNotification:aNotification];
+ [[self class] performSelectorOnMainThread:@selector( _postNotification: ) withObject:aNotification waitUntilDone:NO];
+}
+
+- (void) postNotificationOnMainThreadWithName:(NSString *)aName object:(id)anObject {
+ if( pthread_main_np() ) return [self postNotificationName:aName object:anObject userInfo:nil];
+ NSMutableDictionary *info = [[NSMutableDictionary allocWithZone:nil] initWithCapacity:2];
+ if (aName) {
+ [info setObject:aName forKey:@"name"];
+ }
+ if (anObject) {
+ [info setObject:anObject forKey:@"object"];
+ }
+ [[self class] performSelectorOnMainThread:@selector(_postNotificationViaDictionary:)
+ withObject:info
+ waitUntilDone:NO];
+}
+@end
diff --git a/Source/SPArrayAdditions.h b/Source/SPArrayAdditions.h
index a8f55c8a..5d8114ef 100644
--- a/Source/SPArrayAdditions.h
+++ b/Source/SPArrayAdditions.h
@@ -27,9 +27,41 @@ static inline id NSArrayObjectAtIndex(NSArray *self, NSUInteger i)
return (id)CFArrayGetValueAtIndex((CFArrayRef)self, (long)i);
}
-static inline void NSMutableArrayAddObject(NSArray *self, id anObject)
+/**
+ * Set up a static function to allow fast mutable array insertion using
+ * cached selectors.
+ * At least in 10.7, inserting items into an array at a known point
+ * using NSMutableArray methods appears to be the fastest way of adding
+ * items to a CF/NSMutableArray.
+ */
+static inline void NSMutableArrayInsertObject(NSMutableArray *self, id anObject, NSUInteger anIndex)
{
- CFArrayAppendValue((CFMutableArrayRef)self, anObject);
+ typedef id (*NSMutableArrayInsertObjectPtr)(NSMutableArray*, SEL, id, NSUInteger);
+ static NSMutableArrayInsertObjectPtr cachedMethodPointer;
+ static SEL cachedSelector;
+
+ if (!cachedSelector) cachedSelector = @selector(insertObject:atIndex:);
+ if (!cachedMethodPointer) cachedMethodPointer = (NSMutableArrayInsertObjectPtr)[self methodForSelector:cachedSelector];
+
+ cachedMethodPointer(self, cachedSelector, anObject, anIndex);
+}
+/**
+ * Set up a static function to allow fast mutable array insertion using
+ * cached selectors.
+ * At least in 10.7, adding items to an array using NSMutableArray methods
+ * appears to be the fastest approach to adding items to a CF/NSMutableArray;
+ * only NSMutableArrayInsertObject is faster if the position is known.
+ */
+static inline void NSMutableArrayAddObject(NSMutableArray *self, id anObject)
+{
+ typedef id (*NSMutableArrayAddObjectPtr)(NSMutableArray*, SEL, id);
+ static NSMutableArrayAddObjectPtr cachedMethodPointer;
+ static SEL cachedSelector;
+
+ if (!cachedSelector) cachedSelector = @selector(addObject:);
+ if (!cachedMethodPointer) cachedMethodPointer = (NSMutableArrayAddObjectPtr)[self methodForSelector:cachedSelector];
+
+ cachedMethodPointer(self, cachedSelector, anObject);
}
static inline void NSMutableArrayReplaceObject(NSArray *self, CFIndex idx, id anObject)
diff --git a/Source/SPBundleHTMLOutputController.m b/Source/SPBundleHTMLOutputController.m
index 1b37be2e..9243741c 100644
--- a/Source/SPBundleHTMLOutputController.m
+++ b/Source/SPBundleHTMLOutputController.m
@@ -126,6 +126,7 @@
- (void)dealloc
{
if(webPreferences) [webPreferences release];
+ [super dealloc];
}
- (void)keyDown:(NSEvent *)theEvent
diff --git a/Source/SPCSVExporter.m b/Source/SPCSVExporter.m
index 651f0ffd..a552db78 100644
--- a/Source/SPCSVExporter.m
+++ b/Source/SPCSVExporter.m
@@ -23,13 +23,12 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPCSVExporter.h"
#import "SPFileHandle.h"
#import "SPTableData.h"
#import "SPExportUtilities.h"
#import "SPExportFile.h"
+#import "SPMySQL.h"
@implementation SPCSVExporter
@@ -77,7 +76,7 @@
NSArray *csvRow = nil;
NSScanner *csvNumericTester = nil;
- MCPStreamingResult *streamingResult = nil;
+ SPMySQLFastStreamingResult *streamingResult = nil;
NSString *escapedEscapeString, *escapedFieldSeparatorString, *escapedEnclosingString, *escapedLineEndString, *dataConversionString;
id csvCell;
@@ -122,7 +121,7 @@
// Make a streaming request for the data if the data array isn't set
if ((![self csvDataArray]) && [self csvTableName]) {
- totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self csvTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue];
+ totalRows = [[connection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self csvTableName] backtickQuotedString]]] integerValue];
streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self csvTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]];
}
@@ -184,12 +183,12 @@
NSDictionary *tableDetails = nil;
// Determine whether the supplied table is actually a table or a view via the CREATE TABLE command, and get the table details
- MCPResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [[self csvTableName] backtickQuotedString]]];
+ SPMySQLResult *queryResult = [connection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [[self csvTableName] backtickQuotedString]]];
[queryResult setReturnDataAsStrings:YES];
- if ([queryResult numOfRows]) {
- id object = [[[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]] objectForKey:@"Create View"];
+ if ([queryResult numberOfRows]) {
+ id object = [[queryResult getRowAsDictionary] objectForKey:@"Create View"];
tableDetails = [[NSDictionary alloc] initWithDictionary:(object) ? [[self csvTableData] informationForView:[self csvTableName]] : [[self csvTableData] informationForTable:[self csvTableName]]];
}
@@ -238,11 +237,11 @@
else {
// If still requested to read the field names, get the field names
if ([self csvOutputFieldNames]) {
- csvRow = [streamingResult fetchFieldNames];
+ csvRow = [streamingResult fieldNames];
[self setCsvOutputFieldNames:NO];
}
else {
- csvRow = [streamingResult fetchNextRowAsArray];
+ csvRow = [streamingResult getRowAsArray];
if (!csvRow) break;
}
@@ -266,7 +265,7 @@
csvCell = NSArrayObjectAtIndex(csvRow, i);
// For NULL objects supplied from a queryResult, add an unenclosed null string as per prefs
- if ([csvCell isKindOfClass:[NSNull class]]) {
+ if ([csvCell isNSNull]) {
[csvString appendString:[self csvNULLString]];
if (i < (csvCellCount - 1)) [csvString appendString:[self csvFieldSeparatorString]];
@@ -285,7 +284,7 @@
[csvCellString setString:[NSString stringWithString:dataConversionString]];
[dataConversionString release];
}
- else if ([csvCell isKindOfClass:[MCPGeometryData class]]) {
+ else if ([csvCell isKindOfClass:[SPMySQLGeometryData class]]) {
[csvCellString setString:[csvCell wktString]];
}
else {
diff --git a/Source/SPCSVParser.m b/Source/SPCSVParser.m
index e012e323..431c89a8 100644
--- a/Source/SPCSVParser.m
+++ b/Source/SPCSVParser.m
@@ -284,7 +284,7 @@
// Skip empty rows
if ([csvRowArray count] == 0
|| ([csvRowArray count] == 1
- && ([[csvRowArray objectAtIndex:0] isMemberOfClass:[NSNull class]]
+ && ([csvRowArray objectAtIndex:0] == [NSNull null]
|| ![[csvRowArray objectAtIndex:0] length])))
{
@@ -659,4 +659,4 @@
[super dealloc];
}
-@end \ No newline at end of file
+@end
diff --git a/Source/SPCategoryAdditions.h b/Source/SPCategoryAdditions.h
index daed3536..2ca3a50e 100644
--- a/Source/SPCategoryAdditions.h
+++ b/Source/SPCategoryAdditions.h
@@ -32,6 +32,7 @@
#import "SPArrayAdditions.h"
#import "SPMutableArrayAdditions.h"
#import "SPStringAdditions.h"
+#import "SPObjectAdditions.h"
#import "SPTextViewAdditions.h"
#import "SPWindowAdditions.h"
#import "SPDataAdditions.h"
@@ -41,5 +42,5 @@
#import "SPColorAdditions.h"
#import "SPFileManagerAdditions.h"
-#import "NSNotificationAdditions.h"
+#import "NSNotificationCenterThreadingAdditions.h"
#import "NSMutableArray-MultipleSort.h"
diff --git a/Source/SPColorAdditions.m b/Source/SPColorAdditions.m
index b9353921..aee0458a 100644
--- a/Source/SPColorAdditions.m
+++ b/Source/SPColorAdditions.m
@@ -71,19 +71,19 @@
unsigned int color = 0;
scanner = [NSScanner scannerWithString:code];
if( ! [scanner scanHexInt:&color] ) return nil;
- return [self colorWithCalibratedRed:( ( ( color >> 24 ) & 0xff ) / 255. ) green:( ( ( color >> 16 ) & 0xff ) / 255. ) blue:( ( ( color >> 8) & 0xff ) / 255. ) alpha:( ( color & 0xff ) / 255. )];
+ return [self colorWithCalibratedRed:( ( ( color >> 24 ) & 0xff ) / 255.f ) green:( ( ( color >> 16 ) & 0xff ) / 255.f ) blue:( ( ( color >> 8) & 0xff ) / 255.f ) alpha:( ( color & 0xff ) / 255.f )];
}
else if( [code length] == 6 ) { // decode colors like #ffee33
unsigned int color = 0;
scanner = [NSScanner scannerWithString:code];
if( ! [scanner scanHexInt:&color] ) return nil;
- return [self colorWithCalibratedRed:( ( ( color >> 16 ) & 0xff ) / 255. ) green:( ( ( color >> 8 ) & 0xff ) / 255. ) blue:( ( color & 0xff ) / 255. ) alpha:1.];
+ return [self colorWithCalibratedRed:( ( ( color >> 16 ) & 0xff ) / 255.f ) green:( ( ( color >> 8 ) & 0xff ) / 255.f ) blue:( ( color & 0xff ) / 255.f ) alpha:1.f];
}
else if( [code length] == 3 ) { // decode short-hand colors like #fe3
unsigned int color = 0;
scanner = [NSScanner scannerWithString:code];
if( ! [scanner scanHexInt:&color] ) return nil;
- return [self colorWithCalibratedRed:( ( ( ( ( color >> 8 ) & 0xf ) << 4 ) | ( ( color >> 8 ) & 0xf ) ) / 255. ) green:( ( ( ( ( color >> 4 ) & 0xf ) << 4 ) | ( ( color >> 4 ) & 0xf ) ) / 255. ) blue:( ( ( ( color & 0xf ) << 4 ) | ( color & 0xf ) ) / 255. ) alpha:1.];
+ return [self colorWithCalibratedRed:( ( ( ( ( color >> 8 ) & 0xf ) << 4 ) | ( ( color >> 8 ) & 0xf ) ) / 255.f ) green:( ( ( ( ( color >> 4 ) & 0xf ) << 4 ) | ( ( color >> 4 ) & 0xf ) ) / 255.f ) blue:( ( ( ( color & 0xf ) << 4 ) | ( color & 0xf ) ) / 255.f ) alpha:1.f];
}
return nil;
diff --git a/Source/SPConnectionController.h b/Source/SPConnectionController.h
index e8ee5e9d..dcf1c6d7 100644
--- a/Source/SPConnectionController.h
+++ b/Source/SPConnectionController.h
@@ -23,8 +23,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPConnectionControllerDelegateProtocol.h"
#ifndef SP_REFACTOR /* headers */
@@ -34,7 +32,8 @@
SPFavoritesController,
SPSSHTunnel,
SPTreeNode,
- SPFavoritesOutlineView
+ SPFavoritesOutlineView,
+ SPMySQLConnection
#ifndef SP_REFACTOR /* class decl */
,SPKeychain,
BWAnchoredButtonBar,
@@ -58,14 +57,10 @@
SPDatabaseDocument *dbDocument;
SPSSHTunnel *sshTunnel;
+ SPMySQLConnection *mySQLConnection;
#ifndef SP_REFACTOR /* ivars */
SPKeychain *keychain;
-#endif
-
- MCPConnection *mySQLConnection;
-
-#ifndef SP_REFACTOR /* ivars */
NSView *databaseConnectionSuperview;
NSSplitView *databaseConnectionView;
NSOpenPanel *keySelectionPanel;
@@ -73,11 +68,11 @@
NSUserDefaults *prefs;
NSMutableArray *favorites;
+#ifndef SP_REFACTOR /* ivars */
BOOL automaticFavoriteSelection;
BOOL cancellingConnection;
BOOL isConnecting;
-#ifndef SP_REFACTOR /* ivars */
// Standard details
NSInteger previousType;
#endif
@@ -227,7 +222,7 @@
- (IBAction)updateKeyLocationFileVisibility:(id)sender;
- (void)resizeTabViewToConnectionType:(NSUInteger)theType animating:(BOOL)animate;
- (IBAction)sortFavorites:(id)sender;
-- (IBAction)reverseSortFavorites:(id)sender;
+- (IBAction)reverseSortFavorites:(NSMenuItem *)sender;
- (void)resizeTabViewToConnectionType:(NSUInteger)theType animating:(BOOL)animate;
diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m
index 4b7db791..75752c1d 100644
--- a/Source/SPConnectionController.m
+++ b/Source/SPConnectionController.m
@@ -40,6 +40,7 @@
#import "SPTreeNode.h"
#import "SPFavoritesExporter.h"
#import "SPFavoritesImporter.h"
+#import "SPMySQL.h"
// Constants
static NSString *SPRemoveNode = @"RemoveNode";
diff --git a/Source/SPConnectionDelegate.h b/Source/SPConnectionDelegate.h
index 777b032a..04bee877 100644
--- a/Source/SPConnectionDelegate.h
+++ b/Source/SPConnectionDelegate.h
@@ -25,13 +25,13 @@
#import "SPDatabaseDocument.h"
-#import <MCPKit/MCPConnectionDelegate.h>
+#import "SPMySQLConnectionDelegate.h"
-@interface SPDatabaseDocument (SPConnectionDelegate) <MCPConnectionDelegate>
+@interface SPDatabaseDocument (SPConnectionDelegate) <SPMySQLConnectionDelegate>
- (void) closeAndDisconnect;
-- (NSString *)keychainPasswordForConnection:(MCPConnection *)connection;
-- (NSString *)keychainPasswordForSSHConnection:(MCPConnection *)connection;
+- (NSString *)keychainPasswordForConnection:(SPMySQLConnection *)connection;
+- (NSString *)keychainPasswordForSSHConnection:(SPMySQLConnection *)connection;
@end
diff --git a/Source/SPConnectionDelegate.m b/Source/SPConnectionDelegate.m
index f02d5648..9480a99e 100644
--- a/Source/SPConnectionDelegate.m
+++ b/Source/SPConnectionDelegate.m
@@ -28,11 +28,12 @@
#import "SPQueryController.h"
#import "SPKeychain.h"
#import "SPAlertSheets.h"
+#import "SPMySQLConstants.h"
@implementation SPDatabaseDocument (SPConnectionDelegate)
#pragma mark -
-#pragma mark MCPKit connection delegate methods
+#pragma mark SPMySQLConnection delegate methods
/**
* Invoked when the framework is about to perform a query.
@@ -60,18 +61,9 @@
}
/**
- * Invoked when the framework is in the process of reconnecting to the server and needs to know
- * which database to select.
- */
-- (NSString *)onReconnectShouldSelectDatabase:(id)connection
-{
- return selectedDatabase;
-}
-
-/**
* Invoked when the current connection needs a password from the Keychain.
*/
-- (NSString *)keychainPasswordForConnection:(MCPConnection *)connection
+- (NSString *)keychainPasswordForConnection:(SPMySQLConnection *)connection
{
// If no keychain item is available, return an empty password
@@ -89,8 +81,10 @@
/**
* Invoked when the current connection needs a ssh password from the Keychain.
+ * This isn't actually part of the SPMySQLConnection delegate protocol, but is here
+ * due to its similarity to the previous method.
*/
-- (NSString *)keychainPasswordForSSHConnection:(MCPConnection *)connection
+- (NSString *)keychainPasswordForSSHConnection:(SPMySQLConnection *)connection
{
// If no keychain item is available, return an empty password
@@ -123,9 +117,9 @@
/**
* Invoked when the connection fails and the framework needs to know how to proceed.
*/
-- (MCPConnectionCheck)connectionLost:(id)connection
+- (SPMySQLConnectionLostDecision)connectionLost:(id)connection
{
- NSInteger connectionErrorCode = MCPConnectionCheckDisconnect;
+ NSInteger connectionErrorCode = SPMySQLConnectionLostDisconnect;
// Only display the reconnect dialog if the window is visible
if ([self parentWindow] && [[self parentWindow] isVisible]) {
@@ -144,7 +138,7 @@
[connectionErrorDialog orderOut:nil];
// If 'disconnect' was selected, trigger a window close.
- if (connectionErrorCode == MCPConnectionCheckDisconnect) {
+ if (connectionErrorCode == SPMySQLConnectionLostDisconnect) {
[self performSelectorOnMainThread:@selector(closeAndDisconnect) withObject:nil waitUntilDone:YES];
}
}
@@ -179,7 +173,7 @@
_isConnected = NO;
if ([[[self parentTabViewItem] tabView] numberOfTabViewItems] == 1) {
[theParentWindow orderOut:self];
- [theParentWindow setAlphaValue:0.0];
+ [theParentWindow setAlphaValue:0.0f];
[theParentWindow performSelector:@selector(close) withObject:nil afterDelay:1.0];
} else {
[[[self parentTabViewItem] tabView] performSelector:@selector(removeTabViewItem:) withObject:[self parentTabViewItem] afterDelay:0.5];
diff --git a/Source/SPConnectionHandler.m b/Source/SPConnectionHandler.m
index 4ce34c44..8c9f911c 100644
--- a/Source/SPConnectionHandler.m
+++ b/Source/SPConnectionHandler.m
@@ -29,6 +29,7 @@
#import "SPSSHTunnel.h"
#import "SPKeychain.h"
#import "RegexKitLite.h"
+#import "SPMySQL.h"
static NSString *SPLocalhostAddress = @"127.0.0.1";
@@ -63,23 +64,31 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ mySQLConnection = [[SPMySQLConnection alloc] init];
+
+ // Set up shared details
+ [mySQLConnection setUsername:[self user]];
+
// Initialise to socket if appropriate.
if ([self type] == SPSocketConnection) {
- mySQLConnection = [[MCPConnection alloc] initToSocket:[self socket] withLogin:[self user]];
+ [mySQLConnection setUseSocket:YES];
+ [mySQLConnection setSocketPath:[self socket]];
// Otherwise, initialise to host, using tunnel if appropriate
}
else {
+ [mySQLConnection setUseSocket:NO];
+
if ([self type] == SPSSHTunnelConnection) {
- mySQLConnection = [[MCPConnection alloc] initToHost:SPLocalhostAddress
- withLogin:[self user]
- usingPort:[sshTunnel localPort]];
- [mySQLConnection setConnectionProxy:sshTunnel];
+ [mySQLConnection setHost:@"127.0.0.1"];
+
+ [mySQLConnection setPort:[sshTunnel localPort]];
+ [mySQLConnection setProxy:sshTunnel];
}
else {
- mySQLConnection = [[MCPConnection alloc] initToHost:[self host]
- withLogin:[self user]
- usingPort:([[self port] length] ? [[self port] integerValue] : 3306)];
+ [mySQLConnection setHost:[self host]];
+
+ if ([[self port] length]) [mySQLConnection setPort:[[self port] integerValue]];
}
}
@@ -90,9 +99,19 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
// Enable SSL if set
if ([self useSSL]) {
- [mySQLConnection setSSL:YES
- usingKeyFilePath:[self sslKeyFileLocationEnabled] ? [self sslKeyFileLocation] : nil
- certificatePath:[self sslCertificateFileLocationEnabled] ? [self sslCertificateFileLocation] : nil certificateAuthorityCertificatePath:[self sslCACertFileLocationEnabled] ? [self sslCACertFileLocation] : nil];
+ [mySQLConnection setUseSSL:YES];
+
+ if ([self sslKeyFileLocationEnabled]) {
+ [mySQLConnection setSslKeyFilePath:[self sslKeyFileLocation]];
+ }
+
+ if ([self sslCertificateFileLocationEnabled]) {
+ [mySQLConnection setSslCertificatePath:[self sslCertificateFileLocation]];
+ }
+
+ if ([self sslCACertFileLocationEnabled]) {
+ [mySQLConnection setSslCACertificatePath:[self sslCACertFileLocation]];
+ }
}
// Connection delegate must be set before actual connection attempt is made
@@ -102,9 +121,9 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
[mySQLConnection setDelegateQueryLogging:[prefs boolForKey:SPConsoleEnableLogging]];
// Set options from preferences
- [mySQLConnection setConnectionTimeout:[[prefs objectForKey:SPConnectionTimeoutValue] integerValue]];
+ [mySQLConnection setTimeout:[[prefs objectForKey:SPConnectionTimeoutValue] integerValue]];
[mySQLConnection setUseKeepAlive:[[prefs objectForKey:SPUseKeepAlive] boolValue]];
- [mySQLConnection setKeepAliveInterval:[[prefs objectForKey:SPKeepAliveInterval] doubleValue]];
+ [mySQLConnection setKeepAliveInterval:[[prefs objectForKey:SPKeepAliveInterval] floatValue]];
// Connect
[mySQLConnection connect];
@@ -116,7 +135,7 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
[[NSRunLoop currentRunLoop] runMode:NSModalPanelRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
// If the state is connection refused, attempt the MySQL connection again with the host using the hostfield value.
- if ([sshTunnel state] == PROXY_STATE_FORWARDING_FAILED) {
+ if ([sshTunnel state] == SPMySQLProxyForwardingFailed) {
if ([sshTunnel localPortFallback]) {
[mySQLConnection setPort:[sshTunnel localPortFallback]];
[mySQLConnection connect];
@@ -130,24 +149,24 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
if (![mySQLConnection isConnected]) {
NSString *errorMessage = @"";
- if (sshTunnel && [sshTunnel state] == PROXY_STATE_FORWARDING_FAILED) {
- errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because the port connection via SSH was refused.\n\nPlease ensure that your MySQL host is set up to allow TCP/IP connections (no --skip-networking) and is configured to allow connections from the host you are tunnelling via.\n\nYou may also want to check the port is correct and that you have the necessary privileges.\n\nChecking the error detail will show the SSH debug log which may provide more details.\n\nMySQL said: %@", @"message of panel when SSH port forwarding failed"), [self host], [mySQLConnection getLastErrorMessage]];
+ if (sshTunnel && [sshTunnel state] == SPMySQLProxyForwardingFailed) {
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because the port connection via SSH was refused.\n\nPlease ensure that your MySQL host is set up to allow TCP/IP connections (no --skip-networking) and is configured to allow connections from the host you are tunnelling via.\n\nYou may also want to check the port is correct and that you have the necessary privileges.\n\nChecking the error detail will show the SSH debug log which may provide more details.\n\nMySQL said: %@", @"message of panel when SSH port forwarding failed"), [self host], [mySQLConnection lastErrorMessage]];
[[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"SSH port forwarding failed", @"title when ssh tunnel port forwarding failed") errorMessage:errorMessage detail:[sshTunnel debugMessages]];
}
- else if ([mySQLConnection getLastErrorID] == 1045) { // "Access denied" error
- errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because access was denied.\n\nDouble-check your username and password and ensure that access from your current location is permitted.\n\nMySQL said: %@", @"message of panel when connection to host failed due to access denied error"), [self host], [mySQLConnection getLastErrorMessage]];
+ else if ([mySQLConnection lastErrorID] == 1045) { // "Access denied" error
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@ because access was denied.\n\nDouble-check your username and password and ensure that access from your current location is permitted.\n\nMySQL said: %@", @"message of panel when connection to host failed due to access denied error"), [self host], [mySQLConnection lastErrorMessage]];
[[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Access denied!", @"connection failed due to access denied title") errorMessage:errorMessage detail:nil];
}
- else if ([self type] == SPSocketConnection && (![self socket] || ![[self socket] length]) && ![mySQLConnection findSocketPath]) {
- errorMessage = [NSString stringWithFormat:NSLocalizedString(@"The socket file could not be found in any common location. Please supply the correct socket location.\n\nMySQL said: %@", @"message of panel when connection to socket failed because optional socket could not be found"), [mySQLConnection getLastErrorMessage]];
+ else if ([self type] == SPSocketConnection && (![self socket] || ![[self socket] length]) && ![mySQLConnection socketPath]) {
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"The socket file could not be found in any common location. Please supply the correct socket location.\n\nMySQL said: %@", @"message of panel when connection to socket failed because optional socket could not be found"), [mySQLConnection lastErrorMessage]];
[[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Socket not found!", @"socket not found title") errorMessage:errorMessage detail:nil];
}
else if ([self type] == SPSocketConnection) {
- errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect via the socket, or the request timed out.\n\nDouble-check that the socket path is correct and that you have the necessary privileges, and that the server is running.\n\nMySQL said: %@", @"message of panel when connection to host failed"), [mySQLConnection getLastErrorMessage]];
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect via the socket, or the request timed out.\n\nDouble-check that the socket path is correct and that you have the necessary privileges, and that the server is running.\n\nMySQL said: %@", @"message of panel when connection to host failed"), [mySQLConnection lastErrorMessage]];
[[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Socket connection failed!", @"socket connection failed title") errorMessage:errorMessage detail:nil];
}
else {
- errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [self host], (long)[[prefs objectForKey:SPConnectionTimeoutValue] integerValue], [mySQLConnection getLastErrorMessage]];
+ errorMessage = [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).\n\nMySQL said: %@", @"message of panel when connection to host failed"), [self host], (long)[[prefs objectForKey:SPConnectionTimeoutValue] integerValue], [mySQLConnection lastErrorMessage]];
[[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Connection failed!", @"connection failed title") errorMessage:errorMessage detail:nil];
}
@@ -165,8 +184,8 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
}
if ([self database] && ![[self database] isEqualToString:@""]) {
- if (![mySQLConnection selectDB:[self database]]) {
- [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Could not select database", @"message when database selection failed") errorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [self database], [mySQLConnection getLastErrorMessage]] detail:nil];
+ if (![mySQLConnection selectDatabase:[self database]]) {
+ [[self onMainThread] failConnectionWithTitle:NSLocalizedString(@"Could not select database", @"message when database selection failed") errorMessage:[NSString stringWithFormat:NSLocalizedString(@"Connected to host, but unable to connect to database %@.\n\nBe sure that the database exists and that you have the necessary privileges.\n\nMySQL said: %@", @"message of panel when connection to db failed"), [self database], [mySQLConnection lastErrorMessage]] detail:nil];
// Tidy up
isConnecting = NO;
@@ -300,14 +319,14 @@ static NSString *SPLocalhostAddress = @"127.0.0.1";
return;
}
- if (newState == PROXY_STATE_IDLE) {
+ if (newState == SPMySQLProxyIdle) {
[dbDocument setTitlebarStatus:NSLocalizedString(@"SSH Disconnected", @"SSH disconnected titlebar marker")];
[self failConnectionWithTitle:NSLocalizedString(@"SSH connection failed!", @"SSH connection failed title") errorMessage:[theTunnel lastError] detail:[sshTunnel debugMessages]];
[self _restoreConnectionInterface];
}
- else if (newState == PROXY_STATE_CONNECTED) {
+ else if (newState == SPMySQLProxyConnected) {
[dbDocument setTitlebarStatus:NSLocalizedString(@"SSH Connected", @"SSH connected titlebar marker")];
[self initiateMySQLConnection];
diff --git a/Source/SPConstants.h b/Source/SPConstants.h
index 41cad9ec..01750e95 100644
--- a/Source/SPConstants.h
+++ b/Source/SPConstants.h
@@ -231,6 +231,11 @@ extern const NSUInteger SPNarrowDownCompletionMaxRows;
// Default monospaced font name
extern NSString *SPDefaultMonospacedFontName;
+// System database names
+extern NSString *SPMySQLDatabase;
+extern NSString *SPMySQLInformationSchemaDatabase;
+extern NSString *SPMySQLPerformanceSchemaDatabase;
+
// Table view drag types
extern NSString *SPDefaultPasteboardDragType;
extern NSString *SPFavoritesPasteboardDragType;
@@ -570,7 +575,7 @@ extern const NSInteger SPBundleRedirectActionShowAsTextTooltip;
extern const NSInteger SPBundleRedirectActionShowAsHTMLTooltip;
extern const NSInteger SPBundleRedirectActionLastCode;
-// sequel URL scheme
+// URL scheme
extern NSString *SPURLSchemeQueryInputPathHeader;
extern NSString *SPURLSchemeQueryResultPathHeader;
extern NSString *SPURLSchemeQueryResultStatusPathHeader;
diff --git a/Source/SPConstants.m b/Source/SPConstants.m
index 1ce6181b..01adcab2 100644
--- a/Source/SPConstants.m
+++ b/Source/SPConstants.m
@@ -31,6 +31,11 @@ const NSUInteger SPNarrowDownCompletionMaxRows = 15;
// Default monospaced font name
NSString *SPDefaultMonospacedFontName = @"Monaco";
+// System database names
+NSString *SPMySQLDatabase = @"mysql";
+NSString *SPMySQLInformationSchemaDatabase = @"information_schema";
+NSString *SPMySQLPerformanceSchemaDatabase = @"performance_schema";
+
// Table view drag types
NSString *SPDefaultPasteboardDragType = @"SequelProPasteboard";
NSString *SPFavoritesPasteboardDragType = @"SPFavoritesPasteboard";
@@ -216,7 +221,17 @@ NSString *SPMainToolbarTableInfo = @"SwitchToTableInfoToolbarIte
NSString *SPMainToolbarTableRelations = @"SwitchToTableRelationsToolbarItemIdentifier";
NSString *SPMainToolbarTableTriggers = @"SwitchToTableTriggersToolbarItemIdentifier";
NSString *SPMainToolbarUserManager = @"SwitchToUserManagerToolbarItemIdentifier";
-NSString **SPViewModeToMainToolbarMap[] = {nil, &SPMainToolbarTableStructure, &SPMainToolbarTableContent, &SPMainToolbarCustomQuery, &SPMainToolbarTableInfo, &SPMainToolbarTableRelations, &SPMainToolbarTableTriggers};
+
+NSString **SPViewModeToMainToolbarMap[] =
+{
+ nil,
+ &SPMainToolbarTableStructure,
+ &SPMainToolbarTableContent,
+ &SPMainToolbarCustomQuery,
+ &SPMainToolbarTableInfo,
+ &SPMainToolbarTableRelations,
+ &SPMainToolbarTableTriggers
+};
// Preferences toolbar
NSString *SPPreferenceToolbarGeneral = @"SPPreferenceToolbarGeneral";
@@ -376,7 +391,7 @@ const NSInteger SPBundleRedirectActionShowAsTextTooltip = 207;
const NSInteger SPBundleRedirectActionShowAsHTMLTooltip = 208;
const NSInteger SPBundleRedirectActionLastCode = 208;
-// sequel URL scheme
+// URL scheme
NSString *SPURLSchemeQueryInputPathHeader = @"/tmp/SP_QUERY_";
NSString *SPURLSchemeQueryResultPathHeader = @"/tmp/SP_QUERY_RESULT_";
NSString *SPURLSchemeQueryResultStatusPathHeader = @"/tmp/SP_QUERY_RESULT_STATUS_";
diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m
index e13ae61e..3cdf4213 100644
--- a/Source/SPCopyTable.m
+++ b/Source/SPCopyTable.m
@@ -22,11 +22,6 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-#import <MCPKit/MCPKit.h>
-#ifndef SP_REFACTOR /* headers */
-#import "MCPGeometryData.h"
-#endif
-
#import "SPCopyTable.h"
#import "SPTableContent.h"
#import "SPTableTriggers.h"
@@ -41,6 +36,7 @@
#import "SPBundleEditorController.h"
#import "SPAppController.h"
#import "SPTablesList.h"
+#import "SPMySQL.h"
NSInteger MENU_EDIT_COPY = 2001;
NSInteger MENU_EDIT_COPY_WITH_COLUMN = 2002;
@@ -166,7 +162,7 @@ NSInteger kBlobAsImageFile = 4;
// Loop through the rows, adding their descriptive contents
NSUInteger rowIndex = [selectedRows firstIndex];
NSString *nullString = [prefs objectForKey:SPNullValue];
- Class mcpGeometryData = [MCPGeometryData class];
+ Class spmysqlGeometryData = [SPMySQLGeometryData class];
NSUInteger rowCounter = 0;
if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) {
@@ -219,7 +215,7 @@ NSInteger kBlobAsImageFile = 4;
[result appendString:@"BLOB\t"];
}
}
- else if ([cellData isKindOfClass:mcpGeometryData]) {
+ else if ([cellData isKindOfClass:spmysqlGeometryData]) {
if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) {
NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", tmpBlobFileDirectory, rowCounter, c];
SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]];
@@ -304,7 +300,7 @@ NSInteger kBlobAsImageFile = 4;
// Loop through the rows, adding their descriptive contents
NSUInteger rowIndex = [selectedRows firstIndex];
NSString *nullString = [prefs objectForKey:SPNullValue];
- Class mcpGeometryData = [MCPGeometryData class];
+ Class spmysqlGeometryData = [SPMySQLGeometryData class];
NSUInteger rowCounter = 0;
@@ -358,7 +354,7 @@ NSInteger kBlobAsImageFile = 4;
[result appendString:@"\"BLOB\","];
}
}
- else if ([cellData isKindOfClass:mcpGeometryData]) {
+ else if ([cellData isKindOfClass:spmysqlGeometryData]) {
if((withBlobHandling == kBlobAsFile || withBlobHandling == kBlobAsImageFile) && tmpBlobFileDirectory && [tmpBlobFileDirectory length]) {
NSString *fp = [NSString stringWithFormat:@"%@/%ld_%ld.pdf", tmpBlobFileDirectory, rowCounter, c];
SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[cellData coordinates]];
@@ -519,15 +515,15 @@ NSInteger kBlobAsImageFile = 4;
case 1:
case 2:
if ([cellData isKindOfClass:nsDataClass]) {
- [value appendFormat:@"X'%@', ", [mySQLConnection prepareBinaryData:cellData]];
+ [value appendString:[mySQLConnection escapeAndQuoteData:cellData]];
} else {
- [value appendFormat:@"'%@', ", [mySQLConnection prepareString:[cellData description]]];
+ [value appendString:[mySQLConnection escapeAndQuoteString:[cellData description]]];
}
break;
// GEOMETRY
case 3:
- [value appendFormat:@"X'%@', ", [mySQLConnection prepareBinaryData:[cellData data]]];
+ [value appendString:[mySQLConnection escapeAndQuoteData:[cellData data]]];
break;
// Unhandled cases - abort
default:
@@ -620,7 +616,7 @@ NSInteger kBlobAsImageFile = 4;
NSUInteger rowIndex = [selectedRows firstIndex];
NSString *nullString = [prefs objectForKey:SPNullValue];
Class nsDataClass = [NSData class];
- Class mcpGeometryData = [MCPGeometryData class];
+ Class spmysqlGeometryData = [SPMySQLGeometryData class];
NSStringEncoding connectionEncoding = [mySQLConnection stringEncoding];
while ( rowIndex != NSNotFound )
{
@@ -642,7 +638,7 @@ NSInteger kBlobAsImageFile = 4;
[displayString release];
}
}
- else if ([cellData isKindOfClass:mcpGeometryData]) {
+ else if ([cellData isKindOfClass:spmysqlGeometryData]) {
[result appendFormat:@"%@\t", [cellData wktString]];
} else
[result appendFormat:@"%@\t", [cellData description]];
@@ -708,7 +704,7 @@ NSInteger kBlobAsImageFile = 4;
// Determine the available size
NSScrollView *parentScrollView = (NSScrollView*)[[self superview] superview];
- CGFloat visibleTableWidth = [parentScrollView bounds].size.width - [NSScroller scrollerWidth] - [columnDefinitions count] * 3.5;
+ CGFloat visibleTableWidth = [parentScrollView bounds].size.width - [NSScroller scrollerWidth] - [columnDefinitions count] * 3.5f;
for (NSDictionary *columnDefinition in columnDefinitions) {
if ([[NSThread currentThread] isCancelled]) return nil;
@@ -738,7 +734,7 @@ NSInteger kBlobAsImageFile = 4;
for (NSString *columnIdentifier in columnIdentifiers) {
columnWidth = [[columnWidths objectForKey:columnIdentifier] integerValue];
if (columnWidth > SP_MAX_CELL_WIDTH_MULTICOLUMN) {
- columnWidth -= ceil((double)(columnWidth - SP_MAX_CELL_WIDTH_MULTICOLUMN) / availableWidthToReduce * widthToReduce);
+ columnWidth -= ceilf((double)(columnWidth - SP_MAX_CELL_WIDTH_MULTICOLUMN) / availableWidthToReduce * widthToReduce);
[columnWidths setObject:[NSNumber numberWithUnsignedInteger:columnWidth] forKey:columnIdentifier];
}
}
@@ -767,13 +763,13 @@ NSInteger kBlobAsImageFile = 4;
#endif
NSUInteger columnIndex = (NSUInteger)[[columnDefinition objectForKey:@"datacolumnindex"] integerValue];
NSDictionary *stringAttributes = [NSDictionary dictionaryWithObject:tableFont forKey:NSFontAttributeName];
- Class mcpGeometryData = [MCPGeometryData class];
+ Class spmysqlGeometryData = [SPMySQLGeometryData class];
// Check the number of rows available to check, sampling every n rows
if ([tableStorage count] < rowsToCheck)
rowStep = 1;
else
- rowStep = floor([tableStorage count] / rowsToCheck);
+ rowStep = floorf([tableStorage count] / rowsToCheck);
rowsToCheck = [tableStorage count];
@@ -787,8 +783,8 @@ NSInteger kBlobAsImageFile = 4;
// Retrieve the cell's content
contentString = [tableStorage cellDataAtRow:i column:columnIndex];
- // Get WKT string out of the MCPGeometryData for calculation
- if ([contentString isKindOfClass:mcpGeometryData])
+ // Get WKT string out of the SPMySQLGeometryData for calculation
+ if ([contentString isKindOfClass:spmysqlGeometryData])
contentString = [contentString wktString];
// Replace NULLs with their placeholder string
diff --git a/Source/SPCustomQuery.h b/Source/SPCustomQuery.h
index aa78a250..1e330682 100644
--- a/Source/SPCustomQuery.h
+++ b/Source/SPCustomQuery.h
@@ -23,7 +23,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
#import <WebKit/WebKit.h>
#import "SPCopyTable.h"
@@ -47,9 +46,9 @@
#define SP_HISTORY_CLEAR_MENUITEM_TAG 300002
#ifndef SP_REFACTOR
-@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView, SPFieldEditorController;
+@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, BWSplitView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult;
#else
-@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, NSSplitView, SPFieldEditorController;
+@class SPCopyTable, SPQueryFavoriteManager, SPDataStorage, NSSplitView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult;
#endif
@interface SPCustomQuery : NSObject
@@ -129,7 +128,7 @@
SPQueryFavoriteManager *favoritesManager;
NSUserDefaults *prefs;
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
NSString *usedQuery;
NSRange currentQueryRange;
@@ -221,7 +220,7 @@
- (IBAction)copyQueryHistory:(id)sender;
- (IBAction)clearQueryHistory:(id)sender;
- (IBAction)showCompletionList:(id)sender;
-- (IBAction)toggleQueryInfoPaneCollapse:(id)sender;
+- (IBAction)toggleQueryInfoPaneCollapse:(NSButton *)sender;
// Query actions
- (void)performQueries:(NSArray *)queries withCallback:(SEL)customQueryCallbackMethod;
@@ -239,7 +238,7 @@
// Accessors
- (NSArray *)currentResult;
- (NSArray *)currentDataResultWithNULLs:(BOOL)includeNULLs;
-- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult;
+- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult;
// Retrieving and setting table state
- (void) updateTableView;
@@ -271,7 +270,7 @@
- (void)tableSortCallback;
// Other
-- (void)setConnection:(MCPConnection *)theConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
- (void)doPerformQueryService:(NSString *)query;
- (void)doPerformLoadQueryService:(NSString *)query;
- (void)selectCurrentQuery;
diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m
index 307e5c9a..f69db3b7 100644
--- a/Source/SPCustomQuery.m
+++ b/Source/SPCustomQuery.m
@@ -25,6 +25,7 @@
#import "SPCustomQuery.h"
#import "SPSQLParser.h"
+#import "SPMySQL.h"
#ifndef SP_REFACTOR /* headers */
#import "SPGrowlController.h"
#endif
@@ -45,6 +46,7 @@
#import "SPGeometryDataView.h"
#import "SPAppController.h"
#import "SPBundleHTMLOutputController.h"
+#include <pthread.h>
#ifndef SP_REFACTOR /* headers */
#import <BWToolkitFramework/BWToolkitFramework.h>
@@ -537,7 +539,7 @@
/**
* Toggle whether the query info pane is visible.
*/
-- (IBAction)toggleQueryInfoPaneCollapse:(id)sender
+- (IBAction)toggleQueryInfoPaneCollapse:(NSButton *)sender
{
[queryInfoPaneSplitView toggleCollapse:sender];
@@ -582,12 +584,12 @@
- (void)performQueriesTask:(NSDictionary *)taskArguments
{
- NSAutoreleasePool *queryRunningPool = [[NSAutoreleasePool alloc] init];
- NSArray *queries = [taskArguments objectForKey:@"queries"];
- MCPStreamingResult *streamingResult = nil;
- NSMutableString *errors = [NSMutableString string];
- SEL callbackMethod = NULL;
- NSString *taskButtonString;
+ NSAutoreleasePool *queryRunningPool = [[NSAutoreleasePool alloc] init];
+ NSArray *queries = [taskArguments objectForKey:@"queries"];
+ SPMySQLFastStreamingResult *streamingResult = nil;
+ NSMutableString *errors = [NSMutableString string];
+ SEL callbackMethod = NULL;
+ NSString *taskButtonString;
NSUInteger i, totalQueriesRun = 0, totalAffectedRows = 0;
double executionTime = 0;
@@ -624,7 +626,7 @@
}
// Disable automatic query retries on failure for the custom queries
- [mySQLConnection setAllowQueryRetries:NO];
+ [mySQLConnection setRetryQueriesOnConnectionFailure:NO];
NSUInteger queryCount = [queries count];
NSMutableArray *tempQueries = [NSMutableArray arrayWithCapacity:queryCount];
@@ -656,16 +658,16 @@
// Run the query, timing execution (note this also includes network and overhead)
streamingResult = [[mySQLConnection streamingQueryString:query] retain];
- executionTime += [mySQLConnection lastQueryExecutionTime];
+ executionTime += [streamingResult queryExecutionTime];
totalQueriesRun++;
// If this is the last query, retrieve and store the result; otherwise,
// discard the result without fully loading.
- if (totalQueriesRun == queryCount || [mySQLConnection queryCancelled]) {
+ if (totalQueriesRun == queryCount || [mySQLConnection lastQueryWasCancelled]) {
// Retrieve and cache the column definitions for the result array
if (cqColumnDefinition) [cqColumnDefinition release];
- cqColumnDefinition = [[streamingResult fetchResultFieldsStructure] retain];
+ cqColumnDefinition = [[streamingResult fieldDefinitions] retain];
if(!reloadingExistingResult) {
[[self onMainThread] updateTableView];
@@ -692,24 +694,24 @@
}
// Record any affected rows
- if ( [mySQLConnection affectedRows] != (my_ulonglong)~0 )
- totalAffectedRows += (NSUInteger)[mySQLConnection affectedRows];
- else if ( [streamingResult numOfRows] )
- totalAffectedRows += (NSUInteger)[streamingResult numOfRows];
+ if ( [mySQLConnection rowsAffectedByLastQuery] != (unsigned long long)~0 )
+ totalAffectedRows += (NSUInteger)[mySQLConnection rowsAffectedByLastQuery];
+ else if ( [streamingResult numberOfRows] )
+ totalAffectedRows += (NSUInteger)[streamingResult numberOfRows];
[streamingResult release];
// Store any error messages
- if ([mySQLConnection queryErrored] || [mySQLConnection queryCancelled]) {
+ if ([mySQLConnection queryErrored] || [mySQLConnection lastQueryWasCancelled]) {
NSString *errorString;
- if ([mySQLConnection queryCancelled]) {
- if ([mySQLConnection queryCancellationUsedReconnect])
+ if ([mySQLConnection lastQueryWasCancelled]) {
+ if ([mySQLConnection lastQueryWasCancelledUsingReconnect])
errorString = NSLocalizedString(@"Query cancelled. Please note that to cancel the query the connection had to be reset; transactions and connection variables were reset.", @"Query cancel by resetting connection error");
else
errorString = NSLocalizedString(@"Query cancelled.", @"Query cancelled error");
} else {
- errorString = [mySQLConnection getLastErrorMessage];
+ errorString = [mySQLConnection lastErrorMessage];
}
// If the query errored, append error to the error log for display at the end
@@ -726,7 +728,7 @@
[[errorText onMainThread] setString:errors];
// ask the user to continue after detecting an error
- if (![mySQLConnection queryCancelled]) {
+ if (![mySQLConnection lastQueryWasCancelled]) {
[tableDocumentInstance setTaskIndicatorShouldAnimate:NO];
SPBeginWaitingAlertSheet(@"title",
@@ -735,7 +737,7 @@
@selector(sheetDidEnd:returnCode:contextInfo:),
@"runAllContinueStopSheet",
NSLocalizedString(@"MySQL Error", @"mysql error message"),
- [mySQLConnection getLastErrorMessage],
+ [mySQLConnection lastErrorMessage],
&runAllContinueStopSheetReturnCode
);
[tableDocumentInstance setTaskIndicatorShouldAnimate:YES];
@@ -768,7 +770,7 @@
databaseWasChanged = YES;
}
// If the query was cancelled, end all queries.
- if ([mySQLConnection queryCancelled]) break;
+ if ([mySQLConnection lastQueryWasCancelled]) break;
}
// Reload table list if at least one query began with drop, alter, rename, or create
@@ -797,7 +799,7 @@
if ( !queryCount ) {
streamingResult = [mySQLConnection streamingQueryString:@""];
[streamingResult cancelResultLoad];
- [errors setString:[mySQLConnection getLastErrorMessage]];
+ [errors setString:[mySQLConnection lastErrorMessage]];
}
// add query to history
@@ -814,7 +816,7 @@
// Set up the status string
NSString *statusString = nil;
NSString *statusErrorString = [errors length]?NSLocalizedString(@"Errors", @"Errors title"):NSLocalizedString(@"No errors", @"No errors title");
- if ( [mySQLConnection queryCancelled] ) {
+ if ( [mySQLConnection lastQueryWasCancelled] ) {
if (totalQueriesRun > 1) {
statusString = [NSString stringWithFormat:NSLocalizedString(@"%@; Cancelled in query %ld, after %@", @"text showing multiple queries were cancelled"),
statusErrorString,
@@ -859,7 +861,7 @@
[[affectedRowsText onMainThread] setStringValue:statusString];
// Restore automatic query retries
- [mySQLConnection setAllowQueryRetries:YES];
+ [mySQLConnection setRetryQueriesOnConnectionFailure:YES];
#ifndef SP_REFACTOR /* [tableDocumentInstance setQueryMode:] */
[tableDocumentInstance setQueryMode:SPInterfaceQueryMode];
@@ -934,9 +936,8 @@
/**
* Processes a supplied streaming result set, loading it into the data array.
*/
-- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult
+- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult
{
- NSArray *tempRow;
NSAutoreleasePool *dataLoadingPool;
// Remove all items from the table
@@ -948,7 +949,7 @@
// Set the column count on the data store before setting up anything else -
// ensures that SPDataStorage is set up for timer-driven data loads
- [resultData setColumnCount:[theResult numOfFields]];
+ [resultData setColumnCount:[theResult numberOfFields]];
// Set up the table updates timer
[[self onMainThread] initQueryLoadTimer];
@@ -957,10 +958,10 @@
dataLoadingPool = [[NSAutoreleasePool alloc] init];
// Loop through the result rows as they become available
- while ((tempRow = [theResult fetchNextRowAsArray])) {
+ for (NSArray *eachRow in theResult) {
pthread_mutex_lock(&resultDataLock);
- SPDataStorageAddRow(resultData, tempRow);
+ SPDataStorageAddRow(resultData, eachRow);
resultDataCount++;
pthread_mutex_unlock(&resultDataLock);
@@ -1286,7 +1287,7 @@
NSInteger firstErrorOccuredInQuery = [[errorDetails objectForKey:@"firstErrorQueryNumber"] integerValue];
// If errors occur, display them
- if ( [mySQLConnection queryCancelled] || ([errorsString length] && !queryIsTableSorter)) {
+ if ( [mySQLConnection lastQueryWasCancelled] || ([errorsString length] && !queryIsTableSorter)) {
// set the error text
[errorText setString:[errorsString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
@@ -1297,7 +1298,7 @@
NSRange errorLineNumberRange = [errorsString rangeOfRegex:@"([0-9]+)[^0-9]*$" options:RKLNoOptions inRange:NSMakeRange(0, [errorsString length]) capture:1L error:nil];
// if error ID 1064 and a line number was found
- if([mySQLConnection getLastErrorID] == 1064 && errorLineNumberRange.length)
+ if([mySQLConnection lastErrorID] == 1064 && errorLineNumberRange.length)
{
// Get the line number
NSUInteger errorAtLine = [[errorsString substringWithRange:errorLineNumberRange] integerValue];
@@ -1499,7 +1500,7 @@
/**
* Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once
*/
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
currentQueryRanges = nil;
@@ -1755,7 +1756,7 @@
[tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")];
// Actual check whether field can be identified bijectively
- MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
+ SPMySQLResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
[[columnDefinition objectForKey:@"db"] backtickQuotedString],
[tableForColumn backtickQuotedString],
fieldIDQueryStr]];
@@ -1765,7 +1766,7 @@
return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
}
- NSArray *tempRow = [tempResult fetchRowAsArray];
+ NSArray *tempRow = [tempResult getRowAsArray];
if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] > 1) {
// try to identify the cell by using blob data
@@ -1785,7 +1786,7 @@
return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
}
- tempRow = [tempResult fetchRowAsArray];
+ tempRow = [tempResult getRowAsArray];
if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] < 1) {
[tableDocumentInstance endTask];
@@ -1808,7 +1809,6 @@
- (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database includeBlobs:(BOOL)includeBlobs
{
NSArray *dataRow;
- NSDictionary *theRow;
id field;
NSMutableArray *argumentParts = [NSMutableArray array];
@@ -1827,17 +1827,14 @@
dataRow = [resultData rowContentsAtIndex:rowIndex];
// Get the primary key if there is one, using any columns present within it
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@",
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@",
[database backtickQuotedString], [tableForColumn backtickQuotedString]]];
[theResult setReturnDataAsStrings:YES];
- if ([theResult numOfRows]) [theResult dataSeek:0];
NSMutableArray *primaryColumnsInSpecifiedTable = [NSMutableArray array];
- NSUInteger i;
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
- theRow = [theResult fetchRowAsDictionary];
- if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
+ for (NSDictionary *eachRow in theResult) {
+ if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
for (field in columnsInSpecifiedTable) {
- if([[field objectForKey:@"org_name"] isEqualToString:[theRow objectForKey:@"Field"]]) {
+ if([[field objectForKey:@"org_name"] isEqualToString:[eachRow objectForKey:@"Field"]]) {
[primaryColumnsInSpecifiedTable addObject:field];
}
}
@@ -1850,34 +1847,38 @@
// Build up the argument
for (field in columnsToQuery) {
id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] integerValue]];
- if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) {
+
+ if ([aValue isNSNull]) {
[argumentParts addObject:[NSString stringWithFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]]];
- } else {
- if ([[field objectForKey:@"typegrouping"] isEqualToString:@"textdata"]) {
- if(includeBlobs) {
- [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]];
- }
- }
- else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"blobdata"] || [[field objectForKey:@"type"] isEqualToString:@"BINARY"] || [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"]) {
- if(includeBlobs) {
- [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]];
- }
+ }
+ else {
+ NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"];
+
+ // Skip blob-type fields if requested
+ if (!includeBlobs
+ && ([fieldTypeGrouping isEqualToString:@"textdata"] ||
+ [fieldTypeGrouping isEqualToString:@"blobdata"] ||
+ [[field objectForKey:@"type"] isEqualToString:@"BINARY"] ||
+ [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"]))
+ {
+ continue;
}
- else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"bit"]) {
+
+ if ([[field objectForKey:@"typegrouping"] isEqualToString:@"bit"]) {
[argumentParts addObject:[NSString stringWithFormat:@"%@=b'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]];
}
else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"integer"]) {
[fieldIDQueryStr appendFormat:@"%@=%@ AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]];
}
else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"geometry"]) {
- [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:[aValue data]]]];
}
// BLOB/TEXT data
else if ([aValue isKindOfClass:[NSData class]]) {
- [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:aValue]]];
}
else {
- [argumentParts addObject:[NSString stringWithFormat:@"%@='%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteString:aValue]]];
}
}
}
@@ -1914,11 +1915,11 @@
NSString *newObject = nil;
if ( [anObject isKindOfClass:[NSCalendarDate class]] ) {
- newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]];
+ newObject = [mySQLConnection escapeAndQuoteString:[anObject description]];
} else if ( [anObject isKindOfClass:[NSNumber class]] ) {
newObject = [anObject stringValue];
} else if ( [anObject isKindOfClass:[NSData class]] ) {
- newObject = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:anObject]];
+ newObject = [mySQLConnection escapeAndQuoteData:anObject];
} else {
if ( [[anObject description] isEqualToString:@"CURRENT_TIMESTAMP"] ) {
newObject = @"CURRENT_TIMESTAMP";
@@ -1935,7 +1936,7 @@
&& [[anObject description] isEqualToString:@"NOW()"]) {
newObject = @"NOW()";
} else {
- newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]];
+ newObject = [mySQLConnection escapeAndQuoteString:[anObject description]];
}
}
@@ -1947,13 +1948,13 @@
// Check for errors while UPDATE
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection lastErrorMessage]]);
return;
}
// This shouldn't happen – for safety reasons
- if ( ![mySQLConnection affectedRows] ) {
+ if ( ![mySQLConnection rowsAffectedByLastQuery] ) {
#ifndef SP_REFACTOR
if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) {
SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
@@ -2330,7 +2331,7 @@
return nil;
}
}
- else if ([theValue isKindOfClass:[MCPGeometryData class]]) {
+ else if ([theValue isKindOfClass:[SPMySQLGeometryData class]]) {
SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[theValue coordinates]];
image = [v thumbnailImage];
if(image) {
@@ -3064,7 +3065,7 @@
if(![searchString length]) return @"";
NSRange aRange;
- MCPResult *theResult = nil;
+ SPMySQLResult *theResult = nil;
NSDictionary *tableDetails;
NSMutableString *theHelp = [NSMutableString string];
@@ -3083,14 +3084,16 @@
return SP_HELP_NOT_AVAILABLE;
}
// nothing found?
- if(![theResult numOfRows]) {
+ if(![theResult numberOfRows]) {
+
// try to search via: HELP 'searchString%'
theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"HELP '%@%%'", [searchString stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
+
// really nothing found?
- if(![theResult numOfRows])
+ if(![theResult numberOfRows])
return @"";
}
- tableDetails = [[NSDictionary alloc] initWithDictionary:[theResult fetchRowAsDictionary]];
+ tableDetails = [[NSDictionary alloc] initWithDictionary:[theResult getRowAsDictionary]];
if ([tableDetails objectForKey:@"description"]) { // one single help topic found
if ([tableDetails objectForKey:@"name"]) {
@@ -3165,9 +3168,9 @@
}
} else { // list all found topics
- NSUInteger i;
- NSUInteger r = (NSUInteger)[theResult numOfRows];
- if (r) [theResult dataSeek:0];
+ NSUInteger r = (NSUInteger)[theResult numberOfRows];
+ if (r) [theResult seekToRow:0];
+
// check if HELP 'contents' is called
if(![searchString isEqualToString:SP_HELP_TOC_SEARCH_STRING])
[theHelp appendFormat:@"<br><i>%@ “%@”</i><br>", NSLocalizedString(@"Help topics for", @"help topics for"), searchString];
@@ -3176,9 +3179,9 @@
// iterate through all found rows and print them as HTML ul/li list
[theHelp appendString:@"<ul>"];
- for ( i = 0 ; i < r ; i++ ) {
- NSArray *anArray = [theResult fetchRowAsArray];
- NSString *topic = [anArray objectAtIndex:[anArray count]-2];
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
+ for (NSArray *eachRow in theResult) {
+ NSString *topic = [eachRow objectAtIndex:[eachRow count]-2];
[theHelp appendFormat:@"<li><a title='%@ “%@”' href='%@' class='internallink'>%@</a></li>",
NSLocalizedString(@"Show MySQL help for", @"show mysql help for"), topic, topic, topic];
}
@@ -3998,7 +4001,7 @@
value = [prefs objectForKey:SPNullValue];
}
- if ([value isKindOfClass:[MCPGeometryData class]]) {
+ if ([value isKindOfClass:[SPMySQLGeometryData class]]) {
value = [value wktString];
}
diff --git a/Source/SPDBActionCommons.h b/Source/SPDBActionCommons.h
index 6ff6e11c..7ae7ec79 100644
--- a/Source/SPDBActionCommons.h
+++ b/Source/SPDBActionCommons.h
@@ -22,18 +22,18 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPMySQLConnection;
@interface SPDBActionCommons : NSObject
{
- MCPConnection *connection;
+ SPMySQLConnection *connection;
NSWindow *messageWindow;
}
/**
- * @property connection References the MCPKit connection to MySQL; it has to be set.
+ * @property connection References the SPMySQL.framework MySQL connection; it has to be set.
*/
-@property (retain) MCPConnection *connection;
+@property (retain) SPMySQLConnection *connection;
/**
* @property messageWindow The NSWindow instance to send message sheets to.
diff --git a/Source/SPDataImport.h b/Source/SPDataImport.h
index 1b668be9..6bad573d 100644
--- a/Source/SPDataImport.h
+++ b/Source/SPDataImport.h
@@ -23,7 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPMySQLConnection;
typedef enum {
SPFieldMapperInProgress = 1,
@@ -77,7 +77,7 @@ typedef enum {
IBOutlet id singleProgressTitle;
IBOutlet id singleProgressText;
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
NSMutableArray *nibObjectsToRelease;
@@ -138,7 +138,7 @@ typedef enum {
- (NSString *)mappedUpdateSetStatementStringForRowArray:(NSArray *)csvRowArray;
// Additional methods
-- (void)setConnection:(MCPConnection *)theConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
- (void)showErrorSheetWithMessage:(NSString*)message;
// Import delegate notifications
diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m
index 794c8fbf..97c6d0f6 100644
--- a/Source/SPDataImport.m
+++ b/Source/SPDataImport.m
@@ -39,8 +39,8 @@
#import "SPFieldMapperController.h"
#import "SPFileHandle.h"
#import "SPEncodingPopupAccessory.h"
+#import "SPMySQL.h"
-#import <MCPKit/MCPKit.h>
#import <UniversalDetector/UniversalDetector.h>
#define SP_FILE_READ_ERROR_STRING NSLocalizedString(@"File read error", @"File read error title (Import Dialog)")
@@ -424,9 +424,9 @@
[fileEncodingDetector analyzeData:[detectorFileHandle readDataOfLength:2500000]];
sqlEncoding = [fileEncodingDetector encoding];
[fileEncodingDetector release];
- if ([MCPConnection mySQLEncodingForStringEncoding:sqlEncoding]) {
+ if ([SPMySQLConnection mySQLCharsetForStringEncoding:sqlEncoding]) {
connectionEncodingToRestore = [mySQLConnection encoding];
- [mySQLConnection queryString:[NSString stringWithFormat:@"SET NAMES '%@'", [MCPConnection mySQLEncodingForStringEncoding:sqlEncoding]]];
+ [mySQLConnection queryString:[NSString stringWithFormat:@"SET NAMES '%@'", [SPMySQLConnection mySQLCharsetForStringEncoding:sqlEncoding]]];
}
}
@@ -564,11 +564,11 @@
if (![query length]) continue;
// Run the query
- [mySQLConnection queryString:query usingEncoding:sqlEncoding streamingResult:NO];
+ [mySQLConnection queryString:query usingEncoding:sqlEncoding withResultType:SPMySQLResultAsResult];
// Check for any errors
- if ([mySQLConnection queryErrored] && ![[mySQLConnection getLastErrorMessage] isEqualToString:@"Query was empty"]) {
- [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage]];
+ if ([mySQLConnection queryErrored] && ![[mySQLConnection lastErrorMessage] isEqualToString:@"Query was empty"]) {
+ [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage]];
// If not set to ignore errors, ask what to do. Use NSAlert rather than
// SPBeginWaitingAlertSheet as there is already a modal sheet in progress.
@@ -580,7 +580,7 @@
defaultButton:NSLocalizedString(@"Continue", @"continue button")
alternateButton:NSLocalizedString(@"Ignore All Errors", @"ignore errors button")
otherButton:NSLocalizedString(@"Stop", @"stop button")
- informativeTextWithFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage]
+ informativeTextWithFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage]
];
[sqlErrorAlert setAlertStyle:NSWarningAlertStyle];
sqlImportErrorSheetReturnCode = [sqlErrorAlert runModal];
@@ -632,11 +632,11 @@
if ([query length] && !progressCancelled) {
// Run the query
- [mySQLConnection queryString:query usingEncoding:sqlEncoding streamingResult:NO];
+ [mySQLConnection queryString:query usingEncoding:sqlEncoding withResultType:SPMySQLResultAsResult];
// Check for any errors
- if ([mySQLConnection queryErrored] && ![[mySQLConnection getLastErrorMessage] isEqualToString:@"Query was empty"]) {
- [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection getLastErrorMessage]];
+ if ([mySQLConnection queryErrored] && ![[mySQLConnection lastErrorMessage] isEqualToString:@"Query was empty"]) {
+ [errors appendFormat:NSLocalizedString(@"[ERROR in query %ld] %@\n", @"error text when multiple custom query failed"), (long)(queriesPerformed+1), [mySQLConnection lastErrorMessage]];
}
// Increment the processed queries count
@@ -672,7 +672,7 @@
[tablesListInstance updateTables:self];
// Re-query the structure of all databases in the background
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
// Import finished Growl notification
[[SPGrowlController sharedGrowlController] notifyWithTitle:@"Import Finished"
@@ -1067,10 +1067,10 @@
[tableDocumentInstance showConsole:nil];
[errors appendFormat:
NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"),
- (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]];
+ (long)(rowsImported+1),[mySQLConnection lastErrorMessage]];
}
- if ( insertRemainingRowsAfterUpdate && ![mySQLConnection affectedRows]) {
+ if ( insertRemainingRowsAfterUpdate && ![mySQLConnection rowsAffectedByLastQuery]) {
query = [[NSMutableString alloc] initWithString:insertRemainingBaseString];
[query appendString:[self mappedValueStringForRowArray:[parsedRows objectAtIndex:i]]];
@@ -1084,7 +1084,7 @@
if ([mySQLConnection queryErrored]) {
[errors appendFormat:
NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"),
- (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]];
+ (long)(rowsImported+1),[mySQLConnection lastErrorMessage]];
}
}
@@ -1120,7 +1120,7 @@
if ([mySQLConnection queryErrored]) {
[errors appendFormat:
NSLocalizedString(@"[ERROR in row %ld] %@\n", @"error text when reading of csv file gave errors"),
- (long)(rowsImported+1),[mySQLConnection getLastErrorMessage]];
+ (long)(rowsImported+1),[mySQLConnection lastErrorMessage]];
}
rowsImported++;
if (fileIsCompressed) {
@@ -1194,7 +1194,7 @@
[tablesListInstance performSelectorOnMainThread:@selector(updateTables:) withObject:self waitUntilDone:YES];
// Re-query the structure of all databases in the background
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
// Select the new table
[tablesListInstance selectItemWithName:selectedTableTarget];
@@ -1379,7 +1379,7 @@
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
NSMutableString *globalVar = [NSMutableString string];
id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn);
- if([insertItem isKindOfClass:[NSNull class]]) {
+ if([insertItem isNSNull]) {
[globalVar setString:@"NULL"];
} else if([insertItem isSPNotLoaded]) {
[globalVar setString:@"NULL"];
@@ -1417,7 +1417,7 @@
if (cellData == [NSNull null]) {
[setString appendString:@"NULL"];
} else {
- [setString appendFormat:@"'%@'", [mySQLConnection prepareString:cellData]];
+ [setString appendString:[mySQLConnection escapeAndQuoteString:cellData]];
}
}
}
@@ -1431,7 +1431,7 @@
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
NSMutableString *globalVar = [NSMutableString string];
id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn);
- if([insertItem isKindOfClass:[NSNull class]]) {
+ if([insertItem isNSNull]) {
[globalVar setString:@"NULL"];
} else if([insertItem isSPNotLoaded]) {
[globalVar setString:@"NULL"];
@@ -1469,7 +1469,8 @@
if (cellData == [NSNull null]) {
[whereString appendString:@" IS NULL"];
} else {
- [whereString appendFormat:@"='%@'", [mySQLConnection prepareString:cellData]];
+ [whereString appendString:@"="];
+ [whereString appendString:[mySQLConnection escapeAndQuoteString:cellData]];
}
}
}
@@ -1505,7 +1506,7 @@
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
NSMutableString *globalVar = [NSMutableString string];
id insertItem = NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn);
- if([insertItem isKindOfClass:[NSNull class]]) {
+ if([insertItem isNSNull]) {
[globalVar setString:@"NULL"];
} else if([insertItem isSPNotLoaded]) {
[globalVar setString:@"NULL"];
@@ -1549,9 +1550,10 @@
if([geometryFields count] && [geometryFieldsMapIndex containsIndex:i]) {
[valueString appendString:[(NSString*)cellData getGeomFromTextString]];
} else if([bitFields count] && [bitFieldsMapIndex containsIndex:i]) {
- [valueString appendFormat:@"b'%@'", [mySQLConnection prepareString:cellData]];
+ [valueString appendString:@"b"];
+ [valueString appendString:[mySQLConnection escapeAndQuoteString:cellData]];
} else {
- [valueString appendFormat:@"'%@'", [mySQLConnection prepareString:cellData]];
+ [valueString appendString:[mySQLConnection escapeAndQuoteString:cellData]];
}
}
}
@@ -1636,7 +1638,7 @@
/**
* Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once.
*/
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
NSButtonCell *switchButton = [[NSButtonCell alloc] init];
diff --git a/Source/SPDatabaseCopy.m b/Source/SPDatabaseCopy.m
index 66b6ba1b..2c9e11ad 100644
--- a/Source/SPDatabaseCopy.m
+++ b/Source/SPDatabaseCopy.m
@@ -25,6 +25,7 @@
#import "SPDBActionCommons.h"
#import "SPDatabaseCopy.h"
#import "SPTableCopy.h"
+#import "SPMySQL.h"
@implementation SPDatabaseCopy
@@ -58,7 +59,7 @@
if (sourceExists && !targetExists) {
// Retrieve the list of tables/views/funcs/triggers from the source database
- tables = [connection listTablesFromDB:sourceDatabaseName];
+ tables = [connection tablesFromDatabase:sourceDatabaseName];
}
else {
return NO;
diff --git a/Source/SPDatabaseData.h b/Source/SPDatabaseData.h
index b0c988eb..e315ca6a 100644
--- a/Source/SPDatabaseData.h
+++ b/Source/SPDatabaseData.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPServerSupport;
+@class SPServerSupport, SPMySQLConnection;
/**
* @class SPDatabaseData SPDatabaseData.h
@@ -45,14 +43,14 @@
NSMutableArray *characterSetEncodings;
NSMutableDictionary *cachedCollationsByEncoding;
- MCPConnection *connection;
+ SPMySQLConnection *connection;
SPServerSupport *serverSupport;
}
/**
* @property connection The current database connection
*/
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
/**
* @property serverSupport The connection's associated SPServerSupport instance
diff --git a/Source/SPDatabaseData.m b/Source/SPDatabaseData.m
index 2aa809b1..2317902e 100644
--- a/Source/SPDatabaseData.m
+++ b/Source/SPDatabaseData.m
@@ -26,10 +26,11 @@
#import "SPDatabaseData.h"
#import "SPServerSupport.h"
#import "SPDatabaseCharacterSets.h"
+#import "SPMySQL.h"
@interface SPDatabaseData (PrivateAPI)
-- (NSMutableArray *)_getDatabaseDataForQuery:(NSString *)query;
+- (NSArray *)_getDatabaseDataForQuery:(NSString *)query;
NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo, void *context);
@@ -162,12 +163,12 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo,
[storageEngines addObject:[NSDictionary dictionaryWithObject:@"MyISAM" forKey:@"Engine"]];
// Check if InnoDB support is enabled
- MCPResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'have_innodb'"];
+ SPMySQLResult *result = [connection queryString:@"SHOW VARIABLES LIKE 'have_innodb'"];
[result setReturnDataAsStrings:YES];
- if ([result numOfRows] == 1) {
- if ([[[result fetchRowAsDictionary] objectForKey:@"Value"] isEqualToString:@"YES"]) {
+ if ([result numberOfRows] == 1) {
+ if ([[[result getRowAsDictionary] objectForKey:@"Value"] isEqualToString:@"YES"]) {
[storageEngines addObject:[NSDictionary dictionaryWithObject:@"InnoDB" forKey:@"Engine"]];
}
}
@@ -201,9 +202,9 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo,
if ([serverSupport supportsInformationSchemaEngines])
{
// Check the information_schema.engines table is accessible
- MCPResult *result = [connection queryString:@"SHOW TABLES IN information_schema LIKE 'ENGINES'"];
+ SPMySQLResult *result = [connection queryString:@"SHOW TABLES IN information_schema LIKE 'ENGINES'"];
- if ([result numOfRows] == 1) {
+ if ([result numberOfRows] == 1) {
// Table is accessible so get available storage engines
// Note, that the case of the column names specified in this query are important.
@@ -212,7 +213,7 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo,
}
else {
// Get storage engines
- NSMutableArray *engines = [self _getDatabaseDataForQuery:@"SHOW STORAGE ENGINES"];
+ NSArray *engines = [self _getDatabaseDataForQuery:@"SHOW STORAGE ENGINES"];
// We only want to include engines that are supported
for (NSDictionary *engine in engines)
@@ -308,22 +309,14 @@ NSInteger _sortMySQL4CharsetEntry(NSDictionary *itemOne, NSDictionary *itemTwo,
* Executes the supplied query against the current connection and returns the result as an array of
* NSDictionarys, one for each row.
*/
-- (NSMutableArray *)_getDatabaseDataForQuery:(NSString *)query
+- (NSArray *)_getDatabaseDataForQuery:(NSString *)query
{
- NSMutableArray *array = [NSMutableArray array];
+ SPMySQLResult *result = [connection queryString:query];
- MCPResult *result = [connection queryString:query];
+ if ([connection queryErrored]) return [NSArray array];
- if (![connection queryErrored]) {
- [result dataSeek:0];
-
- for (NSUInteger i = 0; i < [result numOfRows]; i++)
- {
- [array addObject:[result fetchRowAsDictionary]];
- }
- }
-
- return array;
+ [result setReturnDataAsStrings:YES];
+ return [result getAllRows];
}
/**
diff --git a/Source/SPDatabaseDocument.h b/Source/SPDatabaseDocument.h
index b56991f5..1c6fe296 100644
--- a/Source/SPDatabaseDocument.h
+++ b/Source/SPDatabaseDocument.h
@@ -25,7 +25,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
#ifndef SP_REFACTOR /* headers */
#import <WebKit/WebKit.h>
#endif
@@ -34,7 +33,7 @@
#ifndef SP_REFACTOR /* class forward decls */
SPProcessListController, SPServerVariablesController, SPUserManager, SPWindowController,
#endif
-SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPServerSupport, SPCustomQuery;
+SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPServerSupport, SPCustomQuery, SPDatabaseStructure, SPMySQLConnection;
#import "SPConnectionControllerDelegateProtocol.h"
@@ -102,7 +101,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
IBOutlet id addDatabaseButton;
IBOutlet id databaseCopyNameField;
- IBOutlet id copyDatabaseDataButton;
+ IBOutlet NSButton *copyDatabaseDataButton;
IBOutlet id copyDatabaseMessageField;
IBOutlet id copyDatabaseButton;
@@ -146,14 +145,14 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
IBOutlet id inputTextWindowSecureTextField;
NSInteger passwordSheetReturnCode;
+ // Master connection
+ SPMySQLConnection *mySQLConnection;
+
// Controllers
SPConnectionController *connectionController;
#ifndef SP_REFACTOR /* ivars */
SPProcessListController *processListController;
SPServerVariablesController *serverVariablesController;
-#endif
- MCPConnection *mySQLConnection;
-#ifndef SP_REFACTOR /* ivars */
NSInteger currentTabIndex;
#endif
@@ -222,7 +221,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
#ifndef SP_REFACTOR /* ivars */
NSThread *printThread;
- id statusValues;
+ NSArray *statusValues;
NSInteger saveDocPrefSheetStatus;
@@ -238,6 +237,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
NSString *processID;
BOOL windowTitleStatusViewIsVisible;
#endif
+ SPDatabaseStructure *databaseStructureRetrieval;
}
#ifdef SP_REFACTOR /* ivars */
@@ -269,6 +269,7 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
@property (readwrite, retain) NSString *processID;
#endif
@property (readonly) SPServerSupport *serverSupport;
+@property (readonly) SPDatabaseStructure *databaseStructureRetrieval;
#ifndef SP_REFACTOR /* method decls */
- (BOOL)isUntitled;
@@ -280,8 +281,8 @@ SPDatabaseData, SPTablesList, SPTableStructure, SPTableContent, SPTableData, SPS
// Connection callback and methods
#endif
-- (void)setConnection:(MCPConnection *)theConnection;
-- (MCPConnection *)getConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
+- (SPMySQLConnection *)getConnection;
- (void)setKeychainID:(NSString *)theID;
// Database methods
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index f29727b3..38027ac8 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -36,6 +36,8 @@ enum {
#import "SPConnectionController.h"
#import "SPConnectionControllerInitializer.h"
+#import "SPMySQL.h"
+
#import "SPTablesList.h"
#import "SPTableStructure.h"
#ifndef SP_REFACTOR /* headers */
@@ -59,6 +61,7 @@ enum {
#import "SPTableData.h"
#endif
#import "SPDatabaseData.h"
+#import "SPDatabaseStructure.h"
#ifndef SP_REFACTOR /* headers */
#import "SPAppController.h"
#import "SPExtendedTableInfo.h"
@@ -119,6 +122,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
#endif
@synthesize isProcessing;
@synthesize serverSupport;
+@synthesize databaseStructureRetrieval;
#ifndef SP_REFACTOR /* ivars */
@synthesize processID;
#endif
@@ -218,6 +222,8 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[nibLoader release];
[nibObjectsToRelease addObjectsFromArray:dbViewTopLevelObjects];
#endif
+
+ databaseStructureRetrieval = [[SPDatabaseStructure alloc] initWithDelegate:self];
}
return self;
@@ -300,18 +306,6 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// Hide the activity list
[self setActivityPaneHidden:[NSNumber numberWithInteger:1]];
- // Bind the background color of the create syntax text view to the users preference
- [createTableSyntaxTextView setAllowsDocumentBackgroundColorChange:YES];
-
- NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
-
- [bindingOptions setObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
-
- [createTableSyntaxTextView bind:@"backgroundColor"
- toObject:[NSUserDefaultsController sharedUserDefaultsController]
- withKeyPath:@"values.CustomQueryEditorBackgroundColor"
- options:bindingOptions];
-
// Load additional nibs, keeping track of the top-level objects to allow correct release
NSArray *connectionDialogTopLevelObjects = nil;
NSNib *nibLoader = [[NSNib alloc] initWithNibNamed:@"ConnectionErrorDialog" bundle:[NSBundle mainBundle]];
@@ -394,7 +388,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
#pragma mark -
#pragma mark Connection callback and methods
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
_isConnected = YES;
mySQLConnection = [theConnection retain];
@@ -433,6 +427,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[chooseDatabaseButton setEnabled:!_isWorkingLevel];
+ // Set the connection on the database structure builder
+ [databaseStructureRetrieval setConnectionToClone:mySQLConnection];
+
[databaseDataInstance setConnection:mySQLConnection];
// Pass the support class to the data instance
@@ -571,7 +568,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
*
* @return The document's connection
*/
-- (MCPConnection *) getConnection
+- (SPMySQLConnection *) getConnection
{
return mySQLConnection;
}
@@ -605,28 +602,25 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[[chooseDatabaseButton menu] addItem:[NSMenuItem separatorItem]];
#endif
- MCPResult *queryResult = [mySQLConnection listDBs];
-
- if ([queryResult numOfRows]) [queryResult dataSeek:0];
-
if (allDatabases) [allDatabases release];
if (allSystemDatabases) [allSystemDatabases release];
- allDatabases = [[NSMutableArray alloc] initWithCapacity:(NSUInteger)[queryResult numOfRows]];
+ NSArray *theDatabaseList = [mySQLConnection databases];
+ allDatabases = [[NSMutableArray alloc] initWithCapacity:[theDatabaseList count]];
allSystemDatabases = [[NSMutableArray alloc] initWithCapacity:2];
- for (NSUInteger i = 0 ; i < [queryResult numOfRows] ; i++)
- {
- NSString *database = NSArrayObjectAtIndex([queryResult fetchRowAsArray], 0);
+ for (NSString *databaseName in theDatabaseList) {
- // If the database is either information_schema or mysql then it is classed as a system table
- // 5.5.3+ performance_schema
- if ([database isEqualToString:@"information_schema"] || [database isEqualToString:@"mysql"] || [database isEqualToString:@"performance_schema"]) {
- [allSystemDatabases addObject:database];
- }
+ // If the database is either information_schema or mysql then it is classed as a
+ // system table; similarly, for 5.5.3+, performance_schema
+ if ([databaseName isEqualToString:SPMySQLDatabase] ||
+ [databaseName isEqualToString:SPMySQLInformationSchemaDatabase] ||
+ [databaseName isEqualToString:SPMySQLPerformanceSchemaDatabase]) {
+ [allSystemDatabases addObject:databaseName];
+ }
else {
- [allDatabases addObject:database];
+ [allDatabases addObject:databaseName];
}
}
@@ -927,7 +921,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[self _addDatabase];
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:databaseStructureRetrieval withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
} else {
// reset chooseDatabaseButton
@@ -979,21 +973,15 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
NSString *dbName = nil;
// Notify listeners that a query has started
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:self];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:self];
-#endif
- MCPResult *theResult = [mySQLConnection queryString:@"SELECT DATABASE()"];
+ SPMySQLResult *theResult = [mySQLConnection queryString:@"SELECT DATABASE()"];
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
if (![mySQLConnection queryErrored]) {
- NSInteger i;
- NSInteger r = (NSInteger)[theResult numOfRows];
- if (r) [theResult dataSeek:0];
- for ( i = 0 ; i < r ; i++ ) {
- dbName = NSArrayObjectAtIndex([theResult fetchRowAsArray], 0);
+ for (NSArray *eachRow in theResult) {
+ dbName = NSArrayObjectAtIndex(eachRow, 0);
}
- if(![dbName isKindOfClass:[NSNull class]]) {
+ if(![dbName isNSNull]) {
if(![dbName isEqualToString:selectedDatabase]) {
if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil;
selectedDatabase = [[NSString alloc] initWithString:dbName];
@@ -1012,11 +1000,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
}
//query finished
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:self];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:self];
-#endif
}
#ifndef SP_REFACTOR /* navigatorSchemaPathExistsForDatabase: */
@@ -1364,7 +1348,15 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if (!taskCanBeCancelled) return;
[taskCancelButton setEnabled:NO];
- [mySQLConnection cancelCurrentQuery];
+
+ // See whether there is an active database structure task and whether it can be used
+ // to cancel the query, for speed (no connection overhead!)
+ if (databaseStructureRetrieval && [databaseStructureRetrieval connection]) {
+ [mySQLConnection setLastQueryWasCancelled:YES];
+ [[databaseStructureRetrieval connection] killQueryOnThreadID:[mySQLConnection mysqlConnectionThreadId]];
+ } else {
+ [mySQLConnection cancelCurrentQuery];
+ }
if (taskCancellationCallbackObject && taskCancellationCallbackSelector) {
[taskCancellationCallbackObject performSelector:taskCancellationCallbackSelector];
@@ -1558,7 +1550,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
*/
- (void)detectDatabaseEncoding
{
- MCPResult *charSetResult;
+ SPMySQLResult *charSetResult;
NSString *mysqlEncoding = nil;
_supportsEncoding = YES;
@@ -1567,11 +1559,11 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if ([serverSupport supportsCharacterSetDatabaseVar]) {
charSetResult = [mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set_database'"];
[charSetResult setReturnDataAsStrings:YES];
- mysqlEncoding = [[charSetResult fetchRowAsDictionary] objectForKey:@"Value"];
+ mysqlEncoding = [[charSetResult getRowAsDictionary] objectForKey:@"Value"];
}
// MySQL 4.0 or older -> only default character set possible, cannot choose others using "set names xy"
else {
- mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] fetchRowAsDictionary] objectForKey:@"Value"];
+ mysqlEncoding = [[[mySQLConnection queryString:@"SHOW VARIABLES LIKE 'character_set'"] getRowAsDictionary] objectForKey:@"Value"];
}
[selectedDatabaseEncoding release];
@@ -1657,13 +1649,13 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- MCPResult *theResult = [mySQLConnection queryString:query];
+ SPMySQLResult *theResult = [mySQLConnection queryString:query];
[theResult setReturnDataAsStrings:YES];
// Check for errors, only displaying if the connection hasn't been terminated
if ([mySQLConnection queryErrored]) {
if ([mySQLConnection isConnected]) {
- NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while creating table syntax.\n\n: %@", @"Error shown when unable to show create table syntax"),[mySQLConnection getLastErrorMessage]], @"OK", nil, nil);
+ NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while creating table syntax.\n\n: %@", @"Error shown when unable to show create table syntax"), [mySQLConnection lastErrorMessage]], @"OK", nil, nil);
}
return;
@@ -1671,9 +1663,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
NSString *tableSyntax;
if (type == SPTableTypeProc)
- tableSyntax = [NSString stringWithFormat:@"DELIMITER ;;\n%@;;\nDELIMITER ", [[theResult fetchRowAsArray] objectAtIndex:colOffs]];
+ tableSyntax = [NSString stringWithFormat:@"DELIMITER ;;\n%@;;\nDELIMITER ", [[theResult getRowAsArray] objectAtIndex:colOffs]];
else
- tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:colOffs];
+ tableSyntax = [[theResult getRowAsArray] objectAtIndex:colOffs];
// A NULL value indicates that the user does not have permission to view the syntax
if ([tableSyntax isNSNull]) {
@@ -1756,7 +1748,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECK TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECK TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -1769,7 +1761,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to check the %@.\n\nMySQL said:%@",@"an error occurred while trying to check the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to check the %@.\n\nMySQL said:%@",@"an error occurred while trying to check the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -1779,10 +1771,10 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSArray *resultStatuses = [theResult getAllRows];
BOOL statusOK = YES;
- for(id res in result) {
- if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
+ for (NSDictionary *eachRow in theResult) {
+ if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
statusOK = NO;
break;
}
@@ -1790,7 +1782,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// Process result
if([selectedItems count] == 1) {
- NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
+ NSDictionary *lastresult = [resultStatuses lastObject];
message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Check table successfully passed.",@"check table successfully passed message") : NSLocalizedString(@"Check table failed.", @"check table failed message");
@@ -1812,7 +1804,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
} else {
message = NSLocalizedString(@"MySQL said:",@"mysql said message");
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while checking selected items", @"error while checking selected items message")];
@@ -1832,7 +1824,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"ANALYZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"ANALYZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -1845,7 +1837,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while analyzing the %@.\n\nMySQL said:%@",@"an error occurred while analyzing the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while analyzing the %@.\n\nMySQL said:%@",@"an error occurred while analyzing the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -1855,18 +1847,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSArray *resultStatuses = [theResult getAllRows];
BOOL statusOK = YES;
- for(id res in result) {
- if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
+ for (NSDictionary *eachRow in resultStatuses) {
+ if(![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
statusOK = NO;
break;
}
}
// Process result
- if([selectedItems count] == 1) {
- NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
+ if ([selectedItems count] == 1) {
+ NSDictionary *lastresult = [resultStatuses lastObject];
message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully analyzed table.",@"analyze table successfully passed message") : NSLocalizedString(@"Analyze table failed.", @"analyze table failed message");
@@ -1888,7 +1880,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
} else {
message = NSLocalizedString(@"MySQL said:",@"mysql said message");
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while analyzing selected items", @"error while analyzing selected items message")];
@@ -1908,7 +1900,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"OPTIMIZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"OPTIMIZE TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -1921,7 +1913,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while optimzing the %@.\n\nMySQL said:%@",@"an error occurred while trying to optimze the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while optimzing the %@.\n\nMySQL said:%@",@"an error occurred while trying to optimze the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -1931,18 +1923,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSArray *resultStatuses = [theResult getAllRows];
BOOL statusOK = YES;
- for(id res in result) {
- if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
+ for (NSDictionary *eachRow in resultStatuses) {
+ if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
statusOK = NO;
break;
}
}
// Process result
- if([selectedItems count] == 1) {
- NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
+ if ([selectedItems count] == 1) {
+ NSDictionary *lastresult = [resultStatuses lastObject];
message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully optimized table.",@"optimize table successfully passed message") : NSLocalizedString(@"Optimize table failed.", @"optimize table failed message");
@@ -1964,7 +1956,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
} else {
message = NSLocalizedString(@"MySQL said:",@"mysql said message");
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while optimizing selected items", @"error while optimizing selected items message")];
@@ -1983,7 +1975,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"REPAIR TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"REPAIR TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -1996,7 +1988,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while repairing the %@.\n\nMySQL said:%@",@"an error occurred while trying to repair the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while repairing the %@.\n\nMySQL said:%@",@"an error occurred while trying to repair the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -2006,18 +1998,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSArray *resultStatuses = [theResult getAllRows];
BOOL statusOK = YES;
- for(id res in result) {
- if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
+ for (NSDictionary *eachRow in resultStatuses) {
+ if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
statusOK = NO;
break;
}
}
// Process result
- if([selectedItems count] == 1) {
- NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
+ if ([selectedItems count] == 1) {
+ NSDictionary *lastresult = [resultStatuses lastObject];
message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully repaired table.",@"repair table successfully passed message") : NSLocalizedString(@"Repair table failed.", @"repair table failed message");
@@ -2026,7 +2018,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
message = NSLocalizedString(@"Successfully repaired all selected items.",@"successfully repaired all selected items message");
}
- if(message) {
+ if (message) {
[[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Repair %@", @"REPAIR one or more tables - result title"), what]
defaultButton:@"OK"
alternateButton:nil
@@ -2039,7 +2031,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
} else {
message = NSLocalizedString(@"MySQL said:",@"mysql said message");
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while repairing selected items", @"error while repairing selected items message")];
@@ -2058,7 +2050,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"FLUSH TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"FLUSH TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -2071,7 +2063,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while flushing the %@.\n\nMySQL said:%@",@"an error occurred while trying to flush the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while flushing the %@.\n\nMySQL said:%@",@"an error occurred while trying to flush the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -2081,18 +2073,18 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
return;
}
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSArray *resultStatuses = [theResult getAllRows];
BOOL statusOK = YES;
- for(id res in result) {
- if(![[res objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
+ for (NSDictionary *eachRow in resultStatuses) {
+ if (![[eachRow objectForKey:@"Msg_type"] isEqualToString:@"status"]) {
statusOK = NO;
break;
}
}
// Process result
- if([selectedItems count] == 1) {
- NSDictionary *lastresult = [[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject];
+ if ([selectedItems count] == 1) {
+ NSDictionary *lastresult = [resultStatuses lastObject];
message = ([[lastresult objectForKey:@"Msg_type"] isEqualToString:@"status"]) ? NSLocalizedString(@"Successfully flushed table.",@"flush table successfully passed message") : NSLocalizedString(@"Flush table failed.", @"flush table failed message");
@@ -2101,7 +2093,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
message = NSLocalizedString(@"Successfully flushed all selected items.",@"successfully flushed all selected items message");
}
- if(message) {
+ if (message) {
[[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Flush %@", @"FLUSH one or more tables - result title"), what]
defaultButton:@"OK"
alternateButton:nil
@@ -2114,7 +2106,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
} else {
message = NSLocalizedString(@"MySQL said:",@"mysql said message");
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:message];
[alert setMessageText:NSLocalizedString(@"Error while flushing selected items", @"error while flushing selected items message")];
@@ -2133,7 +2125,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([selectedItems count] == 0) return;
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECKSUM TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"CHECKSUM TABLE %@", [selectedItems componentsJoinedAndBacktickQuoted]]];
NSString *what = ([selectedItems count]>1) ? NSLocalizedString(@"selected items", @"selected items") : [NSString stringWithFormat:@"%@ '%@'", NSLocalizedString(@"table", @"table"), [self table]];
@@ -2145,7 +2137,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while performing the checksum on %@.\n\nMySQL said:%@",@"an error occurred while performing the checksum on the %@.\n\nMySQL said:%@"), what, [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while performing the checksum on %@.\n\nMySQL said:%@",@"an error occurred while performing the checksum on the %@.\n\nMySQL said:%@"), what, [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:parentWindow
modalDelegate:self
didEndSelector:NULL
@@ -2156,8 +2148,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
}
// Process result
- if([selectedItems count] == 1) {
- message = [[[theResult fetch2DResultAsType:MCPTypeDictionary] lastObject] objectForKey:@"Checksum"];
+ NSArray *resultStatuses = [theResult getAllRows];
+ if ([selectedItems count] == 1) {
+ message = [[resultStatuses lastObject] objectForKey:@"Checksum"];
[[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Checksum %@",@"checksum %@ message"), what]
defaultButton:@"OK"
alternateButton:nil
@@ -2168,9 +2161,8 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
didEndSelector:NULL
contextInfo:NULL];
} else {
- NSDictionary *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
if (statusValues) [statusValues release], statusValues = nil;
- statusValues = [result retain];
+ statusValues = [resultStatuses retain];
NSAlert *alert = [[NSAlert new] autorelease];
[alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Checksums of %@",@"Checksums of %@ message"), what]];
[alert setMessageText:NSLocalizedString(@"Table checksum",@"table checksum message")];
@@ -2298,9 +2290,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
}
// Before displaying the user manager make sure the current user has access to the mysql.user table.
- MCPResult *result = [mySQLConnection queryString:@"SELECT * FROM `mysql`.`user` ORDER BY `user`"];
+ SPMySQLResult *result = [mySQLConnection queryString:@"SELECT * FROM `mysql`.`user` ORDER BY `user`"];
- if ([mySQLConnection queryErrored] && ([result numOfRows] == 0)) {
+ if ([mySQLConnection queryErrored] && ([result numberOfRows] == 0)) {
NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Unable to get list of users", @"unable to get list of users message")
defaultButton:NSLocalizedString(@"OK", @"OK button")
@@ -2358,7 +2350,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
SPBeginAlertSheet(NSLocalizedString(@"Flushed Privileges", @"title of panel when successfully flushed privs"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, NSLocalizedString(@"Successfully flushed privileges.", @"message of panel when successfully flushed privs"));
} else {
//error while flushing privileges
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"), [mySQLConnection getLastErrorMessage]]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't flush privileges.\nMySQL said: %@", @"message of panel when flushing privs failed"), [mySQLConnection lastErrorMessage]]);
}
}
@@ -5088,7 +5080,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
}
// Get create syntax
- MCPResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@",
+ SPMySQLResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@",
itemTypeStr,
[item backtickQuotedString]
]];
@@ -5096,15 +5088,15 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
- if ( ![queryResult numOfRows] ) {
+ if ( ![queryResult numberOfRows] ) {
//error while getting table structure
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection lastErrorMessage]]);
status = @"1";
} else {
- NSString *syntaxString = [[queryResult fetchRowAsArray] objectAtIndex:queryCol];
+ NSString *syntaxString = [[queryResult getRowAsArray] objectAtIndex:queryCol];
// A NULL value indicates that the user does not have permission to view the syntax
if ([syntaxString isNSNull]) {
@@ -5179,21 +5171,21 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
SPFileHandle *fh = [SPFileHandle fileHandleForWritingAtPath:resultFileName];
if(!fh) NSLog(@"Couldn't create file handle to %@", resultFileName);
- MCPStreamingResult *theResult = [mySQLConnection streamingQueryString:query];
+ SPMySQLResult *theResult = [mySQLConnection streamingQueryString:query];
[theResult setReturnDataAsStrings:YES];
if ([mySQLConnection queryErrored]) {
- [fh writeData:[[NSString stringWithFormat:@"MySQL said: %@", [mySQLConnection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [fh writeData:[[NSString stringWithFormat:@"MySQL said: %@", [mySQLConnection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
status = @"1";
} else {
// write header
if(writeAsCsv)
- [fh writeData:[[[theResult fetchFieldNames] componentsJoinedAsCSV] dataUsingEncoding:NSUTF8StringEncoding]];
+ [fh writeData:[[[theResult fieldNames] componentsJoinedAsCSV] dataUsingEncoding:NSUTF8StringEncoding]];
else
- [fh writeData:[[[theResult fetchFieldNames] componentsJoinedByString:@"\t"] dataUsingEncoding:NSUTF8StringEncoding]];
+ [fh writeData:[[[theResult fieldNames] componentsJoinedByString:@"\t"] dataUsingEncoding:NSUTF8StringEncoding]];
[fh writeData:[[NSString stringWithString:@"\n"] dataUsingEncoding:NSUTF8StringEncoding]];
- NSArray *columnDefinition = [theResult fetchResultFieldsStructure];
+ NSArray *columnDefinition = [theResult fieldDefinitions];
// Write table meta data
NSMutableString *tableMetaData = [NSMutableString string];
@@ -5221,10 +5213,10 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
NSUInteger i, j;
NSArray *theRow;
NSMutableString *result = [NSMutableString string];
- if(writeAsCsv) {
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
+ if (writeAsCsv) {
+ for ( i = 0 ; i < [theResult numberOfRows] ; i++ ) {
[result setString:@""];
- theRow = [theResult fetchNextRowAsArray];
+ theRow = [theResult getRowAsArray];
for( j = 0 ; j < [theRow count] ; j++ ) {
NSEvent* event = [NSApp currentEvent];
@@ -5238,9 +5230,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([result length]) [result appendString:@","];
id cell = NSArrayObjectAtIndex(theRow, j);
- if([cell isKindOfClass:[NSNull class]])
+ if([cell isNSNull])
[result appendString:@"\"NULL\""];
- else if([cell isKindOfClass:[MCPGeometryData class]])
+ else if([cell isKindOfClass:[SPMySQLGeometryData class]])
[result appendFormat:@"\"%@\"", [cell wktString]];
else if([cell isKindOfClass:[NSData class]]) {
NSString *displayString = [[NSString alloc] initWithData:cell encoding:[mySQLConnection stringEncoding]];
@@ -5261,9 +5253,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
}
}
else {
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
+ for ( i = 0 ; i < [theResult numberOfRows] ; i++ ) {
[result setString:@""];
- theRow = [theResult fetchNextRowAsArray];
+ theRow = [theResult getRowAsArray];
for( j = 0 ; j < [theRow count] ; j++ ) {
NSEvent* event = [NSApp currentEvent];
@@ -5277,9 +5269,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if([result length]) [result appendString:@"\t"];
id cell = NSArrayObjectAtIndex(theRow, j);
- if([cell isKindOfClass:[NSNull class]])
+ if([cell isNSNull])
[result appendString:@"NULL"];
- else if([cell isKindOfClass:[MCPGeometryData class]])
+ else if([cell isKindOfClass:[SPMySQLGeometryData class]])
[result appendFormat:@"%@", [cell wktString]];
else if([cell isKindOfClass:[NSData class]]) {
NSString *displayString = [[NSString alloc] initWithData:cell encoding:[mySQLConnection stringEncoding]];
@@ -5328,11 +5320,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
- (void)registerActivity:(NSDictionary*)commandDict
{
[runningActivitiesArray addObject:commandDict];
-#ifndef SP_REFACTOR
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:nil];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
-#endif
+ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
if([runningActivitiesArray count] || [[[NSApp delegate] runningActivities] count])
[self performSelector:@selector(setActivityPaneHidden:) withObject:[NSNumber numberWithInteger:0] afterDelay:1.0];
@@ -5364,12 +5352,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[self setActivityPaneHidden:[NSNumber numberWithInteger:1]];
}
-#ifndef SP_REFACTOR
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:nil];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
-#endif
-
+ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPActivitiesUpdateNotification object:self];
}
- (void)setActivityPaneHidden:(NSNumber*)hide
@@ -5664,6 +5647,9 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
#endif
+ [databaseStructureRetrieval destroy];
+ [databaseStructureRetrieval release];
+
[allDatabases release];
[allSystemDatabases release];
#ifndef SP_REFACTOR /* dealloc ivars */
@@ -5817,13 +5803,13 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
if ([mySQLConnection queryErrored]) {
// An error occurred
- SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection getLastErrorMessage]]);
+ SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Couldn't create database.\nMySQL said: %@", @"message of panel when creation of db failed"), [mySQLConnection lastErrorMessage]]);
return;
}
// Error while selecting the new database (is this even possible?)
- if (![mySQLConnection selectDB:[databaseNameField stringValue]] ) {
+ if (![mySQLConnection selectDatabase:[databaseNameField stringValue]] ) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, parentWindow, self, nil, nil, [NSString stringWithFormat:NSLocalizedString(@"Unable to connect to database %@.\nBe sure that you have the necessary privileges.", @"message of panel when connection to db failed after selecting from popupbutton"), [databaseNameField stringValue]]);
[self setDatabases:self];
@@ -5871,7 +5857,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
[self performSelector:@selector(showErrorSheetWith:)
withObject:[NSArray arrayWithObjects:NSLocalizedString(@"Error", @"error"),
[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete the database.\nMySQL said: %@", @"message of panel when deleting db failed"),
- [mySQLConnection getLastErrorMessage]],
+ [mySQLConnection lastErrorMessage]],
nil]
afterDelay:0.3];
@@ -5882,9 +5868,10 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// do to threading we have to delete it from 'allDatabases' directly
// before calling navigator
[allDatabases removeObject:[self database]];
+
// This only deletes the db and refreshes the navigator since nothing is changed
// that's why we can run this on main thread
- [mySQLConnection queryDbStructureWithUserInfo:nil];
+ [databaseStructureRetrieval queryDbStructureWithUserInfo:nil];
// Delete was successful
if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil;
@@ -5935,7 +5922,7 @@ static NSString *SPCreateSyntx = @"SPCreateSyntax";
// Attempt to select the specified database, and abort on failure
#ifndef SP_REFACTOR /* patch */
if ([chooseDatabaseButton indexOfItemWithTitle:targetDatabaseName] == NSNotFound
- || ![mySQLConnection selectDB:targetDatabaseName])
+ || ![mySQLConnection selectDatabase:targetDatabaseName])
#else
if ( ![mySQLConnection selectDB:targetDatabaseName] )
#endif
diff --git a/Source/SPDatabaseInfo.m b/Source/SPDatabaseInfo.m
index 3c70aec9..fc487718 100644
--- a/Source/SPDatabaseInfo.m
+++ b/Source/SPDatabaseInfo.m
@@ -24,6 +24,7 @@
#import "SPDBActionCommons.h"
#import "SPDatabaseInfo.h"
+#import "SPMySQL.h"
@implementation SPDatabaseInfo
@@ -36,40 +37,12 @@
- (NSArray *)listDBs
{
- return [self listDBsLike:nil];
+ return [connection databases];
}
- (NSArray *)listDBsLike:(NSString *)dbsName
{
- NSString *listDBStatement = nil;
-
- if ((dbsName == nil) || ([dbsName isEqualToString:@""])) {
- listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES"];
- }
- else {
- listDBStatement = [NSString stringWithFormat:@"SHOW DATABASES LIKE %@", [dbsName backtickQuotedString]];
- }
-
- MCPResult *theResult = [connection queryString:listDBStatement];
-
- if ([connection queryErrored]) return NO;
-
- NSMutableArray *names = [NSMutableArray array];
- NSMutableString *name;
-
- if ([theResult numOfRows] > 1) {
-
- NSUInteger i;
-
- for (i = 0 ; i < [theResult numOfRows]; i++)
- {
- name = [[theResult fetchRowAsArray] objectAtIndex:0];
-
- [names addObject:name];
- }
- }
-
- return names;
+ return [connection databasesLike:dbsName];
}
@end
diff --git a/Source/SPDatabaseRename.m b/Source/SPDatabaseRename.m
index b7aa3f73..1877e955 100644
--- a/Source/SPDatabaseRename.m
+++ b/Source/SPDatabaseRename.m
@@ -26,6 +26,7 @@
#import "SPDatabaseRename.h"
#import "SPTableCopy.h"
#import "SPDatabaseInfo.h"
+#import "SPMySQL.h"
@implementation SPDatabaseRename
@@ -59,7 +60,7 @@
if (sourceExists && !targetExists) {
// Retrieve the list of tables/views/funcs/triggers from the source database
- tables = [connection listTablesFromDB:sourceDatabaseName];
+ tables = [connection tablesFromDatabase:sourceDatabaseName];
}
else {
return NO;
@@ -78,7 +79,7 @@
[dbActionTableCopy release];
- tables = [connection listTablesFromDB:sourceDatabaseName];
+ tables = [connection tablesFromDatabase:sourceDatabaseName];
if ([tables count] == 0) {
[self dropDatabase:sourceDatabaseName];
diff --git a/Source/SPDatabaseStructure.h b/Source/SPDatabaseStructure.h
new file mode 100644
index 00000000..52e43ec8
--- /dev/null
+++ b/Source/SPDatabaseStructure.h
@@ -0,0 +1,58 @@
+//
+// $Id$
+//
+// SPDatabaseStructure.h
+// sequel-pro
+//
+// Created by Hans-Jörg Bibiko on March 25, 2010
+// Copyright (c) 2010 Hans-Jörg Bibiko. 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; either version 2 of the License, or
+// (at your option) any later version.
+//
+// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+@class SPMySQLConnection, SPDatabaseDocument;
+
+@interface SPDatabaseStructure : NSObject {
+ SPDatabaseDocument *delegate;
+ SPMySQLConnection *mySQLConnection;
+
+ NSMutableDictionary *structure;
+ NSMutableArray *allKeysofDbStructure;
+
+ NSMutableArray *structureRetrievalThreads;
+
+ pthread_mutex_t threadManagementLock;
+ pthread_mutex_t dataLock;
+ pthread_mutex_t connectionCheckLock;
+}
+
+// Setup and teardown
+- (id)initWithDelegate:(SPDatabaseDocument *)theDelegate;
+- (void)setConnectionToClone:(SPMySQLConnection *)aConnection;
+- (void)destroy;
+
+// Information
+- (SPMySQLConnection *)connection;
+
+// Structure retrieval from the server
+- (void)queryDbStructureWithUserInfo:(NSDictionary*)userInfo;
+- (BOOL)isQueryingDatabaseStructure;
+
+// Structure information
+- (NSDictionary *)structure;
+- (NSArray *)allStructureKeys;
+
+@end
diff --git a/Source/SPDatabaseStructure.m b/Source/SPDatabaseStructure.m
new file mode 100644
index 00000000..3579e269
--- /dev/null
+++ b/Source/SPDatabaseStructure.m
@@ -0,0 +1,653 @@
+//
+// $Id$
+//
+// SPDatabaseStructure.m
+// sequel-pro
+//
+// Created by Hans-Jörg Bibiko on March 25, 2010
+// Copyright (c) 2010 Hans-Jörg Bibiko. 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; either version 2 of the License, or
+// (at your option) any later version.
+//
+// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "SPDatabaseStructure.h"
+#import "SPDatabaseDocument.h"
+#import "SPConnectionDelegate.h"
+#import "SPTablesList.h"
+#import "RegexKitLite.h"
+#import "SPMySQL.h"
+#import <pthread.h>
+
+@interface SPDatabaseStructure (Private_API)
+
+- (void)_updateGlobalVariablesWithStructure:(NSDictionary *)aStructure keys:(NSArray *)theKeys;
+- (void)_cloneConnectionFromConnection:(SPMySQLConnection *)aConnection;
+- (BOOL)_ensureConnection;
+
+@end
+
+#pragma mark -
+
+@implementation SPDatabaseStructure
+
+#pragma mark -
+#pragma mark Setup and teardown
+
+/**
+ * Prevent SPDatabaseStructure from being init'd normally.
+ */
+- (id)init
+{
+ [NSException raise:NSInternalInconsistencyException format:@"SPDatabaseStructures should not be init'd directly; use initWithDelegate: instead."];
+ return nil;
+}
+
+/**
+ * Standard init method, constructing the SPDatabaseStructure around a SPMySQL
+ * connection pointer and a delegate.
+ */
+- (id)initWithDelegate:(SPDatabaseDocument *)theDelegate
+{
+ if ((self = [super init])) {
+
+ // Keep a weak reference to the delegate
+ delegate = theDelegate;
+
+ // Start with no root connection
+ mySQLConnection = nil;
+
+ // Set up empty structure and keys storage
+ structureRetrievalThreads = [[NSMutableArray alloc] init];
+ structure = [[NSMutableDictionary alloc] initWithCapacity:1];
+ allKeysofDbStructure = [[NSMutableArray alloc] initWithCapacity:20];
+
+ // Set up the connection, thread management and data locks
+ pthread_mutex_init(&threadManagementLock, NULL);
+ pthread_mutex_init(&dataLock, NULL);
+ pthread_mutex_init(&connectionCheckLock, NULL);
+ }
+
+ return self;
+}
+
+/**
+ * Rather than supplying a connection to SPDatabaseStructure, the class instead
+ * will set up its own connection to allow background querying. The supplied
+ * connection will be used to look up details for the clone process.
+ */
+- (void)setConnectionToClone:(SPMySQLConnection *)aConnection
+{
+
+ // Perform the task in a background thread to avoid blocking the UI
+ [NSThread detachNewThreadSelector:@selector(_cloneConnectionFromConnection:) toTarget:self withObject:aConnection];
+}
+
+/**
+ * Ensure that processing is completed.
+ */
+- (void)destroy
+{
+ delegate = nil;
+
+ // Ensure all the retrieval threads have ended
+ pthread_mutex_lock(&threadManagementLock);
+ if ([structureRetrievalThreads count]) {
+ for (NSThread *eachThread in structureRetrievalThreads) {
+ [eachThread cancel];
+ }
+ while ([structureRetrievalThreads count]) {
+ pthread_mutex_unlock(&threadManagementLock);
+ usleep(100000);
+ pthread_mutex_lock(&threadManagementLock);
+ }
+ }
+ pthread_mutex_unlock(&threadManagementLock);
+
+}
+
+- (void)dealloc
+{
+ [self destroy];
+ [structureRetrievalThreads release];
+
+ pthread_mutex_destroy(&threadManagementLock);
+ pthread_mutex_destroy(&dataLock);
+ pthread_mutex_destroy(&connectionCheckLock);
+
+ if (mySQLConnection) [mySQLConnection release], mySQLConnection = nil;
+ if (structure) [structure release], structure = nil;
+ if (allKeysofDbStructure) [allKeysofDbStructure release], allKeysofDbStructure = nil;
+
+ [super dealloc];
+}
+
+#pragma mark -
+#pragma mark Information
+
+- (SPMySQLConnection *)connection
+{
+ return mySQLConnection;
+}
+
+#pragma mark -
+#pragma mark Structure retrieval from the server
+
+/**
+ * Updates the dict containing the structure of all available databases (mainly for completion/navigator)
+ * executed on the helper connection.
+ * Should always be executed on a background thread.
+ */
+- (void)queryDbStructureWithUserInfo:(NSDictionary*)userInfo
+{
+ NSAutoreleasePool *queryPool = [[NSAutoreleasePool alloc] init];
+ BOOL structureWasUpdated = NO;
+
+ // Lock the management lock
+ pthread_mutex_lock(&threadManagementLock);
+
+ // If 'cancelQuerying' is set try to interrupt any current querying
+ if (userInfo && [userInfo objectForKey:@"cancelQuerying"]) {
+ for (NSThread *eachThread in structureRetrievalThreads) {
+ [eachThread cancel];
+ }
+ }
+
+ // Add this thread to the group
+ [structureRetrievalThreads addObject:[NSThread currentThread]];
+
+ // Only allow one request to be running against the server at any one time, to prevent
+ // escessive server i/o or slowdown. Loop until this is the first thread in the array
+ while ([structureRetrievalThreads objectAtIndex:0] != [NSThread currentThread]) {
+ if ([[NSThread currentThread] isCancelled]) {
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+ [queryPool release];
+ return;
+ }
+
+ pthread_mutex_unlock(&threadManagementLock);
+ usleep(1000000);
+ pthread_mutex_lock(&threadManagementLock);
+ }
+ pthread_mutex_unlock(&threadManagementLock);
+
+ // This thread is now first on the stack, and about to process the structure.
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"SPDBStructureIsUpdating" object:delegate];
+
+ NSString *connectionID;
+ if([delegate respondsToSelector:@selector(connectionID)])
+ connectionID = [NSString stringWithString:[delegate connectionID]];
+ else
+ connectionID = @"_";
+
+ // Re-init with already cached data from navigator controller
+ NSMutableDictionary *queriedStructure = [NSMutableDictionary dictionary];
+ NSDictionary *dbstructure = [delegate getDbStructure];
+ if (dbstructure) [queriedStructure setDictionary:[NSMutableDictionary dictionaryWithDictionary:dbstructure]];
+
+ NSMutableArray *queriedStructureKeys = [NSMutableArray array];
+ NSArray *dbStructureKeys = [delegate allSchemaKeys];
+ if (dbStructureKeys) [queriedStructureKeys setArray:dbStructureKeys];
+
+ // Retrieve all the databases known of by the delegate
+ NSMutableArray *connectionDatabases = [NSMutableArray array];
+ [connectionDatabases addObjectsFromArray:[delegate allSystemDatabaseNames]];
+ [connectionDatabases addObjectsFromArray:[delegate allDatabaseNames]];
+
+ // Add all known databases coming from connection if they aren't parsed yet
+ for (id db in connectionDatabases) {
+ NSString *dbid = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, db];
+ if(![queriedStructure objectForKey:dbid]) {
+ structureWasUpdated = YES;
+ [queriedStructure setObject:db forKey:dbid];
+ [queriedStructureKeys addObject:dbid];
+ }
+ }
+
+ // Check the existing databases in the 'structure' and 'allKeysOfDbStructure' stores,
+ // and remove any that are no longer found in the connectionDatabases list (indicating deletion).
+ // Iterate through extracted keys to avoid <NSCFDictionary> mutation while being enumerated.
+ NSArray *keys = [queriedStructure allKeys];
+ for(id key in keys) {
+ NSString *db = [[key componentsSeparatedByString:SPUniqueSchemaDelimiter] objectAtIndex:1];
+ if(![connectionDatabases containsObject:db]) {
+ structureWasUpdated = YES;
+ [queriedStructure removeObjectForKey:key];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT SELF BEGINSWITH %@", [NSString stringWithFormat:@"%@%@", key, SPUniqueSchemaDelimiter]];
+ [queriedStructureKeys filterUsingPredicate:predicate];
+ [queriedStructureKeys removeObject:key];
+ }
+ }
+
+ NSString *currentDatabase = nil;
+ if ([delegate respondsToSelector:@selector(database)])
+ currentDatabase = [delegate database];
+
+ // Determine whether the database details need to be queried.
+ BOOL shouldQueryStructure = YES;
+ NSString *db_id = nil;
+
+ // If no database is selected, no need to check further
+ if(!currentDatabase || (currentDatabase && ![currentDatabase length])) {
+ shouldQueryStructure = NO;
+
+ // Otherwise, build up the schema key for the database to be retrieved.
+ } else {
+ db_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, currentDatabase];
+
+ // Check to see if a cache already exists for the database.
+ if ([queriedStructure objectForKey:db_id] && [[queriedStructure objectForKey:db_id] isKindOfClass:[NSDictionary class]]) {
+
+ // The cache is available. If the `mysql` or `information_schema` databases are being queried,
+ // never requery as their structure will never change.
+ // 5.5.3+ also has performance_schema meta database
+ if ([currentDatabase isEqualToString:@"mysql"] || [currentDatabase isEqualToString:@"information_schema"] || [currentDatabase isEqualToString:@"performance_schema"]) {
+ shouldQueryStructure = NO;
+
+ // Otherwise, if the forceUpdate flag wasn't supplied or evaluates to false, also don't update.
+ } else if (userInfo == nil || ![userInfo objectForKey:@"forceUpdate"] || ![[userInfo objectForKey:@"forceUpdate"] boolValue]) {
+ shouldQueryStructure = NO;
+ }
+ }
+ }
+
+ // If it has been determined that no new structure needs to be retrieved, clean up and return.
+ if (!shouldQueryStructure) {
+
+ // Update the global variables
+ [self _updateGlobalVariablesWithStructure:queriedStructure keys:queriedStructureKeys];
+
+ if (structureWasUpdated) {
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"SPDBStructureWasUpdated" object:delegate];
+ }
+
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+ return;
+ }
+
+ // Retrieve the tables and views for this database from SPTablesList
+ NSMutableArray *tablesAndViews = [NSMutableArray array];
+ for (id aTable in [[delegate valueForKeyPath:@"tablesListInstance"] allTableNames]) {
+ NSDictionary *aTableDict = [NSDictionary dictionaryWithObjectsAndKeys:
+ aTable, @"name",
+ @"0", @"type",
+ nil];
+ [tablesAndViews addObject:aTableDict];
+ }
+ for (id aView in [[delegate valueForKeyPath:@"tablesListInstance"] allViewNames]) {
+ NSDictionary *aViewDict = [NSDictionary dictionaryWithObjectsAndKeys:
+ aView, @"name",
+ @"1", @"type",
+ nil];
+ [tablesAndViews addObject:aViewDict];
+ }
+
+ // Do not parse more than 2000 tables/views per db
+ if ([tablesAndViews count] > 2000) {
+ NSLog(@"%lu items in database %@. Only 2000 items can be parsed. Stopped parsing.", (unsigned long)[tablesAndViews count], currentDatabase);
+
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+ return;
+ }
+
+ // For future usage - currently unused
+ // If the affected item name and type - for example, table type and table name - were supplied, extract it.
+ NSString *affectedItem = nil;
+ NSInteger affectedItemType = -1;
+ if(userInfo && [userInfo objectForKey:@"affectedItem"]) {
+ affectedItem = [userInfo objectForKey:@"affectedItem"];
+ if([userInfo objectForKey:@"affectedItemType"])
+ affectedItemType = [[userInfo objectForKey:@"affectedItemType"] intValue];
+ else
+ affectedItem = nil;
+ }
+
+ // Delete all stored data for the database to be updated, leaving the structure key
+ [queriedStructure removeObjectForKey:db_id];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT SELF BEGINSWITH %@", [NSString stringWithFormat:@"%@%@", db_id, SPUniqueSchemaDelimiter]];
+ [queriedStructureKeys filterUsingPredicate:predicate];
+
+ // Set up the database as an empty mutable dictionary ready for tables, and store a reference
+ [queriedStructure setObject:[NSMutableDictionary dictionary] forKey:db_id];
+ NSMutableDictionary *databaseStructure = [queriedStructure objectForKey:db_id];
+
+ NSString *currentDatabaseEscaped = [currentDatabase stringByReplacingOccurrencesOfString:@"`" withString:@"``"];
+
+ NSUInteger uniqueCounter = 0; // used to make field data unique
+ SPMySQLResult *theResult;
+
+ // Loop through the known tables and views, retrieving details for each
+ for (NSDictionary *aTableDict in tablesAndViews) {
+
+ // Extract the name
+ NSString *aTableName = [aTableDict objectForKey:@"name"];
+
+ if(!aTableName) continue;
+ if(![aTableName isKindOfClass:[NSString class]]) continue;
+ if(![aTableName length]) continue;
+
+ BOOL cancelThread = NO;
+
+ // If the thread has been cancelled, abort without saving
+ if ([[NSThread currentThread] isCancelled]) cancelThread = YES;
+
+ // Check connection state before use
+ while (!cancelThread && pthread_mutex_trylock(&connectionCheckLock)) {
+ usleep(100000);
+ if ([[NSThread currentThread] isCancelled]) {
+ cancelThread = YES;
+ break;
+ }
+ }
+
+ if (cancelThread) {
+ pthread_mutex_trylock(&connectionCheckLock);
+ pthread_mutex_unlock(&connectionCheckLock);
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+ return;
+ }
+
+ if (![self _ensureConnection]) {
+ pthread_mutex_unlock(&connectionCheckLock);
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+ return;
+ }
+ pthread_mutex_unlock(&connectionCheckLock);
+
+ // Retrieve the column details
+ theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW FULL COLUMNS FROM `%@` FROM `%@`", [aTableName stringByReplacingOccurrencesOfString:@"`" withString:@"``"], currentDatabaseEscaped]];
+ if (!theResult) {
+ continue;
+ }
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
+ [theResult setReturnDataAsStrings:YES];
+
+ // Add a structure key for this table
+ NSString *table_id = [NSString stringWithFormat:@"%@%@%@", db_id, SPUniqueSchemaDelimiter, aTableName];
+ [queriedStructureKeys addObject:table_id];
+
+ // Add a mutable dictionary to the structure and store a reference
+ [databaseStructure setObject:[NSMutableDictionary dictionary] forKey:table_id];
+ NSMutableDictionary *tableStructure = [databaseStructure objectForKey:table_id];
+
+ // Loop through the fields, extracting details for each
+ for (NSArray *row in theResult) {
+ NSString *field = [row objectAtIndex:0];
+ NSString *type = [row objectAtIndex:1];
+ NSString *type_display = [type stringByReplacingOccurrencesOfRegex:@"\\(.*?,.*?\\)" withString:@"(…)"];
+ NSString *collation = [row objectAtIndex:2];
+ NSString *isnull = [row objectAtIndex:3];
+ NSString *key = [row objectAtIndex:4];
+ NSString *def = [row objectAtIndex:5];
+ NSString *extra = [row objectAtIndex:6];
+ NSString *priv = @"";
+ NSString *comment = @"";
+ if ([row count] > 7) priv = [row objectAtIndex:7];
+ if ([row count] > 8) comment = [row objectAtIndex:8];
+
+ NSString *charset = @"";
+ if (![collation isNSNull]) {
+ NSArray *a = [collation componentsSeparatedByString:@"_"];
+ charset = [a objectAtIndex:0];
+ }
+
+ // Add a structure key for this field
+ NSString *field_id = [NSString stringWithFormat:@"%@%@%@", table_id, SPUniqueSchemaDelimiter, field];
+ [queriedStructureKeys addObject:field_id];
+
+ [tableStructure setObject:[NSArray arrayWithObjects:type, def, isnull, charset, collation, key, extra, priv, comment, type_display, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
+ [tableStructure setObject:[aTableDict objectForKey:@"type"] forKey:@" struct_type "];
+ uniqueCounter++;
+ }
+
+ // Allow a tiny pause between iterations
+ usleep(10);
+ }
+
+ // If the MySQL version is higher than 5, also retrieve function/procedure details via the information_schema table
+ if ([mySQLConnection serverMajorVersion] >= 5) {
+ BOOL cancelThread = NO;
+
+ if ([[NSThread currentThread] isCancelled]) cancelThread = YES;
+
+ // Check connection state before use
+ while (!cancelThread && pthread_mutex_trylock(&connectionCheckLock)) {
+ usleep(100000);
+ if ([[NSThread currentThread] isCancelled]) {
+ cancelThread = YES;
+ break;
+ }
+ }
+
+ if (!cancelThread) {
+ if (![self _ensureConnection]) cancelThread = YES;
+ pthread_mutex_unlock(&connectionCheckLock);
+ };
+
+ // Return if the thread is due to be cancelled
+ if (cancelThread) {
+ pthread_mutex_trylock(&connectionCheckLock);
+ pthread_mutex_unlock(&connectionCheckLock);
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+ return;
+ }
+
+ // Retrieve the column details
+ theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM `information_schema`.`ROUTINES` WHERE `information_schema`.`ROUTINES`.`ROUTINE_SCHEMA` = '%@'", [currentDatabase stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
+
+ // Loop through the rows and extract the function details
+ for (NSArray *row in theResult) {
+ NSString *fname = [row objectAtIndex:0];
+ NSString *type = ([[row objectAtIndex:4] isEqualToString:@"FUNCTION"]) ? @"3" : @"2";
+ NSString *dtd = [row objectAtIndex:5];
+ NSString *det = [row objectAtIndex:11];
+ NSString *dataaccess = [row objectAtIndex:12];
+ NSString *security_type = [row objectAtIndex:14];
+ NSString *definer = [row objectAtIndex:19];
+
+ // Generate "table" and "field" names and add to structure key store
+ NSString *table_id = [NSString stringWithFormat:@"%@%@%@", db_id, SPUniqueSchemaDelimiter, fname];
+ NSString *field_id = [NSString stringWithFormat:@"%@%@%@", table_id, SPUniqueSchemaDelimiter, fname];
+ [queriedStructureKeys addObject:table_id];
+ [queriedStructureKeys addObject:field_id];
+
+ // Ensure that a dictionary exists for this "table" name
+ if(![[queriedStructure valueForKey:db_id] valueForKey:table_id])
+ [[queriedStructure valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
+
+ // Add the "field" details
+ [[[queriedStructure valueForKey:db_id] valueForKey:table_id] setObject:
+ [NSArray arrayWithObjects:dtd, dataaccess, det, security_type, definer, [NSNumber numberWithUnsignedLongLong:uniqueCounter], nil] forKey:field_id];
+ [[[queriedStructure valueForKey:db_id] valueForKey:table_id] setObject:type forKey:@" struct_type "];
+ uniqueCounter++;
+ }
+ }
+
+ // Update the global variables
+ [self _updateGlobalVariablesWithStructure:queriedStructure keys:queriedStructureKeys];
+
+ // Notify that the structure querying has been performed
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"SPDBStructureWasUpdated" object:delegate];
+
+ // Remove this thread from the processing stack
+ pthread_mutex_lock(&threadManagementLock);
+ [structureRetrievalThreads removeObject:[NSThread currentThread]];
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [queryPool release];
+}
+
+- (BOOL)isQueryingDatabaseStructure
+{
+ pthread_mutex_lock(&threadManagementLock);
+ BOOL returnValue = ([structureRetrievalThreads count] > 0);
+ pthread_mutex_unlock(&threadManagementLock);
+
+ return returnValue;
+}
+
+#pragma mark -
+#pragma mark Structure information
+
+/**
+ * Returns a dict containing the structure of all available databases
+ */
+- (NSDictionary *)structure
+{
+ pthread_mutex_lock(&dataLock);
+ NSDictionary *d = [NSDictionary dictionaryWithDictionary:structure];
+ pthread_mutex_unlock(&dataLock);
+
+ return d;
+}
+
+/**
+ * Returns all keys of the db structure
+ */
+- (NSArray *)allStructureKeys
+{
+ pthread_mutex_lock(&dataLock);
+ NSArray *r = [NSArray arrayWithArray:allKeysofDbStructure];
+ pthread_mutex_unlock(&dataLock);
+
+ return r;
+}
+
+#pragma mark -
+#pragma mark SPMySQLConnection delegate methods
+
+/**
+ * Forward keychain password requests to the database object.
+ */
+- (NSString *)keychainPasswordForConnection:(id)connection
+{
+ return [delegate keychainPasswordForConnection:connection];
+}
+
+@end
+
+#pragma mark -
+#pragma mark Private API
+
+@implementation SPDatabaseStructure (Private_API)
+
+/**
+ * Update the global variables, using the data lock for multithreading safety.
+ */
+- (void)_updateGlobalVariablesWithStructure:(NSDictionary *)aStructure keys:(NSArray *)theKeys
+{
+
+ NSString *connectionID = [delegate connectionID];
+
+ // Return if the delegate indicates disconnection
+ if([connectionID length] < 2) return;
+
+ pthread_mutex_lock(&dataLock);
+
+ [structure setObject:aStructure forKey:connectionID];
+ [allKeysofDbStructure setArray:theKeys];
+
+ pthread_mutex_unlock(&dataLock);
+}
+
+/**
+ * Set up a new connection in a background thread
+ */
+- (void)_cloneConnectionFromConnection:(SPMySQLConnection *)aConnection
+{
+ NSAutoreleasePool *connectionPool = [[NSAutoreleasePool alloc] init];
+
+ pthread_mutex_lock(&connectionCheckLock);
+
+ // If a connection is already set, ensure it's idle before releasing it
+ if (mySQLConnection) {
+ pthread_mutex_lock(&threadManagementLock);
+ if ([structureRetrievalThreads count]) {
+ for (NSThread *eachThread in structureRetrievalThreads) {
+ [eachThread cancel];
+ }
+ while ([structureRetrievalThreads count]) {
+ pthread_mutex_unlock(&threadManagementLock);
+ usleep(100000);
+ pthread_mutex_lock(&threadManagementLock);
+ }
+ }
+ pthread_mutex_unlock(&threadManagementLock);
+
+ [mySQLConnection release];
+ mySQLConnection = nil;
+ }
+
+ // Create a copy of the supplied connection
+ mySQLConnection = [aConnection copy];
+
+ // Set the delegate to this instance
+ [mySQLConnection setDelegate:self];
+
+ // Trigger the connection
+ [self _ensureConnection];
+
+ pthread_mutex_unlock(&connectionCheckLock);
+
+ [connectionPool drain];
+}
+
+- (BOOL)_ensureConnection
+{
+ if (!mySQLConnection || !delegate) return NO;
+
+ // Check the connection state
+ if ([mySQLConnection isConnected] && [mySQLConnection checkConnection]) return YES;
+
+ // The connection isn't connected. Check the parent connection state, and if that
+ // also isn't connected, return.
+ if (![[delegate getConnection] isConnected]) return NO;
+
+ // Copy the local port from the parent connection, in case a proxy has changed
+ [mySQLConnection setPort:[[delegate getConnection] port]];
+
+ // Attempt a connection
+ if (![mySQLConnection connect]) return NO;
+
+ // Ensure the encoding is set to UTF8
+ [mySQLConnection setEncoding:@"utf8"];
+
+ // Return success
+ return YES;
+}
+
+@end \ No newline at end of file
diff --git a/Source/SPDatabaseViewController.m b/Source/SPDatabaseViewController.m
index 171ff8f6..dcea5cdc 100644
--- a/Source/SPDatabaseViewController.m
+++ b/Source/SPDatabaseViewController.m
@@ -32,6 +32,7 @@
#import "SPTableData.h"
#import "SPTablesList.h"
#import "SPTableTriggers.h"
+#import "SPMySQL.h"
#ifdef SP_REFACTOR /* headers */
#import "SPTableStructure.h"
#endif
@@ -320,11 +321,7 @@
#endif
// Notify listeners of the table change
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-#endif
return;
}
@@ -467,11 +464,8 @@
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
// Notify listeners of the table change now that the state is fully set up.
-#ifndef SP_REFACTOR
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-#endif
+ [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
+
#ifndef SP_REFACTOR /* [spHistoryControllerInstance restoreViewStates] */
// Restore view states as appropriate
diff --git a/Source/SPEditorPreferencePane.m b/Source/SPEditorPreferencePane.m
index f2802180..3c948e74 100644
--- a/Source/SPEditorPreferencePane.m
+++ b/Source/SPEditorPreferencePane.m
@@ -281,14 +281,14 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined";
[[NSColorPanel sharedColorPanel] close];
[prefs setObject:SPDefaultColorSchemeName forKey:SPCustomQueryEditorThemeName];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000 green:0.455 blue:0.000 alpha:1.000]] forKey:SPCustomQueryEditorCommentColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.769 green:0.102 blue:0.086 alpha:1.000]] forKey:SPCustomQueryEditorQuoteColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.200 green:0.250 blue:1.000 alpha:1.000]] forKey:SPCustomQueryEditorSQLKeywordColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000 green:0.000 blue:0.658 alpha:1.000]] forKey:SPCustomQueryEditorBacktickColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.506 green:0.263 blue:0.000 alpha:1.000]] forKey:SPCustomQueryEditorNumericColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.500 green:0.500 blue:0.500 alpha:1.000]] forKey:SPCustomQueryEditorVariableColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.950 green:0.950 blue:0.950 alpha:1.000]] forKey:SPCustomQueryEditorHighlightQueryColor];
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.7098 green:0.8352 blue:1.000 alpha:1.000]] forKey:SPCustomQueryEditorSelectionColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000f green:0.455f blue:0.000f alpha:1.000f]] forKey:SPCustomQueryEditorCommentColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.769f green:0.102f blue:0.086f alpha:1.000f]] forKey:SPCustomQueryEditorQuoteColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.200f green:0.250f blue:1.000f alpha:1.000f]] forKey:SPCustomQueryEditorSQLKeywordColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.000f green:0.000f blue:0.658f alpha:1.000f]] forKey:SPCustomQueryEditorBacktickColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.506f green:0.263f blue:0.000f alpha:1.000f]] forKey:SPCustomQueryEditorNumericColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.500f green:0.500f blue:0.500f alpha:1.000f]] forKey:SPCustomQueryEditorVariableColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.950f green:0.950f blue:0.950f alpha:1.000f]] forKey:SPCustomQueryEditorHighlightQueryColor];
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithDeviceRed:0.7098f green:0.8352f blue:1.000f alpha:1.000f]] forKey:SPCustomQueryEditorSelectionColor];
[prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor blackColor]] forKey:SPCustomQueryEditorTextColor];
[prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor blackColor]] forKey:SPCustomQueryEditorCaretColor];
[prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor whiteColor]] forKey:SPCustomQueryEditorBackgroundColor];
diff --git a/Source/SPExportController.h b/Source/SPExportController.h
index 7a4fcb3c..9c084334 100644
--- a/Source/SPExportController.h
+++ b/Source/SPExportController.h
@@ -23,7 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-@class MCPConnection, BWAnchoredButtonBar;
+@class SPMySQLConnection, BWAnchoredButtonBar;
/**
* @class SPExportController SPExportController.h
@@ -162,7 +162,7 @@
/**
* Database connection
*/
- MCPConnection *connection;
+ SPMySQLConnection *connection;
/**
* Concurrent operation queue
@@ -238,7 +238,7 @@
/**
* @property connection Database connection
*/
-@property(readwrite, assign) MCPConnection *connection;
+@property(readwrite, assign) SPMySQLConnection *connection;
- (void)exportTables:(NSArray *)table asFormat:(SPExportType)format usingSource:(SPExportSource)source;
- (void)openExportErrorsSheetWithString:(NSString *)errors;
@@ -258,10 +258,10 @@
- (IBAction)exportCustomQueryResultAsFormat:(id)sender;
- (IBAction)toggleXMLOutputFormat:(id)sender;
-- (IBAction)toggleSQLIncludeStructure:(id)sender;
-- (IBAction)toggleSQLIncludeContent:(id)sender;
-- (IBAction)toggleSQLIncludeDropSyntax:(id)sender;
-- (IBAction)toggleNewFilePerTable:(id)sender;
+- (IBAction)toggleSQLIncludeStructure:(NSButton *)sender;
+- (IBAction)toggleSQLIncludeContent:(NSButton *)sender;
+- (IBAction)toggleSQLIncludeDropSyntax:(NSButton *)sender;
+- (IBAction)toggleNewFilePerTable:(NSButton *)sender;
- (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
diff --git a/Source/SPExportController.m b/Source/SPExportController.m
index 21ab667b..17720928 100644
--- a/Source/SPExportController.m
+++ b/Source/SPExportController.m
@@ -23,8 +23,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPExportController.h"
#import "SPExportInitializer.h"
#import "SPTablesList.h"
@@ -36,6 +34,7 @@
#import "SPExportFilenameUtilities.h"
#import "SPExportFileNameTokenObject.h"
#import "SPDatabaseDocument.h"
+#import "SPMySQL.h"
// Constants
static const NSUInteger SPExportUIPadding = 20;
@@ -574,7 +573,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled";
/**
* Toggles the export button when choosing to include or table structures in an SQL export.
*/
-- (IBAction)toggleSQLIncludeStructure:(id)sender
+- (IBAction)toggleSQLIncludeStructure:(NSButton *)sender
{
if (![sender state])
{
@@ -593,7 +592,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled";
/**
* Toggles the export button when choosing to include or exclude table contents in an SQL export.
*/
-- (IBAction)toggleSQLIncludeContent:(id)sender
+- (IBAction)toggleSQLIncludeContent:(NSButton *)sender
{
[[exportTableList tableColumnWithIdentifier:SPTableViewContentColumnID] setHidden:(![sender state])];
@@ -603,7 +602,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled";
/**
* Toggles the export button when choosing to include or exclude table drop syntax in an SQL export.
*/
-- (IBAction)toggleSQLIncludeDropSyntax:(id)sender
+- (IBAction)toggleSQLIncludeDropSyntax:(NSButton *)sender
{
[[exportTableList tableColumnWithIdentifier:SPTableViewDropColumnID] setHidden:(![sender state])];
@@ -613,7 +612,7 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled";
/**
* Toggles whether XML and CSV files should be combined into a single file.
*/
-- (IBAction)toggleNewFilePerTable:(id)sender
+- (IBAction)toggleNewFilePerTable:(NSButton *)sender
{
[self _updateExportFormatInformation];
}
@@ -795,12 +794,12 @@ static const NSString *SPSQLExportDropEnabled = @"SQLExportDropEnabled";
// to set the export's link case sensitivity setting
if (isDot && serverLowerCaseTableNameValue == NSNotFound) {
- MCPResult *caseResult = [connection queryString:@"SHOW VARIABLES LIKE 'lower_case_table_names'"];
+ SPMySQLResult *caseResult = [connection queryString:@"SHOW VARIABLES LIKE 'lower_case_table_names'"];
[caseResult setReturnDataAsStrings:YES];
- if ([caseResult numOfRows] == 1) {
- serverLowerCaseTableNameValue = [[[caseResult fetchRowAsDictionary] objectForKey:@"Value"] integerValue];
+ if ([caseResult numberOfRows] == 1) {
+ serverLowerCaseTableNameValue = [[[caseResult getRowAsDictionary] objectForKey:@"Value"] integerValue];
}
else {
serverLowerCaseTableNameValue = 0;
diff --git a/Source/SPExportFileUtilities.m b/Source/SPExportFileUtilities.m
index b23d0b78..325ddb60 100644
--- a/Source/SPExportFileUtilities.m
+++ b/Source/SPExportFileUtilities.m
@@ -29,6 +29,7 @@
#import "SPExportFile.h"
#import "SPDatabaseDocument.h"
#import "SPCustomQuery.h"
+#import "SPMySQL.h"
typedef enum
{
diff --git a/Source/SPExportInitializer.m b/Source/SPExportInitializer.m
index f9d23b63..69a282b4 100644
--- a/Source/SPExportInitializer.m
+++ b/Source/SPExportInitializer.m
@@ -23,8 +23,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPExportInitializer.h"
#import "SPTableData.h"
#import "SPDatabaseDocument.h"
@@ -43,6 +41,7 @@
#import "SPExportFileUtilities.h"
#import "SPExportFilenameUtilities.h"
#import "SPExportFileNameTokenObject.h"
+#import "SPMySQL.h"
@implementation SPExportController (SPExportInitializer)
diff --git a/Source/SPExporter.h b/Source/SPExporter.h
index abc880a0..e58c8d65 100644
--- a/Source/SPExporter.h
+++ b/Source/SPExporter.h
@@ -48,11 +48,11 @@
* explicity called.
*/
-@class MCPConnection, SPExportFile;
+@class SPMySQLConnection, SPExportFile;
@interface SPExporter : NSOperation
{
- MCPConnection *connection;
+ SPMySQLConnection *connection;
double exportProgressValue;
double exportMaxProgress;
@@ -74,7 +74,7 @@
/**
* @property connection The MySQL connection to use
*/
-@property(readwrite, retain) MCPConnection *connection;
+@property(readwrite, retain) SPMySQLConnection *connection;
/**
* @property exportProgressValue The export's current progress value
diff --git a/Source/SPExtendedTableInfo.h b/Source/SPExtendedTableInfo.h
index 962eed6a..72087f67 100644
--- a/Source/SPExtendedTableInfo.h
+++ b/Source/SPExtendedTableInfo.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPTableData, SPDatabaseData, SPTablesList;
+@class SPTableData, SPDatabaseData, SPTablesList, SPMySQLConnection;
@interface SPExtendedTableInfo : NSObject
{
@@ -57,10 +55,10 @@
NSString *selectedTable;
- MCPConnection *connection;
+ SPMySQLConnection *connection;
}
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, retain) SPMySQLConnection *connection;
// IBAction methods
- (IBAction)reloadTable:(id)sender;
diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m
index a1e59110..9baaecab 100644
--- a/Source/SPExtendedTableInfo.m
+++ b/Source/SPExtendedTableInfo.m
@@ -33,9 +33,14 @@
#import "SPAlertSheets.h"
#import "SPTableStructure.h"
#import "SPServerSupport.h"
+#import "SPMySQL.h"
-@interface SPExtendedTableInfo (PrivateAPI)
+static NSString *SPUpdateTableTypeCurrentType = @"SPUpdateTableTypeCurrentType";
+static NSString *SPUpdateTableTypeNewType = @"SPUpdateTableTypeNewType";
+@interface SPExtendedTableInfo ()
+
+- (void)_changeCurrentTableTypeFrom:(NSString *)currentType to:(NSString *)newType;
- (NSString *)_formatValueWithKey:(NSString *)key inDictionary:(NSDictionary *)statusDict;
@end
@@ -49,17 +54,6 @@
*/
- (void)awakeFromNib
{
- [tableCreateSyntaxTextView setAllowsDocumentBackgroundColorChange:YES];
-
- NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
-
- [bindingOptions setObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
-
- [tableCreateSyntaxTextView bind:@"backgroundColor"
- toObject:[NSUserDefaultsController sharedUserDefaultsController]
- withKeyPath:@"values.CustomQueryEditorBackgroundColor"
- options:bindingOptions];
-
// Add observers for document task activity
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(startDocumentTaskForTab:)
@@ -95,24 +89,32 @@
NSString *currentType = [tableDataInstance statusValueForKey:@"Engine"];
// Check if the user selected the same type
- if ([currentType isEqualToString:newType]) {
- return;
- }
-
- // Alter table's storage type
- [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ %@ = %@", [selectedTable backtickQuotedString], [[tableDocumentInstance serverSupport] engineTypeQueryName], newType]];
-
- if ([connection getLastErrorID] == 0) {
- // Reload the table's data
- [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]];
- }
- else {
- [sender selectItemWithTitle:currentType];
-
- SPBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"),
- NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table type to '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), newType, [connection getLastErrorMessage]]);
- }
+ if ([currentType isEqualToString:newType]) return;
+
+ NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Change table type", @"change table type message")
+ defaultButton:NSLocalizedString(@"Change", @"change button")
+ alternateButton:NSLocalizedString(@"Cancel", @"cancel button")
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to change this table's type to %@?\n\nPlease be aware that changing a table's type has the potential to cause the loss of some or all of it's data. This action cannot be undone.", @"change table type informative message"), newType];
+
+ [alert setAlertStyle:NSCriticalAlertStyle];
+
+ NSArray *buttons = [alert buttons];
+
+ // Change the alert's cancel button to have the key equivalent of return
+ [[buttons objectAtIndex:0] setKeyEquivalent:@"d"];
+ [[buttons objectAtIndex:0] setKeyEquivalentModifierMask:NSCommandKeyMask];
+ [[buttons objectAtIndex:1] setKeyEquivalent:@"\r"];
+
+ NSMutableDictionary *dataDict = [[NSMutableDictionary alloc] initWithCapacity:2];
+
+ [dataDict setObject:currentType forKey:SPUpdateTableTypeCurrentType];
+ [dataDict setObject:newType forKey:SPUpdateTableTypeNewType];
+
+ [alert beginSheetModalForWindow:[tableDocumentInstance parentWindow]
+ modalDelegate:self
+ didEndSelector:@selector(confirmChangeTableTypeDidEnd:returnCode:contextInfo:)
+ contextInfo:dataDict];
}
/**
@@ -129,7 +131,7 @@
// Alter table's character set encoding
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ CHARACTER SET = %@", [selectedTable backtickQuotedString], newEncoding]];
- if ([connection getLastErrorID] == 0) {
+ if (![connection queryErrored]) {
// Reload the table's data
[self reloadTable:self];
}
@@ -138,7 +140,7 @@
SPBeginAlertSheet(NSLocalizedString(@"Error changing table encoding", @"error changing table encoding message"),
NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table encoding to '%@'.\n\nMySQL said: %@", @"error changing table encoding informative message"), newEncoding, [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table encoding to '%@'.\n\nMySQL said: %@", @"error changing table encoding informative message"), newEncoding, [connection lastErrorMessage]]);
}
}
@@ -156,7 +158,7 @@
// Alter table's character set collation
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COLLATE = %@", [selectedTable backtickQuotedString], newCollation]];
- if ([connection getLastErrorID] == 0) {
+ if (![connection queryErrored]) {
// Reload the table's data
[self reloadTable:self];
}
@@ -165,7 +167,7 @@
SPBeginAlertSheet(NSLocalizedString(@"Error changing table collation", @"error changing table collation message"),
NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table collation to '%@'.\n\nMySQL said: %@", @"error changing table collation informative message"), newCollation, [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table collation to '%@'.\n\nMySQL said: %@", @"error changing table collation informative message"), newCollation, [connection lastErrorMessage]]);
}
}
@@ -245,7 +247,8 @@
[tableCreateSyntaxTextView didChangeText];
[tableCreateSyntaxTextView setEditable:NO];
}
- } else {
+ }
+ else {
[tableCreateSyntaxTextView setEditable:YES];
[tableCreateSyntaxTextView shouldChangeTextInRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length]) replacementString:@""];
[tableCreateSyntaxTextView setString:@""];
@@ -278,6 +281,7 @@
[tableEncodingPopUpButton addItemWithTitle:[statusFields objectForKey:@"CharacterSetClient"]];
[tableCollationPopUpButton addItemWithTitle:[statusFields objectForKey:@"Collation"]];
}
+
return;
}
@@ -353,7 +357,9 @@
// Set comments
NSString *commentText = [statusFields objectForKey:@"Comment"];
+
if (!commentText) commentText = @"";
+
[tableCommentsTextView setEditable:YES];
[tableCommentsTextView shouldChangeTextInRange:NSMakeRange(0, [[tableCommentsTextView string] length]) replacementString:commentText];
[tableCommentsTextView setString:commentText];
@@ -366,14 +372,16 @@
[tableCreateSyntaxTextView setString:@""];
[tableCreateSyntaxTextView didChangeText];
[tableCreateSyntaxTextView shouldChangeTextInRange:NSMakeRange(0, 0) replacementString:[tableDataInstance tableCreateSyntax]];
+
if ([tableDataInstance tableCreateSyntax]) {
[tableCreateSyntaxTextView insertText:[[tableDataInstance tableCreateSyntax] stringByAppendingString:@";"]];
}
+
[tableCreateSyntaxTextView didChangeText];
[tableCreateSyntaxTextView setEditable:NO];
// Validate Reset AUTO_INCREMENT button
- if ([statusFields objectForKey:@"Auto_increment"] && ![[statusFields objectForKey:@"Auto_increment"] isKindOfClass:[NSNull class]]) {
+ if ([statusFields objectForKey:@"Auto_increment"] && ![[statusFields objectForKey:@"Auto_increment"] isNSNull]) {
[resetAutoIncrementResetButton setHidden:NO];
}
}
@@ -389,35 +397,59 @@
NSMutableDictionary *tableInfo = [NSMutableDictionary dictionary];
NSDictionary *statusFields = [tableDataInstance statusValues];
- if([tableTypePopUpButton titleOfSelectedItem])
+ if ([tableTypePopUpButton titleOfSelectedItem]) {
[tableInfo setObject:[tableTypePopUpButton titleOfSelectedItem] forKey:@"type"];
- if([tableEncodingPopUpButton titleOfSelectedItem])
+ }
+
+ if ([tableEncodingPopUpButton titleOfSelectedItem]) {
[tableInfo setObject:[tableEncodingPopUpButton titleOfSelectedItem] forKey:@"encoding"];
- if([tableCollationPopUpButton titleOfSelectedItem])
+ }
+
+ if ([tableCollationPopUpButton titleOfSelectedItem]) {
[tableInfo setObject:[tableCollationPopUpButton titleOfSelectedItem] forKey:@"collation"];
+ }
- if([self _formatValueWithKey:@"Create_time" inDictionary:statusFields])
+ if ([self _formatValueWithKey:@"Create_time" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Create_time" inDictionary:statusFields] forKey:@"createdAt"];
- if([self _formatValueWithKey:@"Update_time" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Update_time" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Update_time" inDictionary:statusFields] forKey:@"updatedAt"];
- if([self _formatValueWithKey:@"Rows" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Rows" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Rows" inDictionary:statusFields] forKey:@"rowNumber"];
- if([self _formatValueWithKey:@"Row_format" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Row_format" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Row_format" inDictionary:statusFields] forKey:@"rowFormat"];
- if([self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Avg_row_length" inDictionary:statusFields] forKey:@"rowAvgLength"];
- if([self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Auto_increment" inDictionary:statusFields] forKey:@"rowAutoIncrement"];
- if([self _formatValueWithKey:@"Data_length" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Data_length" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Data_length" inDictionary:statusFields] forKey:@"dataSize"];
- if([self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Max_data_length" inDictionary:statusFields] forKey:@"maxDataSize"];
- if([self _formatValueWithKey:@"Index_length" inDictionary:statusFields])
+ }
+
+ if ([self _formatValueWithKey:@"Index_length" inDictionary:statusFields]) {
[tableInfo setObject:[self _formatValueWithKey:@"Index_length" inDictionary:statusFields] forKey:@"indexSize"];
+ }
+
[tableInfo setObject:[self _formatValueWithKey:@"Data_free" inDictionary:statusFields] forKey:@"sizeFree"];
- if([tableCommentsTextView string])
+ if ([tableCommentsTextView string]) {
[tableInfo setObject:[tableCommentsTextView string] forKey:@"comments"];
+ }
NSError *error = nil;
NSArray *HTMLExcludes = [NSArray arrayWithObjects:@"doctype", @"html", @"head", @"body", @"xml", nil];
@@ -428,12 +460,12 @@
// Set tableCreateSyntaxTextView's font size temporarily to 10pt for printing
NSFont *oldFont = [tableCreateSyntaxTextView font];
BOOL editableStatus = [tableCreateSyntaxTextView isEditable];
+
[tableCreateSyntaxTextView setEditable:YES];
- [tableCreateSyntaxTextView setFont:[NSFont fontWithName:[oldFont fontName] size:10.0]];
+ [tableCreateSyntaxTextView setFont:[NSFont fontWithName:[oldFont fontName] size:10.0f]];
// Convert tableCreateSyntaxTextView to HTML
- NSData *HTMLData = [[tableCreateSyntaxTextView textStorage] dataFromRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length])
- documentAttributes:attributes error:&error];
+ NSData *HTMLData = [[tableCreateSyntaxTextView textStorage] dataFromRange:NSMakeRange(0, [[tableCreateSyntaxTextView string] length]) documentAttributes:attributes error:&error];
// Restore original font settings
[tableCreateSyntaxTextView setFont:oldFont];
@@ -468,21 +500,37 @@
if (![currentComment isEqualToString:newComment]) {
// Alter table's comment
- [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COMMENT = '%@'", [selectedTable backtickQuotedString], [connection prepareString:newComment]]];
+ [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ COMMENT = %@", [selectedTable backtickQuotedString], [connection escapeAndQuoteString:newComment]]];
- if ([connection getLastErrorID] == 0) {
+ if (![connection queryErrored]) {
// Reload the table's data
[self reloadTable:self];
}
else {
SPBeginAlertSheet(NSLocalizedString(@"Error changing table comment", @"error changing table comment message"),
NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table's comment to '%@'.\n\nMySQL said: %@", @"error changing table comment informative message"), newComment, [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table's comment to '%@'.\n\nMySQL said: %@", @"error changing table comment informative message"), newComment, [connection lastErrorMessage]]);
}
}
}
}
+/**
+ * Called when the user dismisses the change table type confirmation dialog.
+ */
+- (void)confirmChangeTableTypeDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSDictionary *)contextInfo
+{
+ if (returnCode == NSAlertDefaultReturn) {
+ [self _changeCurrentTableTypeFrom:[contextInfo objectForKey:SPUpdateTableTypeCurrentType]
+ to:[contextInfo objectForKey:SPUpdateTableTypeNewType]];
+ }
+ else {
+ [tableTypePopUpButton selectItemWithTitle:[contextInfo objectForKey:SPUpdateTableTypeCurrentType]];
+ }
+
+ [contextInfo release];
+}
+
#pragma mark -
#pragma mark Task interaction
@@ -514,8 +562,10 @@
// If we are viewing tables in the information_schema database, then disable all controls that cause table
// changes as these tables are not modifiable by anyone.
- //also affects mysql and performance_schema
- BOOL isSystemSchemaDb = ([[tableDocumentInstance database] isEqualToString:@"information_schema"] || [[tableDocumentInstance database] isEqualToString:@"performance_schema"] || [[tableDocumentInstance database] isEqualToString:@"mysql"]);
+ // also affects mysql and performance_schema
+ BOOL isSystemSchemaDb = ([[tableDocumentInstance database] isEqualToString:SPMySQLInformationSchemaDatabase] ||
+ [[tableDocumentInstance database] isEqualToString:SPMySQLPerformanceSchemaDatabase] ||
+ [[tableDocumentInstance database] isEqualToString:SPMySQLDatabase]);
if ([[databaseDataInstance getDatabaseStorageEngines] count] && [statusFields objectForKey:@"Engine"]) {
[tableTypePopUpButton setEnabled:(!isSystemSchemaDb)];
@@ -525,8 +575,7 @@
[tableEncodingPopUpButton setEnabled:(!isSystemSchemaDb)];
}
- if ([[databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]] count]
- && [statusFields objectForKey:@"Collation"])
+ if ([[databaseDataInstance getDatabaseCollationsForEncoding:[tableDataInstance tableEncoding]] count] && [statusFields objectForKey:@"Collation"])
{
[tableCollationPopUpButton setEnabled:(!isSystemSchemaDb)];
}
@@ -548,9 +597,30 @@
[super dealloc];
}
-@end
+#pragma mark -
+#pragma mark Private API
-@implementation SPExtendedTableInfo (PrivateAPI)
+/**
+ * Changes the current table's storage engine to the supplied type.
+ */
+- (void)_changeCurrentTableTypeFrom:(NSString *)currentType to:(NSString *)newType
+{
+ // Alter table's storage type
+ [connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ %@ = %@", [selectedTable backtickQuotedString], [[tableDocumentInstance serverSupport] engineTypeQueryName], newType]];
+
+ if ([connection queryErrored]) {
+
+ // Reload the table's data
+ [tableDocumentInstance loadTable:selectedTable ofType:[tableDocumentInstance tableType]];
+ }
+ else {
+ [tableTypePopUpButton selectItemWithTitle:currentType];
+
+ SPBeginAlertSheet(NSLocalizedString(@"Error changing table type", @"error changing table type message"),
+ NSLocalizedString(@"OK", @"OK button"), nil, nil, [NSApp mainWindow], self, nil, nil,
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the table type to '%@'.\n\nMySQL said: %@", @"error changing table type informative message"), newType, [connection lastErrorMessage]]);
+ }
+}
/**
* Format and returns the value within the info dictionary with the associated key.
@@ -559,7 +629,7 @@
{
NSString *value = [infoDict objectForKey:key];
- if ([value isKindOfClass:[NSNull class]]) {
+ if ([value isNSNull]) {
value = @"";
}
else {
@@ -603,12 +673,7 @@
}
}
- if ([key isEqualToString:@"Auto_increment"]) {
- return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label");
- }
- else {
- return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label");
- }
+ return ([value length] > 0) ? value : NSLocalizedString(@"Not available", @"not available label");
}
@end
diff --git a/Source/SPFavoritesController.m b/Source/SPFavoritesController.m
index 1ac410e5..c53bbae3 100644
--- a/Source/SPFavoritesController.m
+++ b/Source/SPFavoritesController.m
@@ -54,7 +54,8 @@ static SPFavoritesController *sharedFavoritesController = nil;
{
@synchronized(self) {
return [[self sharedFavoritesController] retain];
- }
+ }
+ return nil;
}
- (id)init
diff --git a/Source/SPFieldEditorController.h b/Source/SPFieldEditorController.h
index b629acbf..f45b6070 100644
--- a/Source/SPFieldEditorController.h
+++ b/Source/SPFieldEditorController.h
@@ -22,7 +22,6 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
/**
* @class SPFieldEditorController SPFieldEditorController.h
diff --git a/Source/SPFieldEditorController.m b/Source/SPFieldEditorController.m
index 2df24c24..549c994e 100644
--- a/Source/SPFieldEditorController.m
+++ b/Source/SPFieldEditorController.m
@@ -35,6 +35,7 @@
#include <objc/objc-runtime.h>
#import "SPCustomQuery.h"
#import "SPTableContent.h"
+#import "SPMySQLGeometryData.h"
@interface SPFieldEditorController (SPFieldEditorControllerDelegate)
@@ -351,7 +352,7 @@
[editTextView setHidden:YES];
[editTextScrollView setHidden:YES];
[editSheetSegmentControl setSelectedSegment:2];
- } else if ([sheetEditData isKindOfClass:[MCPGeometryData class]]) {
+ } else if ([sheetEditData isKindOfClass:[SPMySQLGeometryData class]]) {
SPGeometryDataView *v = [[[SPGeometryDataView alloc] initWithCoordinates:[sheetEditData coordinates] targetDimension:2000.0f] autorelease];
image = [v thumbnailImage];
stringValue = [[sheetEditData wktString] retain];
@@ -547,7 +548,7 @@
NSSavePanel *panel = [NSSavePanel savePanel];
NSString *fileDefault = @"";
- if([editSheetSegmentControl selectedSegment] == 1 && [sheetEditData isKindOfClass:[MCPGeometryData class]]) {
+ if([editSheetSegmentControl selectedSegment] == 1 && [sheetEditData isKindOfClass:[SPMySQLGeometryData class]]) {
[panel setAllowedFileTypes:[NSArray arrayWithObject:@"pdf"]];
[panel setAllowsOtherFileTypes:NO];
} else {
@@ -716,7 +717,7 @@
[sheetEditData writeToURL:fileURL atomically:YES];
}
- else if ( [sheetEditData isKindOfClass:[MCPGeometryData class]] ) {
+ else if ( [sheetEditData isKindOfClass:[SPMySQLGeometryData class]] ) {
if ( [editSheetSegmentControl selectedSegment] == 0 || editImage == nil ) {
diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h
index 860eef81..6fb31b8e 100644
--- a/Source/SPFieldMapperController.h
+++ b/Source/SPFieldMapperController.h
@@ -22,14 +22,11 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPTextView, SPTableView, SPTablesList, SPMySQLConnection;
-@class SPTextView, SPTableView, SPTablesList;
-
-#ifndef SP_REFACTOR
@interface SPFieldMapperController : NSWindowController
-#else
-@interface SPFieldMapperController : NSWindowController <NSTokenFieldCellDelegate>
+#ifdef SP_REFACTOR
+<NSTokenFieldCellDelegate>
#endif
{
IBOutlet SPTableView *fieldMapperTableView;
@@ -41,8 +38,8 @@
IBOutlet id rowUpButton;
IBOutlet id rowDownButton;
IBOutlet id recordCountLabel;
- IBOutlet id importFieldNamesHeaderSwitch;
- IBOutlet id addRemainingDataSwitch;
+ IBOutlet NSButton *importFieldNamesHeaderSwitch;
+ IBOutlet NSButton *addRemainingDataSwitch;
IBOutlet id importButton;
IBOutlet id advancedBox;
IBOutlet NSPopUpButton *alignByPopup;
@@ -65,20 +62,20 @@
IBOutlet NSButton *addGlobalValueButton;
IBOutlet NSButton *removeGlobalValueButton;
IBOutlet NSButton *insertNULLValueButton;
- IBOutlet id replaceAfterSavingCheckBox;
+ IBOutlet NSButton *replaceAfterSavingCheckBox;
IBOutlet NSPopUpButton *insertPullDownButton;
IBOutlet NSMenu *recentGlobalValueMenu;
- IBOutlet id ignoreCheckBox;
- IBOutlet id ignoreUpdateCheckBox;
- IBOutlet id delayedCheckBox;
- IBOutlet id delayedReplaceCheckBox;
- IBOutlet id onupdateCheckBox;
- IBOutlet id lowPriorityCheckBox;
- IBOutlet id lowPriorityReplaceCheckBox;
- IBOutlet id lowPriorityUpdateCheckBox;
- IBOutlet id highPriorityCheckBox;
- IBOutlet id skipexistingRowsCheckBox;
+ IBOutlet NSButton *ignoreCheckBox;
+ IBOutlet NSButton *ignoreUpdateCheckBox;
+ IBOutlet NSButton *delayedCheckBox;
+ IBOutlet NSButton *delayedReplaceCheckBox;
+ IBOutlet NSButton *onupdateCheckBox;
+ IBOutlet NSButton *lowPriorityCheckBox;
+ IBOutlet NSButton *lowPriorityReplaceCheckBox;
+ IBOutlet NSButton *lowPriorityUpdateCheckBox;
+ IBOutlet NSButton *highPriorityCheckBox;
+ IBOutlet NSButton *skipexistingRowsCheckBox;
IBOutlet SPTextView *onupdateTextView;
IBOutlet id gobackButton;
@@ -131,7 +128,7 @@
NSString *primaryKeyField;
NSNumber *lastDisabledCSVFieldcolumn;
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
NSString *sourcePath;
@@ -146,7 +143,7 @@
- (id)initWithDelegate:(id)managerDelegate;
-- (void)setConnection:(MCPConnection *)theConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
- (void)setImportDataArray:(id)theFieldMappingImportArray hasHeader:(BOOL)hasHeader isPreview:(BOOL)isPreview;
// Getter methods
diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m
index ae76f8e2..5e97903b 100644
--- a/Source/SPFieldMapperController.m
+++ b/Source/SPFieldMapperController.m
@@ -31,6 +31,7 @@
#import "SPCategoryAdditions.h"
#import "RegexKitLite.h"
#import "SPDatabaseData.h"
+#import "SPMySQL.h"
#define SP_NUMBER_OF_RECORDS_STRING NSLocalizedString(@"%ld of %@%lu records", @"Label showing the index of the selected CSV row")
@@ -232,7 +233,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
#pragma mark -
#pragma mark Setter methods
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
[mySQLConnection retain];
@@ -423,7 +424,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new column '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new column informative message"), [fieldMappingTableColumnNames objectAtIndex:currentIndex], createString, [mySQLConnection getLastErrorMessage]]];
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new column '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new column informative message"), [fieldMappingTableColumnNames objectAtIndex:currentIndex], createString, [mySQLConnection lastErrorMessage]]];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
@@ -473,7 +474,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection getLastErrorMessage]]];
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection lastErrorMessage]]];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil];
@@ -1191,7 +1192,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
[globalValuesSheet makeFirstResponder:globalValuesTableView];
// Replace the current map pair with the last selected global value
- if([replaceAfterSavingCheckBox state] == NSOnState && [globalValuesTableView numberOfSelectedRows] == 1) {
+ if ([replaceAfterSavingCheckBox state] == NSOnState && [globalValuesTableView numberOfSelectedRows] == 1) {
[fieldMappingArray replaceObjectAtIndex:[fieldMapperTableView selectedRow] withObject:[NSNumber numberWithInteger:[globalValuesTableView selectedRow]+numberOfImportColumns]];
@@ -1407,7 +1408,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
CGFloat dist = 1e6f;
for(j=0; j < [fileHeaderNames count]; j++) {
id fileHeaderName = NSArrayObjectAtIndex(fileHeaderNames,j);
- if([fileHeaderName isKindOfClass:[NSNull class]] || [fileHeaderName isSPNotLoaded]) continue;
+ if([fileHeaderName isNSNull] || [fileHeaderName isSPNotLoaded]) continue;
NSString *headerName = [(NSString*)fileHeaderName lowercaseString];
NSString *tableHeadName = [NSArrayObjectAtIndex(tableHeaderNames,i) lowercaseString];
dist = [tableHeadName levenshteinDistanceWithWord:headerName];
@@ -1486,7 +1487,7 @@ static NSString *SPTableViewSqlColumnID = @"sql";
fieldMappingArray = [[NSMutableArray alloc] init];
for (i = 0; i < [fieldMappingTableColumnNames count]; i++) {
if (i < [NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow) count]
- && ![NSArrayObjectAtIndex(NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow), i) isKindOfClass:[NSNull class]]) {
+ && NSArrayObjectAtIndex(NSArrayObjectAtIndex(fieldMappingImportArray, fieldMappingCurrentRow), i) != [NSNull null]) {
value = i;
} else {
value = 0;
diff --git a/Source/SPGeometryDataView.m b/Source/SPGeometryDataView.m
index d68bb57b..3150bc19 100644
--- a/Source/SPGeometryDataView.m
+++ b/Source/SPGeometryDataView.m
@@ -43,7 +43,7 @@
*/
- (id)initWithCoordinates:(NSDictionary*)coord
{
- return [self initWithCoordinates:coord targetDimension:400.0];
+ return [self initWithCoordinates:coord targetDimension:400.0f];
}
/**
@@ -56,7 +56,7 @@
- (id)initWithCoordinates:(NSDictionary*)coord targetDimension:(CGFloat)targetDimension
{
- margin_offset = 10.0;
+ margin_offset = 10.0f;
type = [coord objectForKey:@"type"];
coordinates = [coord objectForKey:@"coordinates"];
@@ -72,7 +72,7 @@
if(maxDim != 0)
zoom_factor = targetDimension/maxDim;
else
- zoom_factor = 1.0;
+ zoom_factor = 1.0f;
width*=zoom_factor;
height*=zoom_factor;
@@ -85,14 +85,14 @@
lineColor = [NSColor blackColor];
borderLineColor = [NSColor grayColor];
- backgroundColor = [NSColor colorWithCalibratedRed:1 green:1 blue:1 alpha:0.96];
+ backgroundColor = [NSColor colorWithCalibratedRed:1 green:1 blue:1 alpha:0.96f];
pointFillColor = [NSColor redColor];
pointStrokeColor = [NSColor grayColor];
- polygonFillColor1 = [NSColor colorWithCalibratedRed:0.0 green:1.0 blue:0.0 alpha:0.1];
- polygonFillColor2 = [NSColor colorWithCalibratedRed:0.0 green:1.0 blue:1.0 alpha:0.1];
- polygonFillColor3 = [NSColor colorWithCalibratedRed:1.0 green:0.0 blue:0.0 alpha:0.1];
+ polygonFillColor1 = [NSColor colorWithCalibratedRed:0.0f green:1.0f blue:0.0f alpha:0.1f];
+ polygonFillColor2 = [NSColor colorWithCalibratedRed:0.0f green:1.0f blue:1.0f alpha:0.1f];
+ polygonFillColor3 = [NSColor colorWithCalibratedRed:1.0f green:0.0f blue:0.0f alpha:0.1f];
- lineWidth = 1.0;
+ lineWidth = 1.0f;
return self;
}
@@ -109,7 +109,7 @@
// Draw a rect as border
path = [NSBezierPath bezierPathWithRect:[self bounds]];
- [path setLineWidth:0.1];
+ [path setLineWidth:0.1f];
[backgroundColor set];
[path fill];
[borderLineColor set];
diff --git a/Source/SPIndexesController.h b/Source/SPIndexesController.h
index bbe34f28..e014a4a7 100644
--- a/Source/SPIndexesController.h
+++ b/Source/SPIndexesController.h
@@ -23,9 +23,16 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, SPTableView, MCPConnection, BWAnchoredButtonBar;
+#ifndef SP_REFACTOR
+@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, SPMySQLConnection, BWAnchoredButtonBar, SPTableView;
+#else
+@class SPDatabaseDocument, SPTablesList, SPTableData, SPTableStructure, SPMySQLConnection, SPTableView;
+#endif
@interface SPIndexesController : NSWindowController
+#ifdef SP_REFACTOR
+<NSTableViewDelegate, NSTableViewDataSource>
+#endif
{
// Controllers
IBOutlet SPDatabaseDocument *dbDocument;
@@ -49,6 +56,7 @@
IBOutlet NSButton *addIndexedColumnButton;
IBOutlet NSButton *removeIndexedColumnButton;
IBOutlet NSButton *confirmAddIndexButton;
+#ifndef SP_REFACTOR
IBOutlet BWAnchoredButtonBar *anchoredButtonBar;
// Advanced options view
@@ -57,6 +65,7 @@
IBOutlet NSButton *indexAdvancedOptionsViewLabelButton;
IBOutlet NSPopUpButton *indexStorageTypePopUpButton;
IBOutlet NSTextField *indexKeyBlockSizeTextField;
+#endif
BOOL _mainNibLoaded;
NSString *table;
@@ -68,15 +77,26 @@
NSUserDefaults *prefs;
#endif
- MCPConnection *connection;
+ SPMySQLConnection *connection;
+#ifndef SP_REFACTOR /* ivars */
BOOL showAdvancedView;
NSInteger heightOffset;
NSUInteger windowMinWidth;
NSUInteger windowMinHeigth;
+#endif
}
+#ifdef SP_REFACTOR
+@property (assign) SPTableView* indexesTableView;
+@property (assign) SPTableStructure* tableStructure;
+@property (assign) NSButton* addIndexButton;
+@property (assign) NSButton* removeIndexButton;
+
+- (void)setDatabaseDocument:(SPDatabaseDocument*)db;
+#endif
+
/**
* @property table The table currently being viewed
*/
@@ -85,7 +105,7 @@
/**
* @property connection The MySQL connection to use
*/
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
- (IBAction)addIndex:(id)sender;
- (IBAction)removeIndex:(id)sender;
diff --git a/Source/SPIndexesController.m b/Source/SPIndexesController.m
index 8bdfb5bc..def31ea2 100644
--- a/Source/SPIndexesController.m
+++ b/Source/SPIndexesController.m
@@ -28,7 +28,7 @@
#import "SPServerSupport.h"
#import "SPTableContent.h"
#import "SPTableData.h"
-#import <MCPKit/MCPKit.h>
+#import "SPMySQL.h"
#import "SPDatabaseDocument.h"
#import "SPTablesList.h"
#import "SPTableView.h"
@@ -833,9 +833,9 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize";
[tempIndexedColumns release];
// Check for errors, but only if the query wasn't cancelled
- if ([connection queryErrored] && ![connection queryCancelled]) {
+ if ([connection queryErrored] && ![connection lastQueryWasCancelled]) {
SPBeginAlertSheet(NSLocalizedString(@"Unable to add index", @"add index error message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [dbDocument parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to add the index.\n\nMySQL said: %@", @"add index error informative message"), [connection lastErrorMessage]]);
}
else {
[tableData resetAllData];
@@ -889,11 +889,11 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize";
[connection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [table backtickQuotedString], [constraintName backtickQuotedString]]];
// Check for errors, but only if the query wasn't cancelled
- if ([connection queryErrored] && ![connection queryCancelled]) {
+ if ([connection queryErrored] && ![connection lastQueryWasCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"];
- [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), constraintName, [connection getLastErrorMessage]] forKey:@"message"];
+ [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), constraintName, [connection lastErrorMessage]] forKey:@"message"];
[(SPTableStructure*)[tableStructure onMainThread] showErrorSheetWith:errorDictionary];
}
@@ -908,11 +908,11 @@ static const NSString *SPNewIndexKeyBlockSize = @"IndexKeyBlockSize";
}
// Check for errors, but only if the query wasn't cancelled
- if ([connection queryErrored] && ![connection queryCancelled]) {
+ if ([connection queryErrored] && ![connection lastQueryWasCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Unable to delete index", @"error deleting index message") forKey:@"title"];
- [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to delete the index.\n\nMySQL said: %@", @"error deleting index informative message"), [connection getLastErrorMessage]] forKey:@"message"];
+ [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occured while trying to delete the index.\n\nMySQL said: %@", @"error deleting index informative message"), [connection lastErrorMessage]] forKey:@"message"];
[(SPTableStructure*)[tableStructure onMainThread] showErrorSheetWith:errorDictionary];
}
diff --git a/Source/SPLogger.m b/Source/SPLogger.m
index b1e16bba..40bcaa69 100644
--- a/Source/SPLogger.m
+++ b/Source/SPLogger.m
@@ -79,6 +79,7 @@ int _isSPLeaksLog(struct direct *entry);
@synchronized(self) {
return [[self logger] retain];
}
+ return nil;
}
- (id)init
diff --git a/Source/SPNarrowDownCompletion.h b/Source/SPNarrowDownCompletion.h
index 44118380..5c22df2d 100644
--- a/Source/SPNarrowDownCompletion.h
+++ b/Source/SPNarrowDownCompletion.h
@@ -26,6 +26,8 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
+@class SPDatabaseStructure;
+
#ifndef SP_REFACTOR
@interface SPNarrowDownCompletion : NSWindow
#else
@@ -74,6 +76,7 @@
NSMutableCharacterSet* textualInputCharacters;
+ SPDatabaseStructure *databaseStructureRetrieval;
#ifndef SP_REFACTOR
NSUserDefaults *prefs;
#endif
@@ -85,7 +88,7 @@
dictMode:(BOOL)mode dbMode:(BOOL)theDbMode tabTriggerMode:(BOOL)tabTriggerMode fuzzySearch:(BOOL)fuzzySearch
backtickMode:(NSInteger)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName
selectedDb:(NSString*)selectedDb caretMovedLeft:(BOOL)caretMovedLeft autoComplete:(BOOL)autoComplete oneColumn:(BOOL)oneColumn
- alias:(NSString*)anAlias isQueryingDBStructure:(BOOL)isQueryingDBStructure;
+ alias:(NSString*)anAlias withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure;
- (void)setCaretPos:(NSPoint)aPos;
- (void)insert_text:(NSString* )aString;
- (void)insertAutocompletePlaceholder;
diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m
index 9079954d..4dc2711d 100644
--- a/Source/SPNarrowDownCompletion.m
+++ b/Source/SPNarrowDownCompletion.m
@@ -35,6 +35,7 @@
#import "RegexKitLite.h"
#import "SPTextView.h"
#import "SPQueryDocumentsController.h"
+#import "SPDatabaseStructure.h"
#pragma mark -
#pragma mark attribute definition
@@ -165,12 +166,20 @@
if(suggestions) [suggestions release];
if (filtered) [filtered release];
+ if (databaseStructureRetrieval) [databaseStructureRetrieval release];
[super dealloc];
}
- (void)close
{
+
+ // Invalidate the timer now to prevent retain cycles preventing deallocation
+ if (stateTimer != nil) {
+ [stateTimer invalidate];
+ [stateTimer release];
+ }
+
closeMe = YES;
[theView setCompletionIsOpen:NO];
[super close];
@@ -186,7 +195,7 @@
timeCounter++;
if(timeCounter > 20) {
timeCounter = 0;
- if(![[theView valueForKeyPath:@"mySQLConnection"] isQueryingDatabaseStructure]) {
+ if(![databaseStructureRetrieval isQueryingDatabaseStructure]) {
isQueryingDatabaseStructure = NO;
if(stateTimer) {
[stateTimer invalidate];
@@ -222,7 +231,7 @@
dictMode:(BOOL)mode dbMode:(BOOL)theDbMode tabTriggerMode:(BOOL)tabTriggerMode fuzzySearch:(BOOL)fuzzySearch
backtickMode:(NSInteger)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName
selectedDb:(NSString*)selectedDb caretMovedLeft:(BOOL)caretMovedLeft autoComplete:(BOOL)autoComplete oneColumn:(BOOL)oneColumn
- alias:(NSString*)anAlias isQueryingDBStructure:(BOOL)isQueryingDBStructure
+ alias:(NSString*)anAlias withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure
{
if((self = [self init]))
{
@@ -238,10 +247,6 @@
theAliasName = anAlias;
oneColumnMode = oneColumn;
- isQueryingDatabaseStructure = isQueryingDBStructure;
-
- if(isQueryingDatabaseStructure)
- stateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.07f target:self selector:@selector(updateSyncArrowStatus) userInfo:nil repeats:YES] retain];
fuzzyMode = fuzzySearch;
if(fuzzyMode)
@@ -299,6 +304,11 @@
if(someAdditionalWordCharacters)
[textualInputCharacters addCharactersInString:someAdditionalWordCharacters];
+ databaseStructureRetrieval = [theDatabaseStructure retain];
+ isQueryingDatabaseStructure = [databaseStructureRetrieval isQueryingDatabaseStructure];
+
+ if(isQueryingDatabaseStructure)
+ stateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.07f target:self selector:@selector(updateSyncArrowStatus) userInfo:nil repeats:YES] retain];
}
return self;
}
diff --git a/Source/SPNavigatorController.h b/Source/SPNavigatorController.h
index 20b3a796..f294b000 100644
--- a/Source/SPNavigatorController.h
+++ b/Source/SPNavigatorController.h
@@ -22,12 +22,12 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPNavigatorOutlineView;
@interface SPNavigatorController : NSWindowController
{
#ifndef SP_REFACTOR /* ivars */
- IBOutlet id outlineSchema2;
+ IBOutlet SPNavigatorOutlineView *outlineSchema2;
IBOutlet id navigatorWindow;
IBOutlet id infoTable;
IBOutlet id searchField;
@@ -70,6 +70,7 @@
- (IBAction)outlineViewAction:(id)sender;
- (IBAction)reloadAllStructures:(id)sender;
- (IBAction)filterTree:(id)sender;
+- (void)reloadAfterFiltering;
- (IBAction)syncButtonAction:(id)sender;
- (void)updateEntriesForConnection:(id)object;
diff --git a/Source/SPNavigatorController.m b/Source/SPNavigatorController.m
index 3435cbcd..2b27a598 100644
--- a/Source/SPNavigatorController.m
+++ b/Source/SPNavigatorController.m
@@ -33,6 +33,8 @@
#import "SPTooltip.h"
#import "SPAppController.h"
#import "SPDatabaseViewController.h"
+#import "SPMySQL.h"
+#import "SPDatabaseStructure.h"
#import <objc/message.h>
#endif
@@ -68,6 +70,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
@synchronized(self) {
return [[self sharedNavigatorController] retain];
}
+ return nil;
}
- (id)init
@@ -114,9 +117,8 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
[functionIcon release];
[fieldIcon release];
#endif
-#ifdef SP_REFACTOR /* patch */
+
[super dealloc];
-#endif
}
/**
* The following base protocol methods are implemented to ensure the singleton status of this class.
@@ -446,12 +448,12 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
[[schemaData objectForKey:connectionName] removeObjectForKey:db];
}
}
- id structureData = [theConnection getDbStructure];
+ id structureData = [[doc databaseStructureRetrieval] structure];
if(structureData && [structureData objectForKey:connectionName] && [[structureData objectForKey:connectionName] isKindOfClass:NSDictionaryClass]) {
for(id item in [[structureData objectForKey:connectionName] allKeys])
[[schemaData objectForKey:connectionName] setObject:[[structureData objectForKey:connectionName] objectForKey:item] forKey:item];
- NSArray *a = [theConnection getAllKeysOfDbStructure];
+ NSArray *a = [[doc databaseStructureRetrieval] allStructureKeys];
if(a)
[allSchemaKeys setObject:a forKey:connectionName];
} else {
@@ -796,7 +798,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
[expandStatus2 removeObjectForKey:[[parentObject allKeysForObject:item] objectAtIndex:0]];
}
-- (id)outlineView:(id)outlineView child:(NSInteger)index ofItem:(id)item
+- (id)outlineView:(id)outlineView child:(NSInteger)childIndex ofItem:(id)item
{
if (item == nil) {
@@ -819,7 +821,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
// No parent return the child by using the normal sort routine
if(!parentObject || ![parentObject isKindOfClass:NSDictionaryClass])
- return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)];
+ return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)];
// Get the parent key name for storing
id parentKeys = [parentObject allKeysForObject:item];
@@ -829,26 +831,26 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
// For safety reasons
if(!itemRef)
- return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)];
+ return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)];
// Not yet cached so do it
if(![cachedSortedKeys objectForKey:itemRef])
[cachedSortedKeys setObject:[allKeys sortedArrayUsingFunction:compareStrings context:nil] forKey:itemRef];
- return [item objectForKey:NSArrayObjectAtIndex([cachedSortedKeys objectForKey:itemRef],index)];
+ return [item objectForKey:NSArrayObjectAtIndex([cachedSortedKeys objectForKey:itemRef],childIndex)];
}
// If something failed return the child by using the normal way
- return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)];
+ return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)];
} else {
- return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],index)];
+ return [item objectForKey:NSArrayObjectAtIndex([allKeys sortedArrayUsingFunction:compareStrings context:nil],childIndex)];
}
}
else if ([item isKindOfClass:[NSArray class]])
{
- return NSArrayObjectAtIndex(item,index);
+ return NSArrayObjectAtIndex(item,childIndex);
}
return nil;
@@ -1013,9 +1015,9 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
if(!parentObject) return 0;
if([outlineView levelForItem:item] == 3 && [outlineView isExpandable:[outlineView itemAtRow:[outlineView rowForItem:item]-1]])
- return 5.0;
+ return 5.0f;
- return 18.0;
+ return 18.0f;
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldExpandItem:(id)item
@@ -1062,7 +1064,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
NSUInteger i = 0;
for(i=0; i<[selectedItem count]-2; i++) {
NSString *item = NSArrayObjectAtIndex(selectedItem, i);
- if(![item length]) continue;
+ if([item isNSNull] || ![item length]) continue;
[infoArray addObject:[NSString stringWithFormat:@"%@: %@",
[self tableInfoLabelForIndex:i ofType:0],
[item stringByReplacingOccurrencesOfString:@"," withString:@", "]]];
@@ -1160,7 +1162,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
// Use first row as dummy to increase the distance between content and header
- return (row == 0) ? 5.0 : 16.0;
+ return (row == 0) ? 5.0f : 16.0f;
}
- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(NSInteger)rowIndex
@@ -1210,11 +1212,11 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
#pragma mark -
#pragma mark others
-- (NSString*)tableInfoLabelForIndex:(NSInteger)index ofType:(NSInteger)type
+- (NSString*)tableInfoLabelForIndex:(NSInteger)anIndex ofType:(NSInteger)type
{
if(type == 0 || type == 1) // TABLE / VIEW
- switch(index) {
+ switch(anIndex) {
case 0:
return NSLocalizedString(@"Type", @"type label (Navigator)");
case 1:
@@ -1236,7 +1238,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
}
if(type == 2) // PROCEDURE
- switch(index) {
+ switch(anIndex) {
case 0:
return @"DTD Identifier";
case 1:
@@ -1249,7 +1251,7 @@ static NSComparisonResult compareStrings(NSString *s1, NSString *s2, void* conte
return @"Definer";
}
if(type == 3) // FUNCTION
- switch(index) {
+ switch(anIndex) {
case 0:
return NSLocalizedString(@"Return Type", @"return type label (Navigator)");
case 1:
diff --git a/Source/SPNotLoaded.m b/Source/SPNotLoaded.m
index 49e6cbfa..3938823f 100644
--- a/Source/SPNotLoaded.m
+++ b/Source/SPNotLoaded.m
@@ -30,7 +30,7 @@ static SPNotLoaded *notLoaded = nil;
@implementation SPNotLoaded
// Return the singleton object
-+ (SPNotLoaded *) notLoaded
++ (SPNotLoaded *)notLoaded
{
@synchronized(self) {
if (notLoaded == nil) {
@@ -40,16 +40,19 @@ static SPNotLoaded *notLoaded = nil;
return notLoaded;
}
-+ (id) allocWithZone:(NSZone *)zone
++ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self) {
return [[self notLoaded] retain];
}
+
+ return nil;
}
-- (id) init
+- (id)init
{
Class notLoadedClass = [self class];
+
@synchronized(notLoadedClass) {
if (notLoaded == nil) {
if ((self = [super init])) {
@@ -57,18 +60,19 @@ static SPNotLoaded *notLoaded = nil;
}
}
}
+
return notLoaded;
}
-- (id) copyWithZone:(NSZone *)zone { return self; }
+- (id)copyWithZone:(NSZone *)zone { return self; }
-- (id) retain { return self; }
+- (id)retain { return self; }
-- (NSUInteger) retainCount { return NSUIntegerMax; }
+- (NSUInteger)retainCount { return NSUIntegerMax; }
-- (oneway void) release {}
+- (oneway void)release {}
-- (id) autorelease { return self; }
+- (id)autorelease { return self; }
@end
@@ -78,11 +82,13 @@ static SPNotLoaded *notLoaded = nil;
*/
@implementation NSObject (SPNotLoadedTest)
-- (BOOL) isSPNotLoaded
+- (BOOL)isSPNotLoaded
{
static id SPNotLoadedForComparison;
+
if (!SPNotLoadedForComparison) SPNotLoadedForComparison = [SPNotLoaded notLoaded];
- return (self == SPNotLoadedForComparison);
+
+ return (self == SPNotLoadedForComparison);
}
@end
diff --git a/Source/SPObjectAdditions.h b/Source/SPObjectAdditions.h
new file mode 100644
index 00000000..215354b5
--- /dev/null
+++ b/Source/SPObjectAdditions.h
@@ -0,0 +1,31 @@
+//
+// $Id$
+//
+// SPObjectAdditions.h
+// sequel-pro
+//
+// Created by Rowan Beentje (rowan.beent.je) on February 22, 2012
+// Copyright (c) 2012 Rowan Beentje. 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; either version 2 of the License, or
+// (at your option) any later version.
+//
+// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+@interface NSObject (SPObjectAdditions)
+
+// Detect whether an object is a NSNull instance
+- (BOOL)isNSNull;
+
+@end
diff --git a/Source/SPObjectAdditions.m b/Source/SPObjectAdditions.m
new file mode 100644
index 00000000..de762f59
--- /dev/null
+++ b/Source/SPObjectAdditions.m
@@ -0,0 +1,40 @@
+//
+// $Id$
+//
+// SPObjectAdditions.m
+// sequel-pro
+//
+// Created by Rowan Beentje (rowan.beent.je) on February 22, 2012
+// Copyright (c) 2012 Rowan Beentje. 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; either version 2 of the License, or
+// (at your option) any later version.
+//
+// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+@implementation NSObject (SPObjectAdditions)
+
+/**
+ * Detect whether an object is a NSNull instance
+ */
+- (BOOL)isNSNull
+{
+ id const null = [NSNull null];
+
+ // [NSNull null] is documented as being a singleton class so a pointer equality
+ // check is possible - and much faster than checking class membership.
+ return (self == null);
+}
+
+@end
diff --git a/Source/SPProcessListController.h b/Source/SPProcessListController.h
index df5f48a6..fbbdc906 100644
--- a/Source/SPProcessListController.h
+++ b/Source/SPProcessListController.h
@@ -23,11 +23,11 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPMySQLConnection;
@interface SPProcessListController : NSWindowController
{
- MCPConnection *connection;
+ SPMySQLConnection *connection;
BOOL showFullProcessList, processListThreadRunning;
@@ -49,7 +49,7 @@
IBOutlet NSMenuItem *autoRefreshIntervalMenuItem;
}
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
- (IBAction)copy:(id)sender;
- (IBAction)closeSheet:(id)sender;
@@ -57,9 +57,9 @@
- (IBAction)saveServerProcesses:(id)sender;
- (IBAction)killProcessQuery:(id)sender;
- (IBAction)killProcessConnection:(id)sender;
-- (IBAction)toggleShowProcessID:(id)sender;
-- (IBAction)toggeleShowFullProcessList:(id)sender;
-- (IBAction)toggleProcessListAutoRefresh:(id)sender;
+- (IBAction)toggleShowProcessID:(NSMenuItem *)sender;
+- (IBAction)toggeleShowFullProcessList:(NSMenuItem *)sender;
+- (IBAction)toggleProcessListAutoRefresh:(NSButton *)sender;
- (IBAction)setAutoRefreshInterval:(id)sender;
- (IBAction)setCustomAutoRefreshInterval:(id)sender;
diff --git a/Source/SPProcessListController.m b/Source/SPProcessListController.m
index 382940a1..c8e1f312 100644
--- a/Source/SPProcessListController.m
+++ b/Source/SPProcessListController.m
@@ -27,6 +27,7 @@
#import "SPDatabaseDocument.h"
#import "SPAlertSheets.h"
#import "SPAppController.h"
+#import "SPMySQL.h"
// Constants
static NSString *SPKillProcessQueryMode = @"SPKillProcessQueryMode";
@@ -100,7 +101,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
// Also, if available restore the table's column widths
NSNumber *columnWidth = [[prefs objectForKey:SPProcessListTableColumnWidths] objectForKey:[[column headerCell] stringValue]];
- if (columnWidth) [column setWidth:[columnWidth doubleValue]];
+ if (columnWidth) [column setWidth:[columnWidth floatValue]];
}
// Register as an observer for the when the UseMonospacedFonts preference changes
@@ -287,7 +288,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
/**
* Toggles the display of the process ID table column.
*/
-- (IBAction)toggleShowProcessID:(id)sender
+- (IBAction)toggleShowProcessID:(NSMenuItem *)sender
{
[[processListTableView tableColumnWithIdentifier:SPTableViewIDColumnIdentifier] setHidden:([sender state])];
}
@@ -295,7 +296,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
/**
* Toggles the display of the FULL process list.
*/
-- (IBAction)toggeleShowFullProcessList:(id)sender
+- (IBAction)toggeleShowFullProcessList:(NSMenuItem *)sender
{
showFullProcessList = (!showFullProcessList);
@@ -305,7 +306,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
/**
* Toggles whether or not auto refresh is enabled.
*/
-- (IBAction)toggleProcessListAutoRefresh:(id)sender
+- (IBAction)toggleProcessListAutoRefresh:(NSButton *)sender
{
BOOL enable = [sender state];
@@ -690,18 +691,16 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
// Get processes
if ([connection isConnected]) {
- MCPResult *processList = (showFullProcessList) ? [connection queryString:@"SHOW FULL PROCESSLIST"] : [connection listProcesses];
+ SPMySQLResult *processList = (showFullProcessList) ? [connection queryString:@"SHOW FULL PROCESSLIST"] : [connection listProcesses];
[processList setReturnDataAsStrings:YES];
-
- if ([processList numOfRows]) [processList dataSeek:0];
-
+
[processes removeAllObjects];
- for (i = 0; i < [processList numOfRows]; i++)
+ for (i = 0; i < [processList numberOfRows]; i++)
{
- //MCPKit currently returns numbers as NSString, which will break sorting of numbers in this case.
- NSMutableDictionary *rowsFixed = [[processList fetchRowAsDictionary] mutableCopy];
+ //SPMySQL.framewokr currently returns numbers as NSString, which will break sorting of numbers in this case.
+ NSMutableDictionary *rowsFixed = [[processList getRowAsDictionary] mutableCopy];
id idColumn = [rowsFixed objectForKey:@"Id"];
//Id is a signed int(11) - this is a signed 32 bit int value
@@ -742,7 +741,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
// Check for errors
if ([connection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Unable to kill query", @"error killing query message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill the query associated with connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill the query associated with connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection lastErrorMessage]]);
}
// Refresh the process list
@@ -760,7 +759,7 @@ static NSString *SPTableViewIDColumnIdentifier = @"Id";
// Check for errors
if ([connection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Unable to kill connection", @"error killing connection message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occured while attempting to kill connection %lu.\n\nMySQL said: %@", @"error killing query informative message"), (unsigned long)processId, [connection lastErrorMessage]]);
}
// Refresh the process list
diff --git a/Source/SPQueryController.m b/Source/SPQueryController.m
index 82a19091..6c425bc7 100644
--- a/Source/SPQueryController.m
+++ b/Source/SPQueryController.m
@@ -67,9 +67,7 @@ static SPQueryController *sharedQueryController = nil;
return [[self sharedQueryController] retain];
}
-#ifdef SP_REFACTOR
- return nil; // only here to stop clang's 'can reach end of non-void function'
-#endif
+ return nil;
}
- (id)init
diff --git a/Source/SPQueryFavoriteManager.m b/Source/SPQueryFavoriteManager.m
index 28f824fe..1b5ce3dc 100644
--- a/Source/SPQueryFavoriteManager.m
+++ b/Source/SPQueryFavoriteManager.m
@@ -82,18 +82,6 @@
*/
- (void)awakeFromNib
{
- [favoriteQueryTextView setAllowsDocumentBackgroundColorChange:YES];
-
- NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
-
- [bindingOptions setObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
-
- [favoriteQueryTextView bind:@"backgroundColor"
- toObject:[NSUserDefaultsController sharedUserDefaultsController]
- withKeyPath:@"values.CustomQueryEditorBackgroundColor"
- options:bindingOptions];
-
-
[favorites addObject:[NSDictionary dictionaryWithObjectsAndKeys:
@"Global", @"name",
@"", @"headerOfFileURL",
diff --git a/Source/SPSQLExporter.m b/Source/SPSQLExporter.m
index 4c7903fc..607f34d5 100644
--- a/Source/SPSQLExporter.m
+++ b/Source/SPSQLExporter.m
@@ -23,14 +23,13 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPSQLExporter.h"
#import "SPTablesList.h"
#import "SPFileHandle.h"
#import "SPExportUtilities.h"
#import "SPExportFile.h"
#import "SPTableData.h"
+#import "SPMySQL.h"
@interface SPSQLExporter (PrivateAPI)
@@ -86,8 +85,8 @@
sqlTableDataInstance = [[[SPTableData alloc] init] autorelease];
[sqlTableDataInstance setConnection:connection];
- MCPResult *queryResult;
- MCPStreamingResult *streamingResult;
+ SPMySQLResult *queryResult;
+ SPMySQLStreamingResult *streamingResult;
NSArray *row;
NSString *tableName;
@@ -226,8 +225,8 @@
[queryResult setReturnDataAsStrings:YES];
- if ([queryResult numOfRows]) {
- tableDetails = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
+ if ([queryResult numberOfRows]) {
+ tableDetails = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]];
if ([tableDetails objectForKey:@"Create View"]) {
[viewSyntaxes setValue:[[[[tableDetails objectForKey:@"Create View"] copy] autorelease] createViewSyntaxPrettifier] forKey:tableName];
@@ -243,9 +242,9 @@
}
if ([connection queryErrored]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
continue;
}
@@ -291,11 +290,11 @@
}
// Retrieve the number of rows in the table for progress bar drawing
- NSArray *rowArray = [[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [tableName backtickQuotedString]]] fetchRowAsArray];
+ NSArray *rowArray = [[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [tableName backtickQuotedString]]] getRowAsArray];
if ([connection queryErrored] || ![rowArray count]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n\n\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
continue;
}
@@ -307,7 +306,7 @@
// Set up a result set in streaming mode
streamingResult = [[connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [tableName backtickQuotedString]] useLowMemoryBlockingStreaming:([self exportUsingLowMemoryBlockingStreaming])] retain];
- NSArray *fieldNames = [streamingResult fetchFieldNames];
+ NSArray *fieldNames = [streamingResult fieldNames];
// Inform the delegate that we are about to start writing data for the current table
[delegate performSelectorOnMainThread:@selector(sqlExportProcessWillBeginWritingData:) withObject:self waitUntilDone:NO];
@@ -331,7 +330,7 @@
// Inform the delegate that we are about to start writing the data to disk
[delegate performSelectorOnMainThread:@selector(sqlExportProcessWillBeginWritingData:) withObject:self waitUntilDone:NO];
- while ((row = [streamingResult fetchNextRowAsArray]))
+ while ((row = [streamingResult getRowAsArray]))
{
// Check for cancellation flag
if ([self isCancelled]) {
@@ -373,7 +372,7 @@
id object = NSArrayObjectAtIndex(row, t);
// Add NULL values directly to the output row
- if ([object isMemberOfClass:[NSNull class]]) {
+ if (object == [NSNull null]) {
[sqlString appendString:@"NULL"];
}
// If the field is off type BIT, the values need a binary prefix of b'x'.
@@ -384,7 +383,7 @@
else if ([object isKindOfClass:[NSData class]]) {
if ([self sqlOutputEncodeBLOBasHex]) {
- [sqlString appendFormat:@"X'%@'", [connection prepareBinaryData:object]];
+ [sqlString appendString:[connection escapeAndQuoteData:object]];
}
else {
[sqlString appendString:@"'"];
@@ -404,8 +403,8 @@
}
// GEOMETRY data types directly as hex data
- else if ([object isKindOfClass:[MCPGeometryData class]]) {
- [sqlString appendFormat:@"X'%@'", [connection prepareBinaryData:[object data]]];
+ else if ([object isKindOfClass:[SPMySQLGeometryData class]]) {
+ [sqlString appendString:[connection escapeAndQuoteData:[object data]]];
}
else {
[cellValue setString:[object description]];
@@ -420,9 +419,7 @@
}
// Otherwise add a quoted string with special characters escaped
else {
- [sqlString appendString:@"'"];
- [sqlString appendString:[connection prepareString:cellValue]];
- [sqlString appendString:@"'"];
+ [sqlString appendString:[connection escapeAndQuoteString:cellValue]];
}
}
}
@@ -481,10 +478,10 @@
}
if ([connection queryErrored]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
if ([self sqlOutputIncludeErrors]) {
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]]
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]]
dataUsingEncoding:NSUTF8StringEncoding]];
}
}
@@ -494,12 +491,12 @@
[queryResult setReturnDataAsStrings:YES];
- if ([queryResult numOfRows]) {
+ if ([queryResult numberOfRows]) {
[metaString setString:@"\n"];
[metaString appendString:@"DELIMITER ;;\n"];
- for (s = 0; s < [queryResult numOfRows]; s++)
+ for (s = 0; s < [queryResult numberOfRows]; s++)
{
// Check for cancellation flag
if ([self isCancelled]) {
@@ -509,7 +506,7 @@
return;
}
- NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
+ NSDictionary *triggers = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]];
// Definer is user@host but we need to escape it to `user`@`host`
NSArray *triggersDefiner = [[triggers objectForKey:@"Definer"] componentsSeparatedByString:@"@"];
@@ -534,10 +531,10 @@
}
if ([connection queryErrored]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
if ([self sqlOutputIncludeErrors]) {
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]]
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]]
dataUsingEncoding:NSUTF8StringEncoding]];
}
}
@@ -591,7 +588,7 @@
[queryResult setReturnDataAsStrings:YES];
- if ([queryResult numOfRows]) {
+ if ([queryResult numberOfRows]) {
[metaString setString:@"\n"];
[metaString appendFormat:@"--\n-- Dumping routines (%@) for database %@\n--\nDELIMITER ;;\n\n", procedureType,
@@ -599,7 +596,7 @@
// Loop through the definitions, exporting if enabled
- for (s = 0; s < [queryResult numOfRows]; s++)
+ for (s = 0; s < [queryResult numberOfRows]; s++)
{
// Check for cancellation flag
if ([self isCancelled]) {
@@ -609,7 +606,7 @@
return;
}
- NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult fetchRowAsDictionary]];
+ NSDictionary *proceduresList = [[NSDictionary alloc] initWithDictionary:[queryResult getRowAsDictionary]];
NSString *procedureName = [NSString stringWithFormat:@"%@", [proceduresList objectForKey:@"Name"]];
// Only proceed if the item is in the list of items
@@ -661,20 +658,20 @@
[NSArrayObjectAtIndex(procedureDefiner, 1) backtickQuotedString]
];
- MCPResult *createProcedureResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW CREATE %@ %@ */;;", procedureType,
+ SPMySQLResult *createProcedureResult = [connection queryString:[NSString stringWithFormat:@"/*!50003 SHOW CREATE %@ %@ */;;", procedureType,
[procedureName backtickQuotedString]]];
[createProcedureResult setReturnDataAsStrings:YES];
if ([connection queryErrored]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
if ([self sqlOutputIncludeErrors]) {
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
}
[proceduresList release];
continue;
}
- NSDictionary *procedureInfo = [[NSDictionary alloc] initWithDictionary:[createProcedureResult fetchRowAsDictionary]];
+ NSDictionary *procedureInfo = [[NSDictionary alloc] initWithDictionary:[createProcedureResult getRowAsDictionary]];
[metaString appendFormat:@"/*!50003 SET SESSION SQL_MODE=\"%@\"*/;;\n", [procedureInfo objectForKey:@"sql_mode"]];
@@ -714,10 +711,10 @@
}
if ([connection queryErrored]) {
- [errors appendFormat:@"%@\n", [connection getLastErrorMessage]];
+ [errors appendFormat:@"%@\n", [connection lastErrorMessage]];
if ([self sqlOutputIncludeErrors]) {
- [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection getLastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
+ [[self exportOutputFile] writeData:[[NSString stringWithFormat:@"# Error: %@\n", [connection lastErrorMessage]] dataUsingEncoding:NSUTF8StringEncoding]];
}
}
@@ -806,7 +803,10 @@
for (j = 0; j < [[column objectForKey:@"values"] count]; j++)
{
- [fieldString appendFormat:@"'%@'%@", [connection prepareString:NSArrayObjectAtIndex([column objectForKey:@"values"], j)], ((j + 1) == [[column objectForKey:@"values"] count]) ? @"" : @","];
+ [fieldString appendString:[connection escapeAndQuoteString:NSArrayObjectAtIndex([column objectForKey:@"values"], j)]];
+ if ((j + 1) != [[column objectForKey:@"values"] count]) {
+ [fieldString appendString:@","];
+ }
}
[fieldString appendString:@")"];
@@ -834,7 +834,7 @@
[fieldString appendString:@" DEFAULT CURRENT_TIMESTAMP"];
}
else {
- [fieldString appendFormat:@" DEFAULT '%@'", [connection prepareString:[column objectForKey:@"default"]]];
+ [fieldString appendFormat:@" DEFAULT %@", [connection escapeAndQuoteString:[column objectForKey:@"default"]]];
}
}
diff --git a/Source/SPSSHTunnel.h b/Source/SPSSHTunnel.h
index bf7fd8a4..231a41a6 100644
--- a/Source/SPSSHTunnel.h
+++ b/Source/SPSSHTunnel.h
@@ -23,9 +23,10 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+#import "SPMySQLConnectionProxy.h"
+#import "SPMySQLConstants.h"
-@interface SPSSHTunnel : NSObject <MCPConnectionProxy>
+@interface SPSSHTunnel : NSObject <SPMySQLConnectionProxy>
{
id delegate;
@@ -78,7 +79,7 @@
- (BOOL)setPasswordKeychainName:(NSString *)theName account:(NSString *)theAccount;
- (BOOL)setPassword:(NSString *)thePassword;
- (BOOL)setKeyFilePath:(NSString *)thePath;
-- (NSInteger)state;
+- (SPMySQLConnectionProxyState)state;
- (NSString *)lastError;
- (NSString *)debugMessages;
- (NSUInteger)localPort;
diff --git a/Source/SPSSHTunnel.m b/Source/SPSSHTunnel.m
index 0c25c181..1d4870b2 100644
--- a/Source/SPSSHTunnel.m
+++ b/Source/SPSSHTunnel.m
@@ -27,6 +27,7 @@
#import "RegexKitLite.h"
#import "SPKeychain.h"
#import "SPAlertSheets.h"
+#import "SPMySQL.h"
#import <netinet/in.h>
@@ -81,7 +82,7 @@
requestedPassphrase = nil;
task = nil;
localPort = 0;
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
requestedResponse = NO;
passwordInKeychain = NO;
@@ -163,12 +164,12 @@
/*
* Get the state of the connection.
*/
-- (NSInteger)state
+- (SPMySQLConnectionProxyState)state
{
// See if an auth dialog is up
if (![answerAvailableLock tryLock]) {
- return PROXY_STATE_WAITING_FOR_AUTH;
+ return SPMySQLProxyWaitingForAuth;
}
[answerAvailableLock unlock];
@@ -204,7 +205,7 @@
{
localPort = 0;
- if (connectionState != PROXY_STATE_IDLE) return;
+ if (connectionState != SPMySQLProxyIdle) return;
[debugMessagesLock lock];
[debugMessages removeAllObjects];
[debugMessagesLock unlock];
@@ -218,18 +219,18 @@
*/
- (void)launchTask:(id) dummy
{
- if (connectionState != PROXY_STATE_IDLE || task) return;
+ if (connectionState != SPMySQLProxyIdle || task) return;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *taskArguments;
NSMutableDictionary *taskEnvironment;
NSString *authenticationAppPath;
- connectionState = PROXY_STATE_CONNECTING;
+ connectionState = SPMySQLProxyConnecting;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
// Enforce a parent window being present for dialogs
if (!parentWindow) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:@"SSH Tunnel started without a parent window. A parent window must be present."];
@@ -279,7 +280,7 @@
// Abort if no local free port could be allocated
if (!localPort || (useHostFallback && !localPortFallback)) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"No local port could be allocated for the SSH Tunnel.", @"SSH tunnel could not be created because no local port could be allocated")];
@@ -379,8 +380,8 @@
object:nil];
// If the task closed unexpectedly, alert appropriately
- if (connectionState != PROXY_STATE_IDLE) {
- connectionState = PROXY_STATE_IDLE;
+ if (connectionState != SPMySQLProxyIdle) {
+ connectionState = SPMySQLProxyIdle;
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel has unexpectedly closed.", @"SSH tunnel unexpectedly closed")];
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
@@ -400,7 +401,7 @@
*/
- (void)disconnect
{
- if (connectionState == PROXY_STATE_IDLE) return;
+ if (connectionState == SPMySQLProxyIdle) return;
// Before terminating the tunnel, check that it's actually running. This is to accommodate tunnels which
// suddenly disappear as a result of network disconnections.
@@ -434,17 +435,17 @@
if ([message rangeOfString:@"Entering interactive session."].location != NSNotFound
|| [message rangeOfString:@"mux_client_request_session: master session id: "].location != NSNotFound)
{
- connectionState = PROXY_STATE_CONNECTED;
+ connectionState = SPMySQLProxyConnected;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
if ([message rangeOfString:@"Connection established"].location != NSNotFound) {
- connectionState = PROXY_STATE_WAITING_FOR_AUTH;
+ connectionState = SPMySQLProxyWaitingForAuth;
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
if ([message rangeOfString:@"bind: Address already in use"].location != NSNotFound) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
[task terminate];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was unable to bind to the local port. This error may occur if you already have an SSH connection to the same server and are using a 'LocalForward' setting in your SSH configuration.\n\nWould you like to fall back to a standard connection to localhost in order to use the existing tunnel?", @"SSH tunnel unable to bind to local port message")];
@@ -452,26 +453,26 @@
}
if ([message rangeOfString:@"closed by remote host." ].location != NSNotFound) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
[task terminate];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was closed 'by the remote host'. This may indicate a networking issue or a network timeout.", @"SSH tunnel was closed by remote host message")];
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
if ([message rangeOfString:@"Permission denied (" ].location != NSNotFound || [message rangeOfString:@"No more authentication methods to try" ].location != NSNotFound) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
[task terminate];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel could not authenticate with the remote host. Please check your password and ensure you still have access.", @"SSH tunnel authentication failed message")];
if (delegate) [delegate performSelectorOnMainThread:stateChangeSelector withObject:self waitUntilDone:NO];
}
if ([message rangeOfString:@"connect failed: Connection refused" ].location != NSNotFound) {
- connectionState = PROXY_STATE_FORWARDING_FAILED;
+ connectionState = SPMySQLProxyForwardingFailed;
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithString:NSLocalizedString(@"The SSH Tunnel was established successfully, but could not forward data to the remote port as the remote port refused the connection.", @"SSH tunnel forwarding port connection refused message")];
}
if ([message rangeOfString:@"Operation timed out" ].location != NSNotFound) {
- connectionState = PROXY_STATE_IDLE;
+ connectionState = SPMySQLProxyIdle;
[task terminate];
if (lastError) [lastError release];
lastError = [[NSString alloc] initWithFormat:NSLocalizedString(@"The SSH Tunnel was unable to connect to host %@, or the request timed out.\n\nBe sure that the address is correct and that you have the necessary privileges, or try increasing the connection timeout (currently %ld seconds).", @"SSH tunnel failed or timed out message"), sshHost, (long)[[[NSUserDefaults standardUserDefaults] objectForKey:SPConnectionTimeoutValue] integerValue]];
@@ -480,7 +481,7 @@
}
}
- if (connectionState != PROXY_STATE_IDLE) {
+ if (connectionState != SPMySQLProxyIdle) {
[[standardError fileHandleForReading] waitForDataInBackgroundAndNotify];
}
@@ -674,7 +675,7 @@
{
delegate = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
- if (connectionState != PROXY_STATE_IDLE) [self disconnect];
+ if (connectionState != SPMySQLProxyIdle) [self disconnect];
[sshHost release];
[sshLogin release];
[remoteHost release];
diff --git a/Source/SPServerVariablesController.h b/Source/SPServerVariablesController.h
index 3e87609a..2f882df5 100644
--- a/Source/SPServerVariablesController.h
+++ b/Source/SPServerVariablesController.h
@@ -23,11 +23,11 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
+@class SPMySQLConnection;
@interface SPServerVariablesController : NSWindowController
{
- MCPConnection *connection;
+ SPMySQLConnection *connection;
NSMutableArray *variables, *variablesFiltered;
@@ -37,7 +37,7 @@
IBOutlet NSSearchField *filterVariablesSearchField;
}
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
- (IBAction)copy:(id)sender;
- (IBAction)copyServerVariableName:(id)sender;
diff --git a/Source/SPServerVariablesController.m b/Source/SPServerVariablesController.m
index 5b9114d8..50f03e31 100644
--- a/Source/SPServerVariablesController.m
+++ b/Source/SPServerVariablesController.m
@@ -26,6 +26,7 @@
#import "SPServerVariablesController.h"
#import "SPDatabaseDocument.h"
#import "SPAppController.h"
+#import "SPMySQL.h"
@interface SPServerVariablesController (PrivateAPI)
@@ -287,20 +288,13 @@
*/
- (void)_getDatabaseServerVariables
{
- NSUInteger i = 0;
// Get processes
- MCPResult *serverVariables = [connection queryString:@"SHOW VARIABLES"];
+ SPMySQLResult *serverVariables = [connection queryString:@"SHOW VARIABLES"];
[serverVariables setReturnDataAsStrings:YES];
- if ([serverVariables numOfRows]) [serverVariables dataSeek:0];
-
[variables removeAllObjects];
-
- for (i = 0; i < [serverVariables numOfRows]; i++)
- {
- [variables addObject:[serverVariables fetchRowAsDictionary]];
- }
+ [variables addObjectsFromArray:[serverVariables getAllRows]];
}
/**
diff --git a/Source/SPTableContent.h b/Source/SPTableContent.h
index 90cfc40c..a95dbae3 100644
--- a/Source/SPTableContent.h
+++ b/Source/SPTableContent.h
@@ -25,9 +25,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPDatabaseDocument, SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView, SPFieldEditorController;
+@class SPDatabaseDocument, SPCopyTable, SPTextAndLinkCell, SPHistoryController, SPTableInfo, SPDataStorage, SPTextView, SPFieldEditorController, SPMySQLConnection, SPMySQLFastStreamingResult;
@class SPTableData, SPDatabaseDocument, SPTablesList, SPTableStructure, SPTableList, SPContentFilterManager;
@interface SPTableContent : NSObject
@@ -55,7 +53,7 @@
IBOutlet id removeButton;
IBOutlet id reloadButton;
#ifndef SP_REFACTOR
- IBOutlet id multipleLineEditingButton;
+ IBOutlet NSButton *multipleLineEditingButton;
IBOutlet id countText;
IBOutlet id limitRowsField;
IBOutlet id limitRowsButton;
@@ -90,7 +88,7 @@
IBOutlet NSPanel *filterTableSetDefaultOperatorSheet;
IBOutlet NSComboBox* filterTableSetDefaultOperatorValue;
#endif
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
BOOL _mainNibLoaded;
BOOL isWorking;
@@ -182,7 +180,7 @@
// Pagination
- (IBAction) navigatePaginationFromButton:(id)sender;
#ifndef SP_REFACTOR
-- (IBAction) togglePagination:(id)sender;
+- (IBAction) togglePagination:(NSButton *)sender;
#endif
- (void) setPaginationViewVisibility:(BOOL)makeVisible;
- (void) updatePaginationState;
@@ -213,11 +211,11 @@
- (void) endDocumentTaskForTab:(NSNotification *)aNotification;
// Additional methods
-- (void)setConnection:(MCPConnection *)theConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
- (void)clickLinkArrow:(SPTextAndLinkCell *)theArrowCell;
- (void)clickLinkArrowTask:(SPTextAndLinkCell *)theArrowCell;
- (IBAction)setCompareTypes:(id)sender;
-- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount;
+- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount;
- (BOOL)saveRowToTable;
- (void) addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
- (NSString *)argumentForRow:(NSInteger)row;
diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m
index a1ff0daa..11e19588 100644
--- a/Source/SPTableContent.m
+++ b/Source/SPTableContent.m
@@ -37,6 +37,7 @@
#import "SPQueryController.h"
#import "SPQueryDocumentsController.h"
#import "SPTextAndLinkCell.h"
+#import "SPMySQL.h"
#ifndef SP_REFACTOR
#import "QLPreviewPanel.h"
#endif
@@ -53,6 +54,7 @@
#import "SPAppController.h"
#import "SPBundleHTMLOutputController.h"
#import "SPCustomQuery.h"
+#import <pthread.h>
@interface SPTableContent ()
@@ -276,11 +278,7 @@
}
// Post a notification that a query will be performed
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#endif
// Set up the table details for the new table, and trigger an interface update
NSDictionary *tableDetails = [NSDictionary dictionaryWithObjectsAndKeys:
@@ -320,11 +318,7 @@
[[tableContentView onMainThread] setNeedsDisplay:YES];
// Post the notification that the query is finished
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
// Clear any details to restore now that they have been restored
[self clearDetailsToRestore];
@@ -745,7 +739,7 @@
NSMutableString *queryString;
NSString *queryStringBeforeLimit = nil;
NSString *filterString;
- MCPStreamingResult *streamingResult;
+ SPMySQLFastStreamingResult *streamingResult;
NSInteger rowsToLoad = [[tableDataInstance statusValueForKey:@"Rows"] integerValue];
#ifndef SP_REFACTOR
@@ -753,11 +747,7 @@
#endif
// Notify any listeners that a query has started
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#endif
// Start construction of the query string
queryString = [NSMutableString stringWithFormat:@"SELECT %@%@ FROM %@",
@@ -817,7 +807,7 @@
// Ensure the number of columns are unchanged; if the column count has changed, abort the load
// and queue a full table reload.
BOOL fullTableReloadRequired = NO;
- if (streamingResult && [dataColumns count] != [streamingResult numOfFields]) {
+ if (streamingResult && [dataColumns count] != [streamingResult numberOfFields]) {
[tableDocumentInstance disableTaskCancellation];
[mySQLConnection cancelCurrentQuery];
[streamingResult cancelResultLoad];
@@ -831,7 +821,7 @@
if (streamingResult) [streamingResult release];
// If the result is empty, and a late page is selected, reset the page
- if (!fullTableReloadRequired && [prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount && ![mySQLConnection queryCancelled]) {
+ if (!fullTableReloadRequired && [prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount && ![mySQLConnection lastQueryWasCancelled]) {
contentPage = 1;
previousTableRowsCount = tableRowsCount;
queryString = [NSMutableString stringWithFormat:@"%@ LIMIT 0,%ld", queryStringBeforeLimit, (long)[prefs integerForKey:SPLimitResultsValue]];
@@ -843,7 +833,7 @@
}
}
- if ([mySQLConnection queryCancelled] || [mySQLConnection queryErrored])
+ if ([mySQLConnection lastQueryWasCancelled] || [mySQLConnection queryErrored])
isInterruptedLoad = YES;
else
isInterruptedLoad = NO;
@@ -869,26 +859,22 @@
// Retrieve and cache the column definitions for editing views
if (cqColumnDefinition) [cqColumnDefinition release];
- cqColumnDefinition = [[streamingResult fetchResultFieldsStructure] retain];
+ cqColumnDefinition = [[streamingResult fieldDefinitions] retain];
// Notify listenters that the query has finished
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
- if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) {
+ if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) {
#ifndef SP_REFACTOR
if(activeFilter == 0) {
#endif
if(filterString)
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded presumably due to used filter clause. \n\nMySQL said: %@", @"message of panel when loading of table failed and presumably due to used filter argument"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded presumably due to used filter clause. \n\nMySQL said: %@", @"message of panel when loading of table failed and presumably due to used filter argument"), [mySQLConnection lastErrorMessage]]);
else
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded.\n\nMySQL said: %@", @"message of panel when loading of table failed"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"The table data couldn't be loaded.\n\nMySQL said: %@", @"message of panel when loading of table failed"), [mySQLConnection lastErrorMessage]]);
}
#ifndef SP_REFACTOR
// Filter task came from filter table
@@ -910,9 +896,8 @@
/**
* Processes a supplied streaming result set, loading it into the data array.
*/
-- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount
+- (void)processResultIntoDataStorage:(SPMySQLFastStreamingResult *)theResult approximateRowCount:(NSUInteger)targetRowCount
{
- NSArray *tempRow;
NSUInteger i;
NSUInteger dataColumnsCount = [dataColumns count];
BOOL *columnBlobStatuses = malloc(dataColumnsCount * sizeof(BOOL));
@@ -949,13 +934,13 @@
// Loop through the result rows as they become available
tableRowsCount = 0;
- while ((tempRow = [theResult fetchNextRowAsArray])) {
+ for (NSArray *eachRow in theResult) {
pthread_mutex_lock(&tableValuesLock);
if (tableRowsCount < previousTableRowsCount) {
- SPDataStorageReplaceRow(tableValues, tableRowsCount, tempRow);
+ SPDataStorageReplaceRow(tableValues, tableRowsCount, eachRow);
} else {
- SPDataStorageAddRow(tableValues, tempRow);
+ SPDataStorageAddRow(tableValues, eachRow);
}
// Alter the values for hidden blob and text fields if appropriate
@@ -1569,7 +1554,7 @@
* layer depending on the current state.
*/
#ifndef SP_REFACTOR
-- (IBAction) togglePagination:(id)sender
+- (IBAction) togglePagination:(NSButton *)sender
{
if ([sender state] == NSOnState) [self setPaginationViewVisibility:YES];
else [self setPaginationViewVisibility:NO];
@@ -1660,7 +1645,6 @@
- (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database includeBlobs:(BOOL)includeBlobs
{
NSArray *dataRow;
- NSDictionary *theRow;
id field;
NSMutableArray *argumentParts = [NSMutableArray array];
@@ -1675,17 +1659,14 @@
dataRow = [tableValues rowContentsAtIndex:rowIndex];
// Get the primary key if there is one, using any columns present within it
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@",
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@.%@",
[database backtickQuotedString], [tableForColumn backtickQuotedString]]];
[theResult setReturnDataAsStrings:YES];
- if ([theResult numOfRows]) [theResult dataSeek:0];
NSMutableArray *primaryColumnsInSpecifiedTable = [NSMutableArray array];
- NSUInteger i;
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
- theRow = [theResult fetchRowAsDictionary];
- if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
+ for (NSDictionary *eachRow in theResult) {
+ if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
for (field in columnsInSpecifiedTable) {
- if([[field objectForKey:@"org_name"] isEqualToString:[theRow objectForKey:@"Field"]]) {
+ if([[field objectForKey:@"org_name"] isEqualToString:[eachRow objectForKey:@"Field"]]) {
[primaryColumnsInSpecifiedTable addObject:field];
}
}
@@ -1698,7 +1679,7 @@
// Build up the argument
for (field in columnsToQuery) {
id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] integerValue]];
- if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) {
+ if ([aValue isNSNull]) {
[argumentParts addObject:[NSString stringWithFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]]];
} else {
NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"];
@@ -1718,14 +1699,14 @@
[argumentParts addObject:[NSString stringWithFormat:@"%@=b'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]];
}
else if ([fieldTypeGrouping isEqualToString:@"geometry"]) {
- [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:[aValue data]]]];
}
// BLOB/TEXT data
else if ([aValue isKindOfClass:[NSData class]]) {
- [argumentParts addObject:[NSString stringWithFormat:@"%@=X'%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteData:aValue]]];
}
else {
- [argumentParts addObject:[NSString stringWithFormat:@"%@='%@'", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]];
+ [argumentParts addObject:[NSString stringWithFormat:@"%@=%@", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection escapeAndQuoteString:aValue]]];
}
}
}
@@ -1790,7 +1771,7 @@
- (IBAction)duplicateRow:(id)sender
{
NSMutableArray *tempRow;
- MCPResult *queryResult;
+ SPMySQLResult *queryResult;
NSDictionary *row;
NSArray *dbDataRow = nil;
NSUInteger i;
@@ -1819,7 +1800,7 @@
// If we have indexes, use argumentForRow
queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@", [selectedTable backtickQuotedString], [self argumentForRow:[tableContentView selectedRow]]]];
- dbDataRow = [queryResult fetchRowAsArray];
+ dbDataRow = [queryResult getRowAsArray];
}
#endif
@@ -1827,12 +1808,10 @@
queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
[queryResult setReturnDataAsStrings:YES];
-
- if ([queryResult numOfRows]) [queryResult dataSeek:0];
-
- for (i = 0; i < [queryResult numOfRows]; i++)
+
+ for (i = 0; i < [queryResult numberOfRows]; i++)
{
- row = [queryResult fetchRowAsDictionary];
+ row = [queryResult getRowAsDictionary];
if ([[row objectForKey:@"Extra"] isEqualToString:@"auto_increment"]) {
[tempRow replaceObjectAtIndex:i withObject:[NSNull null]];
@@ -1904,7 +1883,7 @@
contextInfo = @"removeallrows";
// If table has PRIMARY KEY ask for resetting the auto increment after deletion if given
- if(![[tableDataInstance statusValueForKey:@"Auto_increment"] isKindOfClass:[NSNull class]]) {
+ if(![[tableDataInstance statusValueForKey:@"Auto_increment"] isNSNull]) {
[alert setShowsSuppressionButton:YES];
#ifndef SP_REFACTOR
[[alert suppressionButton] setState:([prefs boolForKey:SPResetAutoIncrementAfterDeletionOfAllRows]) ? NSOnState : NSOffState];
@@ -1980,7 +1959,7 @@
[self performSelector:@selector(showErrorSheetWith:)
withObject:[NSArray arrayWithObjects:NSLocalizedString(@"Error", @"error"),
[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete rows.\n\nMySQL said: %@", @"message when deleteing all rows failed"),
- [mySQLConnection getLastErrorMessage]],
+ [mySQLConnection lastErrorMessage]],
nil]
afterDelay:0.3];
}
@@ -2029,18 +2008,17 @@
primaryKeyFieldNames = [tableDataInstance columnNames];
NSInteger numberOfRows = 0;
+
// Get the number of rows in the table
- MCPResult *r;
- r = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]];
- if (![mySQLConnection queryErrored]) {
- NSArray *a = [r fetchRowAsArray];
- if([a count])
- numberOfRows = [[a objectAtIndex:0] integerValue];
+ NSString *returnedCount = [mySQLConnection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]];
+ if (returnedCount) {
+ numberOfRows = [returnedCount integerValue];
}
+
// Check for uniqueness via LIMIT numberOfRows-1,numberOfRows for speed
if(numberOfRows > 0) {
[mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ GROUP BY %@ LIMIT %ld,%ld", [selectedTable backtickQuotedString], [primaryKeyFieldNames componentsJoinedAndBacktickQuoted], (long)(numberOfRows-1), (long)numberOfRows]];
- if([mySQLConnection affectedRows] == 0)
+ if ([mySQLConnection rowsAffectedByLastQuery] == 0)
primaryKeyFieldNames = nil;
} else {
primaryKeyFieldNames = nil;
@@ -2058,7 +2036,7 @@
[mySQLConnection queryString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", [selectedTable backtickQuotedString], wherePart]];
// Check for errors
- if ( ![mySQLConnection affectedRows] || [mySQLConnection queryErrored]) {
+ if ( ![mySQLConnection rowsAffectedByLastQuery] || [mySQLConnection queryErrored]) {
// If error delete that index from selectedRows for reloading table if
// "ReloadAfterRemovingRow" is disbaled
if(!reloadAfterRemovingRow)
@@ -2086,9 +2064,9 @@
id keyValue = [tableValues cellDataAtRow:anIndex column:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(primaryKeyFieldNames,0)] objectForKey:@"datacolumnindex"] integerValue]];
if([keyValue isKindOfClass:[NSData class]])
- [deleteQuery appendFormat:@"X'%@'", [mySQLConnection prepareBinaryData:keyValue]];
+ [deleteQuery appendString:[mySQLConnection escapeAndQuoteData:keyValue]];
else
- [deleteQuery appendFormat:@"'%@'", [keyValue description]];
+ [deleteQuery appendString:[mySQLConnection escapeAndQuoteString:[keyValue description]]];
// Split deletion query into 256k chunks
if([deleteQuery length] > 256000) {
@@ -2096,7 +2074,7 @@
[mySQLConnection queryString:deleteQuery];
// Remember affected rows for error checking
- affectedRows += (NSInteger)[mySQLConnection affectedRows];
+ affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery];
// Reinit a new deletion query
[deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@ IN (", [selectedTable backtickQuotedString], [NSArrayObjectAtIndex(primaryKeyFieldNames,0) backtickQuotedString]]];
@@ -2115,7 +2093,7 @@
[mySQLConnection queryString:deleteQuery];
// Remember affected rows for error checking
- affectedRows += (NSInteger)[mySQLConnection affectedRows];
+ affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery];
}
errors = (affectedRows > 0) ? [selectedRows count] - affectedRows : [selectedRows count];
@@ -2139,7 +2117,7 @@
[mySQLConnection queryString:deleteQuery];
// Remember affected rows for error checking
- affectedRows += (NSInteger)[mySQLConnection affectedRows];
+ affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery];
// Reinit a new deletion query
[deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE ", [selectedTable backtickQuotedString]]];
@@ -2159,7 +2137,7 @@
[mySQLConnection queryString:deleteQuery];
// Remember affected rows for error checking
- affectedRows += (NSInteger)[mySQLConnection affectedRows];
+ affectedRows += (NSInteger)[mySQLConnection rowsAffectedByLastQuery];
}
errors = (affectedRows > 0) ? [selectedRows count] - affectedRows : [selectedRows count];
@@ -2274,7 +2252,7 @@
else if([o isKindOfClass:[NSString class]]) {
[tempRow addObject:[o description]];
}
- else if([o isKindOfClass:[MCPGeometryData class]]) {
+ else if([o isKindOfClass:[SPMySQLGeometryData class]]) {
SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[o coordinates]];
NSImage *image = [v thumbnailImage];
NSString *imageStr = @"";
@@ -2370,7 +2348,7 @@
/**
* Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once
*/
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
@@ -2697,20 +2675,20 @@
// Convert geometry values to their string values
} else if ([fieldTypeGroup isEqualToString:@"geometry"]) {
- fieldValue = ([rowObject isKindOfClass:[MCPGeometryData class]]) ? [[rowObject wktString] getGeomFromTextString] : [(NSString*)rowObject getGeomFromTextString];
+ fieldValue = ([rowObject isKindOfClass:[SPMySQLGeometryData class]]) ? [[rowObject wktString] getGeomFromTextString] : [(NSString*)rowObject getGeomFromTextString];
// Convert the object to a string (here we can add special treatment for date-, number- and data-fields)
} else {
// I believe these class matches are not ever met at present.
if ([rowObject isKindOfClass:[NSCalendarDate class]]) {
- fieldValue = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[rowObject description]]];
+ fieldValue = [mySQLConnection escapeAndQuoteString:[rowObject description]];
} else if ([rowObject isKindOfClass:[NSNumber class]]) {
fieldValue = [rowObject stringValue];
// Convert data to its hex representation
} else if ([rowObject isKindOfClass:[NSData class]]) {
- fieldValue = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:rowObject]];
+ fieldValue = [mySQLConnection escapeAndQuoteData:rowObject];
} else {
if ([[rowObject description] isEqualToString:@"CURRENT_TIMESTAMP"]) {
@@ -2720,7 +2698,7 @@
} else if ([fieldTypeGroup isEqualToString:@"date"] && [[rowObject description] isEqualToString:@"NOW()"]) {
fieldValue = @"NOW()";
} else {
- fieldValue = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[rowObject description]]];
+ fieldValue = [mySQLConnection escapeAndQuoteString:[rowObject description]];
}
}
}
@@ -2730,11 +2708,8 @@
[rowValuesToSave addObject:fieldValue];
}
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#endif
+
NSMutableString *queryString;
// Use INSERT syntax when creating new rows
@@ -2760,14 +2735,10 @@
// Run the query
[mySQLConnection queryString:queryString];
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
// If no rows have been changed, show error if appropriate.
- if ( ![mySQLConnection affectedRows] && ![mySQLConnection queryErrored] ) {
+ if ( ![mySQLConnection rowsAffectedByLastQuery] && ![mySQLConnection queryErrored] ) {
#ifndef SP_REFACTOR
if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) {
SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
@@ -2809,7 +2780,7 @@
// Set the insertId for fields with auto_increment
for ( i = 0; i < [dataColumns count] ; i++ ) {
if ([[NSArrayObjectAtIndex(dataColumns, i) objectForKey:@"autoincrement"] integerValue]) {
- [tableValues replaceObjectInRow:currentlyEditingRow column:i withObject:[[NSNumber numberWithUnsignedLongLong:[mySQLConnection insertId]] description]];
+ [tableValues replaceObjectInRow:currentlyEditingRow column:i withObject:[[NSNumber numberWithUnsignedLongLong:[mySQLConnection lastInsertID]] description]];
}
}
#ifndef SP_REFACTOR
@@ -2837,7 +2808,7 @@
}
else {
SPBeginAlertSheet(NSLocalizedString(@"Couldn't write row", @"Couldn't write row error"), NSLocalizedString(@"Edit row", @"Edit row button"), NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
- [NSString stringWithFormat:NSLocalizedString(@"MySQL said:\n\n%@", @"message of panel when error while adding row to db"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"MySQL said:\n\n%@", @"message of panel when error while adding row to db"), [mySQLConnection lastErrorMessage]]);
return NO;
}
}
@@ -2942,8 +2913,7 @@
*/
- (NSString *)argumentForRow:(NSInteger)row excludingLimits:(BOOL)excludeLimits
{
- MCPResult *theResult;
- NSDictionary *theRow;
+ SPMySQLResult *theResult;
id tempValue;
NSMutableString *value = [NSMutableString string];
NSMutableString *argument = [NSMutableString string];
@@ -2963,11 +2933,9 @@
keys = [[NSMutableArray alloc] init];
theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
[theResult setReturnDataAsStrings:YES];
- if ([theResult numOfRows]) [theResult dataSeek:0];
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
- theRow = [theResult fetchRowAsDictionary];
- if ( [[theRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
- [keys addObject:[theRow objectForKey:@"Field"]];
+ for (NSDictionary *eachRow in theResult) {
+ if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
+ [keys addObject:[eachRow objectForKey:@"Field"]];
}
}
}
@@ -3015,17 +2983,17 @@
else {
// If the field is of type BIT then it needs a binary prefix
if ([[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"type"] isEqualToString:@"BIT"]) {
- [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection prepareString:tempValue]]];
+ [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection escapeString:tempValue includingQuotes:NO]]];
}
- else if ([tempValue isKindOfClass:[MCPGeometryData class]]) {
- [value setString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:[tempValue data]]]];
+ else if ([tempValue isKindOfClass:[SPMySQLGeometryData class]]) {
+ [value setString:[mySQLConnection escapeAndQuoteData:[tempValue data]]];
}
// BLOB/TEXT data
else if ([tempValue isKindOfClass:[NSData class]]) {
- [value setString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:tempValue]]];
+ [value setString:[mySQLConnection escapeAndQuoteData:tempValue]];
}
else
- [value setString:[NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:tempValue]]];
+ [value setString:[mySQLConnection escapeAndQuoteString:tempValue]];
[argument appendFormat:@"%@ = %@", [NSArrayObjectAtIndex(keys, i) backtickQuotedString], value];
}
@@ -3120,7 +3088,7 @@
[tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")];
// Actual check whether field can be identified bijectively
- MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
+ SPMySQLResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
[[columnDefinition objectForKey:@"db"] backtickQuotedString],
[tableForColumn backtickQuotedString],
fieldIDQueryStr]];
@@ -3130,7 +3098,7 @@
return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
}
- NSArray *tempRow = [tempResult fetchRowAsArray];
+ NSArray *tempRow = [tempResult getRowAsArray];
if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] > 1) {
// try to identify the cell by using blob data
@@ -3150,7 +3118,7 @@
return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
}
- tempRow = [tempResult fetchRowAsArray];
+ tempRow = [tempResult getRowAsArray];
if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] < 1) {
[tableDocumentInstance endTask];
@@ -3309,11 +3277,11 @@
NSString *newObject = nil;
if ( [anObject isKindOfClass:[NSCalendarDate class]] ) {
- newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]];
+ newObject = [mySQLConnection escapeAndQuoteString:[anObject description]];
} else if ( [anObject isKindOfClass:[NSNumber class]] ) {
newObject = [anObject stringValue];
} else if ( [anObject isKindOfClass:[NSData class]] ) {
- newObject = [NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:anObject]];
+ newObject = [mySQLConnection escapeAndQuoteData:anObject];
} else {
if ( [[anObject description] isEqualToString:@"CURRENT_TIMESTAMP"] ) {
newObject = @"CURRENT_TIMESTAMP";
@@ -3327,7 +3295,7 @@
&& [[anObject description] isEqualToString:@"NOW()"]) {
newObject = @"NOW()";
} else {
- newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]];
+ newObject = [mySQLConnection escapeAndQuoteString:[anObject description]];
}
}
@@ -3340,7 +3308,7 @@
// Check for errors while UPDATE
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), NSLocalizedString(@"Cancel", @"cancel button"), nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't write field.\nMySQL said: %@", @"message of panel when error while updating field to db"), [mySQLConnection lastErrorMessage]]);
[tableDocumentInstance endTask];
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
@@ -3349,7 +3317,7 @@
// This shouldn't happen – for safety reasons
- if ( ![mySQLConnection affectedRows] ) {
+ if ( ![mySQLConnection rowsAffectedByLastQuery] ) {
#ifndef SP_REFACTOR
if ( [prefs boolForKey:SPShowNoAffectedRowsError] ) {
SPBeginAlertSheet(NSLocalizedString(@"Warning", @"warning"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
@@ -3864,7 +3832,7 @@
*/
- (NSInteger)fetchNumberOfRows
{
- return [[[[mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue];
+ return [[mySQLConnection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [selectedTable backtickQuotedString]]] integerValue];
}
/**
@@ -3951,7 +3919,7 @@
return nil;
}
}
- else if ([theValue isKindOfClass:[MCPGeometryData class]]) {
+ else if ([theValue isKindOfClass:[SPMySQLGeometryData class]]) {
SPGeometryDataView *v = [[SPGeometryDataView alloc] initWithCoordinates:[theValue coordinates]];
image = [v thumbnailImage];
if(image) {
@@ -4035,7 +4003,7 @@
theValue = SPDataStorageObjectAtRowAndColumn(tableValues, rowIndex, columnIndex);
}
- if([theValue isKindOfClass:[MCPGeometryData class]])
+ if([theValue isKindOfClass:[SPMySQLGeometryData class]])
return [theValue wktString];
if ([theValue isNSNull])
@@ -4242,7 +4210,7 @@
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't sort table. MySQL said: %@", @"message of panel when sorting of table failed"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't sort table. MySQL said: %@", @"message of panel when sorting of table failed"), [mySQLConnection lastErrorMessage]]);
[tableDocumentInstance endTask];
[sortPool drain];
return;
@@ -4403,14 +4371,14 @@
// Only get the data for the selected column, not all of them
NSString *query = [NSString stringWithFormat:@"SELECT %@ FROM %@ WHERE %@", [[[aTableColumn headerCell] stringValue] backtickQuotedString], [selectedTable backtickQuotedString], wherePart];
- MCPResult *tempResult = [mySQLConnection queryString:query];
- if (![tempResult numOfRows]) {
+ SPMySQLResult *tempResult = [mySQLConnection queryString:query];
+ if (![tempResult numberOfRows]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
NSLocalizedString(@"Couldn't load the row. Reload the table to be sure that the row exists and use a primary key for your table.", @"message of panel when loading of row failed"));
return NO;
}
- NSArray *tempRow = [tempResult fetchRowAsArray];
+ NSArray *tempRow = [tempResult getRowAsArray];
[tableValues replaceObjectInRow:rowIndex column:[[tableContentView tableColumns] indexOfObject:aTableColumn] withObject:[tempRow objectAtIndex:0]];
[tableContentView reloadData];
}
diff --git a/Source/SPTableCopy.m b/Source/SPTableCopy.m
index d390243c..1059e032 100644
--- a/Source/SPTableCopy.m
+++ b/Source/SPTableCopy.m
@@ -24,6 +24,7 @@
#import "SPDBActionCommons.h"
#import "SPTableCopy.h"
+#import "SPMySQL.h"
@implementation SPTableCopy
@@ -31,10 +32,10 @@
{
NSString *showCreateTableStatment = [NSString stringWithFormat:@"SHOW CREATE TABLE %@.%@", [sourceDB backtickQuotedString], [tableName backtickQuotedString]];
- MCPResult *theResult = [connection queryString:showCreateTableStatment];
+ SPMySQLResult *theResult = [connection queryString:showCreateTableStatment];
- if ([theResult numOfRows] != 0) {
- return [[theResult fetchRowAsArray] objectAtIndex:1];
+ if ([theResult numberOfRows] != 0) {
+ return [[theResult getRowAsArray] objectAtIndex:1];
}
return @"";
diff --git a/Source/SPTableData.h b/Source/SPTableData.h
index b4042527..94c95da4 100644
--- a/Source/SPTableData.h
+++ b/Source/SPTableData.h
@@ -23,10 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPDatabaseDocument;
-@class SPTablesList;
+@class SPDatabaseDocument, SPTablesList, SPMySQLConnection;
@interface SPTableData : NSObject
{
@@ -36,13 +33,13 @@
NSMutableArray *columns;
NSMutableArray *columnNames;
NSMutableArray *constraints;
- NSMutableArray *triggers;
+ NSArray *triggers;
NSMutableDictionary *status;
NSString *tableEncoding;
NSString *tableCreateSyntax;
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
pthread_mutex_t dataProcessingLock;
@@ -51,7 +48,7 @@
@property (readonly, assign) BOOL tableHasAutoIncrementField;
-- (void) setConnection:(MCPConnection *)theConnection;
+- (void) setConnection:(SPMySQLConnection *)theConnection;
- (NSString *) tableEncoding;
- (NSString *) tableCreateSyntax;
- (NSArray *) columns;
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index 297718b9..0c0814d6 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -30,6 +30,8 @@
#import "SPAlertSheets.h"
#import "RegexKitLite.h"
#import "SPServerSupport.h"
+#import "SPMySQL.h"
+#include <pthread.h>
@interface SPTableData (PrivateAPI)
@@ -70,7 +72,7 @@
*
* @param theConnection The used connection for the SPDatabaseDocument
*/
-- (void) setConnection:(MCPConnection *)theConnection
+- (void) setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
[mySQLConnection retain];
@@ -164,7 +166,7 @@
}
}
- return (NSArray *)triggers;
+ return triggers;
}
/**
@@ -476,7 +478,7 @@
[constraints removeAllObjects];
// Retrieve the CREATE TABLE syntax for the table
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE TABLE %@", [tableName backtickQuotedString]]];
[theResult setReturnDataAsStrings:YES];
// Check for any errors, but only display them if a connection still exists
@@ -485,10 +487,10 @@
SPBeginAlertSheet(NSLocalizedString(@"Error retrieving table information", @"error retrieving table information message"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving the information for table '%@'. Please try again.\n\nMySQL said: %@", @"error retrieving table information informative message"),
- tableName, [mySQLConnection getLastErrorMessage]]);
+ tableName, [mySQLConnection lastErrorMessage]]);
// If the current table doesn't exist anymore reload table list
- if([mySQLConnection getLastErrorID] == 1146) {
+ if([mySQLConnection lastErrorID] == 1146) {
// Release the table loading lock to allow reselection/reloading to requery the database.
pthread_mutex_unlock(&dataProcessingLock);
@@ -503,8 +505,8 @@
}
// Retrieve the table syntax string
- NSArray *syntaxResult = [theResult fetchRowAsArray];
- NSArray *resultFieldNames = [theResult fetchFieldNames];
+ NSArray *syntaxResult = [theResult getRowAsArray];
+ NSArray *resultFieldNames = [theResult fieldNames];
// Only continue if syntaxResult is not nil. This accommodates causes where the above query caused the
// connection reconnect dialog to appear and the user chose to close the connection.
@@ -798,7 +800,6 @@
NSMutableArray *tableColumns;
NSDictionary *resultRow;
NSMutableDictionary *tableColumn, *viewData;
- NSUInteger i;
BOOL changeEncoding = ![[mySQLConnection encoding] isEqualToString:@"utf8"];
// Catch unselected views and return nil
@@ -811,7 +812,7 @@
}
// Retrieve the CREATE TABLE syntax for the table
- MCPResult *theResult = [mySQLConnection queryString: [NSString stringWithFormat: @"SHOW CREATE TABLE %@",
+ SPMySQLResult *theResult = [mySQLConnection queryString: [NSString stringWithFormat: @"SHOW CREATE TABLE %@",
[viewName backtickQuotedString]
]];
[theResult setReturnDataAsStrings:YES];
@@ -822,7 +823,7 @@
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"),
- [mySQLConnection getLastErrorMessage]]);
+ [mySQLConnection lastErrorMessage]]);
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
}
return nil;
@@ -830,7 +831,7 @@
// Retrieve the table syntax string
if (tableCreateSyntax) [tableCreateSyntax release], tableCreateSyntax = nil;
- NSString *syntaxString = [[theResult fetchRowAsArray] objectAtIndex:1];
+ NSString *syntaxString = [[theResult getRowAsArray] objectAtIndex:1];
// A NULL value indicates that the user does not have permission to view the syntax
if ([syntaxString isNSNull]) {
@@ -856,20 +857,18 @@
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"),
- [mySQLConnection getLastErrorMessage]]);
+ [mySQLConnection lastErrorMessage]]);
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
}
return nil;
}
// Loop through the fields and capture details
- if ([theResult numOfRows]) [theResult dataSeek:0];
tableColumns = [[NSMutableArray alloc] init];
tableColumn = [[NSMutableDictionary alloc] init];
fieldParser = [[SPSQLParser alloc] init];
- for ( i = 0; i < [theResult numOfRows] ; i++ ) {
+ for (resultRow in theResult) {
[tableColumn removeAllObjects];
- resultRow = [theResult fetchRowAsDictionary];
// Add the column index and name
[tableColumn setObject:[NSString stringWithFormat:@"%llu", (unsigned long long)[tableColumns count]] forKey:@"datacolumnindex"];
@@ -938,7 +937,7 @@
[escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])];
[escapedTableName replaceOccurrencesOfString:@"'" withString:@"\\\'" options:0 range:NSMakeRange(0, [escapedTableName length])];
- MCPResult *tableStatusResult = nil;
+ SPMySQLResult *tableStatusResult = nil;
if ([tableListInstance tableType] == SPTableTypeProc) {
NSMutableString *escapedDatabaseName = [NSMutableString stringWithString:[tableDocumentInstance database]];
@@ -967,7 +966,7 @@
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving status data.\nMySQL said: %@", @"message of panel when retrieving view information failed"),
- [mySQLConnection getLastErrorMessage]]);
+ [mySQLConnection lastErrorMessage]]);
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
}
pthread_mutex_unlock(&dataProcessingLock);
@@ -975,7 +974,7 @@
}
// Retrieve the status as a dictionary and set as the cache
- [status setDictionary:[tableStatusResult fetchRowAsDictionary]];
+ [status setDictionary:[tableStatusResult getRowAsDictionary]];
if ([tableListInstance tableType] == SPTableTypeTable) {
@@ -1001,10 +1000,10 @@
// [status objectForKey:@"Rows"] is NULL then try to get the number of rows via SELECT COUNT(1) FROM `foo`
// this happens e.g. for db "information_schema"
- if([[status objectForKey:@"Rows"] isKindOfClass:[NSNull class]]) {
+ if([[status objectForKey:@"Rows"] isNSNull]) {
tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [escapedTableName backtickQuotedString] ]];
if (![mySQLConnection queryErrored])
- [status setObject:[[tableStatusResult fetchRowAsArray] objectAtIndex:0] forKey:@"Rows"];
+ [status setObject:[[tableStatusResult getRowAsArray] objectAtIndex:0] forKey:@"Rows"];
[status setObject:@"y" forKey:@"RowsCountAccurate"];
}
@@ -1042,7 +1041,7 @@
[mySQLConnection setEncoding:@"utf8"];
}
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */",
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"/*!50003 SHOW TRIGGERS WHERE `Table` = %@ */",
[[tableListInstance tableName] tickQuotedString]]];
[theResult setReturnDataAsStrings:YES];
@@ -1052,7 +1051,7 @@
SPBeginAlertSheet(NSLocalizedString(@"Error retrieving trigger information", @"error retrieving trigger information message"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving the trigger information for table '%@'. Please try again.\n\nMySQL said: %@", @"error retrieving table information informative message"),
- [tableListInstance tableName], [mySQLConnection getLastErrorMessage]]);
+ [tableListInstance tableName], [mySQLConnection lastErrorMessage]]);
if (triggers) [triggers release], triggers = nil;
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
}
@@ -1062,10 +1061,7 @@
}
if (triggers) [triggers release];
- triggers = [[NSMutableArray alloc] init];
- for (NSUInteger i=0; i<[theResult numOfRows]; i++) {
- [triggers addObject:[theResult fetchRowAsDictionary]];
- }
+ triggers = [[NSArray alloc] initWithArray:[theResult getAllRows]];
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
@@ -1298,32 +1294,31 @@
NSString *selectedTable = [tableListInstance tableName];
if(![selectedTable length]) return nil;
- MCPResult *r;
- NSArray *resultRow;
- NSUInteger i;
+ SPMySQLResult *r;
NSMutableArray *keyColumns = [NSMutableArray array];
// select all columns that are primary keys
// MySQL before 5.0.3 does not support the WHERE syntax
r = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@ /*!50003 WHERE `key` = 'PRI'*/", [selectedTable backtickQuotedString]]];
[r setReturnDataAsStrings:YES];
+ [r setDefaultRowReturnType:SPMySQLResultRowAsArray];
- if([r numOfRows] < 1) {
+ if ([r numberOfRows] < 1) {
if (changeEncoding && [mySQLConnection isConnected]) [mySQLConnection restoreStoredEncoding];
return nil;
}
if ([mySQLConnection queryErrored]) {
if ([mySQLConnection isConnected]) {
- NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the PRIMARY KEY data:\n\n%@",@"message when the query that fetches the primary keys fails"), [mySQLConnection getLastErrorMessage]], @"OK", nil, nil);
+ NSRunAlertPanel(@"Error", [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the PRIMARY KEY data:\n\n%@",@"message when the query that fetches the primary keys fails"), [mySQLConnection lastErrorMessage]], @"OK", nil, nil);
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
}
return nil;
}
- for( i = 0; i < [r numOfRows]; i++ ) {
- resultRow = [r fetchRowAsArray];
+ for (NSArray *resultRow in r) {
+
// check if the row is indeed a key (for MySQL servers before 5.0.3)
if ([[NSArrayObjectAtIndex(resultRow ,3) description] isEqualToString:@"PRI"]) {
[keyColumns addObject:[NSArrayObjectAtIndex(resultRow ,0) description]];
@@ -1382,4 +1377,4 @@
#endif
-@end \ No newline at end of file
+@end
diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h
index 5a8b9c40..99fa251f 100644
--- a/Source/SPTableRelations.h
+++ b/Source/SPTableRelations.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPTableView;
+@class SPTableView, SPMySQLConnection;
@interface SPTableRelations : NSObject
{
@@ -53,7 +51,7 @@
IBOutlet NSProgressIndicator *dataProgressIndicator;
IBOutlet NSTextField *progressStatusTextField;
- MCPConnection *connection;
+ SPMySQLConnection *connection;
NSUserDefaults *prefs;
NSMutableArray *relationData;
@@ -61,7 +59,7 @@
}
@property (readonly) NSMutableArray *relationData;
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
// IB action methods
- (IBAction)addRelation:(id)sender;
diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m
index eacdc8f6..44d05ee7 100644
--- a/Source/SPTableRelations.m
+++ b/Source/SPTableRelations.m
@@ -30,6 +30,7 @@
#import "SPTableView.h"
#import "SPAlertSheets.h"
#import "RegexKitLite.h"
+#import "SPMySQL.h"
static NSString *SPRemoveRelation = @"SPRemoveRelation";
@@ -177,12 +178,12 @@ static NSString *SPRelationOnDeleteKey = @"on_delete";
if ([connection queryErrored]) {
// Retrieve the last connection error message.
- NSString *errorText = [connection getLastErrorMessage];
+ NSString *errorText = [connection lastErrorMessage];
// An error ID of 1005 indicates a foreign key error. These are thrown for many reasons, but the two
// most common are 121 (name probably in use) and 150 (types don't exactly match).
// Retrieve the InnoDB status and extract the most recent error for more helpful text.
- if ([connection getLastErrorID] == 1005) {
+ if ([connection lastErrorID] == 1005) {
NSString *statusText = [connection getFirstFieldFromQuery:@"SHOW INNODB STATUS"];
NSString *detailErrorString = [statusText stringByMatching:@"latest foreign key error\\s+-----*\\s+[0-9: ]*(.*?)\\s+-----" options:(RKLCaseless | RKLDotAll) inRange:NSMakeRange(0, [statusText length]) capture:1L error:NULL];
if (detailErrorString) {
@@ -249,13 +250,10 @@ static NSString *SPRelationOnDeleteKey = @"on_delete";
// Get all InnoDB tables in the current database
// TODO: MySQL 4 compatibility
- MCPResult *result = [connection queryString:[NSString stringWithFormat:@"SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND engine = 'InnoDB' AND table_schema = %@", [[tableDocumentInstance database] tickQuotedString]]];
-
- [result dataSeek:0];
-
- for (NSUInteger i = 0; i < [result numOfRows]; i++)
- {
- [refTablePopUpButton addItemWithTitle:[[result fetchRowAsArray] objectAtIndex:0]];
+ SPMySQLResult *result = [connection queryString:[NSString stringWithFormat:@"SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE' AND engine = 'InnoDB' AND table_schema = %@", [[tableDocumentInstance database] tickQuotedString]]];
+ [result setDefaultRowReturnType:SPMySQLResultRowAsArray];
+ for (NSArray *eachRow in result) {
+ [refTablePopUpButton addItemWithTitle:[eachRow objectAtIndex:0]];
}
// Reset other fields
@@ -505,7 +503,7 @@ static NSString *SPRelationOnDeleteKey = @"on_delete";
SPBeginAlertSheet(NSLocalizedString(@"Unable to delete relation", @"error deleting relation message"),
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], nil, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"The selected relation couldn't be deleted.\n\nMySQL said: %@", @"error deleting relation informative message"), [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"The selected relation couldn't be deleted.\n\nMySQL said: %@", @"error deleting relation informative message"), [connection lastErrorMessage]]);
// Abort loop
break;
diff --git a/Source/SPTableStructure.h b/Source/SPTableStructure.h
index 63ac74b8..a97f70b2 100644
--- a/Source/SPTableStructure.h
+++ b/Source/SPTableStructure.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPDatabaseDocument, SPTableFieldValidation, SPTableData, SPDatabaseData, SPTablesList, SPIndexesController, SPTableView;
+@class SPDatabaseDocument, SPTableFieldValidation, SPTableData, SPDatabaseData, SPTablesList, SPIndexesController, SPTableView, SPMySQLConnection, SPMySQLResult;
@interface SPTableStructure : NSObject
#ifdef SP_REFACTOR
@@ -70,9 +68,7 @@
#endif
IBOutlet NSPopUpButtonCell *encodingPopupCell;
- MCPConnection *mySQLConnection;
- MCPResult *tableSourceResult;
- MCPResult *indexResult;
+ SPMySQLConnection *mySQLConnection;
SPTableFieldValidation *fieldValidation;
@@ -123,15 +119,15 @@
- (IBAction)resetAutoIncrement:(id)sender;
- (void)resetAutoincrementSheetDidEnd:(NSWindow *)theSheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
- (IBAction)showOptimizedFieldType:(id)sender;
-- (IBAction)toggleColumnView:(id)sender;
+- (IBAction)toggleColumnView:(NSMenuItem *)sender;
- (BOOL)cancelRowEditing;
// Index sheet methods
- (IBAction)closeSheet:(id)sender;
// Additional methods
-- (void)setConnection:(MCPConnection *)theConnection;
-- (NSArray *)fetchResultAsArray:(MCPResult *)theResult;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
+- (NSArray *)convertIndexResultToArray:(SPMySQLResult *)theResult;
- (BOOL)saveRowOnDeselect;
- (BOOL)addRowToDB;
- (void)addRowErrorSheetDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo;
diff --git a/Source/SPTableStructure.m b/Source/SPTableStructure.m
index f9c56eb9..2fbd6b5b 100644
--- a/Source/SPTableStructure.m
+++ b/Source/SPTableStructure.m
@@ -36,6 +36,7 @@
#import "SPIndexesController.h"
#import "RegexKitLite.h"
#import "SPTableFieldValidation.h"
+#import "SPMySQL.h"
@interface SPTableStructure (PrivateAPI)
@@ -232,6 +233,7 @@
{
NSArray *theTableIndexes;
NSMutableDictionary *theTableEnumLists = [NSMutableDictionary dictionary];
+ SPMySQLResult *indexResult;
// Check whether a save of the current row is required.
if ( ![[self onMainThread] saveRowOnDeselect] ) return;
@@ -249,32 +251,25 @@
[theTableFields addObject:[[col mutableCopy] autorelease]];
// Retrieve the indexes for the table
- indexResult = [[mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]] retain];
+ indexResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEX FROM %@", [aTable backtickQuotedString]]];
// If an error occurred, reset the interface and abort
if ([mySQLConnection queryErrored]) {
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
[[self onMainThread] setTableDetails:nil];
if ([mySQLConnection isConnected]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while retrieving information.\nMySQL said: %@", @"message of panel when retrieving information failed"),
- [mySQLConnection getLastErrorMessage]]);
+ [mySQLConnection lastErrorMessage]]);
}
-
- if (indexResult) [indexResult release];
-
+
return;
}
// Process the indexes into a local array of dictionaries
- theTableIndexes = [self fetchResultAsArray:indexResult];
- [indexResult release];
+ theTableIndexes = [self convertIndexResultToArray:indexResult];
// Set the Key column
for (NSDictionary* theIndex in theTableIndexes)
@@ -357,7 +352,7 @@
// Normalize default
if(![theField objectForKey:@"default"])
[theField setObject:@"" forKey:@"default"];
- else if([[theField objectForKey:@"default"] isKindOfClass:[NSNull class]])
+ else if([[theField objectForKey:@"default"] isNSNull])
[theField setObject:[prefs stringForKey:SPNullValue] forKey:@"default"];
// Init Extra field
@@ -385,11 +380,7 @@
autoIncrementIndex = nil;
// Send the query finished/work complete notification
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
[theTableFields release];
}
@@ -407,7 +398,7 @@
[tableDocumentInstance setStatusRequiresReload:YES];
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
[self loadTable:selectedTable];
}
@@ -533,7 +524,7 @@
*/
- (IBAction)showOptimizedFieldType:(id)sender
{
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT %@ FROM %@ PROCEDURE ANALYSE(0,8192)",
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT %@ FROM %@ PROCEDURE ANALYSE(0,8192)",
[[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"] backtickQuotedString],
[selectedTable backtickQuotedString]]];
@@ -546,7 +537,7 @@
defaultButton:@"OK"
alternateButton:nil
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while fetching the optimized field type.\n\nMySQL said:%@",@"an error occurred while fetching the optimized field type.\n\nMySQL said:%@"), [mySQLConnection getLastErrorMessage]]]
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while fetching the optimized field type.\n\nMySQL said:%@",@"an error occurred while fetching the optimized field type.\n\nMySQL said:%@"), [mySQLConnection lastErrorMessage]]]
beginSheetModalForWindow:[tableDocumentInstance parentWindow]
modalDelegate:self
didEndSelector:NULL
@@ -556,13 +547,10 @@
return;
}
- NSArray *result = [theResult fetch2DResultAsType:MCPTypeDictionary];
+ NSDictionary *analysisResult = [theResult getRowAsDictionary];
- NSString *type = nil;
-
- if([result count])
- type = [[result objectAtIndex:0] objectForKey:@"Optimal_fieldtype"];
- if(!type || [type isKindOfClass:[NSNull class]] || ![type length])
+ NSString *type = [analysisResult objectForKey:@"Optimal_fieldtype"];
+ if (!type || [type isNSNull] || ![type length])
type = NSLocalizedString(@"No optimized field type found.", @"no optimized field type found. message");
[[NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Optimized type for field '%@'", @"Optimized type for field %@"), [[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"]]
@@ -580,31 +568,31 @@
/**
* Control the visibility of the columns
*/
-- (IBAction)toggleColumnView:(id)sender
+- (IBAction)toggleColumnView:(NSMenuItem *)sender
{
NSString *columnIdentifierName = nil;
- switch([sender tag]) {
+ switch ([sender tag]) {
case 7:
- columnIdentifierName = @"Key";
+ columnIdentifierName = @"Key";
break;
case 10:
- columnIdentifierName = @"encoding";
+ columnIdentifierName = @"encoding";
break;
case 11:
- columnIdentifierName = @"collation";
+ columnIdentifierName = @"collation";
break;
case 12:
- columnIdentifierName = @"comment";
+ columnIdentifierName = @"comment";
break;
default:
return;
}
- for(NSTableColumn *col in [tableSourceView tableColumns]) {
+ for (NSTableColumn *col in [tableSourceView tableColumns]) {
- if([[col identifier] isEqualToString:columnIdentifierName]) {
+ if ([[col identifier] isEqualToString:columnIdentifierName]) {
[col setHidden:([sender state] == NSOffState) ? NO : YES];
[(NSMenuItem *)sender setState:![sender state]];
break;
@@ -864,7 +852,7 @@
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to reset AUTO_INCREMENT of table '%@'.\n\nMySQL said: %@", @"error resetting auto_increment informative message"),
- selTable, [mySQLConnection getLastErrorMessage]]);
+ selTable, [mySQLConnection lastErrorMessage]]);
}
// reload data
@@ -884,9 +872,9 @@
/**
* Converts the supplied result to an array containing a (mutable) dictionary for each row
*/
-- (NSArray *)fetchResultAsArray:(MCPResult *)theResult
+- (NSArray *)convertIndexResultToArray:(SPMySQLResult *)theResult
{
- NSUInteger numOfRows = (NSUInteger)[theResult numOfRows];
+ NSUInteger numOfRows = (NSUInteger)[theResult numberOfRows];
NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows];
NSMutableDictionary *tempRow;
NSArray *keys;
@@ -896,9 +884,8 @@
// Ensure table information is returned as strings to avoid problems with some server versions
[theResult setReturnDataAsStrings:YES];
- if (numOfRows) [theResult dataSeek:0];
for ( i = 0 ; i < (NSInteger)numOfRows ; i++ ) {
- tempRow = [NSMutableDictionary dictionaryWithDictionary:[theResult fetchRowAsDictionary]];
+ tempRow = [NSMutableDictionary dictionaryWithDictionary:[theResult getRowAsDictionary]];
// Replace NSNull instances with the NULL string from preferences
keys = [tempRow allKeys];
@@ -1028,7 +1015,7 @@
}
// Otherwise, use the provided default
else {
- [queryString appendFormat:@"\n DEFAULT '%@' ", [mySQLConnection prepareString:[theRow objectForKey:@"default"]]];
+ [queryString appendFormat:@"\n DEFAULT %@ ", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"default"]]];
}
}
@@ -1115,7 +1102,7 @@
}
// Otherwise, use the provided default
else {
- [queryString appendFormat:@"\n DEFAULT '%@'", [mySQLConnection prepareString:[theRow objectForKey:@"default"]]];
+ [queryString appendFormat:@"\n DEFAULT %@", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"default"]]];
}
}
@@ -1126,7 +1113,7 @@
// Any column comments
if ([(NSString *)[theRow objectForKey:@"comment"] length]) {
- [queryString appendFormat:@"\n COMMENT '%@'", [mySQLConnection prepareString:[theRow objectForKey:@"comment"]]];
+ [queryString appendFormat:@"\n COMMENT %@", [mySQLConnection escapeAndQuoteString:[theRow objectForKey:@"comment"]]];
}
if (!isEditingNewRow) {
@@ -1201,18 +1188,18 @@
[tableDocumentInstance setContentRequiresReload:YES];
// Query the structure of all databases in the background
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", selectedTable, @"affectedItem", [NSNumber numberWithInteger:[tablesListInstance tableType]], @"affectedItemType", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", selectedTable, @"affectedItem", [NSNumber numberWithInteger:[tablesListInstance tableType]], @"affectedItemType", nil]];
return YES;
}
else {
alertSheetOpened = YES;
- if([mySQLConnection getLastErrorID] == 1146) { // If the current table doesn't exist anymore
+ if([mySQLConnection lastErrorID] == 1146) { // If the current table doesn't exist anymore
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"),
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to alter table '%@'.\n\nMySQL said: %@", @"error while trying to alter table message"),
- selectedTable, [mySQLConnection getLastErrorMessage]]);
+ selectedTable, [mySQLConnection lastErrorMessage]]);
isEditingRow = NO;
isEditingNewRow = NO;
@@ -1237,14 +1224,14 @@
NSLocalizedString(@"Edit row", @"Edit row button"),
NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to add the field '%@' via\n\n%@\n\nMySQL said: %@", @"error adding field informative message"),
- [theRow objectForKey:@"name"], queryString, [mySQLConnection getLastErrorMessage]]);
+ [theRow objectForKey:@"name"], queryString, [mySQLConnection lastErrorMessage]]);
}
else {
SPBeginAlertSheet(NSLocalizedString(@"Error changing field", @"error changing field message"),
NSLocalizedString(@"Edit row", @"Edit row button"),
NSLocalizedString(@"Discard changes", @"discard changes button"), nil, [tableDocumentInstance parentWindow], self, @selector(addRowErrorSheetDidEnd:returnCode:contextInfo:), nil,
[NSString stringWithFormat:NSLocalizedString(@"An error occurred when trying to change the field '%@' via\n\n%@\n\nMySQL said: %@", @"error changing field informative message"),
- [theRow objectForKey:@"name"], queryString, [mySQLConnection getLastErrorMessage]]);
+ [theRow objectForKey:@"name"], queryString, [mySQLConnection lastErrorMessage]]);
}
return NO;
@@ -1431,7 +1418,7 @@
/**
* Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once
*/
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
@@ -1449,7 +1436,7 @@
{
if ( ![defaultValues objectForKey:field] ) {
return [prefs objectForKey:SPNullValue];
- } else if ( [[defaultValues objectForKey:field] isMemberOfClass:[NSNull class]] ) {
+ } else if ( [[defaultValues objectForKey:field] isNSNull] ) {
return [prefs objectForKey:SPNullValue];
} else {
return [defaultValues objectForKey:field];
@@ -1502,18 +1489,15 @@
NSString *nullValue = [prefs stringForKey:SPNullValue];
CFStringRef escapedNullValue = CFXMLCreateStringByEscapingEntities(NULL, ((CFStringRef)nullValue), NULL);
- MCPResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
- MCPResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]];
+ SPMySQLResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
+ SPMySQLResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]];
[structureQueryResult setReturnDataAsStrings:YES];
[indexesQueryResult setReturnDataAsStrings:YES];
- if ([structureQueryResult numOfRows]) [structureQueryResult dataSeek:0];
- if ([indexesQueryResult numOfRows]) [indexesQueryResult dataSeek:0];
-
- [tempResult addObject:[structureQueryResult fetchFieldNames]];
+ [tempResult addObject:[structureQueryResult fieldNames]];
- NSMutableArray *temp = [[indexesQueryResult fetchFieldNames] mutableCopy];
+ NSMutableArray *temp = [[indexesQueryResult fieldNames] mutableCopy];
// Remove the 'table' column
[temp removeObjectAtIndex:0];
@@ -1522,8 +1506,8 @@
[temp release];
- for (i = 0; i < [structureQueryResult numOfRows]; i++) {
- NSMutableArray *row = [[structureQueryResult fetchRowAsArray] mutableCopy];
+ for (i = 0; i < [structureQueryResult numberOfRows]; i++) {
+ NSMutableArray *row = [[structureQueryResult getRowAsArray] mutableCopy];
// For every NULL value replace it with the user's NULL value placeholder so we can actually print it
for (j = 0; j < [row count]; j++)
@@ -1538,8 +1522,8 @@
[row release];
}
- for (i = 0; i < [indexesQueryResult numOfRows]; i++) {
- NSMutableArray *eachIndex = [[indexesQueryResult fetchRowAsArray] mutableCopy];
+ for (i = 0; i < [indexesQueryResult numberOfRows]; i++) {
+ NSMutableArray *eachIndex = [[indexesQueryResult getRowAsArray] mutableCopy];
// Remove the 'table' column values
[eachIndex removeObjectAtIndex:0];
@@ -1658,10 +1642,10 @@
[mySQLConnection queryString:[NSString stringWithFormat:@"ALTER TABLE %@ DROP FOREIGN KEY %@", [selectedTable backtickQuotedString], [relationName backtickQuotedString]]];
// Check for errors, but only if the query wasn't cancelled
- if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) {
+ if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Unable to delete relation", @"error deleting relation message") forKey:@"title"];
- [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), relationName, [mySQLConnection getLastErrorMessage]] forKey:@"message"];
+ [errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to delete the relation '%@'.\n\nMySQL said: %@", @"error deleting relation informative message"), relationName, [mySQLConnection lastErrorMessage]] forKey:@"message"];
[[self onMainThread] showErrorSheetWith:errorDictionary];
}
}
@@ -1671,12 +1655,12 @@
[selectedTable backtickQuotedString], [[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"] backtickQuotedString]]];
// Check for errors, but only if the query wasn't cancelled
- if ([mySQLConnection queryErrored] && ![mySQLConnection queryCancelled]) {
+ if ([mySQLConnection queryErrored] && ![mySQLConnection lastQueryWasCancelled]) {
NSMutableDictionary *errorDictionary = [NSMutableDictionary dictionary];
[errorDictionary setObject:NSLocalizedString(@"Error", @"error") forKey:@"title"];
[errorDictionary setObject:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete field %@.\nMySQL said: %@", @"message of panel when field cannot be deleted"),
[[tableFields objectAtIndex:[tableSourceView selectedRow]] objectForKey:@"name"],
- [mySQLConnection getLastErrorMessage]] forKey:@"message"];
+ [mySQLConnection lastErrorMessage]] forKey:@"message"];
[[self onMainThread] showErrorSheetWith:errorDictionary];
}
else {
diff --git a/Source/SPTableStructureDelegate.m b/Source/SPTableStructureDelegate.m
index ca44c0a6..fdcf6b3b 100644
--- a/Source/SPTableStructureDelegate.m
+++ b/Source/SPTableStructureDelegate.m
@@ -30,6 +30,7 @@
#import "SPTableData.h"
#import "SPTableView.h"
#import "SPTableFieldValidation.h"
+#import "SPMySQL.h"
@implementation SPTableStructure (SPTableStructureDelegate)
@@ -326,13 +327,13 @@
[queryString appendString:@" DEFAULT CURRENT_TIMESTAMP"];
}
else if ([(NSString *)[originalRow objectForKey:@"default"] length]) {
- [queryString appendFormat:@" DEFAULT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"default"]]];
+ [queryString appendFormat:@" DEFAULT %@", [mySQLConnection escapeAndQuoteString:[originalRow objectForKey:@"default"]]];
}
}
// Any column comments
if ([(NSString *)[originalRow objectForKey:@"comment"] length]) {
- [queryString appendFormat:@" COMMENT '%@'", [mySQLConnection prepareString:[originalRow objectForKey:@"comment"]]];
+ [queryString appendFormat:@" COMMENT %@", [mySQLConnection escapeAndQuoteString:[originalRow objectForKey:@"comment"]]];
}
// Unparsed details - column formats, storage, reference definitions
@@ -353,7 +354,7 @@
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error moving field", @"error moving field message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to move the field.\n\nMySQL said: %@", @"error moving field informative message"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to move the field.\n\nMySQL said: %@", @"error moving field informative message"), [mySQLConnection lastErrorMessage]]);
}
else {
[tableDataInstance resetAllData];
diff --git a/Source/SPTableTextFieldCell.m b/Source/SPTableTextFieldCell.m
index 799cb4c0..ea70b01e 100644
--- a/Source/SPTableTextFieldCell.m
+++ b/Source/SPTableTextFieldCell.m
@@ -61,7 +61,7 @@
NSSize cellSize = [super cellSize];
cellSize.width = [[self attributedStringValue] size].width + (([self image] != nil) ? [[self image] size].width : 0) + 25;
- cellSize.height = [[self attributedStringValue] size].height + 14.0;
+ cellSize.height = [[self attributedStringValue] size].height + 14.0f;
return cellSize;
}
diff --git a/Source/SPTableTriggers.h b/Source/SPTableTriggers.h
index 5cc8d59d..3ffac7fe 100644
--- a/Source/SPTableTriggers.h
+++ b/Source/SPTableTriggers.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPTableView;
+@class SPTableView, SPMySQLConnection;
@interface SPTableTriggers : NSObject
{
@@ -50,7 +48,7 @@
IBOutlet NSBox *addTriggerTableBox;
IBOutlet NSButton *confirmAddTriggerButton;
- MCPConnection *connection;
+ SPMySQLConnection *connection;
NSMutableArray *triggerData;
@@ -64,7 +62,7 @@
NSString *editTriggerActionTime;
}
-@property (readwrite, assign) MCPConnection *connection;
+@property (readwrite, assign) SPMySQLConnection *connection;
- (void)loadTriggers;
- (void)resetInterface;
diff --git a/Source/SPTableTriggers.m b/Source/SPTableTriggers.m
index 742579d8..ee5a6d5a 100644
--- a/Source/SPTableTriggers.m
+++ b/Source/SPTableTriggers.m
@@ -30,6 +30,7 @@
#import "SPTableView.h"
#import "SPAlertSheets.h"
#import "SPServerSupport.h"
+#import "SPMySQL.h"
// Constants
static const NSString *SPTriggerName = @"TriggerName";
@@ -189,7 +190,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode";
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"),
- [connection getLastErrorMessage]]);
+ [connection lastErrorMessage]]);
return;
}
@@ -229,7 +230,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode";
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [NSApp mainWindow], nil, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"The specified trigger was unable to be created.\n\nMySQL said: %@", @"error creating trigger informative message"),
- [connection getLastErrorMessage]]);
+ [connection lastErrorMessage]]);
// In case of error, re-create the original trigger statement
if (isEdit) {
@@ -347,12 +348,12 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode";
/**
* Double-click action on table cells - for the time being, return NO to disable editing.
*/
-- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSUInteger)rowIndex
+- (BOOL)tableView:(NSTableView *)tableView shouldEditTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex
{
if ([tableDocumentInstance isWorking]) return NO;
// Start Edit panel
- if (([triggerData count] > rowIndex) && [triggerData objectAtIndex:rowIndex]) {
+ if (((NSInteger)[triggerData count] > rowIndex) && [triggerData objectAtIndex:rowIndex]) {
[self _editTriggerAtIndex:rowIndex];
}
@@ -428,7 +429,7 @@ static const NSString *SPTriggerSQLMode = @"TriggerSQLMode";
SPBeginAlertSheet(NSLocalizedString(@"Unable to delete trigger", @"error deleting trigger message"),
NSLocalizedString(@"OK", @"OK button"),
nil, nil, [tableDocumentInstance parentWindow], nil, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), [connection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"The selected trigger couldn't be deleted.\n\nMySQL said: %@", @"error deleting trigger informative message"), [connection lastErrorMessage]]);
// Abort loop
break;
diff --git a/Source/SPTablesList.h b/Source/SPTablesList.h
index e5e76548..6da4f6cc 100644
--- a/Source/SPTablesList.h
+++ b/Source/SPTablesList.h
@@ -23,9 +23,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPHistoryController, SPTableView;
+@class SPHistoryController, SPTableView, SPMySQLConnection;
@class SPDatabaseDocument, SPDatabaseData, SPTableStructure, SPTableContent;
#ifdef SP_REFACTOR
@@ -103,7 +101,7 @@
IBOutlet NSMenuItem *separatorTableMenuItem3;
#endif
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
#ifndef SP_REFACTOR /* ivars */
// Table list context menu items
@@ -153,7 +151,7 @@
- (IBAction)togglePaneCollapse:(id)sender;
#endif
// Additional methods
-- (void)setConnection:(MCPConnection *)theConnection;
+- (void)setConnection:(SPMySQLConnection *)theConnection;
- (void)setSelectionState:(NSDictionary *)selectionDetails;
#ifndef SP_REFACTOR /* method decls */
- (void)selectTableAtIndex:(NSNumber *)row;
diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m
index c587095c..0283eb98 100644
--- a/Source/SPTablesList.m
+++ b/Source/SPTablesList.m
@@ -27,6 +27,7 @@
#import "SPDatabaseDocument.h"
#import "SPTableStructure.h"
#import "SPDatabaseViewController.h"
+#import "SPMySQL.h"
#ifndef SP_REFACTOR /* headers */
#import "SPTableContent.h"
@@ -103,9 +104,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
*/
- (IBAction)updateTables:(id)sender
{
- MCPResult *theResult;
- NSArray *resultRow;
- NSUInteger i;
+ SPMySQLResult *theResult;
NSString *previousSelectedTable = nil;
NSString *previousFilterString = nil;
BOOL previousTableListIsSelectable = tableListIsSelectable;
@@ -135,11 +134,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
if ([tableDocumentInstance database]) {
// Notify listeners that a query has started
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance];
-#endif
// Use UTF8 for identifier-based queries
if (changeEncoding) {
@@ -150,25 +145,24 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
// Select the table list for the current database. On MySQL versions after 5 this will include
// views; on MySQL versions >= 5.0.02 select the "full" list to also select the table type column.
theResult = [mySQLConnection queryString:@"SHOW /*!50002 FULL*/ TABLES"];
- if ([theResult numOfRows]) [theResult dataSeek:0];
- if ([theResult numOfFields] == 1) {
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
- [tables addObject:[[theResult fetchRowAsArray] objectAtIndex:0]];
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
+ if ([theResult numberOfFields] == 1) {
+ for (NSArray *eachRow in theResult) {
+ [tables addObject:[eachRow objectAtIndex:0]];
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeTable]];
}
} else {
- for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
- resultRow = [theResult fetchRowAsArray];
+ for (NSArray *eachRow in theResult) {
+
// Due to encoding problems it can be the case that [resultRow objectAtIndex:0]
// return NSNull, thus catch that case for safety reasons
- NSString *row = [resultRow objectAtIndex:0];
- NSString *tableName;
- if([row isKindOfClass:[NSString class]])
- tableName = [NSString stringWithUTF8String:[row cStringUsingEncoding:[mySQLConnection stringEncoding]]];
- else
+ id tableName = [eachRow objectAtIndex:0];
+ if ([tableName isNSNull]) {
tableName = @"...";
+ }
[tables addObject:tableName];
- if ([[resultRow objectAtIndex:1] isEqualToString:@"VIEW"]) {
+
+ if ([[eachRow objectAtIndex:1] isEqualToString:@"VIEW"]) {
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeView]];
tableListContainsViews = YES;
} else {
@@ -187,31 +181,31 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
* backward compatibility with pre 4 I believe. I left the other methods below, in case.
*/
if ([[tableDocumentInstance serverSupport] supportsInformationSchema]) {
- NSString *pQuery = [NSString stringWithFormat:@"SELECT * FROM information_schema.routines WHERE routine_schema = '%@' ORDER BY routine_name",[tableDocumentInstance database]];
+ NSString *pQuery = [NSString stringWithFormat:@"SELECT * FROM information_schema.routines WHERE routine_schema = %@ ORDER BY routine_name", [[tableDocumentInstance database] tickQuotedString]];
theResult = [mySQLConnection queryString:pQuery];
+ [theResult setDefaultRowReturnType:SPMySQLResultRowAsArray];
// Check for mysql errors - if information_schema is not accessible for some reasons
// omit adding procedures and functions
- if(![mySQLConnection queryErrored] && theResult != nil && [theResult numOfRows] ) {
- // add the header row
+ if(![mySQLConnection queryErrored] && theResult != nil && [theResult numberOfRows] ) {
+
+ // Add the header row
[tables addObject:NSLocalizedString(@"PROCS & FUNCS",@"header for procs & funcs list")];
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeNone]];
- [theResult dataSeek:0];
- if( [theResult numOfFields] == 1 ) {
- for( i = 0; i < [theResult numOfRows]; i++ ) {
- [tables addObject:NSArrayObjectAtIndex([theResult fetchRowAsArray],3)];
- if( [NSArrayObjectAtIndex([theResult fetchRowAsArray], 4) isEqualToString:@"PROCEDURE"]) {
+ if( [theResult numberOfFields] == 1 ) {
+ for (NSArray *eachRow in theResult) {
+ [tables addObject:NSArrayObjectAtIndex(eachRow, 3)];
+ if ([NSArrayObjectAtIndex(eachRow, 4) isEqualToString:@"PROCEDURE"]) {
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeProc]];
} else {
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeFunc]];
}
}
} else {
- for( i = 0; i < [theResult numOfRows]; i++ ) {
- resultRow = [theResult fetchRowAsArray];
- [tables addObject:NSArrayObjectAtIndex(resultRow, 3)];
- if( [NSArrayObjectAtIndex(resultRow, 4) isEqualToString:@"PROCEDURE"] ) {
+ for (NSArray *eachRow in theResult) {
+ [tables addObject:NSArrayObjectAtIndex(eachRow, 3)];
+ if ([NSArrayObjectAtIndex(eachRow, 4) isEqualToString:@"PROCEDURE"]) {
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeProc]];
} else {
[tableTypes addObject:[NSNumber numberWithInteger:SPTableTypeFunc]];
@@ -276,11 +270,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
// Notify listeners that the query has finished
-#ifndef SP_REFACTOR
[[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#else
- [[NSNotificationCenter defaultCenter] sequelProPostNotificationOnMainThreadWithName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
-#endif
}
// Add the table headers even if no tables were found
@@ -343,10 +333,10 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
// Query the structure of all databases in the background
if (sender == self)
// Invoked by SP
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:nil];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:nil];
else
// User press refresh button ergo force update
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", [NSNumber numberWithBool:YES], @"cancelQuerying", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", [NSNumber numberWithBool:YES], @"cancelQuerying", nil]];
}
/**
@@ -364,7 +354,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
NSArray *engines = [databaseDataInstance getDatabaseStorageEngines];
// Add default menu item
- [tableTypeButton addItemWithTitle:@"Default"];
+ [tableTypeButton addItemWithTitle:NSLocalizedString(@"Default",@"New Table Sheet : Table Engine Dropdown : Default")];
[[tableTypeButton menu] addItem:[NSMenuItem separatorItem]];
for (NSDictionary *engine in engines)
@@ -374,7 +364,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
// Populate the table encoding popup button with a default menu item
[tableEncodingButton removeAllItems];
- [tableEncodingButton addItemWithTitle:@"Default"];
+ [tableEncodingButton addItemWithTitle:NSLocalizedString(@"Default",@"New Table Sheet : Table Encoding Dropdown : Default")];
// Retrieve the server-supported encodings and add them to the menu
NSArray *encodings = [databaseDataInstance getDatabaseCharacterSetEncodings];
@@ -728,7 +718,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
/**
* Sets the connection (received from SPDatabaseDocument) and makes things that have to be done only once
*/
-- (void)setConnection:(MCPConnection *)theConnection
+- (void)setConnection:(SPMySQLConnection *)theConnection
{
mySQLConnection = theConnection;
[self updateTables:self];
@@ -790,19 +780,9 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
NSIndexSet *indexes = [tablesListView selectedRowIndexes];
// Update the selected table name and type
if (selectedTableName) [selectedTableName release];
-
+ selectedTableName = nil;
#ifndef SP_REFACTOR /* ui manipulation */
- if ([indexes count]) {
- selectedTableName = [[NSString alloc] initWithString:@""];
- }
- else {
-#endif
- selectedTableName = nil;
-#ifndef SP_REFACTOR /* ui manipulation */
- }
-#endif
-#ifndef SP_REFACTOR /* ui manipulation */
// Set gear menu items Remove/Duplicate table/view according to the table types
// if at least one item is selected
@@ -907,9 +887,9 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
[[tableSubMenu itemAtIndex:8] setHidden:NO];
[[tableSubMenu itemAtIndex:9] setHidden:NO];
[[tableSubMenu itemAtIndex:10] setHidden:NO];
+#endif
return;
-#endif
}
// If a new selection has been provided, store variables and update the interface to match
@@ -1180,7 +1160,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
/**
* Returns the currently selected table type, or -1 if no table or multiple tables are selected
*/
-- (SPTableType)tableType
+- (SPTableType) tableType
{
return selectedTableType;
}
@@ -1382,6 +1362,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
return YES;
}
+#endif
#pragma mark -
#pragma mark Data validation
@@ -1447,6 +1428,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
return isValid;
}
+#ifndef SP_REFACTOR
#pragma mark -
#pragma mark Datasource methods
@@ -1538,7 +1520,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
[tableDocumentInstance updateWindowTitle:self];
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
}
#pragma mark -
@@ -1598,8 +1580,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
if ([tablesListView numberOfSelectedRows] != 1) {
// Ensure the state is cleared
- if ([tableDocumentInstance table]) [tableDocumentInstance loadTable:nil ofType:SPTableTypeNone];
- else [self setSelectionState:nil];
+ if ([tableDocumentInstance table]) {
+ [tableDocumentInstance loadTable:nil ofType:SPTableTypeNone];
+ } else {
+ [self setSelectionState:nil];
+ [tableInfoInstance tableChanged:nil];
+ }
if (selectedTableName) [selectedTableName release], selectedTableName = nil;
selectedTableType = SPTableTypeNone;
return;
@@ -1748,7 +1734,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to import a table via: \n%@\n\n\nMySQL said: %@", @"error importing table informative message"),
- query, [mySQLConnection getLastErrorMessage]]];
+ query, [mySQLConnection lastErrorMessage]]];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"truncateTableError"];
@@ -1865,11 +1851,16 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
NSUInteger i;
NSInteger lastTableType = NSNotFound, tableType;
NSRange substringRange;
+ NSString *filterString = [listFilterField stringValue];
for (i = 0; i < [tables count]; i++) {
tableType = [[tableTypes objectAtIndex:i] integerValue];
if (tableType == SPTableTypeNone) continue;
- substringRange = [[tables objectAtIndex:i] rangeOfString:[listFilterField stringValue] options:NSCaseInsensitiveSearch];
- if (substringRange.location == NSNotFound) continue;
+
+ // First check the table name against the string as a regex, falling back to direct string match
+ if (![[tables objectAtIndex:i] isMatchedByRegex:filterString]) {
+ substringRange = [[tables objectAtIndex:i] rangeOfString:filterString options:NSCaseInsensitiveSearch];
+ if (substringRange.location == NSNotFound) continue;
+ }
// Add a title if necessary
if ((tableType == SPTableTypeTable || tableType == SPTableTypeView) && lastTableType == NSNotFound)
@@ -2158,7 +2149,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
[alert addButtonWithTitle:NSLocalizedString(@"Stop", @"stop button")];
}
[alert setMessageText:NSLocalizedString(@"Error", @"error")];
- [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete '%@'.\nMySQL said: %@", @"message of panel when an item cannot be deleted"), [tables objectAtIndex:currentIndex], [mySQLConnection getLastErrorMessage]]];
+ [alert setInformativeText:[NSString stringWithFormat:NSLocalizedString(@"Couldn't delete '%@'.\n\nMySQL said: %@", @"message of panel when an item cannot be deleted"), [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]];
[alert setAlertStyle:NSWarningAlertStyle];
if ([indexes indexLessThanIndex:currentIndex] == NSNotFound) {
[alert beginSheetModalForWindow:[tableDocumentInstance parentWindow] modalDelegate:self didEndSelector:nil contextInfo:nil];
@@ -2192,7 +2183,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
}
@@ -2217,7 +2208,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
alternateButton:nil
otherButton:nil
informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to truncate the table '%@'.\n\nMySQL said: %@", @"error truncating table informative message"),
- [filteredTables objectAtIndex:currentIndex], [mySQLConnection getLastErrorMessage]]];
+ [filteredTables objectAtIndex:currentIndex], [mySQLConnection lastErrorMessage]]];
[alert setAlertStyle:NSCriticalAlertStyle];
// NSArray *buttons = [alert buttons];
@@ -2277,7 +2268,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
engineStatement = [NSString stringWithFormat:@"%@ = %@", [[tableDocumentInstance serverSupport] engineTypeQueryName], [[tableDocumentInstance serverSupport] supportsQuotingEngineTypeInCreateSyntax] ? [tableType backtickQuotedString] : tableType];
}
- NSString *createStatement = [NSString stringWithFormat:@"CREATE TABLE %@ (%@) %@ %@", [tableName backtickQuotedString], ([tableType isEqualToString:@"CSV"]) ? @"id INT NOT NULL" : @"id INT", charSetStatement, engineStatement];
+ NSString *createStatement = [NSString stringWithFormat:@"CREATE TABLE %@ (id INT(11) UNSIGNED NOT NULL%@) %@ %@", [tableName backtickQuotedString], [tableType isEqualToString:@"CSV"] ? @"" : @" PRIMARY KEY AUTO_INCREMENT", charSetStatement, engineStatement];
// Create the table
[mySQLConnection queryString:createStatement];
@@ -2328,7 +2319,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
#endif
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
}
else {
@@ -2338,7 +2329,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
SPBeginAlertSheet(NSLocalizedString(@"Error adding new table", @"error adding new table message"),
NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self,
@selector(sheetDidEnd:returnCode:contextInfo:), SPAddRow,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@'.\n\nMySQL said: %@", @"error adding new table informative message"), tableName, [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@'.\n\nMySQL said: %@", @"error adding new table informative message"), tableName, [mySQLConnection lastErrorMessage]]);
if (changeEncoding) [mySQLConnection restoreStoredEncoding];
[[tablesListView onMainThread] reloadData];
@@ -2392,16 +2383,17 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
}
// Get table/view structure
- MCPResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@",
+ SPMySQLResult *queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@",
[tableType uppercaseString],
[[filteredTables objectAtIndex:[tablesListView selectedRow]] backtickQuotedString]
]];
[queryResult setReturnDataAsStrings:YES];
- if ( ![queryResult numOfRows] ) {
+ if ( ![queryResult numberOfRows] ) {
+
//error while getting table structure
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't get create syntax.\nMySQL said: %@", @"message of panel when table information cannot be retrieved"), [mySQLConnection lastErrorMessage]]);
} else {
//insert new table name in create syntax and create new table
@@ -2409,14 +2401,14 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
NSString *scanString;
if(tblType == SPTableTypeView){
- scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create View"]];
+ scanner = [[NSScanner alloc] initWithString:[[queryResult getRowAsDictionary] objectForKey:@"Create View"]];
[scanner scanUpToString:@"AS" intoString:nil];
[scanner scanUpToString:@"" intoString:&scanString];
[scanner release];
[mySQLConnection queryString:[NSString stringWithFormat:@"CREATE VIEW %@ %@", [[copyTableNameField stringValue] backtickQuotedString], scanString]];
}
else if(tblType == SPTableTypeTable){
- scanner = [[NSScanner alloc] initWithString:[[queryResult fetchRowAsDictionary] objectForKey:@"Create Table"]];
+ scanner = [[NSScanner alloc] initWithString:[[queryResult getRowAsDictionary] objectForKey:@"Create Table"]];
[scanner scanUpToString:@"(" intoString:nil];
[scanner scanUpToString:@"" intoString:&scanString];
[scanner release];
@@ -2435,7 +2427,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
else if(tblType == SPTableTypeFunc || tblType == SPTableTypeProc)
{
// get the create syntax
- MCPResult *theResult;
+ SPMySQLResult *theResult;
if(selectedTableType == SPTableTypeProc)
theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE PROCEDURE %@", [selectedTableName backtickQuotedString]]];
else if([self tableType] == SPTableTypeFunc)
@@ -2447,20 +2439,20 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
if ([mySQLConnection queryErrored]) {
if ([mySQLConnection isConnected]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the create syntax for '%@'.\nMySQL said: %@", @"message of panel when create syntax cannot be retrieved"), selectedTableName, [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occured while retrieving the create syntax for '%@'.\nMySQL said: %@", @"message of panel when create syntax cannot be retrieved"), selectedTableName, [mySQLConnection lastErrorMessage]]);
}
return;
}
[theResult setReturnDataAsStrings:YES];
- NSString *tableSyntax = [[theResult fetchRowAsArray] objectAtIndex:2];
+ NSString *tableSyntax = [[theResult getRowAsArray] objectAtIndex:2];
// replace the old name by the new one and drop the old one
[mySQLConnection queryString:[tableSyntax stringByReplacingOccurrencesOfRegex:[NSString stringWithFormat:@"(?<=%@ )(`[^`]+?`)", [tableType uppercaseString]] withString:[[copyTableNameField stringValue] backtickQuotedString]]];
if ([mySQLConnection queryErrored]) {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't duplicate '%@'.\nMySQL said: %@", @"message of panel when an item cannot be renamed"), [copyTableNameField stringValue], [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't duplicate '%@'.\nMySQL said: %@", @"message of panel when an item cannot be renamed"), [copyTableNameField stringValue], [mySQLConnection lastErrorMessage]]);
}
}
@@ -2468,7 +2460,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
if ([mySQLConnection queryErrored]) {
//error while creating new table
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"Couldn't create '%@'.\nMySQL said: %@", @"message of panel when table cannot be created"), [copyTableNameField stringValue], [mySQLConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"Couldn't create '%@'.\nMySQL said: %@", @"message of panel when table cannot be created"), [copyTableNameField stringValue], [mySQLConnection lastErrorMessage]]);
} else {
if (copyTableContent) {
@@ -2530,7 +2522,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
[tableDocumentInstance loadTable:selectedTableName ofType:selectedTableType];
// Query the structure of all databases in the background (mainly for completion)
- [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
+ [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:[tableDocumentInstance databaseStructureRetrieval] withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]];
}
}
@@ -2577,7 +2569,7 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
[mySQLConnection queryString:[NSString stringWithFormat:@"RENAME TABLE %@ TO %@", [oldTableName backtickQuotedString], [newTableName backtickQuotedString]]];
// check for errors
if ([mySQLConnection queryErrored]) {
- [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming '%@'.\n\nMySQL said: %@", @"rename table error informative message"), oldTableName, [mySQLConnection getLastErrorMessage]];
+ [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming '%@'.\n\nMySQL said: %@", @"rename table error informative message"), oldTableName, [mySQLConnection lastErrorMessage]];
}
return;
@@ -2596,12 +2588,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
default: break;
}
- MCPResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", stringTableType, [oldTableName backtickQuotedString] ] ];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW CREATE %@ %@", stringTableType, [oldTableName backtickQuotedString] ] ];
if ([mySQLConnection queryErrored]) {
- [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't retrieve the syntax for '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't retrieve syntax"), oldTableName, [mySQLConnection getLastErrorMessage]];
+ [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't retrieve the syntax for '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't retrieve syntax"), oldTableName, [mySQLConnection lastErrorMessage]];
}
[theResult setReturnDataAsStrings:YES];
- NSString *oldCreateSyntax = [[theResult fetchRowAsArray] objectAtIndex:2];
+ NSString *oldCreateSyntax = [[theResult getRowAsArray] objectAtIndex:2];
// replace the old name with the new name
NSRange rangeOfProcedureName = [oldCreateSyntax rangeOfString: [NSString stringWithFormat:@"%@ %@", stringTableType, [oldTableName backtickQuotedString] ] ];
@@ -2612,12 +2604,12 @@ static NSString *SPDuplicateTable = @"SPDuplicateTable";
withString: [NSString stringWithFormat:@"%@ %@", stringTableType, [newTableName backtickQuotedString] ] ];
[mySQLConnection queryString: newCreateSyntax];
if ([mySQLConnection queryErrored]) {
- [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't recreate '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't recreate procedure"), oldTableName, [mySQLConnection getLastErrorMessage]];
+ [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't recreate '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't recreate procedure"), oldTableName, [mySQLConnection lastErrorMessage]];
}
[mySQLConnection queryString: [NSString stringWithFormat: @"DROP %@ %@", stringTableType, [oldTableName backtickQuotedString]]];
if ([mySQLConnection queryErrored]) {
- [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't delete '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't delete old procedure"), oldTableName, [mySQLConnection getLastErrorMessage]];
+ [NSException raise:@"MySQL Error" format:NSLocalizedString(@"An error occured while renaming. I couldn't delete '%@'.\n\nMySQL said: %@", @"rename precedure/function error - can't delete old procedure"), oldTableName, [mySQLConnection lastErrorMessage]];
}
return;
}
diff --git a/Source/SPTextView.h b/Source/SPTextView.h
index 3309ed1d..5c9c4054 100644
--- a/Source/SPTextView.h
+++ b/Source/SPTextView.h
@@ -23,14 +23,13 @@
// More info at <http://code.google.com/p/sequel-pro/>
#import <Cocoa/Cocoa.h>
-#import <MCPKit/MCPKit.h>
#import "NoodleLineNumberView.h"
#import "SPCopyTable.h"
#define SP_TEXT_SIZE_TRIGGER_FOR_PARTLY_PARSING 10000
-@class SPNarrowDownCompletion, SPDatabaseDocument, SPTablesList, SPCustomQuery;
+@class SPNarrowDownCompletion, SPDatabaseDocument, SPTablesList, SPCustomQuery, SPMySQLConnection;
@interface SPTextView : NSTextView
#ifdef SP_REFACTOR
@@ -65,7 +64,7 @@
NSUserDefaults *prefs;
#endif
- MCPConnection *mySQLConnection;
+ SPMySQLConnection *mySQLConnection;
NSInteger mySQLmajorVersion;
NSInteger snippetControlArray[20][3];
@@ -142,7 +141,7 @@
#endif
- (void) doSyntaxHighlighting;
- (NSBezierPath*)roundedBezierPathAroundRange:(NSRange)aRange;
-- (void) setConnection:(MCPConnection *)theConnection withVersion:(NSInteger)majorVersion;
+- (void) setConnection:(SPMySQLConnection *)theConnection withVersion:(NSInteger)majorVersion;
- (void) doCompletionByUsingSpellChecker:(BOOL)isDictMode fuzzyMode:(BOOL)fuzzySearch autoCompleteMode:(BOOL)autoCompleteMode;
- (void) doAutoCompletion;
- (void) refreshCompletion;
diff --git a/Source/SPTextView.m b/Source/SPTextView.m
index 65115813..137ff021 100644
--- a/Source/SPTextView.m
+++ b/Source/SPTextView.m
@@ -36,6 +36,8 @@
#import "SPBundleHTMLOutputController.h"
#import "SPDatabaseViewController.h"
#import "SPAppController.h"
+#import "SPMySQL.h"
+#import "SPDatabaseStructure.h"
#pragma mark -
#pragma mark lex init
@@ -174,7 +176,9 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
#ifndef SP_REFACTOR
[self setQueryHiliteColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorHighlightQueryColor]]];
- [self setQueryEditorBackgroundColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorBackgroundColor]]];
+ NSColor *backgroundColor = [NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorBackgroundColor]];
+ [self setQueryEditorBackgroundColor:backgroundColor];
+ [self setBackgroundColor:backgroundColor];
[self setCommentColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorCommentColor]]];
[self setQuoteColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorQuoteColor]]];
[self setKeywordColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorSQLKeywordColor]]];
@@ -221,7 +225,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
#endif
}
-- (void) setConnection:(MCPConnection *)theConnection withVersion:(NSInteger)majorVersion
+- (void) setConnection:(SPMySQLConnection *)theConnection withVersion:(NSInteger)majorVersion
{
mySQLConnection = theConnection;
mySQLmajorVersion = majorVersion;
@@ -234,7 +238,9 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
{
#ifndef SP_REFACTOR
if ([keyPath isEqualToString:SPCustomQueryEditorBackgroundColor]) {
- [self setQueryEditorBackgroundColor:[NSUnarchiver unarchiveObjectWithData:[change objectForKey:NSKeyValueChangeNewKey]]];
+ NSColor *backgroundColor = [NSUnarchiver unarchiveObjectWithData:[change objectForKey:NSKeyValueChangeNewKey]];
+ [self setQueryEditorBackgroundColor:backgroundColor];
+ [self setBackgroundColor:backgroundColor];
[self setNeedsDisplayInRect:[self bounds]];
} else if ([keyPath isEqualToString:SPCustomQueryEditorFont]) {
[self setFont:[NSUnarchiver unarchiveObjectWithData:[change objectForKey:NSKeyValueChangeNewKey]]];
@@ -386,9 +392,10 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
// Put information_schema and/or mysql db at the end if not selected
// 5.5.3+ also has performance_schema
- NSString* mysql_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, @"mysql"];
- NSString* inf_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, @"information_schema"];
- NSString* perf_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, @"performance_schema"];
+ NSString* mysql_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, SPMySQLDatabase];
+ NSString* inf_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, SPMySQLInformationSchemaDatabase];
+ NSString* perf_id = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, SPMySQLPerformanceSchemaDatabase];
+
if(currentDb && ![currentDb isEqualToString:mysql_id] && [sortedDbs containsObject:mysql_id]) {
[sortedDbs removeObject:mysql_id];
[sortedDbs addObject:mysql_id];
@@ -818,7 +825,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
NSString *theDb = (dbName == nil) ? [NSString stringWithString:currentDb] : [NSString stringWithString:dbName];
NSString *connectionID = [tableDocumentInstance connectionID];
NSString *conID = [NSString stringWithFormat:@"%@%@%@", connectionID, SPUniqueSchemaDelimiter, theDb];
- NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[[mySQLConnection getDbStructure] objectForKey:connectionID]];
+ NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[[[tableDocumentInstance databaseStructureRetrieval] structure] objectForKey:connectionID]];
if(theDb && dbs != nil && [dbs count] && [dbs objectForKey:conID] && [[dbs objectForKey:conID] isKindOfClass:[NSDictionary class]]) {
NSArray *allTables = [[dbs objectForKey:conID] allKeys];
// Check if found table name is known, if not parse for aliases
@@ -880,7 +887,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
autoComplete:autoCompleteMode
oneColumn:isDictMode
alias:alias
- isQueryingDBStructure:[mySQLConnection isQueryingDatabaseStructure]];
+ withDBStructureRetriever:[tableDocumentInstance databaseStructureRetrieval]];
completionParseRangeLocation = parseRange.location;
@@ -1445,7 +1452,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
if (tablesListInstance && [tablesListInstance tableName])
currentTable = [tablesListInstance tableName];
- NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[[mySQLConnection getDbStructure] objectForKey:connectionID]];
+ NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[[[tableDocumentInstance databaseStructureRetrieval] structure] objectForKey:connectionID]];
if(currentDb != nil && currentTable != nil && dbs != nil && [dbs count] && [dbs objectForKey:currentDb] && [[dbs objectForKey:currentDb] objectForKey:currentTable]) {
NSDictionary * theTable = [[dbs objectForKey:currentDb] objectForKey:currentTable];
NSArray *allFields = [theTable allKeys];
@@ -1517,7 +1524,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
autoComplete:NO
oneColumn:NO
alias:nil
- isQueryingDBStructure:NO];
+ withDBStructureRetriever:nil];
//Get the NSPoint of the first character of the current word
NSRange glyphRange = [[self layoutManager] glyphRangeForCharacterRange:NSMakeRange(aRange.location,1) actualCharacterRange:NULL];
@@ -1674,7 +1681,7 @@ NSInteger _alphabeticSort(id string1, id string2, void *reverse)
autoComplete:NO
oneColumn:YES
alias:nil
- isQueryingDBStructure:NO];
+ withDBStructureRetriever:nil];
//Get the NSPoint of the first character of the current word
NSRange glyphRange = [[self layoutManager] glyphRangeForCharacterRange:NSMakeRange(r2.location,1) actualCharacterRange:NULL];
diff --git a/Source/SPUserMO.h b/Source/SPUserMO.h
index b77dfd04..90706ef5 100644
--- a/Source/SPUserMO.h
+++ b/Source/SPUserMO.h
@@ -38,4 +38,4 @@
- (void)addChildrenObject:(NSManagedObject *)value;
- (void)removeChildrenObject:(NSManagedObject *)value;
-@end \ No newline at end of file
+@end
diff --git a/Source/SPUserManager.h b/Source/SPUserManager.h
index 3df63a6f..11bb736e 100644
--- a/Source/SPUserManager.h
+++ b/Source/SPUserManager.h
@@ -22,9 +22,7 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
-@class SPServerSupport, BWAnchoredButtonBar;
+@class SPServerSupport, SPMySQLConnection, BWAnchoredButtonBar;
@interface SPUserManager : NSWindowController
{
@@ -35,7 +33,7 @@
BOOL isInitializing;
- MCPConnection *mySqlConnection;
+ SPMySQLConnection *mySqlConnection;
SPServerSupport *serverSupport;
IBOutlet NSOutlineView *outlineView;
@@ -75,7 +73,7 @@
NSMutableString *errorsString;
}
-@property (nonatomic, retain) MCPConnection *mySqlConnection;
+@property (nonatomic, retain) SPMySQLConnection *mySqlConnection;
@property (nonatomic, retain) SPServerSupport *serverSupport;
@property (nonatomic, retain) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m
index 565cfc6f..9fb2cc18 100644
--- a/Source/SPUserManager.m
+++ b/Source/SPUserManager.m
@@ -29,6 +29,7 @@
#import "SPConnectionController.h"
#import "SPServerSupport.h"
#import "SPAlertSheets.h"
+#import "SPMySQL.h"
#import <BWToolkitFramework/BWAnchoredButtonBar.h>
static const NSString *SPTableViewNameColumnID = @"NameColumn";
@@ -140,23 +141,12 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
NSMutableString *privKey;
NSArray *privRow;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
- NSMutableArray *resultAsArray = [NSMutableArray array];
NSMutableArray *usersResultArray = [NSMutableArray array];
// Select users from the mysql.user table
- MCPResult *result = [self.mySqlConnection queryString:@"SELECT * FROM mysql.user ORDER BY user"];
-
- NSUInteger rows = (NSUInteger)[result numOfRows];
-
- if (rows > 0) [result dataSeek:0];
-
- for (NSUInteger i = 0; i < rows; i++)
- {
- [resultAsArray addObject:[result fetchRowAsDictionary]];
- }
-
- [usersResultArray addObjectsFromArray:resultAsArray];
+ SPMySQLResult *result = [self.mySqlConnection queryString:@"SELECT * FROM mysql.user ORDER BY user"];
+ [result setReturnDataAsStrings:YES];
+ [usersResultArray addObjectsFromArray:[result getAllRows]];
[self _initializeTree:usersResultArray];
@@ -169,12 +159,11 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
if ([serverSupport supportsShowPrivileges]) {
result = [self.mySqlConnection queryString:@"SHOW PRIVILEGES"];
-
[result setReturnDataAsStrings:YES];
}
- if (result && [result numOfRows]) {
- while ((privRow = [result fetchRowAsArray]))
+ if (result && [result numberOfRows]) {
+ while ((privRow = [result getRowAsArray]))
{
privKey = [NSMutableString stringWithString:[[privRow objectAtIndex:0] lowercaseString]];
@@ -189,11 +178,10 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
}
// If that fails, base privilege support on the mysql.users columns
else {
- result = [self.mySqlConnection queryString:@"SHOW COLUMNS FROM mysql.user"];
-
+ result = [self.mySqlConnection queryString:@"SHOW COLUMNS FROM mysql.user"];
[result setReturnDataAsStrings:YES];
- while ((privRow = [result fetchRowAsArray]))
+ while ((privRow = [result getRowAsArray]))
{
privKey = [NSMutableString stringWithString:[privRow objectAtIndex:0]];
@@ -308,15 +296,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
{
// Initialize Databases
[schemas removeAllObjects];
-
- MCPResult *results = [self.mySqlConnection listDBs];
-
- if ([results numOfRows]) [results dataSeek:0];
-
- for (NSUInteger i = 0; i < [results numOfRows]; i++)
- {
- [schemas addObject:[results fetchRowAsDictionary]];
- }
+ [schemas addObjectsFromArray:[self.mySqlConnection databases]];
[schemaController rearrangeObjects];
@@ -377,16 +357,11 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
NSString *queryString = [NSString stringWithFormat:@"SELECT * from mysql.db d WHERE d.user = %@ and d.host = %@",
[[[child parent] valueForKey:@"user"] tickQuotedString], [[child valueForKey:@"host"] tickQuotedString]];
- MCPResult *queryResults = [self.mySqlConnection queryString:queryString];
+ SPMySQLResult *queryResults = [self.mySqlConnection queryString:queryString];
+ [queryResults setReturnDataAsStrings:YES];
- if ([queryResults numOfRows] > 0) {
- // Go to the beginning
- [queryResults dataSeek:0];
- }
-
- for (NSUInteger i = 0; i < [queryResults numOfRows]; i++)
+ for (NSDictionary *rowDict in queryResults)
{
- NSDictionary *rowDict = [queryResults fetchRowAsDictionary];
NSManagedObject *dbPriv = [NSEntityDescription insertNewObjectForEntityForName:@"Privileges"
inManagedObjectContext:[self managedObjectContext]];
for (NSString *key in rowDict)
@@ -877,7 +852,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
// The passed in objects should be an array of NSDictionaries with a key
// of "name".
NSManagedObject *selectedHost = [[treeController selectedObjects] objectAtIndex:0];
- NSString *selectedDb = [[[schemaController selectedObjects] objectAtIndex:0] valueForKey:@"Database"];
+ NSString *selectedDb = [[schemaController selectedObjects] objectAtIndex:0];
NSArray *selectedPrivs = [self _fetchPrivsWithUser:[selectedHost valueForKeyPath:@"parent.user"]
schema:[selectedDb stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"]
host:[selectedHost valueForKey:@"host"]];
@@ -1208,12 +1183,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
[[schemaPriv valueForKeyPath:@"user.host"] tickQuotedString],
[dbName tickQuotedString]];
- MCPResult *result = [self.mySqlConnection queryString:statement];
-
- NSUInteger rows = (NSUInteger)[result numOfRows];
- BOOL userExists = YES;
-
- if (rows == 0) userExists = NO;
+ NSArray *matchingUsers = [self.mySqlConnection getAllRowsFromQuery:statement];
for (NSString *key in self.privsSupportedByServer)
{
@@ -1224,7 +1194,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
[grantPrivileges addObject:[privilege replaceUnderscoreWithSpace]];
}
else {
- if (userExists || [grantPrivileges count] > 0) {
+ if ([matchingUsers count] || [grantPrivileges count] > 0) {
[revokePrivileges addObject:[privilege replaceUnderscoreWithSpace]];
}
}
@@ -1429,11 +1399,11 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
{
if ([self.mySqlConnection queryErrored]) {
if (isSaving) {
- [errorsString appendFormat:@"%@\n", [self.mySqlConnection getLastErrorMessage]];
+ [errorsString appendFormat:@"%@\n", [self.mySqlConnection lastErrorMessage]];
} else {
SPBeginAlertSheet(NSLocalizedString(@"An error occurred", @"mysql error occurred message"),
NSLocalizedString(@"OK", @"OK button"), nil, nil, [self window], self, nil, nil,
- [NSString stringWithFormat:NSLocalizedString(@"An error occurred whilst trying to perform the operation.\n\nMySQL said: %@", @"mysql error occurred informative message"), [self.mySqlConnection getLastErrorMessage]]);
+ [NSString stringWithFormat:NSLocalizedString(@"An error occurred whilst trying to perform the operation.\n\nMySQL said: %@", @"mysql error occurred informative message"), [self.mySqlConnection lastErrorMessage]]);
}
return NO;
@@ -1561,7 +1531,7 @@ static const NSString *SPTableViewNameColumnID = @"NameColumn";
// Check to see if the user host node was selected
if ([user valueForKey:@"host"]) {
- NSString *selectedSchema = [[[schemaController selectedObjects] objectAtIndex:0] valueForKey:@"Database"];
+ NSString *selectedSchema = [[schemaController selectedObjects] objectAtIndex:0];
NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"]
schema:[selectedSchema stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"]
host:[user valueForKey:@"host"]];
diff --git a/Source/SPWindowAdditions.m b/Source/SPWindowAdditions.m
index 676019ee..ab0b35bc 100644
--- a/Source/SPWindowAdditions.m
+++ b/Source/SPWindowAdditions.m
@@ -35,7 +35,7 @@
- (CGFloat)toolbarHeight
{
NSRect windowFrame;
- CGFloat toolbarHeight = 0.0;
+ CGFloat toolbarHeight = 0.0f;
if ([self toolbar] && [[self toolbar] isVisible]) {
windowFrame = [NSWindow contentRectForFrameRect:[self frame] styleMask:[self styleMask]];
@@ -83,10 +83,12 @@
if( frontDoc && [frontDoc isKindOfClass:[SPDatabaseDocument class]]
&& [frontDoc valueForKeyPath:@"spHistoryControllerInstance"]
&& ![frontDoc isWorking])
+ {
if([anEvent deltaX] == -1.0f)
[[frontDoc valueForKeyPath:@"spHistoryControllerInstance"] valueForKey:@"goForwardInHistory"];
else if([anEvent deltaX] == 1.0f)
[[frontDoc valueForKeyPath:@"spHistoryControllerInstance"] valueForKey:@"goBackInHistory"];
+ }
}
diff --git a/Source/SPWindowController.m b/Source/SPWindowController.m
index 282ebda5..ed538312 100644
--- a/Source/SPWindowController.m
+++ b/Source/SPWindowController.m
@@ -39,9 +39,9 @@ enum {
#import <PSMTabBar/PSMTabBarControl.h>
#import <PSMTabBar/PSMTabStyle.h>
-@interface SPWindowController (PrivateAPI)
+@interface SPWindowController ()
-- (void) _updateProgressIndicatorForItem:(NSTabViewItem *)theItem;
+- (void)_updateProgressIndicatorForItem:(NSTabViewItem *)theItem;
@end
@@ -212,6 +212,7 @@ enum {
*/
- (IBAction) moveSelectedTabInNewWindow:(id)sender
{
+
static NSPoint cascadeLocation = {.x = 0, .y = 0};
SPDatabaseDocument *selectedDocument = [[tabView selectedTabViewItem] identifier];
@@ -274,6 +275,7 @@ enum {
[newWindowController tabView:[tabBar tabView] didDropTabViewItem:[selectedCell representedObject] inTabBar:control];
[newWindow makeKeyAndOrderFront:nil];
+
}
/**
@@ -584,8 +586,8 @@ enum {
// Draw the background flipped, which is actually the right way up
NSAffineTransform *transform = [NSAffineTransform transform];
- [transform translateXBy:0.0 yBy:[[[self window] contentView] frame].size.height];
- [transform scaleXBy:1.0 yBy:-1.0];
+ [transform translateXBy:0.0f yBy:[[[self window] contentView] frame].size.height];
+ [transform scaleXBy:1.0f yBy:-1.0f];
[transform concat];
[(id <PSMTabStyle>)[[aTabView delegate] style] drawBackgroundInRect:tabFrame];
[viewImage unlockFocus];
@@ -784,20 +786,25 @@ enum {
return [selectedTableDocument performSelector:theSelector withObject:theObject];
}
-@end
-
-@implementation SPWindowController (PrivateAPI)
+/**
+ * When receiving an update for a bound value - an observed value on the
+ * document - ask the tab bar control to redraw as appropriate.
+ */
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
+{
+ [tabBar update];
+}
/**
* Binds a tab bar item's progress indicator to the represented
* tableDocument.
*/
-- (void) _updateProgressIndicatorForItem:(NSTabViewItem *)theItem
+- (void)_updateProgressIndicatorForItem:(NSTabViewItem *)theItem
{
PSMTabBarCell *theCell = [[tabBar cells] objectAtIndex:[tabView indexOfTabViewItem:theItem]];
[[theCell indicator] setControlSize:NSSmallControlSize];
SPDatabaseDocument *theDocument = [theItem identifier];
-
+
[[theCell indicator] setHidden:NO];
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
[bindingOptions setObject:NSNegateBooleanTransformerName forKey:@"NSValueTransformerName"];
@@ -806,13 +813,4 @@ enum {
[theDocument addObserver:self forKeyPath:@"isProcessing" options:0 context:nil];
}
-/**
- * When receiving an update for a bound value - an observed value on the
- * document - ask the tab bar control to redraw as appropriate.
- */
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
-{
- [tabBar update];
-}
-
-@end \ No newline at end of file
+@end
diff --git a/Source/SPXMLExporter.m b/Source/SPXMLExporter.m
index dfd55bf0..8ff99e0d 100644
--- a/Source/SPXMLExporter.m
+++ b/Source/SPXMLExporter.m
@@ -23,12 +23,11 @@
//
// More info at <http://code.google.com/p/sequel-pro/>
-#import <MCPKit/MCPKit.h>
-
#import "SPXMLExporter.h"
#import "SPExportFile.h"
#import "SPFileHandle.h"
#import "SPExportUtilities.h"
+#import "SPMySQL.h"
@implementation SPXMLExporter
@@ -73,9 +72,9 @@
NSString *dataConversionString = nil;
// Result sets
- MCPResult *statusResult = nil;
- MCPResult *structureResult = nil;
- MCPStreamingResult *streamingResult = nil;
+ SPMySQLResult *statusResult = nil;
+ SPMySQLResult *structureResult = nil;
+ SPMySQLFastStreamingResult *streamingResult = nil;
NSMutableArray *xmlTags = [NSMutableArray array];
NSMutableString *xmlString = [NSMutableString string];
@@ -107,7 +106,7 @@
isTableExport = YES;
- totalRows = [[[[connection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] fetchRowAsArray] objectAtIndex:0] integerValue];
+ totalRows = [[connection getFirstFieldFromQuery:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@", [[self xmlTableName] backtickQuotedString]]] integerValue];
streamingResult = [connection streamingQueryString:[NSString stringWithFormat:@"SELECT * FROM %@", [[self xmlTableName] backtickQuotedString]] useLowMemoryBlockingStreaming:[self exportUsingLowMemoryBlockingStreaming]];
// Only include the structure if necessary
@@ -118,17 +117,12 @@
[escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])];
statusResult = [connection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE %@", escapedTableName]];
- if ([structureResult numOfRows] && [statusResult numOfRows]) {
-
- [statusResult dataSeek:0];
- [structureResult dataSeek:0];
-
+ if ([structureResult numberOfRows] && [statusResult numberOfRows]) {
+
[xmlString appendFormat:@"\t<table_structure name=\"%@\">\n", [self xmlTableName]];
- for (i = 0; i < [structureResult numOfRows]; i++)
+ for (NSDictionary *row in structureResult)
{
- NSDictionary *row = [structureResult fetchRowAsDictionary];
-
[xmlString appendFormat:@"\t\t<field field=\"%@\" type=\"%@\" null=\"%@\" key=\"%@\" default=\"%@\" extra=\"%@\" />\n",
[row objectForKey:@"Field"],
[row objectForKey:@"Type"],
@@ -138,7 +132,7 @@
[row objectForKey:@"Extra"]];
}
- NSDictionary *row = [statusResult fetchRowAsDictionary];
+ NSDictionary *row = [statusResult getRowAsDictionary];
[xmlString appendFormat:@"\n\t\t<options name=\"%@\" engine=\"%@\" version=\"%@\" row_format=\"%@\" rows=\"%@\" avg_row_length=\"%@\" data_length=\"%@\" max_data_length=\"%@\" index_length=\"%@\" data_free=\"%@\" create_time=\"%@\" update_time=\"%@\" collation=\"%@\" create_options=\"%@\" comment=\"%@\" />\n",
[row objectForKey:@"Name"],
@@ -175,7 +169,7 @@
if ((!isTableExport) || (isTableExport && [self xmlOutputIncludeContent])) {
// Set up an array of encoded field names as opening and closing tags
- fieldNames = ([self xmlDataArray]) ? NSArrayObjectAtIndex([self xmlDataArray], 0) : [streamingResult fetchFieldNames];
+ fieldNames = ([self xmlDataArray]) ? NSArrayObjectAtIndex([self xmlDataArray], 0) : [streamingResult fieldNames];
for (i = 0; i < [fieldNames count]; i++)
{
@@ -225,7 +219,7 @@
}
// Or by reading an appropriate row from the streaming result
else {
- xmlRow = [streamingResult fetchNextRowAsArray];
+ xmlRow = [streamingResult getRowAsArray];
if (!xmlRow) break;
}
@@ -265,14 +259,14 @@
[xmlItem setString:[NSString stringWithString:dataConversionString]];
[dataConversionString release];
}
- else if ([data isKindOfClass:[NSNull class]]) {
+ else if (data == [NSNull null]) {
dataIsNULL = YES;
if ([self xmlFormat] == SPXMLExportPlainFormat) {
[xmlItem setString:[self xmlNULLString]];
}
}
- else if ([data isKindOfClass:[MCPGeometryData class]]) {
+ else if ([data isKindOfClass:[SPMySQLGeometryData class]]) {
[xmlItem setString:[data wktString]];
}
else {
diff --git a/Source/SPXMLExporterDelegate.m b/Source/SPXMLExporterDelegate.m
index 7f286c46..013019b2 100644
--- a/Source/SPXMLExporterDelegate.m
+++ b/Source/SPXMLExporterDelegate.m
@@ -27,6 +27,7 @@
#import "SPXMLExporter.h"
#import "SPDatabaseDocument.h"
#import "SPExportFile.h"
+#import "SPMySQL.h"
@implementation SPExportController (SPXMLExporterDelegate)