aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2015-06-12 00:01:01 +0200
committerMax <post@wickenrode.com>2015-06-12 00:01:01 +0200
commit197b057a443153bfe7c9817b9b3edd7caeaabe78 (patch)
tree4d6dce847171da8adc0c6b275572004e24dfb738
parentf6be61c780e5d317a2d3a568b75cff0473d4c3eb (diff)
downloadsequelpro-197b057a443153bfe7c9817b9b3edd7caeaabe78.tar.gz
sequelpro-197b057a443153bfe7c9817b9b3edd7caeaabe78.tar.bz2
sequelpro-197b057a443153bfe7c9817b9b3edd7caeaabe78.zip
Fix a popular exception when a user tried to edit a field with a lost connection and then chose "disconnect" when Sequel Pro asks to reconnect (attempt at #2137)
-rw-r--r--Source/SPCopyTable.m5
-rw-r--r--Source/SPTableContent.m73
-rw-r--r--Source/SPTableContentDelegate.m2
3 files changed, 51 insertions, 29 deletions
diff --git a/Source/SPCopyTable.m b/Source/SPCopyTable.m
index 2b5554b5..439ff84d 100644
--- a/Source/SPCopyTable.m
+++ b/Source/SPCopyTable.m
@@ -495,8 +495,9 @@ static const NSInteger kBlobAsImageFile = 4;
// If the data is not loaded, attempt to fetch the value
if ([cellData isSPNotLoaded] && [[self delegate] isKindOfClass:spTableContentClass]) {
+ NSString *whereArgument = [tableInstance argumentForRow:rowIndex];
// Abort if no table name given, not table content, or if there are no indices on this table
- if (!selectedTable || ![[self delegate] isKindOfClass:spTableContentClass] || ![(NSString*)[tableInstance argumentForRow:rowIndex] length]) {
+ if (!selectedTable || ![[self delegate] isKindOfClass:spTableContentClass] || ![whereArgument length]) {
NSBeep();
free(columnMappings);
free(columnTypes);
@@ -509,7 +510,7 @@ static const NSInteger kBlobAsImageFile = 4;
[NSString stringWithFormat:@"SELECT %@ FROM %@ WHERE %@",
[NSArrayObjectAtIndex(tbHeader, columnMappings[c]) backtickQuotedString],
[selectedTable backtickQuotedString],
- [tableInstance argumentForRow:rowIndex]]];
+ whereArgument]];
}
// Check for NULL value
diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m
index 6988b0f3..4cd21bb1 100644
--- a/Source/SPTableContent.m
+++ b/Source/SPTableContent.m
@@ -1884,12 +1884,13 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
if ([prefs boolForKey:SPLoadBlobsAsNeeded]) {
// Abort if there are no indices on this table - argumentForRow will display an error.
- if (![[self argumentForRow:[tableContentView selectedRow]] length]) {
+ NSString *whereArgument = [self argumentForRow:[tableContentView selectedRow]];
+ if (![whereArgument length]) {
return;
}
// If we have indexes, use argumentForRow
- queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@", [selectedTable backtickQuotedString], [self argumentForRow:[tableContentView selectedRow]]]];
+ queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM %@ WHERE %@", [selectedTable backtickQuotedString], whereArgument]];
dbDataRow = [queryResult getRowAsArray];
}
#endif
@@ -2203,9 +2204,14 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
while (anIndex != NSNotFound) {
// Build the AND clause of PRIMARY KEYS
- [deleteQuery appendString:@"("];
- [deleteQuery appendString:[self argumentForRow:anIndex excludingLimits:YES]];
- [deleteQuery appendString:@")"];
+ NSString *whereArg = [self argumentForRow:anIndex excludingLimits:YES];
+ if(![whereArg length]) {
+ SPLog(@"empty WHERE clause not acceptable for DELETE! Abort.");
+ NSBeep();
+ return;
+ }
+
+ [deleteQuery appendFormat:@"(%@)",whereArg];
// Split deletion query into 64k chunks
if([deleteQuery length] > 64000) {
@@ -2825,7 +2831,15 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[queryString appendFormat:@"%@ = %@",
[NSArrayObjectAtIndex(rowFieldsToSave, i) backtickQuotedString], NSArrayObjectAtIndex(rowValuesToSave, i)];
}
- [queryString appendFormat:@" WHERE %@", [self argumentForRow:-2]];
+ NSString *whereArg = [self argumentForRow:-2];
+ if(![whereArg length]) {
+ SPLog(@"Did not find plausible WHERE condition for UPDATE.");
+ NSBeep();
+ [rowFieldsToSave release];
+ [rowValuesToSave release];
+ return NO;
+ }
+ [queryString appendFormat:@" WHERE %@", whereArg];
}
[rowFieldsToSave release];
@@ -3029,25 +3043,22 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
*/
- (NSString *)argumentForRow:(NSInteger)row excludingLimits:(BOOL)excludeLimits
{
- SPMySQLResult *theResult;
- id tempValue;
- NSMutableString *value = [NSMutableString string];
- NSMutableString *argument = [NSMutableString string];
- NSArray *columnNames;
- NSUInteger i;
-
if ( row == -1 )
return @"";
// Retrieve the field names for this table from the data cache. This is used when requesting all data as part
// of the fieldListForQuery method, and also to decide whether or not to preserve the current filter/sort settings.
- columnNames = [tableDataInstance columnNames];
+ NSArray *columnNames = [tableDataInstance columnNames];
// Get the primary key if there is one
if ( !keys ) {
setLimit = NO;
keys = [[NSMutableArray alloc] init];
- theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
+ SPMySQLResult *theResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]];
+ if(!theResult) {
+ SPLog(@"no result from SHOW COLUMNS mysql query! Abort.");
+ return @"";
+ }
[theResult setReturnDataAsStrings:YES];
for (NSDictionary *eachRow in theResult) {
if ( [[eachRow objectForKey:@"Key"] isEqualToString:@"PRI"] ) {
@@ -3074,17 +3085,18 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
#endif
}
+ NSMutableString *argument = [NSMutableString string];
// Walk through the keys list constructing the argument list
- for ( i = 0 ; i < [keys count] ; i++ ) {
+ for (NSUInteger i = 0 ; i < [keys count] ; i++ ) {
if ( i )
[argument appendString:@" AND "];
+ id tempValue;
// Use the selected row if appropriate
if ( row >= 0 ) {
tempValue = [tableValues cellDataAtRow:row column:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] integerValue]];
-
- // Otherwise use the oldRow
}
+ // Otherwise use the oldRow
else {
tempValue = [oldRow objectAtIndex:[[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"datacolumnindex"] integerValue]];
}
@@ -3093,25 +3105,34 @@ static NSString *SPTableFilterSetDefaultOperator = @"SPTableFilterSetDefaultOper
[argument appendFormat:@"%@ IS NULL", [NSArrayObjectAtIndex(keys, i) backtickQuotedString]];
}
else if ([tempValue isSPNotLoaded]) {
- NSLog(@"Exceptional case: SPNotLoaded object found for method “argumentForRow:”!");
+ SPLog(@"Exceptional case: SPNotLoaded object found! Abort.");
return @"";
}
else {
+ NSString *escVal;
+ NSString *fmt = @"%@";
// If the field is of type BIT then it needs a binary prefix
if ([[[tableDataInstance columnWithName:NSArrayObjectAtIndex(keys, i)] objectForKey:@"type"] isEqualToString:@"BIT"]) {
- [value setString:[NSString stringWithFormat:@"b'%@'", [mySQLConnection escapeString:tempValue includingQuotes:NO]]];
+ escVal = [mySQLConnection escapeString:tempValue includingQuotes:NO];
+ fmt = @"b'%@'";
}
else if ([tempValue isKindOfClass:[SPMySQLGeometryData class]]) {
- [value setString:[mySQLConnection escapeAndQuoteData:[tempValue data]]];
+ escVal = [mySQLConnection escapeAndQuoteData:[tempValue data]];
}
// BLOB/TEXT data
else if ([tempValue isKindOfClass:[NSData class]]) {
- [value setString:[mySQLConnection escapeAndQuoteData:tempValue]];
+ escVal = [mySQLConnection escapeAndQuoteData:tempValue];
}
- else
- [value setString:[mySQLConnection escapeAndQuoteString:tempValue]];
-
- [argument appendFormat:@"%@ = %@", [NSArrayObjectAtIndex(keys, i) backtickQuotedString], value];
+ else {
+ escVal = [mySQLConnection escapeAndQuoteString:tempValue];
+ }
+
+ if(!escVal) {
+ SPLog(@"(row=%ld) nil value for key <%@> is invalid! Abort.",row,NSArrayObjectAtIndex(keys, i));
+ return @"";
+ }
+
+ [argument appendFormat:@"%@ = %@", [NSArrayObjectAtIndex(keys, i) backtickQuotedString], [NSString stringWithFormat:fmt,escVal]];
}
}
diff --git a/Source/SPTableContentDelegate.m b/Source/SPTableContentDelegate.m
index 4d7bbb04..07c355b9 100644
--- a/Source/SPTableContentDelegate.m
+++ b/Source/SPTableContentDelegate.m
@@ -239,7 +239,7 @@
// issue that the table has no primary key
NSString *wherePart = [NSString stringWithString:[self argumentForRow:[tableContentView selectedRow]]];
- if ([wherePart length] == 0) return NO;
+ if (![wherePart length]) return NO;
// If the selected cell hasn't been loaded, load it.
if ([[tableValues cellDataAtRow:rowIndex column:[[tableColumn identifier] integerValue]] isSPNotLoaded]) {