aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m5
-rw-r--r--Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m5
-rw-r--r--Interfaces/English.lproj/DBView.xib97
-rw-r--r--Source/SPDataStorage.m390
-rw-r--r--Source/SPDatabaseStructure.m1
-rw-r--r--Source/SPExtendedTableInfo.m7
-rw-r--r--Source/SPQueryFavoriteManager.m2
-rw-r--r--Source/SPTableCopy.m11
8 files changed, 241 insertions, 277 deletions
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
index e5a48d48..d96ebe52 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection Categories/Querying & Preparation.m
@@ -296,7 +296,7 @@
[self _lockConnection];
unsigned long long theAffectedRowCount;
- while (queryAttemptsAllowed > 0) {
+ do {
// While recording the overall execution time (including network lag!), run
// the raw query
@@ -342,8 +342,7 @@
[self _lockConnection];
NSAssert(mySQLConnection != NULL, @"mySQLConnection has disappeared while checking it!");
- queryAttemptsAllowed--;
- }
+ } while (--queryAttemptsAllowed > 0);
id theResult = nil;
diff --git a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
index e102c24d..286296af 100644
--- a/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
+++ b/Frameworks/SPMySQLFramework/Source/SPMySQLConnection.m
@@ -928,7 +928,10 @@ static uint64_t _elapsedMicroSecondsSinceAbsoluteTime(uint64_t comparisonTime)
uint64_t disconnectStartTime_t = mach_absolute_time();
while (![self _tryLockConnection]) {
usleep(100000);
- if (_elapsedSecondsSinceAbsoluteTime(disconnectStartTime_t) > 10) break;
+ if (_elapsedSecondsSinceAbsoluteTime(disconnectStartTime_t) > 10) {
+ NSLog(@"%s: Could not acquire connection lock within time limit (10s). Forcing unlock!",__PRETTY_FUNCTION__);
+ break;
+ }
}
[self _unlockConnection];
[self _cancelKeepAlives];
diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib
index dd04904d..7ffa8fc8 100644
--- a/Interfaces/English.lproj/DBView.xib
+++ b/Interfaces/English.lproj/DBView.xib
@@ -5403,79 +5403,6 @@
<int key="NSCellFlags">68157504</int>
<int key="NSCellFlags2">272761856</int>
<reference key="NSSupport" ref="26"/>
- <object class="NSNumberFormatter" key="NSFormatter" id="597232718">
- <dictionary class="NSMutableDictionary" key="NS.attributes">
- <boolean value="YES" key="allowsFloats"/>
- <boolean value="NO" key="alwaysShowsDecimalSeparator"/>
- <string key="currencyDecimalSeparator">.</string>
- <string key="decimalSeparator">.</string>
- <string key="exponentSymbol">E</string>
- <integer value="0" key="formatWidth"/>
- <integer value="1040" key="formatterBehavior"/>
- <boolean value="NO" key="generatesDecimalNumbers"/>
- <string key="groupingSeparator">,</string>
- <integer value="3" key="groupingSize"/>
- <boolean value="YES" key="lenient"/>
- <integer value="3" key="maximumFractionDigits"/>
- <integer value="309" key="maximumIntegerDigits"/>
- <real value="1" key="minimum"/>
- <integer value="0" key="minimumFractionDigits"/>
- <integer value="1" key="minimumIntegerDigits"/>
- <string key="minusSign">-</string>
- <string key="negativeFormat">#,##0.###</string>
- <string key="negativeInfinitySymbol">-∞</string>
- <string key="negativePrefix">-</string>
- <string key="negativeSuffix"/>
- <string key="nilSymbol"/>
- <string key="notANumberSymbol">NaN</string>
- <integer value="1" key="numberStyle"/>
- <string key="paddingCharacter">*</string>
- <integer value="0" key="paddingPosition"/>
- <string key="perMillSymbol">‰</string>
- <string key="percentSymbol">%</string>
- <string key="plusSign">+</string>
- <string key="positiveFormat">#,##0.###</string>
- <string key="positiveInfinitySymbol">+∞</string>
- <string key="positivePrefix"/>
- <string key="positiveSuffix"/>
- <real value="0.0" key="roundingIncrement"/>
- <integer value="4" key="roundingMode"/>
- <integer value="0" key="secondaryGroupingSize"/>
- <boolean value="YES" key="usesGroupingSeparator"/>
- </dictionary>
- <string key="NS.positiveformat">#,##0.###</string>
- <string key="NS.negativeformat">#,##0.###</string>
- <nil key="NS.positiveattrs"/>
- <nil key="NS.negativeattrs"/>
- <nil key="NS.zero"/>
- <object class="NSAttributedString" key="NS.nil">
- <string key="NSString"/>
- </object>
- <object class="NSAttributedString" key="NS.nan">
- <string key="NSString">NaN</string>
- <dictionary key="NSAttributes" id="10305650"/>
- </object>
- <real value="1" key="NS.min"/>
- <object class="NSDecimalNumberPlaceholder" key="NS.max" id="581212392">
- <int key="NS.exponent">0</int>
- <int key="NS.length">0</int>
- <bool key="NS.negative">YES</bool>
- <bool key="NS.compact">NO</bool>
- <int key="NS.mantissa.bo">1</int>
- <bytes key="NS.mantissa">AAAAAAAAAAAAAAAAAAAAAA</bytes>
- </object>
- <object class="NSDecimalNumberHandler" key="NS.rounding">
- <int key="NS.roundingmode">3</int>
- <bool key="NS.raise.overflow">YES</bool>
- <bool key="NS.raise.underflow">YES</bool>
- <bool key="NS.raise.dividebyzero">YES</bool>
- </object>
- <string key="NS.decimal">.</string>
- <string key="NS.thousand">,</string>
- <bool key="NS.hasthousands">YES</bool>
- <bool key="NS.localized">YES</bool>
- <bool key="NS.allowsfloats">YES</bool>
- </object>
<reference key="NSControlView" ref="735808692"/>
<reference key="NSBackgroundColor" ref="647098198"/>
<reference key="NSTextColor" ref="667308713"/>
@@ -8136,10 +8063,17 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
</object>
<object class="NSAttributedString" key="NS.nan">
<string key="NSString">NaN</string>
- <reference key="NSAttributes" ref="10305650"/>
+ <dictionary key="NSAttributes"/>
</object>
<real value="1" key="NS.min"/>
- <reference key="NS.max" ref="581212392"/>
+ <object class="NSDecimalNumberPlaceholder" key="NS.max">
+ <int key="NS.exponent">0</int>
+ <int key="NS.length">0</int>
+ <bool key="NS.negative">YES</bool>
+ <bool key="NS.compact">NO</bool>
+ <int key="NS.mantissa.bo">1</int>
+ <bytes key="NS.mantissa">AAAAAAAAAAAAAAAAAAAAAA</bytes>
+ </object>
<object class="NSDecimalNumberHandler" key="NS.rounding">
<int key="NS.roundingmode">3</int>
<bool key="NS.raise.overflow">YES</bool>
@@ -19990,17 +19924,10 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA</bytes>
<object class="IBObjectRecord">
<string key="id">5782</string>
<reference key="object" ref="105876720"/>
- <array class="NSMutableArray" key="children">
- <reference ref="597232718"/>
- </array>
+ <array class="NSMutableArray" key="children"/>
<reference key="parent" ref="735808692"/>
</object>
<object class="IBObjectRecord">
- <string key="id">6879</string>
- <reference key="object" ref="597232718"/>
- <reference key="parent" ref="105876720"/>
- </object>
- <object class="IBObjectRecord">
<string key="id">5793</string>
<reference key="object" ref="503851323"/>
<array class="NSMutableArray" key="children">
@@ -26134,10 +26061,6 @@ AAEAAQAAAT0AAwAAAAEAAgAAAVIAAwAAAAEAAQAAAVMAAwAAAAIAAQABAAAAAA</bytes>
<boolean value="NO" key="6877.showNotes"/>
<string key="6878.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<boolean value="NO" key="6878.showNotes"/>
- <integer value="1041" key="6879.IBNumberFormatterBehaviorMetadataKey"/>
- <boolean value="YES" key="6879.IBNumberFormatterLocalizesFormatMetadataKey"/>
- <string key="6879.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
- <boolean value="NO" key="6879.showNotes"/>
<string key="6885.IBPluginDependency">com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference key="6885.IBUserGuides" ref="0"/>
<boolean value="NO" key="6885.showNotes"/>
diff --git a/Source/SPDataStorage.m b/Source/SPDataStorage.m
index bae17111..46db243f 100644
--- a/Source/SPDataStorage.m
+++ b/Source/SPDataStorage.m
@@ -62,41 +62,46 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) setDataStorage:(SPMySQLStreamingResultStore *)newDataStorage updatingExisting:(BOOL)updateExistingStore
{
- NSUInteger i;
- editedRowCount = 0;
- SPClear(editedRows);
- @synchronized(self) {
- if (unloadedColumns) {
- [self _recordClearingUnloadedColumnsAt:mach_absolute_time() from:[NSThread callStackSymbols]];
- free(unloadedColumns), unloadedColumns = NULL;
- }
- }
-
-
- if (dataStorage) {
+ SPMySQLStreamingResultStore *oldDataStorage = dataStorage;
+ if (oldDataStorage) {
// If the table is reloading data, link to the current data store for smoother loads
if (updateExistingStore) {
- [newDataStorage replaceExistingResultStore:dataStorage];
+ [newDataStorage replaceExistingResultStore:oldDataStorage];
}
-
- SPClear(dataStorage);
}
- dataStorage = [newDataStorage retain];
- [dataStorage setDelegate:self];
+ [newDataStorage retain];
- numberOfColumns = [dataStorage numberOfFields];
- editedRows = [NSPointerArray new];
- if ([dataStorage dataDownloaded]) {
- [self resultStoreDidFinishLoadingData:dataStorage];
+ NSPointerArray *newEditedRows = [[NSPointerArray alloc] init];
+ NSUInteger newNumberOfColumns = [newDataStorage numberOfFields];
+ BOOL *newUnloadedColumns = calloc(newNumberOfColumns, sizeof(BOOL));
+ for (NSUInteger i = 0; i < newNumberOfColumns; i++) {
+ newUnloadedColumns[i] = NO;
}
-
+
+ BOOL *oldUnloadedColumns = unloadedColumns;
+ NSPointerArray *oldEditedRows = editedRows;
@synchronized(self) {
- unloadedColumns = calloc(numberOfColumns, sizeof(BOOL));
- for (i = 0; i < numberOfColumns; i++) {
- unloadedColumns[i] = NO;
- }
+ dataStorage = newDataStorage;
+ numberOfColumns = newNumberOfColumns;
+ unloadedColumns = newUnloadedColumns;
+ editedRowCount = 0;
+ editedRows = newEditedRows;
+ }
+ free(oldUnloadedColumns);
+ [oldEditedRows release];
+ [oldDataStorage release];
+
+ // the only delegate callback is resultStoreDidFinishLoadingData:.
+ // We can't set the delegate before exchanging the dataStorage ivar since then
+ // the message would come from an unknown object.
+ // But if we set it afterwards, we risk losing the callback event (since it could've
+ // happened in the meantime) - this is what the following if() is for.
+ [newDataStorage setDelegate:self];
+
+ if ([newDataStorage dataDownloaded]) {
+ [self resultStoreDidFinishLoadingData:newDataStorage];
}
}
@@ -109,30 +114,30 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (NSMutableArray *) rowContentsAtIndex:(NSUInteger)anIndex
{
-
- // If an edited row exists for the supplied index, return it
- if (anIndex < editedRowCount) {
- NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, anIndex);
-
- if (editedRow != NULL) {
- return editedRow;
- }
- }
-
- // Otherwise, prepare to return the underlying storage row
- NSMutableArray *dataArray = SPMySQLResultStoreGetRow(dataStorage, anIndex);
-
- // Modify unloaded cells as appropriate
+ SPNotLoaded *notLoaded = [SPNotLoaded notLoaded];
@synchronized(self) {
+ // If an edited row exists for the supplied index, return it
+ if (anIndex < editedRowCount) {
+ NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, anIndex);
+
+ if (editedRow != NULL) {
+ return editedRow;
+ }
+ }
+
+ // Otherwise, prepare to return the underlying storage row
+ NSMutableArray *dataArray = SPMySQLResultStoreGetRow(dataStorage, anIndex);
+
+ // Modify unloaded cells as appropriate
[self _assesUnloadedColumnsIsSet];
for (NSUInteger i = 0; i < numberOfColumns; i++) {
if (unloadedColumns[i]) {
- CFArraySetValueAtIndex((CFMutableArrayRef)dataArray, i, [SPNotLoaded notLoaded]);
+ CFArraySetValueAtIndex((CFMutableArrayRef)dataArray, i, notLoaded);
}
}
+
+ return dataArray;
}
-
- return dataArray;
}
/**
@@ -140,30 +145,31 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (id) cellDataAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex
{
- // If an edited row exists at the supplied index, return it
- if (rowIndex < editedRowCount) {
- NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
+ SPNotLoaded *notLoaded = [SPNotLoaded notLoaded];
+ @synchronized(self) {
+ // If an edited row exists at the supplied index, return it
+ if (rowIndex < editedRowCount) {
+ NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
- if (editedRow != NULL) {
- return CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
+ if (editedRow != NULL) {
+ return CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
+ }
}
- }
- // Throw an exception if the column index is out of bounds
- if (columnIndex >= numberOfColumns) {
- [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
- }
+ // Throw an exception if the column index is out of bounds
+ if (columnIndex >= numberOfColumns) {
+ [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
+ }
- // If the specified column is not loaded, return a SPNotLoaded reference
- @synchronized(self) {
+ // If the specified column is not loaded, return a SPNotLoaded reference
[self _assesUnloadedColumnsIsSet];
if (unloadedColumns[columnIndex]) {
- return [SPNotLoaded notLoaded];
+ return notLoaded;
}
- }
- // Return the content
- return SPMySQLResultStoreObjectAtRowAndColumn(dataStorage, rowIndex, columnIndex);
+ // Return the content
+ return SPMySQLResultStoreObjectAtRowAndColumn(dataStorage, rowIndex, columnIndex);
+ }
}
/**
@@ -172,35 +178,35 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (id) cellPreviewAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex previewLength:(NSUInteger)previewLength
{
-
- // If an edited row exists at the supplied index, return it
- if (rowIndex < editedRowCount) {
- NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
-
- if (editedRow != NULL) {
- id anObject = CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
- if ([anObject isKindOfClass:[NSString class]] && [(NSString *)anObject length] > 150) {
- return ([NSString stringWithFormat:@"%@...", [anObject substringToIndex:147]]);
+ SPNotLoaded *notLoaded = [SPNotLoaded notLoaded];
+ @synchronized(self) {
+ // If an edited row exists at the supplied index, return it
+ if (rowIndex < editedRowCount) {
+ NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
+
+ if (editedRow != NULL) {
+ id anObject = CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex);
+ if ([anObject isKindOfClass:[NSString class]] && [(NSString *)anObject length] > 150) {
+ return ([NSString stringWithFormat:@"%@...", [anObject substringToIndex:147]]);
+ }
+ return anObject;
}
- return anObject;
}
- }
- // Throw an exception if the column index is out of bounds
- if (columnIndex >= numberOfColumns) {
- [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
- }
+ // Throw an exception if the column index is out of bounds
+ if (columnIndex >= numberOfColumns) {
+ [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
+ }
- // If the specified column is not loaded, return a SPNotLoaded reference
- @synchronized(self) {
+ // If the specified column is not loaded, return a SPNotLoaded reference
[self _assesUnloadedColumnsIsSet];
if (unloadedColumns[columnIndex]) {
- return [SPNotLoaded notLoaded];
+ return notLoaded;
}
- }
- // Return the content
- return SPMySQLResultStorePreviewAtRowAndColumn(dataStorage, rowIndex, columnIndex, previewLength);
+ // Return the content
+ return SPMySQLResultStorePreviewAtRowAndColumn(dataStorage, rowIndex, columnIndex, previewLength);
+ }
}
/**
@@ -208,28 +214,29 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (BOOL) cellIsNullOrUnloadedAtRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex
{
- // If an edited row exists at the supplied index, check it for a NULL.
- if (rowIndex < editedRowCount) {
- NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
+ @synchronized(self) {
+ // If an edited row exists at the supplied index, check it for a NULL.
+ if (rowIndex < editedRowCount) {
+ NSMutableArray *editedRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
- if (editedRow != NULL) {
- return [(id)CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex) isNSNull];
+ if (editedRow != NULL) {
+ return [(id)CFArrayGetValueAtIndex((CFArrayRef)editedRow, columnIndex) isNSNull];
+ }
+ }
+
+ // Throw an exception if the column index is out of bounds
+ if (columnIndex >= numberOfColumns) {
+ [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
}
- }
- // Throw an exception if the column index is out of bounds
- if (columnIndex >= numberOfColumns) {
- [NSException raise:NSRangeException format:@"Requested storage column (col %llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
- }
- @synchronized(self) {
[self _assesUnloadedColumnsIsSet];
if (unloadedColumns[columnIndex]) {
return YES;
}
- }
- return [dataStorage cellIsNullAtRow:rowIndex column:columnIndex];
+ return [dataStorage cellIsNullAtRow:rowIndex column:columnIndex];
+ }
}
#pragma mark -
@@ -242,26 +249,29 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len
{
- NSMutableArray *targetRow = NULL;
-
- // If the start index is out of bounds, return 0 to indicate end of results
- if (state->state >= SPMySQLResultStoreGetRowCount(dataStorage)) return 0;
-
- // If an edited row exists for the supplied index, use that; otherwise use the underlying
- // storage row
- if (state->state < editedRowCount) {
- targetRow = SPDataStorageGetEditedRow(editedRows, state->state);
- }
+ NSMutableArray *targetRow = nil;
+ size_t srcObject;
+
+ SPNotLoaded *notLoaded = [SPNotLoaded notLoaded];
+ @synchronized(self) {
+ srcObject = (size_t)dataStorage ^ (size_t)editedRows ^ editedRowCount;
+ // If the start index is out of bounds, return 0 to indicate end of results
+ if (state->state >= SPMySQLResultStoreGetRowCount(dataStorage)) return 0;
+
+ // If an edited row exists for the supplied index, use that; otherwise use the underlying
+ // storage row
+ if (state->state < editedRowCount) {
+ targetRow = SPDataStorageGetEditedRow(editedRows, state->state);
+ }
- if (targetRow == NULL) {
- targetRow = SPMySQLResultStoreGetRow(dataStorage, state->state);
+ if (targetRow == nil) {
+ targetRow = SPMySQLResultStoreGetRow(dataStorage, state->state);
- // Modify unloaded cells as appropriate
- @synchronized(self) {
+ // Modify unloaded cells as appropriate
[self _assesUnloadedColumnsIsSet];
for (NSUInteger i = 0; i < numberOfColumns; i++) {
if (unloadedColumns[i]) {
- CFArraySetValueAtIndex((CFMutableArrayRef)targetRow, i, [SPNotLoaded notLoaded]);
+ CFArraySetValueAtIndex((CFMutableArrayRef)targetRow, i, notLoaded);
}
}
}
@@ -272,7 +282,7 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
state->state += 1;
state->itemsPtr = stackbuf;
- state->mutationsPtr = (unsigned long *)self;
+ state->mutationsPtr = (unsigned long *)srcObject;
return 1;
}
@@ -287,16 +297,17 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) addRowWithContents:(NSMutableArray *)aRow
{
+ @synchronized(self) {
+ // Verify the row is of the correct length
+ [self _checkNewRow:aRow];
- // Verify the row is of the correct length
- [self _checkNewRow:aRow];
-
- // Add the new row to the editable store
- [editedRows addPointer:aRow];
- editedRowCount++;
+ // Add the new row to the editable store
+ [editedRows addPointer:aRow];
+ editedRowCount++;
- // Update the underlying store as well to keep counts correct
- [dataStorage addDummyRow];
+ // Update the underlying store as well to keep counts correct
+ [dataStorage addDummyRow];
+ }
}
/**
@@ -306,27 +317,29 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) insertRowContents:(NSMutableArray *)aRow atIndex:(NSUInteger)anIndex
{
- unsigned long long numberOfRows = SPMySQLResultStoreGetRowCount(dataStorage);
+ @synchronized(self) {
+ unsigned long long numberOfRows = SPMySQLResultStoreGetRowCount(dataStorage);
- // Verify the row is of the correct length
- [self _checkNewRow:aRow];
+ // Verify the row is of the correct length
+ [self _checkNewRow:aRow];
- // Throw an exception if the index is out of bounds
- if (anIndex > numberOfRows) {
- [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)anIndex, numberOfRows];
- }
+ // Throw an exception if the index is out of bounds
+ if (anIndex > numberOfRows) {
+ [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)anIndex, numberOfRows];
+ }
- // If "inserting" at the end of the array just add a row
- if (anIndex == numberOfRows) {
- return [self addRowWithContents:aRow];
- }
+ // If "inserting" at the end of the array just add a row
+ if (anIndex == numberOfRows) {
+ return [self addRowWithContents:aRow];
+ }
- // Add the new row to the editable store
- [editedRows insertPointer:aRow atIndex:anIndex];
- editedRowCount++;
+ // Add the new row to the editable store
+ [editedRows insertPointer:aRow atIndex:anIndex];
+ editedRowCount++;
- // Update the underlying store to keep counts and indices correct
- [dataStorage insertDummyRowAtIndex:anIndex];
+ // Update the underlying store to keep counts and indices correct
+ [dataStorage insertDummyRowAtIndex:anIndex];
+ }
}
/**
@@ -334,8 +347,10 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) replaceRowAtIndex:(NSUInteger)anIndex withRowContents:(NSMutableArray *)aRow
{
- [self _checkNewRow:aRow];
- [editedRows replacePointerAtIndex:anIndex withPointer:aRow];
+ @synchronized(self) {
+ [self _checkNewRow:aRow];
+ [editedRows replacePointerAtIndex:anIndex withPointer:aRow];
+ }
}
/**
@@ -343,16 +358,18 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) replaceObjectInRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex withObject:(id)anObject
{
- NSMutableArray *editableRow = NULL;
+ NSMutableArray *editableRow = nil;
- if (rowIndex < editedRowCount) {
- editableRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
- }
+ @synchronized(self) {
+ if (rowIndex < editedRowCount) {
+ editableRow = SPDataStorageGetEditedRow(editedRows, rowIndex);
+ }
- // Make sure that the row in question is editable
- if (editableRow == NULL) {
- editableRow = [self rowContentsAtIndex:rowIndex];
- [editedRows replacePointerAtIndex:rowIndex withPointer:editableRow];
+ // Make sure that the row in question is editable
+ if (editableRow == nil) {
+ editableRow = [self rowContentsAtIndex:rowIndex];
+ [editedRows replacePointerAtIndex:rowIndex withPointer:editableRow];
+ }
}
// Modify the cell
@@ -364,18 +381,19 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) removeRowAtIndex:(NSUInteger)anIndex
{
+ @synchronized(self) {
+ // Throw an exception if the index is out of bounds
+ if (anIndex >= SPMySQLResultStoreGetRowCount(dataStorage)) {
+ [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)anIndex, SPMySQLResultStoreGetRowCount(dataStorage)];
+ }
- // Throw an exception if the index is out of bounds
- if (anIndex >= SPMySQLResultStoreGetRowCount(dataStorage)) {
- [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)anIndex, SPMySQLResultStoreGetRowCount(dataStorage)];
- }
-
- // Remove the row from the edited list and underlying storage
- if (anIndex < editedRowCount) {
- editedRowCount--;
- [editedRows removePointerAtIndex:anIndex];
+ // Remove the row from the edited list and underlying storage
+ if (anIndex < editedRowCount) {
+ editedRowCount--;
+ [editedRows removePointerAtIndex:anIndex];
+ }
+ [dataStorage removeRowAtIndex:anIndex];
}
- [dataStorage removeRowAtIndex:anIndex];
}
/**
@@ -384,19 +402,20 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) removeRowsInRange:(NSRange)rangeToRemove
{
+ @synchronized(self) {
+ // Throw an exception if the range is out of bounds
+ if (NSMaxRange(rangeToRemove) > SPMySQLResultStoreGetRowCount(dataStorage)) {
+ [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)(NSMaxRange(rangeToRemove)), SPMySQLResultStoreGetRowCount(dataStorage)];
+ }
- // Throw an exception if the range is out of bounds
- if (NSMaxRange(rangeToRemove) > SPMySQLResultStoreGetRowCount(dataStorage)) {
- [NSException raise:NSRangeException format:@"Requested storage index (%llu) beyond bounds (%llu)", (unsigned long long)(NSMaxRange(rangeToRemove)), SPMySQLResultStoreGetRowCount(dataStorage)];
- }
-
- // Remove the rows from the edited list and underlying storage
- NSUInteger i = MIN(editedRowCount, NSMaxRange(rangeToRemove));
- while (--i >= rangeToRemove.location) {
- editedRowCount--;
- [editedRows removePointerAtIndex:i];
+ // Remove the rows from the edited list and underlying storage
+ NSUInteger i = MIN(editedRowCount, NSMaxRange(rangeToRemove));
+ while (--i >= rangeToRemove.location) {
+ editedRowCount--;
+ [editedRows removePointerAtIndex:i];
+ }
+ [dataStorage removeRowsInRange:rangeToRemove];
}
- [dataStorage removeRowsInRange:rangeToRemove];
}
/**
@@ -404,9 +423,11 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) removeAllRows
{
- editedRowCount = 0;
- [editedRows setCount:0];
- [dataStorage removeAllRows];
+ @synchronized(self) {
+ editedRowCount = 0;
+ [editedRows setCount:0];
+ [dataStorage removeAllRows];
+ }
}
#pragma mark - Unloaded columns
@@ -417,10 +438,10 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void) setColumnAsUnloaded:(NSUInteger)columnIndex
{
- if (columnIndex >= numberOfColumns) {
- [NSException raise:NSRangeException format:@"Invalid column set as unloaded; requested column index (%llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
- }
@synchronized(self) {
+ if (columnIndex >= numberOfColumns) {
+ [NSException raise:NSRangeException format:@"Invalid column set as unloaded; requested column index (%llu) beyond bounds (%llu)", (unsigned long long)columnIndex, (unsigned long long)numberOfColumns];
+ }
[self _assesUnloadedColumnsIsSet];
unloadedColumns[columnIndex] = YES;
}
@@ -433,7 +454,9 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (NSUInteger) count
{
- return (NSUInteger)[dataStorage numberOfRows];
+ @synchronized(self) {
+ return (NSUInteger)[dataStorage numberOfRows];
+ }
}
/**
@@ -441,7 +464,9 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (NSUInteger) columnCount
{
- return numberOfColumns;
+ @synchronized(self) {
+ return numberOfColumns;
+ }
}
/**
@@ -449,7 +474,9 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (BOOL) dataDownloaded
{
- return !dataStorage || [dataStorage dataDownloaded];
+ @synchronized(self) {
+ return !dataStorage || [dataStorage dataDownloaded];
+ }
}
#pragma mark - Delegate callback methods
@@ -459,8 +486,10 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
- (void)resultStoreDidFinishLoadingData:(SPMySQLStreamingResultStore *)resultStore
{
- [editedRows setCount:(NSUInteger)[resultStore numberOfRows]];
- editedRowCount = [editedRows count];
+ @synchronized(self) {
+ [editedRows setCount:(NSUInteger)[resultStore numberOfRows]];
+ editedRowCount = [editedRows count];
+ }
}
/**
@@ -468,7 +497,8 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
*/
#pragma mark -
-- (id) init {
+- (id) init
+{
if ((self = [super init])) {
dataStorage = nil;
editedRows = nil;
@@ -483,10 +513,11 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
return self;
}
-- (void) dealloc {
- SPClear(dataStorage);
- SPClear(editedRows);
+- (void) dealloc
+{
@synchronized(self) {
+ SPClear(dataStorage);
+ SPClear(editedRows);
if (unloadedColumns) {
[self _recordClearingUnloadedColumnsAt:mach_absolute_time() from:[NSThread callStackSymbols]];
free(unloadedColumns), unloadedColumns = NULL;
@@ -506,6 +537,7 @@ static inline NSMutableArray* SPDataStorageGetEditedRow(NSPointerArray* rowStore
@implementation SPDataStorage (PrivateAPI)
+// DO NOT CALL THIS METHOD UNLESS YOU CURRENTLY HAVE A LOCK ON SELF!!!
- (void) _checkNewRow:(NSMutableArray *)aRow
{
if ([aRow count] != numberOfColumns) {
diff --git a/Source/SPDatabaseStructure.m b/Source/SPDatabaseStructure.m
index a4663268..b1bed3c9 100644
--- a/Source/SPDatabaseStructure.m
+++ b/Source/SPDatabaseStructure.m
@@ -275,6 +275,7 @@
// 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];
+ structureWasUpdated = YES;
NSUInteger uniqueCounter = 0; // used to make field data unique
SPMySQLResult *theResult;
diff --git a/Source/SPExtendedTableInfo.m b/Source/SPExtendedTableInfo.m
index 26574621..e2f38a69 100644
--- a/Source/SPExtendedTableInfo.m
+++ b/Source/SPExtendedTableInfo.m
@@ -224,7 +224,11 @@ static NSString *SPMySQLCommentField = @"Comment";
{
[tableRowAutoIncrement setEditable:NO];
- [tableSourceInstance takeAutoIncrementFrom:tableRowAutoIncrement];
+ NSNumberFormatter *fmt = [[[NSNumberFormatter alloc] init] autorelease];
+ [fmt setNumberStyle:NSNumberFormatterDecimalStyle];
+ NSNumber *value = [fmt numberFromString:[tableRowAutoIncrement stringValue]];
+
+ [tableSourceInstance setAutoIncrementTo:value];
}
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
@@ -232,6 +236,7 @@ static NSString *SPMySQLCommentField = @"Comment";
// Listen to ESC to abort editing of auto increment input field
if (command == @selector(cancelOperation:) && control == tableRowAutoIncrement) {
[tableRowAutoIncrement abortEditing];
+ [tableRowAutoIncrement setEditable:NO];
return YES;
}
diff --git a/Source/SPQueryFavoriteManager.m b/Source/SPQueryFavoriteManager.m
index 5857b1b7..542184c4 100644
--- a/Source/SPQueryFavoriteManager.m
+++ b/Source/SPQueryFavoriteManager.m
@@ -488,7 +488,7 @@
#ifndef SP_CODA
- (IBAction)showHelp:(id)sender
{
- [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:NSLocalizedString(@"http://www.sequelpro.com/docs/Query_Favorites", @"Localized help page for query favourites - do not localize if no translated webpage is available")]];
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:NSLocalizedString(@"http://www.sequelpro.com/docs/Working_with_Query_Favorites", @"Localized help page for query favourites - do not localize if no translated webpage is available")]];
}
#endif
diff --git a/Source/SPTableCopy.m b/Source/SPTableCopy.m
index cd3fc42e..07f03846 100644
--- a/Source/SPTableCopy.m
+++ b/Source/SPTableCopy.m
@@ -44,9 +44,9 @@
- (BOOL)copyTable:(NSString *)tableName from:(NSString *)sourceDB to:(NSString *)targetDB
{
NSString *createTableResult = [self _createTableStatementFor:tableName inDatabase:sourceDB];
- NSMutableString *createTableStatement = [[NSMutableString alloc] initWithString:createTableResult];
- if ([[createTableStatement substringToIndex:12] isEqualToString:@"CREATE TABLE"]) {
+ if ([createTableResult hasPrefix:@"CREATE TABLE"]) {
+ NSMutableString *createTableStatement = [[NSMutableString alloc] initWithString:createTableResult];
// Add the target DB name and the separator dot after "CREATE TABLE ".
[createTableStatement insertString:@"." atIndex:13];
@@ -59,8 +59,6 @@
return ![connection queryErrored];
}
- [createTableStatement release];
-
return NO;
}
@@ -151,7 +149,10 @@
SPMySQLResult *theResult = [connection queryString:showCreateTableStatment];
- return [theResult numberOfRows] > 0 ? [[theResult getRowAsArray] objectAtIndex:1] : @"";
+ if([theResult numberOfRows] > 0) return [[theResult getRowAsArray] objectAtIndex:1];
+
+ NSLog(@"query <%@> failed to return the expected result.\n Error state: %@ (%lu)",showCreateTableStatment,[connection lastErrorMessage],[connection lastErrorID]);
+ return nil;
}
@end