aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPTableContent.m
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2015-06-12 00:01:01 +0200
committerMax <post@wickenrode.com>2015-06-17 11:53:08 +0200
commit3d8accc866c35c41717188f933d77f48c708a69f (patch)
tree3088c9f164f0eec86c62cb6f1351ad3e601e156b /Source/SPTableContent.m
parentf12f9ce2853145ddcede5e4aef5511f9380d740f (diff)
downloadsequelpro-3d8accc866c35c41717188f933d77f48c708a69f.tar.gz
sequelpro-3d8accc866c35c41717188f933d77f48c708a69f.tar.bz2
sequelpro-3d8accc866c35c41717188f933d77f48c708a69f.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)
Diffstat (limited to 'Source/SPTableContent.m')
-rw-r--r--Source/SPTableContent.m73
1 files changed, 47 insertions, 26 deletions
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]];
}
}