aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-07-13 21:05:51 +0000
committerrowanbeentje <rowan@beent.je>2009-07-13 21:05:51 +0000
commit778d7280bae1fe413e0b2db799495454ac165c35 (patch)
treeca520b830274ee08aaefe2db02d903caa329ac70 /Source
parent27db10fe504117dd8b4a166dcfc94881528c44c3 (diff)
downloadsequelpro-778d7280bae1fe413e0b2db799495454ac165c35.tar.gz
sequelpro-778d7280bae1fe413e0b2db799495454ac165c35.tar.bz2
sequelpro-778d7280bae1fe413e0b2db799495454ac165c35.zip
Rework data storage and retrieval in TableContent and CustomQuery backing arrays, and make some editable CustomQuery improvements:
- Switch to using arrays for row storage rather than dictionaries. Use the data column index for table column identifiers. - This fixes Issue #316 and also allows sorting by all custom query result columns using a column index rather than the name - Offers significant speed and memory advantages: result building is now 2x-3x faster, memory used for results storage is 30-40% lower, and result access is slightly faster. (Note full 2x-3x speed results won't be seen - result fetching and mysql binary work isn't included in the timing) - No longer need to fetch the first column of data for tables containing only blob types - Correctly escape strings when editing CustomQuery results - Rewrite NSArrayObjectAtIndex to use the native CFArrayGetValueAtIndex rather than cached selectors - neater code and I think slightly faster
Diffstat (limited to 'Source')
-rw-r--r--Source/CMCopyTable.m46
-rw-r--r--Source/CMMCPResult.m5
-rw-r--r--Source/CustomQuery.h2
-rw-r--r--Source/CustomQuery.m62
-rw-r--r--Source/SPArrayAdditions.h6
-rw-r--r--Source/SPTableData.m1
-rw-r--r--Source/TableContent.h6
-rw-r--r--Source/TableContent.m202
8 files changed, 171 insertions, 159 deletions
diff --git a/Source/CMCopyTable.m b/Source/CMCopyTable.m
index 01f4f4a7..e3717c89 100644
--- a/Source/CMCopyTable.m
+++ b/Source/CMCopyTable.m
@@ -167,11 +167,11 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
NSArray *columns = [self tableColumns];
int numColumns = [columns count];
- NSTableColumn *col = nil;
// NSIndexSet *rowIndexes = [self selectedRowIndexes];
NSString *spNULL = [prefs objectForKey:@"NullValue"];
NSMutableString *value = [NSMutableString stringWithCapacity:10];
- NSDictionary *dbDataRow;
+ NSArray *dbDataRow;
+ NSMutableArray *columnMappings;
id enumObj;
id rowData = nil;
id rowEnumObject = nil;
@@ -184,21 +184,11 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
NSMutableString *result = [NSMutableString stringWithCapacity:numColumns];
- // Create an array of table column names
- NSMutableArray *tbHeader = [NSMutableArray arrayWithCapacity:numColumns];
- enumerate(columns, enumObj)
- [tbHeader addObject:[[enumObj headerCell] stringValue]];
-
- // Create an hash of header name and typegrouping
- NSMutableDictionary *headerType = [NSMutableDictionary dictionaryWithCapacity:numColumns];
- enumerate(columnDefinitions, enumObj)
- [headerType setObject:[enumObj objectForKey:@"typegrouping"] forKey:[enumObj objectForKey:@"name"]];
-
// Create array of types according to the column order
NSMutableArray *types = [NSMutableArray arrayWithCapacity:numColumns];
- enumerate(tbHeader, enumObj)
+ enumerate(columns, enumObj)
{
- NSString *t = [headerType objectForKey:enumObj];
+ NSString *t = [[columnDefinitions objectAtIndex:[[enumObj identifier] intValue]] objectForKey:@"typegrouping"];
if([t isEqualToString:@"bit"] || [t isEqualToString:@"integer"] || [t isEqualToString:@"float"])
[types addObject:[NSNumber numberWithInt:0]]; // numeric
else if([t isEqualToString:@"blobdata"])
@@ -209,12 +199,23 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
[types addObject:[NSNumber numberWithInt:1]]; // string (fallback coevally)
}
+ // Create an array of table column names
+ NSMutableArray *tbHeader = [NSMutableArray arrayWithCapacity:numColumns];
+ enumerate(columns, enumObj)
+ [tbHeader addObject:[[enumObj headerCell] stringValue]];
+
[result appendString:[NSString stringWithFormat:@"INSERT INTO %@ (%@)\nVALUES\n",
[(selectedTable == nil)?@"<table>":selectedTable backtickQuotedString], [tbHeader componentsJoinedAndBacktickQuoted]]];
//this is really deprecated in 10.3, but the new method is really weird
NSEnumerator *enumerator = [self selectedRowEnumerator];
+ // Set up an array of table column mappings
+ columnMappings = [[NSMutableArray alloc] initWithCapacity:numColumns];
+ for ( c = 0; c < numColumns; c++ ) {
+ [columnMappings addObject:[[columns objectAtIndex:c] identifier]];
+ }
+
while ( rowEnumObject = [enumerator nextObject] )
{
[value appendString:@"\t("];
@@ -223,8 +224,7 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
rowCounter++;
for ( c = 0; c < numColumns; c++ )
{
- col = [columns objectAtIndex:c];
- rowData = [[tableData objectAtIndex:row] objectForKey:[tbHeader objectAtIndex:c]];
+ rowData = [[tableData objectAtIndex:row] objectAtIndex:[[columnMappings objectAtIndex:c] intValue]];
// Check for NULL value - TODO this is not safe!!
if([[rowData description] isEqualToString:spNULL]){
@@ -251,12 +251,12 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
//if we have indexes, use argumentForRow
dbDataRow = [[mySQLConnection queryString:
[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@",
- [selectedTable backtickQuotedString], [tableInstance argumentForRow:row]]] fetchRowAsDictionary];
- if([[dbDataRow objectForKey:[tbHeader objectAtIndex:c]] isKindOfClass:[NSNull class]])
+ [selectedTable backtickQuotedString], [tableInstance argumentForRow:row]]] fetchRowAsArray];
+ if([[dbDataRow objectAtIndex:[[columnMappings objectAtIndex:c] intValue]] isKindOfClass:[NSNull class]])
[value appendString:@"NULL, "];
else
[value appendString:[NSString stringWithFormat:@"X'%@', ",
- [mySQLConnection prepareBinaryData:[dbDataRow objectForKey:[tbHeader objectAtIndex:c]]]]];
+ [mySQLConnection prepareBinaryData:[dbDataRow objectAtIndex:[[columnMappings objectAtIndex:c] intValue]]]]];
} else {
[value appendString:[NSString stringWithFormat:@"X'%@', ", [mySQLConnection prepareBinaryData:rowData]]];
}
@@ -271,12 +271,12 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
//if we have indexes, use argumentForRow
dbDataRow = [[mySQLConnection queryString:
[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@",
- [selectedTable backtickQuotedString], [tableInstance argumentForRow:row]]] fetchRowAsDictionary];
- if([[dbDataRow objectForKey:[tbHeader objectAtIndex:c]] isKindOfClass:[NSNull class]])
+ [selectedTable backtickQuotedString], [tableInstance argumentForRow:row]]] fetchRowAsArray];
+ if([[dbDataRow objectAtIndex:[[columnMappings objectAtIndex:c] intValue]] isKindOfClass:[NSNull class]])
[value appendString:@"NULL, "];
else
[value appendString:[NSString stringWithFormat:@"'%@', ",
- [mySQLConnection prepareString:[[dbDataRow objectForKey:[tbHeader objectAtIndex:c]] description]]]];
+ [mySQLConnection prepareString:[[dbDataRow objectAtIndex:[[columnMappings objectAtIndex:c] intValue]] description]]]];
} else {
[value appendString:[NSString stringWithFormat:@"'%@', ",
[[rowData description] stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"] ] ];
@@ -326,6 +326,8 @@ int MENU_EDIT_COPY_AS_SQL = 2002;
[result appendString:@";\n"];
+ [columnMappings release];
+
return result;
}
diff --git a/Source/CMMCPResult.m b/Source/CMMCPResult.m
index afc7c2ed..610b6655 100644
--- a/Source/CMMCPResult.m
+++ b/Source/CMMCPResult.m
@@ -327,7 +327,10 @@ modified version for use with sequel-pro
for (i=0; i < numFields; i++)
{
- NSMutableDictionary *fieldStructure = [NSMutableDictionary dictionaryWithCapacity:38];
+ NSMutableDictionary *fieldStructure = [NSMutableDictionary dictionaryWithCapacity:39];
+
+ /* Original column position */
+ [fieldStructure setObject:[NSNumber numberWithInt:i] forKey:@"datacolumnindex"];
/* Name of column */
[fieldStructure setObject:[self stringWithCString:theField[i].name] forKey:@"name"];
diff --git a/Source/CustomQuery.h b/Source/CustomQuery.h
index 1dcd870d..ddd47e0e 100644
--- a/Source/CustomQuery.h
+++ b/Source/CustomQuery.h
@@ -95,7 +95,7 @@
BOOL tableReloadAfterEdting;
BOOL isDesc;
- NSString *sortField;
+ NSNumber *sortField;
BOOL tempAlertWasShown; // a temp value for nightly builts
}
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m
index 0b18848c..ecc32e3d 100644
--- a/Source/CustomQuery.m
+++ b/Source/CustomQuery.m
@@ -634,7 +634,6 @@
return;
}
-
// get column definitions for the result array
cqColumnDefinition = [[theResult fetchResultFieldsStructure] retain];
@@ -658,9 +657,10 @@
// Add columns corresponding to the query result
theColumns = [theResult fetchFieldNames];
+
if(!tableReloadAfterEdting) {
for ( i = 0 ; i < [theResult numOfFields] ; i++) {
- theCol = [[NSTableColumn alloc] initWithIdentifier:[NSArrayObjectAtIndex(cqColumnDefinition,i) objectForKey:@"name"]];
+ theCol = [[NSTableColumn alloc] initWithIdentifier:[NSArrayObjectAtIndex(cqColumnDefinition,i) objectForKey:@"datacolumnindex"]];
[theCol setResizingMask:NSTableColumnUserResizingMask];
[theCol setEditable:YES];
NSTextFieldCell *dataCell = [[[NSTextFieldCell alloc] initTextCell:@""] autorelease];
@@ -703,7 +703,7 @@
}
/*
- * Fetches the result as an array with a dictionary for each row in it
+ * Fetches the result as an array, with an array for each row in it
*/
- (NSArray *)fetchResultAsArray:(CMMCPResult *)theResult
{
@@ -711,11 +711,9 @@
unsigned long numOfRows = [theResult numOfRows];
NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows];
- NSDictionary *tempRow;
- NSMutableDictionary *modifiedRow = [NSMutableDictionary dictionary];
- NSEnumerator *enumerator;
- id key;
- int i;
+ NSArray *tempRow;
+ NSMutableArray *modifiedRow = [NSMutableArray array];
+ int i, j, numOfFields;
Class nullClass = [NSNull class];
id prefsNullValue = [prefs objectForKey:@"NullValue"];
// BOOL prefsLoadBlobsAsNeeded = [prefs boolForKey:@"LoadBlobsAsNeeded"];
@@ -725,14 +723,15 @@
if (numOfRows) [theResult dataSeek:0];
for ( i = 0 ; i < numOfRows ; i++ ) {
- tempRow = [theResult fetchRowAsDictionary];
- enumerator = [tempRow keyEnumerator];
+ tempRow = [theResult fetchRowAsArray];
- while ( key = [enumerator nextObject] ) {
- if ( [[tempRow objectForKey:key] isMemberOfClass:nullClass] ) {
- [modifiedRow setObject:prefsNullValue forKey:key];
+ if ( i == 0 ) numOfFields = [tempRow count];
+
+ for ( j = 0; j < numOfFields; j++) {
+ if ( [NSArrayObjectAtIndex(tempRow, j) isMemberOfClass:nullClass] ) {
+ [modifiedRow addObject:prefsNullValue];
} else {
- [modifiedRow setObject:[tempRow objectForKey:key] forKey:key];
+ [modifiedRow addObject:NSArrayObjectAtIndex(tempRow, j)];
}
}
@@ -746,7 +745,8 @@
// }
// }
- [tempResult addObject:[NSMutableDictionary dictionaryWithDictionary:modifiedRow]];
+ [tempResult addObject:[NSArray arrayWithArray:modifiedRow]];
+ [modifiedRow removeAllObjects];
}
return tempResult;
@@ -1082,7 +1082,7 @@
*/
- (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn
{
-
+ NSArray *dataRow;
id field;
//Look for all columns which are coming from "tableForColumn"
@@ -1097,8 +1097,9 @@
[fieldIDQueryString setString:@"WHERE ("];
// Build WHERE clause
+ dataRow = [fullResult objectAtIndex:rowIndex];
for(field in columnsForFieldTableName) {
- id aValue = [[fullResult objectAtIndex:rowIndex] objectForKey:[field objectForKey:@"name"]];
+ id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] intValue]];
if ([aValue isKindOfClass:[NSNull class]] || [[aValue description] isEqualToString:[prefs stringForKey:@"NullValue"]]) {
[fieldIDQueryString appendFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]];
} else {
@@ -1148,7 +1149,7 @@
if ( aTableView == customQueryView ) {
- id theValue = [NSArrayObjectAtIndex(fullResult, rowIndex) objectForKey:[aTableColumn identifier]];
+ id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(fullResult, rowIndex), [[aTableColumn identifier] intValue]);
if ( [theValue isKindOfClass:[NSData class]] )
return [theValue shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
@@ -1210,7 +1211,7 @@
// Retrieve the column defintion
for(id c in cqColumnDefinition) {
- if([[c objectForKey:@"name"] isEqualToString:[aTableColumn identifier]]) {
+ if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:[aTableColumn identifier]]) {
columnDefinition = [NSDictionary dictionaryWithDictionary:c];
break;
}
@@ -1239,7 +1240,7 @@
if([anObject isEqualToString:[prefs stringForKey:@"NullValue"]])
newObject = @"NULL";
else
- newObject = [NSString stringWithFormat:@"'%@'", [anObject description]];
+ newObject = [NSString stringWithFormat:@"'%@'", [mySQLConnection prepareString:[anObject description]]];
[mySQLConnection queryString:
[NSString stringWithFormat:@"UPDATE %@ SET %@=%@ %@ LIMIT 1",
@@ -1290,17 +1291,18 @@
NSMutableString *queryString = [NSMutableString stringWithString:lastExecutedQuery];
//sets order descending if a header is clicked twice
- if ( [[tableColumn identifier] isEqualTo:sortField] ) {
+ if ( sortField && [[tableColumn identifier] isEqualToNumber:sortField] ) {
isDesc = !isDesc;
} else {
isDesc = NO;
- [customQueryView setIndicatorImage:nil inTableColumn:[customQueryView tableColumnWithIdentifier:sortField]];
+ if (sortField) [customQueryView setIndicatorImage:nil inTableColumn:[customQueryView tableColumnWithIdentifier:sortField]];
}
if (sortField) [sortField release];
- sortField = [[NSString alloc] initWithString:[tableColumn identifier]];
+ sortField = [[NSNumber alloc] initWithInt:[[tableColumn identifier] intValue]];
- NSString* newOrder = [NSString stringWithFormat:@" ORDER BY %@ %@ ", [sortField backtickQuotedString], (isDesc)?@"DESC":@"ASC"];
+ // Order by the column position number to avoid ambiguous name errors
+ NSString* newOrder = [NSString stringWithFormat:@" ORDER BY %i %@ ", [[tableColumn identifier] intValue]+1, (isDesc)?@"DESC":@"ASC"];
//make queryString and perform query
if([queryString isMatchedByRegex:@"(?i)\\s+ORDER\\s+BY\\s+(.|\\n)+(\\s+(DESC|ASC))?(\\s|\\n)+(?=(LI|PR|IN|FO|LO))"])
@@ -1444,7 +1446,7 @@
// Retrieve the column defintion
for(id c in cqColumnDefinition) {
- if([[c objectForKey:@"name"] isEqualToString:[aTableColumn identifier]]) {
+ if([[c objectForKey:@"datacolumnindex"] isEqualToNumber:[aTableColumn identifier]]) {
columnDefinition = [NSDictionary dictionaryWithDictionary:c];
break;
}
@@ -1490,18 +1492,18 @@
//get the value
theRow = [fullResult objectAtIndex:rowIndex];
- if ( [[theRow objectForKey:[aTableColumn identifier]] isKindOfClass:[NSData class]] ) {
- theValue = [[NSString alloc] initWithData:[theRow objectForKey:[aTableColumn identifier]]
+ if ( [[theRow objectAtIndex:[[aTableColumn identifier] intValue]] isKindOfClass:[NSData class]] ) {
+ theValue = [[NSString alloc] initWithData:[theRow objectAtIndex:[[aTableColumn identifier] intValue]]
encoding:[mySQLConnection encoding]];
if (theValue == nil) {
- theValue = [[NSString alloc] initWithData:[theRow objectForKey:[aTableColumn identifier]]
+ theValue = [[NSString alloc] initWithData:[theRow objectAtIndex:[[aTableColumn identifier] intValue]]
encoding:NSASCIIStringEncoding];
}
[theValue autorelease];
- } else if ( [[theRow objectForKey:[aTableColumn identifier]] isMemberOfClass:[NSNull class]] ) {
+ } else if ( [[theRow objectAtIndex:[[aTableColumn identifier] intValue]] isMemberOfClass:[NSNull class]] ) {
theValue = [prefs objectForKey:@"NullValue"];
} else {
- theValue = [theRow objectForKey:[aTableColumn identifier]];
+ theValue = [theRow objectAtIndex:[[aTableColumn identifier] intValue]];
}
[valueTextField setString:[theValue description]];
diff --git a/Source/SPArrayAdditions.h b/Source/SPArrayAdditions.h
index 044699db..2d59d055 100644
--- a/Source/SPArrayAdditions.h
+++ b/Source/SPArrayAdditions.h
@@ -25,11 +25,7 @@
#import <Cocoa/Cocoa.h>
static inline id NSArrayObjectAtIndex(NSArray* self, NSUInteger i) {
- typedef id (*SPArrayObjectAtIndexMethodPtr)(NSArray*, SEL, NSUInteger);
- static SPArrayObjectAtIndexMethodPtr SPNSArrayObjectAtIndex;
- if (!SPNSArrayObjectAtIndex) SPNSArrayObjectAtIndex = (SPArrayObjectAtIndexMethodPtr)[self methodForSelector:@selector(objectAtIndex:)];
- id to_return = SPNSArrayObjectAtIndex(self, @selector(objectAtIndex:), i);
- return to_return;
+ return (id)CFArrayGetValueAtIndex((CFArrayRef)self, i);
}
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index fee2e85e..bcd0c2f6 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -389,6 +389,7 @@
];
}
+ [tableColumn setObject:[NSNumber numberWithInt:[tableColumns count]] forKey:@"datacolumnindex"];
[tableColumn setObject:fieldName forKey:@"name"];
// Split the remaining field definition string by spaces and process
diff --git a/Source/TableContent.h b/Source/TableContent.h
index 7e020792..7224b361 100644
--- a/Source/TableContent.h
+++ b/Source/TableContent.h
@@ -66,9 +66,9 @@
id editData;
NSString *selectedTable, *usedQuery;
- NSMutableArray *fullResult, *filteredResult, *keys;
- NSMutableDictionary *oldRow;
- NSString *compareType, *sortField;
+ NSMutableArray *fullResult, *filteredResult, *keys, *oldRow;
+ NSString *compareType, *lastField;
+ NSNumber *sortCol;
BOOL isEditingRow, isEditingNewRow, isSavingRow, isDesc, setLimit;
NSUserDefaults *prefs;
int numRows, currentlyEditingRow, maxNumRowsOfCurrentTable;
diff --git a/Source/TableContent.m b/Source/TableContent.m
index 61499351..72f9dc22 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -53,11 +53,12 @@
fullResult = [[NSMutableArray alloc] init];
filteredResult = [[NSMutableArray alloc] init];
- oldRow = [[NSMutableDictionary alloc] init];
+ oldRow = [[NSMutableArray alloc] init];
selectedTable = nil;
- sortField = nil;
-
+ sortCol = nil;
+ lastField = nil;
+
areShowingAllRows = false;
currentlyEditingRow = -1;
@@ -82,7 +83,7 @@
- (void)loadTable:(NSString *)aTable
{
int i;
- NSNumber *colWidth;
+ NSNumber *colWidth, *savedSortCol = nil;
NSArray *theColumns, *columnNames;
NSDictionary *columnDefinition;
NSTableColumn *theCol;
@@ -174,7 +175,7 @@
columnDefinition = NSArrayObjectAtIndex(theColumns, i);
// Set up the column
- theCol = [[NSTableColumn alloc] initWithIdentifier:[columnDefinition objectForKey:@"name"]];
+ theCol = [[NSTableColumn alloc] initWithIdentifier:[columnDefinition objectForKey:@"datacolumnindex"]];
[[theCol headerCell] setStringValue:[columnDefinition objectForKey:@"name"]];
[theCol setEditable:YES];
@@ -221,14 +222,20 @@
[theCol setWidth:[colWidth floatValue]];
}
+ // Set the column to be reselected for sorting if appropriate
+ if (lastField && [lastField isEqualToString:[columnDefinition objectForKey:@"name"]])
+ savedSortCol = [columnDefinition objectForKey:@"datacolumnindex"];
+
// Add the column to the table
[tableContentView addTableColumn:theCol];
[theCol release];
}
// If the table has been reloaded and the previously selected sort column is still present, reselect it.
- if (preserveCurrentView && [columnNames containsObject:sortField]) {
- theCol = [tableContentView tableColumnWithIdentifier:sortField];
+ if (preserveCurrentView && savedSortCol) {
+ theCol = [tableContentView tableColumnWithIdentifier:savedSortCol];
+ if (sortCol) [sortCol release];
+ sortCol = [savedSortCol copy];
[tableContentView setHighlightedTableColumn:theCol];
if ( isDesc ) {
[tableContentView setIndicatorImage:[NSImage imageNamed:@"NSDescendingSortIndicator"] inTableColumn:theCol];
@@ -238,9 +245,9 @@
// Otherwise, clear sorting
} else {
- if (sortField) {
- [sortField release];
- sortField = nil;
+ if (sortCol) {
+ [sortCol release];
+ sortCol = nil;
}
isDesc = NO;
}
@@ -308,8 +315,8 @@
// Perform the data query and store the result as an array containing a dictionary per result row
query = [NSString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]];
- if ( sortField ) {
- query = [NSString stringWithFormat:@"%@ ORDER BY %@", query, [sortField backtickQuotedString]];
+ if ( sortCol ) {
+ query = [NSString stringWithFormat:@"%@ ORDER BY %@", query, [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
if ( isDesc )
query = [query stringByAppendingString:@" DESC"];
}
@@ -409,8 +416,8 @@
// queryString = [@"SELECT * FROM " stringByAppendingString:selectedTable];
queryString = [NSString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]];
- if ( sortField ) {
- queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [sortField backtickQuotedString]];
+ if ( sortCol ) {
+ queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
// queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@" ORDER BY %@", [sortField backtickQuotedString]]];
if ( isDesc )
queryString = [queryString stringByAppendingString:@" DESC"];
@@ -628,8 +635,8 @@
}
// Add sorting details if appropriate
- if ( sortField ) {
- queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [sortField backtickQuotedString]];
+ if ( sortCol ) {
+ queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
if ( isDesc )
queryString = [queryString stringByAppendingString:@" DESC"];
}
@@ -716,7 +723,8 @@
- (IBAction)addRow:(id)sender
{
NSArray *columns;
- NSMutableDictionary *column, *newRow = [NSMutableDictionary dictionary];
+ NSMutableDictionary *column;
+ NSMutableArray *newRow = [NSMutableArray array];
int i;
// Check whether a save of the current row is required.
@@ -726,9 +734,9 @@
for ( i = 0 ; i < [columns count] ; i++ ) {
column = NSArrayObjectAtIndex(columns, i);
if ([column objectForKey:@"default"] == nil || [[column objectForKey:@"default"] isEqualToString:@"NULL"]) {
- [newRow setObject:[prefs stringForKey:@"NullValue"] forKey:[column objectForKey:@"name"]];
+ [newRow addObject:[prefs stringForKey:@"NullValue"]];
} else {
- [newRow setObject:[column objectForKey:@"default"] forKey:[column objectForKey:@"name"]];
+ [newRow addObject:[column objectForKey:@"default"]];
}
}
[filteredResult addObject:newRow];
@@ -748,9 +756,10 @@
copies a row of the table-array and goes into edit mode
*/
{
- NSMutableDictionary *tempRow;
+ NSMutableArray *tempRow;
CMMCPResult *queryResult;
- NSDictionary *row, *dbDataRow = nil;
+ NSDictionary *row;
+ NSArray *dbDataRow = nil;
int i;
// Check whether a save of the current row is required.
@@ -764,7 +773,7 @@
}
//copy row
- tempRow = [NSMutableDictionary dictionaryWithDictionary:[filteredResult objectAtIndex:[tableContentView selectedRow]]];
+ tempRow = [NSMutableArray arrayWithArray:[filteredResult objectAtIndex:[tableContentView selectedRow]]];
[filteredResult insertObject:tempRow atIndex:[tableContentView selectedRow]+1];
//if we don't show blobs, read data for this duplicate column from db
@@ -775,7 +784,7 @@
}
//if we have indexes, use argumentForRow
queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@", [selectedTable backtickQuotedString], [self argumentForRow:[tableContentView selectedRow]]]];
- dbDataRow = [queryResult fetchRowAsDictionary];
+ dbDataRow = [queryResult fetchRowAsArray];
}
//set autoincrement fields to NULL
@@ -784,15 +793,15 @@
for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) {
row = [queryResult fetchRowAsDictionary];
if ( [[row objectForKey:@"Extra"] isEqualToString:@"auto_increment"] ) {
- [tempRow setObject:[prefs stringForKey:@"NullValue"] forKey:[row objectForKey:@"Field"]];
+ [tempRow replaceObjectAtIndex:i withObject:[prefs stringForKey:@"NullValue"]];
} else if ( [tableDataInstance columnIsBlobOrText:[row objectForKey:@"Field"]] && [prefs boolForKey:@"LoadBlobsAsNeeded"] && dbDataRow) {
NSString *valueString = nil;
//if what we read from DB is NULL (NSNull), we replace it with the string NULL
- if([[dbDataRow objectForKey:[row objectForKey:@"Field"]] isKindOfClass:[NSNull class]])
+ if([[dbDataRow objectAtIndex:i] isKindOfClass:[NSNull class]])
valueString = [prefs objectForKey:@"NullValue"];
else
- valueString = [dbDataRow objectForKey:[row objectForKey:@"Field"]];
- [tempRow setObject:valueString forKey:[row objectForKey:@"Field"]];
+ valueString = [dbDataRow objectAtIndex:i];
+ [tempRow replaceObjectAtIndex:i withObject:valueString];
}
}
@@ -1247,7 +1256,7 @@
[tempRow removeAllObjects];
enumerator = [tableColumns objectEnumerator];
while ( (tableColumn = [enumerator nextObject]) ) {
- id o = [NSArrayObjectAtIndex(fullResult, i) objectForKey:[[tableColumn headerCell] stringValue]];
+ id o = [NSArrayObjectAtIndex(fullResult, i) objectAtIndex:[[tableColumn identifier] intValue]];
if([o isKindOfClass:[NSNull class]])
[tempRow addObject:@"NULL"];
else if([o isKindOfClass:[NSString class]])
@@ -1430,7 +1439,7 @@
}
/*
- * Fetches the result as an array with a dictionary for each row in it
+ * Fetches the result as an array, with an array for each row in it
*/
- (NSArray *)fetchResultAsArray:(CMMCPResult *)theResult
{
@@ -1438,10 +1447,9 @@
unsigned long numOfRows = [theResult numOfRows];
NSMutableArray *tempResult = [NSMutableArray arrayWithCapacity:numOfRows];
- NSDictionary *tempRow;
- NSMutableDictionary *modifiedRow = [NSMutableDictionary dictionary];
- NSEnumerator *enumerator;
- id key;
+ NSArray *tempRow;
+ NSMutableArray *modifiedRow = [NSMutableArray array];
+ NSMutableArray *columnBlobStatuses = [NSMutableArray array];
int i, j;
Class nullClass = [NSNull class];
id prefsNullValue = [prefs objectForKey:@"NullValue"];
@@ -1450,29 +1458,34 @@
columns = [tableDataInstance columns];
long columnsCount = [columns count];
+ // Build up an array of which columns are blobs for faster iteration
+ for ( i = 0; i < columnsCount ; i++ ) {
+ [columnBlobStatuses addObject:[NSNumber numberWithBool:[tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(columns, i) objectForKey:@"name"] ]]];
+ }
+
if (numOfRows) [theResult dataSeek:0];
for ( i = 0 ; i < numOfRows ; i++ ) {
- tempRow = [theResult fetchRowAsDictionary];
- enumerator = [tempRow keyEnumerator];
+ [modifiedRow removeAllObjects];
+ tempRow = [theResult fetchRowAsArray];
- while ( key = [enumerator nextObject] ) {
- if ( [[tempRow objectForKey:key] isMemberOfClass:nullClass] ) {
- [modifiedRow setObject:prefsNullValue forKey:key];
+ for ( j = 0; j < columnsCount; j++ ) {
+ if ( [NSArrayObjectAtIndex(tempRow, j) isMemberOfClass:nullClass] ) {
+ [modifiedRow addObject:prefsNullValue];
} else {
- [modifiedRow setObject:[tempRow objectForKey:key] forKey:key];
+ [modifiedRow addObject:NSArrayObjectAtIndex(tempRow, j)];
}
}
// Add values for hidden blob and text fields if appropriate
if ( prefsLoadBlobsAsNeeded ) {
for ( j = 0 ; j < columnsCount ; j++ ) {
- if ( [tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(columns, j) objectForKey:@"name"] ] ) {
- [modifiedRow setObject:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields") forKey:[NSArrayObjectAtIndex(columns, j) objectForKey:@"name"]];
+ if ( [NSArrayObjectAtIndex(columnBlobStatuses, j) boolValue] ) {
+ [modifiedRow replaceObjectAtIndex:j withObject:NSLocalizedString(@"(not loaded)", @"value shown for hidden blob and text fields")];
}
}
}
- [tempResult addObject:[NSMutableDictionary dictionaryWithDictionary:modifiedRow]];
+ [tempResult addObject:[NSMutableArray arrayWithArray:modifiedRow]];
}
return tempResult;
@@ -1502,7 +1515,7 @@
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self];
// If editing, compare the new row to the old row and if they are identical finish editing without saving.
- if (!isEditingNewRow && [oldRow isEqualToDictionary:[filteredResult objectAtIndex:currentlyEditingRow]]) {
+ if (!isEditingNewRow && [oldRow isEqualToArray:[filteredResult objectAtIndex:currentlyEditingRow]]) {
isEditingRow = NO;
currentlyEditingRow = -1;
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:self];
@@ -1517,7 +1530,7 @@
NSMutableArray *fieldValues = [[NSMutableArray alloc] init];
// Get the field values
for ( i = 0 ; i < [columnNames count] ; i++ ) {
- rowObject = [NSArrayObjectAtIndex(filteredResult, currentlyEditingRow) objectForKey:NSArrayObjectAtIndex(columnNames, i)];
+ rowObject = [NSArrayObjectAtIndex(filteredResult, currentlyEditingRow) objectAtIndex:i];
// Convert the object to a string (here we can add special treatment for date-, number- and data-fields)
if ( [[rowObject description] isEqualToString:[prefs stringForKey:@"NullValue"]]
|| ([rowObject isMemberOfClass:[NSString class]] && [[rowObject description] isEqualToString:@""]) ) {
@@ -1580,7 +1593,7 @@
} else {
NSBeep();
}
- [filteredResult replaceObjectAtIndex:currentlyEditingRow withObject:[NSMutableDictionary dictionaryWithDictionary:oldRow]];
+ [filteredResult replaceObjectAtIndex:currentlyEditingRow withObject:[NSMutableArray arrayWithArray:oldRow]];
isEditingRow = NO;
isEditingNewRow = NO;
currentlyEditingRow = -1;
@@ -1602,8 +1615,7 @@
// Set the insertId for fields with auto_increment
for ( i = 0; i < [theColumns count] ; i++ ) {
if ([[NSArrayObjectAtIndex(theColumns, i) objectForKey:@"autoincrement"] intValue]) {
- [[filteredResult objectAtIndex:currentlyEditingRow] setObject:[[NSNumber numberWithLong:[mySQLConnection insertId]] description]
- forKey:NSArrayObjectAtIndex(columnNames, i)];
+ [[filteredResult objectAtIndex:currentlyEditingRow] replaceObjectAtIndex:i withObject:[[NSNumber numberWithLong:[mySQLConnection insertId]] description]];
}
}
[fullResult addObject:[filteredResult objectAtIndex:currentlyEditingRow]];
@@ -1620,8 +1632,8 @@
// TODO: this probably needs looking at... it's reloading it all itself?
} else {
query = [NSString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]];
- if ( sortField ) {
- query = [NSString stringWithFormat:@"%@ ORDER BY %@", query, [sortField backtickQuotedString]];
+ if ( sortCol ) {
+ query = [NSString stringWithFormat:@"%@ ORDER BY %@", query, [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
if ( isDesc )
query = [query stringByAppendingString:@" DESC"];
}
@@ -1738,11 +1750,11 @@
// Use the selected row if appropriate
if ( row >= 0 ) {
- tempValue = [NSArrayObjectAtIndex(filteredResult, row) objectForKey:NSArrayObjectAtIndex(keys, i)];
+ tempValue = [NSArrayObjectAtIndex(filteredResult, row) objectAtIndex:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] intValue]];
// Otherwise use the oldRow
} else {
- tempValue = [oldRow objectForKey:NSArrayObjectAtIndex(keys, i)];
+ tempValue = [oldRow objectAtIndex:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] intValue]];
}
if ( [tempValue isKindOfClass:[NSData class]] ) {
@@ -1819,16 +1831,15 @@
if ( [prefs boolForKey:@"LoadBlobsAsNeeded"] ) {
for ( i = 0 ; i < [columnNames count] ; i++ ) {
if (![tableDataInstance columnIsBlobOrText:[NSArrayObjectAtIndex(columns, i) objectForKey:@"name"]] ) {
- [fields addObject:NSArrayObjectAtIndex(columnNames, i)];
+ [fields addObject:[NSArrayObjectAtIndex(columnNames, i) backtickQuotedString]];
+ } else {
+
+ // For blob/text fields, select a null placeholder so the column count is still correct
+ [fields addObject:@"NULL"];
}
}
- // Always select at least one field - the first if there are no non-blob fields.
- if ( [fields count] == 0 ) {
- return [NSArrayObjectAtIndex(columnNames, 0) backtickQuotedString];
- } else {
- return [fields componentsJoinedAndBacktickQuoted];
- }
+ return [fields componentsJoinedByString:@","];
} else {
return @"*";
}
@@ -1857,7 +1868,7 @@
} else {
if ( !isEditingNewRow ) {
[filteredResult replaceObjectAtIndex:[tableContentView selectedRow]
- withObject:[NSMutableDictionary dictionaryWithDictionary:oldRow]];
+ withObject:[NSMutableArray arrayWithArray:oldRow]];
isEditingRow = NO;
} else {
[filteredResult removeObjectAtIndex:[tableContentView selectedRow]];
@@ -1932,9 +1943,9 @@
if ( !areShowingAllRows ) {
// queryString = [@"SELECT * FROM " stringByAppendingString:selectedTable];
queryString = [NSString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]];
- if ( sortField ) {
+ if ( sortCol ) {
// queryString = [queryString stringByAppendingString:[NSString stringWithFormat:@" ORDER BY %@", [sortField backtickQuotedString]]];
- queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [sortField backtickQuotedString]];
+ queryString = [NSString stringWithFormat:@"%@ ORDER BY %@", queryString, [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
if ( isDesc )
queryString = [queryString stringByAppendingString:@" DESC"];
}
@@ -2012,7 +2023,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(int)rowIndex
{
- id theValue = [NSArrayObjectAtIndex(filteredResult, rowIndex) objectForKey:[aTableColumn identifier]];
+ id theValue = NSArrayObjectAtIndex(NSArrayObjectAtIndex(filteredResult, rowIndex), [[aTableColumn identifier] intValue]);
if ( [theValue isKindOfClass:[NSData class]] )
return [theValue shortStringRepresentationUsingEncoding:[mySQLConnection encoding]];
@@ -2039,16 +2050,10 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
if ([cell respondsToSelector:@selector(setTextColor:)])
{
NSArray *columns = [tableDataInstance columns];
- NSArray *columnNames = [tableDataInstance columnNames];
NSString *columnTypeGrouping;
NSUInteger indexOfColumn;
- // We have to find the index of the current column
- // Make sure we find it, otherwise return (We might decide in the future
- // to add a column to the TableView that doesn't correspond to a column
- // of the Mysql table...)
- indexOfColumn = [columnNames indexOfObject:[aTableColumn identifier]];
- if (indexOfColumn == NSNotFound) return;
+ indexOfColumn = [[aTableColumn identifier] intValue];
// Test if the current column is a text or a blob field
columnTypeGrouping = [[columns objectAtIndex:indexOfColumn] objectForKey:@"typegrouping"];
@@ -2081,15 +2086,15 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
// Catch editing events in the row and if the row isn't currently being edited,
// start an edit. This allows edits including enum changes to save correctly.
if ( !isEditingRow ) {
- [oldRow setDictionary:NSArrayObjectAtIndex(filteredResult, rowIndex)];
+ [oldRow setArray:NSArrayObjectAtIndex(filteredResult, rowIndex)];
isEditingRow = YES;
currentlyEditingRow = rowIndex;
}
if ( anObject )
- [NSArrayObjectAtIndex(filteredResult, rowIndex) setObject:anObject forKey:[aTableColumn identifier]];
+ [NSArrayObjectAtIndex(filteredResult, rowIndex) replaceObjectAtIndex:[[aTableColumn identifier] intValue] withObject:anObject];
else
- [NSArrayObjectAtIndex(filteredResult, rowIndex) setObject:@"" forKey:[aTableColumn identifier]];
+ [NSArrayObjectAtIndex(filteredResult, rowIndex) replaceObjectAtIndex:[[aTableColumn identifier] intValue] withObject:@""];
}
@@ -2115,7 +2120,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self];
//sets order descending if a header is clicked twice
- if ( [[tableColumn identifier] isEqualTo:sortField] ) {
+ if ( [[tableColumn identifier] isEqualTo:sortCol] ) {
if ( isDesc ) {
isDesc = NO;
} else {
@@ -2123,14 +2128,18 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
}
} else {
isDesc = NO;
- [tableContentView setIndicatorImage:nil inTableColumn:[tableContentView tableColumnWithIdentifier:sortField]];
+ [tableContentView setIndicatorImage:nil inTableColumn:[tableContentView tableColumnWithIdentifier:sortCol]];
}
- if (sortField) [sortField release];
- sortField = [[NSString alloc] initWithString:[tableColumn identifier]];
+ if (sortCol) [sortCol release];
+ sortCol = [[NSNumber alloc] initWithInt:[[tableColumn identifier] intValue]];
+
+ // Save the sort field name for use when refreshing the table
+ if (lastField) [lastField release];
+ lastField = [[NSString alloc] initWithString:[[[tableDataInstance columns] objectAtIndex:[[tableColumn identifier] intValue]] objectForKey:@"name"]];
//make queryString and perform query
queryString = [NSString stringWithFormat:@"SELECT %@ FROM %@ ORDER BY %@", [self fieldListForQuery],
- [selectedTable backtickQuotedString], [sortField backtickQuotedString]];
+ [selectedTable backtickQuotedString], [[[[tableDataInstance columns] objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
if ( isDesc )
queryString = [queryString stringByAppendingString:@" DESC"];
if ( [prefs boolForKey:@"LimitResults"] ) {
@@ -2242,7 +2251,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
}
// save column size
- [[[tableColumnWidths objectForKey:database] objectForKey:table] setObject:[NSNumber numberWithFloat:[[[aNotification userInfo] objectForKey:@"NSTableColumn"] width]] forKey:[[[aNotification userInfo] objectForKey:@"NSTableColumn"] identifier]];
+ [[[tableColumnWidths objectForKey:database] objectForKey:table] setObject:[NSNumber numberWithFloat:[[[aNotification userInfo] objectForKey:@"NSTableColumn"] width]] forKey:[[[[aNotification userInfo] objectForKey:@"NSTableColumn"] headerCell] stringValue]];
[prefs setObject:tableColumnWidths forKey:@"tableColumnWidths"];
}
@@ -2252,13 +2261,12 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
*/
- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
- int code;
+ int i, code;
NSString *query, *stringValue = nil, *wherePart = nil;
- NSEnumerator *enumerator;
- NSDictionary *tempRow;
- NSMutableDictionary *modifiedRow = [NSMutableDictionary dictionary];
- id key, theValue;
+ NSArray *tempRow;
+ NSMutableArray *modifiedRow = [NSMutableArray array];
+ id theValue;
CMMCPResult *tempResult;
// If not isEditingRow and the preference value for not showing blobs is set, check whether the row contains any blobs.
@@ -2276,27 +2284,26 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
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;
}
- tempRow = [tempResult fetchRowAsDictionary];
- enumerator = [tempRow keyEnumerator];
- while ( key = [enumerator nextObject] ) {
- if ( [[tempRow objectForKey:key] isMemberOfClass:[NSNull class]] ) {
- [modifiedRow setObject:[prefs stringForKey:@"NullValue"] forKey:key];
+ tempRow = [tempResult fetchRowAsArray];
+ for ( i = 0; i < [tempRow count]; i++ ) {
+ if ( [[tempRow objectAtIndex:i] isMemberOfClass:[NSNull class]] ) {
+ [modifiedRow addObject:[prefs stringForKey:@"NullValue"]];
} else {
- [modifiedRow setObject:[tempRow objectForKey:key] forKey:key];
+ [modifiedRow addObject:[tempRow objectAtIndex:i]];
}
}
- [filteredResult replaceObjectAtIndex:rowIndex withObject:[NSMutableDictionary dictionaryWithDictionary:modifiedRow]];
+ [filteredResult replaceObjectAtIndex:rowIndex withObject:[NSMutableArray arrayWithArray:modifiedRow]];
[tableContentView reloadData];
}
}
- BOOL isBlob = [tableDataInstance columnIsBlobOrText:[aTableColumn identifier]];
+ BOOL isBlob = [tableDataInstance columnIsBlobOrText:[[aTableColumn headerCell] stringValue]];
// Open the sheet if the multipleLineEditingButton is enabled or the column was a blob or a text.
if ( [multipleLineEditingButton state] == NSOnState || isBlob ) {
editSheetWillBeInitialized = YES;
- theValue = [[filteredResult objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];
+ theValue = [[filteredResult objectAtIndex:rowIndex] objectAtIndex:[[aTableColumn identifier] intValue]];
NSImage *image = nil;
editData = [theValue retain];
@@ -2397,12 +2404,12 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
if ( code ) {
if ( !isEditingRow ) {
- [oldRow setDictionary:[filteredResult objectAtIndex:rowIndex]];
+ [oldRow setArray:[filteredResult objectAtIndex:rowIndex]];
isEditingRow = YES;
currentlyEditingRow = rowIndex;
}
- [[filteredResult objectAtIndex:rowIndex] setObject:[editData copy] forKey:[aTableColumn identifier]];
+ [[filteredResult objectAtIndex:rowIndex] replaceObjectAtIndex:[[aTableColumn identifier] intValue] withObject:[editData copy]];
// Clean up
[editImage setImage:nil];
@@ -2478,7 +2485,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
// Check if next column is a blob column, and skip to the next non-blob column
i = 1;
while (
- (fieldType = [[tableDataInstance columnWithName:[NSArrayObjectAtIndex([tableContentView tableColumns], column+i) identifier]] objectForKey:@"typegrouping"])
+ (fieldType = [[tableDataInstance columnWithName:[[NSArrayObjectAtIndex([tableContentView tableColumns], column+i) headerCell] stringValue]] objectForKey:@"typegrouping"])
&& ([fieldType isEqualToString:@"textdata"] || [fieldType isEqualToString:@"blobdata"])
) {
i++;
@@ -2505,7 +2512,7 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
[control abortEditing];
if ( isEditingRow && !isEditingNewRow ) {
isEditingRow = NO;
- [filteredResult replaceObjectAtIndex:row withObject:[NSMutableDictionary dictionaryWithDictionary:oldRow]];
+ [filteredResult replaceObjectAtIndex:row withObject:[NSMutableArray arrayWithArray:oldRow]];
} else if ( isEditingNewRow ) {
isEditingRow = NO;
isEditingNewRow = NO;
@@ -2580,7 +2587,8 @@ objectValueForTableColumn:(NSTableColumn *)aTableColumn
[keys release];
[oldRow release];
[compareType release];
- if (sortField) [sortField release];
+ if (sortCol) [sortCol release];
+ if (lastField) [lastField release];
[usedQuery release];
[super dealloc];