aboutsummaryrefslogtreecommitdiffstats
path: root/Source/CustomQuery.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CustomQuery.m')
-rw-r--r--Source/CustomQuery.m72
1 files changed, 56 insertions, 16 deletions
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m
index 826258cd..522fb5d0 100644
--- a/Source/CustomQuery.m
+++ b/Source/CustomQuery.m
@@ -807,7 +807,9 @@
// Remove all items from the table
fullResultCount = 0;
[customQueryView performSelectorOnMainThread:@selector(noteNumberOfRowsChanged) withObject:nil waitUntilDone:YES];
+ pthread_mutex_lock(&fullResultLock);
[fullResult removeAllObjects];
+ pthread_mutex_unlock(&fullResultLock);
// Set up an autorelease pool for row processing
dataLoadingPool = [[NSAutoreleasePool alloc] init];
@@ -815,8 +817,10 @@
// Loop through the result rows as they become available
while (tempRow = [theResult fetchNextRowAsArray]) {
+ pthread_mutex_lock(&fullResultLock);
NSMutableArrayAddObject(fullResult, [NSMutableArray arrayWithArray:tempRow]);
fullResultCount++;
+ pthread_mutex_unlock(&fullResultLock);
// Update the count of rows processed
rowsProcessed++;
@@ -1344,16 +1348,34 @@
- (void)tableView:(CMCopyTable *)aTableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn*)aTableColumn row:(NSInteger)rowIndex
{
if (aTableView == customQueryView) {
-
- // Perform various result set checks to prevent crashes
- if ((fullResultCount == 0) || (rowIndex > fullResultCount)) return;
-
+
// For NULL cell's display the user's NULL value placeholder in grey to easily distinguish it from other values
if ([cell respondsToSelector:@selector(setTextColor:)]) {
-
- id value = NSArrayObjectAtIndex(NSArrayObjectAtIndex(fullResult, rowIndex), [[aTableColumn identifier] intValue]);
+ NSUInteger columnIndex = [[aTableColumn identifier] intValue];
+ id theValue = nil;
+
+ // While the table is being loaded, additional validation is required - data
+ // locks must be used to avoid crashes, and indexes higher than the available
+ // rows or columns may be requested. Use gray to show loading in these cases.
+ if (isWorking) {
+ pthread_mutex_lock(&fullResultLock);
+ if (rowIndex < fullResultCount) {
+ NSMutableArray *rowData = NSArrayObjectAtIndex(fullResult, rowIndex);
+ if (columnIndex < [rowData count]) {
+ theValue = NSArrayObjectAtIndex(rowData, columnIndex);
+ }
+ }
+ pthread_mutex_unlock(&fullResultLock);
+
+ if (!theValue) {
+ [cell setTextColor:[NSColor lightGrayColor]];
+ return;
+ }
+ } else {
+ theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(fullResult, rowIndex), columnIndex);
+ }
- [cell setTextColor:[value isNSNull] ? [NSColor lightGrayColor] : [NSColor blackColor]];
+ [cell setTextColor:[theValue isNSNull] ? [NSColor lightGrayColor] : [NSColor blackColor]];
}
}
}
@@ -1364,19 +1386,35 @@
- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
{
if (aTableView == customQueryView) {
+ NSUInteger columnIndex = [[aTableColumn identifier] intValue];
+ id theValue = nil;
+
+ // While the table is being loaded, additional validation is required - data
+ // locks must be used to avoid crashes, and indexes higher than the available
+ // rows or columns may be requested. Return "..." to indicate loading in these
+ // cases.
+ if (isWorking) {
+ pthread_mutex_lock(&fullResultLock);
+ if (rowIndex < fullResultCount) {
+ NSMutableArray *rowData = NSArrayObjectAtIndex(fullResult, rowIndex);
+ if (columnIndex < [rowData count]) {
+ theValue = NSArrayObjectAtIndex(rowData, columnIndex);
+ }
+ }
+ pthread_mutex_unlock(&fullResultLock);
+
+ if (!theValue) return @"...";
+ } else {
+ theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(fullResult, rowIndex), columnIndex);
+ }
- // Perform various result set checks to prevent crashes
- if ((fullResultCount == 0) || (rowIndex > fullResultCount)) return nil;
-
- id value = NSArrayObjectAtIndex(NSArrayObjectAtIndex(fullResult, rowIndex), [[aTableColumn identifier] intValue]);
-
- if ([value isKindOfClass:[NSData class]])
- return [value shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
+ if ([theValue isKindOfClass:[NSData class]])
+ return [theValue shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
- if ([value isNSNull])
+ if ([theValue isNSNull])
return [prefs objectForKey:SPNullValue];
- return value;
+ return theValue;
}
else {
return @"";
@@ -2607,6 +2645,7 @@
*/
- (void) startDocumentTaskForTab:(NSNotification *)aNotification
{
+ isWorking = YES;
// Only proceed if this view is selected.
if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])
@@ -2623,6 +2662,7 @@
*/
- (void) endDocumentTaskForTab:(NSNotification *)aNotification
{
+ isWorking = NO;
// Only proceed if this view is selected.
if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_CUSTOM_QUERY])