aboutsummaryrefslogtreecommitdiffstats
path: root/Source/CMCopyTable.m
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/CMCopyTable.m
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/CMCopyTable.m')
-rw-r--r--Source/CMCopyTable.m46
1 files changed, 24 insertions, 22 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;
}