From 86541d46e1953b1942ddcbdcbe94d5d2caa69f22 Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sun, 10 Jul 2011 23:54:33 +0000 Subject: - Fix exceptions editing non-unique-keyed views or custom query results with some kinds of binary data, fixing http://spbug.com/l/1412 . - Clean up logic and code --- Source/SPCustomQuery.m | 38 +++++++++++++++++++++++--------------- Source/SPTableContent.m | 32 ++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 29 deletions(-) diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m index eacffe3b..b7d41bfa 100644 --- a/Source/SPCustomQuery.m +++ b/Source/SPCustomQuery.m @@ -1819,6 +1819,7 @@ NSArray *dataRow; NSDictionary *theRow; id field; + NSString *baseString = @"WHERE ("; //Look for all columns which are coming from "tableForColumn" NSMutableArray *columnsForFieldTableName = [NSMutableArray array]; @@ -1829,7 +1830,7 @@ // Try to identify the field bijectively NSMutableString *fieldIDQueryStr = [NSMutableString string]; - [fieldIDQueryStr setString:@"WHERE ("]; + [fieldIDQueryStr setString:baseString]; // --- Build WHERE clause --- dataRow = [resultData rowContentsAtIndex:rowIndex]; @@ -1863,25 +1864,29 @@ if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) { [fieldIDQueryStr appendFormat:@"%@ IS NULL AND ", [[field objectForKey:@"org_name"] backtickQuotedString]]; } else { - if ([[field objectForKey:@"typegrouping"] isEqualToString:@"textdata"]) { - if(includeBlobs) { - [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]; - } - } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"blobdata"] || [[field objectForKey:@"type"] isEqualToString:@"BINARY"] || [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"]) { - if(includeBlobs) { - [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]; - } + NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"]; + + // Skip blob-type fields if requested + if (!includeBlobs + && ([fieldTypeGrouping isEqualToString:@"textdata"] + || [fieldTypeGrouping isEqualToString:@"blobdata"] + || [[field objectForKey:@"type"] isEqualToString:@"BINARY"] + || [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"])) + { + continue; } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"bit"]) { + + // If the field is of type BIT then it needs a binary prefix + if ([fieldTypeGrouping isEqualToString:@"bit"]) { [fieldIDQueryStr appendFormat:@"%@=b'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]; } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"integer"]) { - [fieldIDQueryStr appendFormat:@"%@=%@ AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]; - } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"geometry"]) { + else if ([fieldTypeGrouping isEqualToString:@"geometry"]) { [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]; } + // BLOB/TEXT data + else if ([aValue isKindOfClass:[NSData class]]) { + [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]; + } else { [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]; } @@ -1892,6 +1897,9 @@ if([fieldIDQueryStr length]>12) [fieldIDQueryStr replaceCharactersInRange:NSMakeRange([fieldIDQueryStr length]-5,5) withString:@")"]; + // Check for empty strings + if (![fieldIDQueryStr length] || [fieldIDQueryStr isEqualToString:baseString]) return nil; + return fieldIDQueryStr; } diff --git a/Source/SPTableContent.m b/Source/SPTableContent.m index e88fe9e3..5295bb3d 100644 --- a/Source/SPTableContent.m +++ b/Source/SPTableContent.m @@ -1707,25 +1707,29 @@ if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) { [fieldIDQueryStr appendFormat:@"%@ IS NULL AND ", [[field objectForKey:@"org_name"] backtickQuotedString]]; } else { - if ([[field objectForKey:@"typegrouping"] isEqualToString:@"textdata"]) { - if(includeBlobs) { - [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]; - } - } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"blobdata"] || [[field objectForKey:@"type"] isEqualToString:@"BINARY"] || [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"]) { - if(includeBlobs) { - [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]; - } + NSString *fieldTypeGrouping = [field objectForKey:@"typegrouping"]; + + // Skip blob-type fields if requested + if (!includeBlobs + && ([fieldTypeGrouping isEqualToString:@"textdata"] + || [fieldTypeGrouping isEqualToString:@"blobdata"] + || [[field objectForKey:@"type"] isEqualToString:@"BINARY"] + || [[field objectForKey:@"type"] isEqualToString:@"VARBINARY"])) + { + continue; } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"bit"]) { + + // If the field is of type BIT then it needs a binary prefix + if ([fieldTypeGrouping isEqualToString:@"bit"]) { [fieldIDQueryStr appendFormat:@"%@=b'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]; } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"integer"]) { - [fieldIDQueryStr appendFormat:@"%@=%@ AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]]; - } - else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"geometry"]) { + else if ([fieldTypeGrouping isEqualToString:@"geometry"]) { [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:[aValue data]]]; } + // BLOB/TEXT data + else if ([aValue isKindOfClass:[NSData class]]) { + [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]]; + } else { [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]]; } -- cgit v1.2.3