aboutsummaryrefslogtreecommitdiffstats
path: root/Source/TableContent.m
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2009-10-16 16:46:41 +0000
committerBibiko <bibiko@eva.mpg.de>2009-10-16 16:46:41 +0000
commit967579ef1225a134c50a686ee7caa9a3b5e293f3 (patch)
tree11470982216c5f9579c26bfa07815b73a081e0f5 /Source/TableContent.m
parent507d0089c6bb73a01129f1e356d1e88ca53afb55 (diff)
downloadsequelpro-967579ef1225a134c50a686ee7caa9a3b5e293f3.tar.gz
sequelpro-967579ef1225a134c50a686ee7caa9a3b5e293f3.tar.bz2
sequelpro-967579ef1225a134c50a686ee7caa9a3b5e293f3.zip
• fixed SPArrayAdditions method 'componentsJoinedByCommas' to use a mutable string to avoid crashes if array has a very large number of items (malloc error due to reassigning a NSString pointer)
• added to SPTableData method - (NSArray *) primaryKeyColumnNames - returns all column names which are set as PRIMARY KEYs - return nil if no PRIMARY KEY is set • improved the deletion of rows - if current table has only one PRIMARY KEY field delete all rows via DELETE FROM table WHERE pri_key IN (…) whereby the deletion query will be splitted into 256k chunks Note: line 1790ff It has to be implemented a workaround for tables with more than one PRIMARY KEY – maybe via DELETE FROM table WHERE ( (pri_key1='…' AND pri_key2='…') OR (… AND …) OR … ) splitted in 256k chunks as well
Diffstat (limited to 'Source/TableContent.m')
-rw-r--r--Source/TableContent.m83
1 files changed, 66 insertions, 17 deletions
diff --git a/Source/TableContent.m b/Source/TableContent.m
index 12658d30..49f8e27c 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -1655,7 +1655,8 @@
if ( [tempValue isNSNull] ) {
[argument appendString:[NSString stringWithFormat:@"%@ IS NULL", [NSArrayObjectAtIndex(keys, i) backtickQuotedString]]];
} else if ( [tempValue isSPNotLoaded] ) {
- // TODO
+ NSLog(@"Exceptional case: SPNotLoaded object found for method “argumentForRow:”!");
+ return @"";
} else {
if ( [tempValue isKindOfClass:[NSData class]] )
@@ -1784,30 +1785,78 @@
NSUInteger index = [selectedRows firstIndex];
- while (index != NSNotFound) {
+ NSArray *primaryKeyFieldNames = [tableDataInstance primaryKeyColumnNames];
+
+ // TODO tentative → || [primaryKeyFields count] != 1
+ if(primaryKeyFieldNames == nil || [primaryKeyFieldNames count] != 1) {
+ // delete row by row
+ while (index != NSNotFound) {
- wherePart = [NSString stringWithString:[self argumentForRow:index]];
+ wherePart = [NSString stringWithString:[self argumentForRow:index]];
- //argumentForRow might return empty query, in which case we shouldn't execute the partial query
- if([wherePart length]) {
- [mySQLConnection queryString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", [selectedTable backtickQuotedString], wherePart]];
+ //argumentForRow might return empty query, in which case we shouldn't execute the partial query
+ if([wherePart length]) {
+ [mySQLConnection queryString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@", [selectedTable backtickQuotedString], wherePart]];
- // Check for errors
- if ( ![mySQLConnection affectedRows] || ![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) {
- // If error delete that index from selectedRows for reloading table if
- // "ReloadAfterRemovingRow" is disbaled
+ // Check for errors
+ if ( ![mySQLConnection affectedRows] || ![[mySQLConnection getLastErrorMessage] isEqualToString:@""]) {
+ // If error delete that index from selectedRows for reloading table if
+ // "ReloadAfterRemovingRow" is disbaled
+ if(!reloadAfterRemovingRow)
+ [selectedRows removeIndex:index];
+ errors++;
+ }
+ } else {
if(!reloadAfterRemovingRow)
[selectedRows removeIndex:index];
errors++;
}
- } else {
- if(!reloadAfterRemovingRow)
- [selectedRows removeIndex:index];
- errors++;
+ index = [selectedRows indexGreaterThanIndex:index];
}
- index = [selectedRows indexGreaterThanIndex:index];
- }
+ } else {
+ // if table has only one PRIMARY KEY
+ // delete the fast way by using the PRIMARY KEY in an IN clause
+ NSMutableString *deleteQuery = [NSMutableString string];
+ NSInteger affectedRows = 0;
+
+ [deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@ IN (", [selectedTable backtickQuotedString], [NSArrayObjectAtIndex(primaryKeyFieldNames,0) backtickQuotedString]]];
+
+ while (index != NSNotFound) {
+
+ id keyValue = [NSArrayObjectAtIndex(tableValues, index) objectAtIndex:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(primaryKeyFieldNames,0)] objectForKey:@"datacolumnindex"] intValue]];
+
+ if([keyValue isKindOfClass:[NSData class]])
+ [deleteQuery appendString:[NSString stringWithFormat:@"X'%@'", [mySQLConnection prepareBinaryData:keyValue]]];
+ else
+ [deleteQuery appendString:[NSString stringWithFormat:@"'%@'", [keyValue description]]];
+
+ // Split deletion query into 256k chunks
+ if([deleteQuery length] > 256000) {
+ [deleteQuery appendString:@")"];
+ [mySQLConnection queryString:deleteQuery];
+ // Remember affected rows for error checking
+ affectedRows += [mySQLConnection affectedRows];
+ // Reinit a new deletion query
+ [deleteQuery setString:[NSString stringWithFormat:@"DELETE FROM %@ WHERE %@ IN (", [selectedTable backtickQuotedString], [NSArrayObjectAtIndex(primaryKeyFieldNames,0) backtickQuotedString]]];
+ } else {
+ [deleteQuery appendString:@","];
+ }
+ index = [selectedRows indexGreaterThanIndex:index];
+ }
+
+ // Check if deleteQuery's maximal length was reached for the last index
+ // if yes omit the empty query
+ if(![deleteQuery hasSuffix:@"("]) {
+ // Replace final , by ) and delete the remaining rows
+ [deleteQuery setString:[NSString stringWithFormat:@"%@)", [deleteQuery substringToIndex:([deleteQuery length]-1)]]];
+ [mySQLConnection queryString:deleteQuery];
+ // Remember affected rows for error checking
+ affectedRows += [mySQLConnection affectedRows];
+ }
+ errors = [selectedRows count] - affectedRows;
+ }
+
// Restore Console Log window's updating bahaviour
[[SPQueryController sharedQueryController] setAllowConsoleUpdate:consoleUpdateStatus];
@@ -2327,7 +2376,7 @@
}
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) {