diff options
author | rowanbeentje <rowan@beent.je> | 2009-07-13 21:05:51 +0000 |
---|---|---|
committer | rowanbeentje <rowan@beent.je> | 2009-07-13 21:05:51 +0000 |
commit | 778d7280bae1fe413e0b2db799495454ac165c35 (patch) | |
tree | ca520b830274ee08aaefe2db02d903caa329ac70 /Source/CMCopyTable.m | |
parent | 27db10fe504117dd8b4a166dcfc94881528c44c3 (diff) | |
download | sequelpro-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.m | 46 |
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; } |