aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPCustomQuery.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPCustomQuery.m')
-rw-r--r--Source/SPCustomQuery.m180
1 files changed, 90 insertions, 90 deletions
diff --git a/Source/SPCustomQuery.m b/Source/SPCustomQuery.m
index f8729074..20d7c803 100644
--- a/Source/SPCustomQuery.m
+++ b/Source/SPCustomQuery.m
@@ -1586,10 +1586,12 @@
/*
* Check if table cell is editable
- * Returns the number of possible changes or
+ * Returns as array the minimum number of possible changes or
* -1 if no table name can be found or multiple table origins
+ * -2 for other errors
+ * and the used WHERE clause to identify
*/
-- (NSInteger)fieldEditStatusForRow:(NSInteger)rowIndex andColumn:(NSInteger)columnIndex
+- (NSArray*)fieldEditStatusForRow:(NSInteger)rowIndex andColumn:(NSInteger)columnIndex
{
NSDictionary *columnDefinition = nil;
@@ -1602,7 +1604,7 @@
}
if(!columnDefinition)
- return -2;
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-2], @"", nil];
// Resolve the original table name for current column if AS was used
NSString *tableForColumn = [columnDefinition objectForKey:@"org_table"];
@@ -1613,40 +1615,70 @@
// No table/database name found indicates that the field's column contains data from more than one table as for UNION
// or the field data are not bound to any table as in SELECT 1 or if column database is unset
if(!tableForColumn || ![tableForColumn length] || !dbForColumn || ![dbForColumn length])
- return -1;
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
// if table and database name are given check if field can be identified unambiguously
- NSString *fieldIDQueryStr = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"]];
+ // first without blob data
+ NSString *fieldIDQueryStr = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"] includeBlobs:NO];
if(!fieldIDQueryStr)
- return -1;
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
[tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Checking field data for editing...", @"checking field data for editing task description")];
- // Actual check whether field can be identified bijectively
+ // Actual check whether field can be identified bijectively
MCPResult *tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
[[columnDefinition objectForKey:@"db"] backtickQuotedString],
[tableForColumn backtickQuotedString],
fieldIDQueryStr]];
- [tableDocumentInstance endTask];
-
- if ([mySQLConnection queryErrored])
- return -1;
+ if ([mySQLConnection queryErrored]) {
+ [tableDocumentInstance endTask];
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
+ }
NSArray *tempRow = [tempResult fetchRowAsArray];
- if(![tempRow count])
- return -1;
+ if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] > 1) {
+ // try to identify the cell by using blob data
+ fieldIDQueryStr = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"] includeBlobs:YES];
+ if(!fieldIDQueryStr) {
+ [tableDocumentInstance endTask];
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
+ }
+
+ tempResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT COUNT(1) FROM %@.%@ %@",
+ [[columnDefinition objectForKey:@"db"] backtickQuotedString],
+ [tableForColumn backtickQuotedString],
+ fieldIDQueryStr]];
+
+ if ([mySQLConnection queryErrored]) {
+ [tableDocumentInstance endTask];
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
+ }
+
+ tempRow = [tempResult fetchRowAsArray];
- return [[tempRow objectAtIndex:0] integerValue];
+ if([tempRow count] && [[tempRow objectAtIndex:0] integerValue] < 1) {
+ [tableDocumentInstance endTask];
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:-1], @"", nil];
+ }
+
+ }
+
+ [tableDocumentInstance endTask];
+
+ if(fieldIDQueryStr == nil)
+ fieldIDQueryStr = @"";
+
+ return [NSArray arrayWithObjects:[NSNumber numberWithInteger:[[tempRow objectAtIndex:0] integerValue]], fieldIDQueryStr, nil];
}
/*
* Collect all columns for a given 'tableForColumn' table and
- * return a WHERE clause for identifying the field in quesyion.
+ * return a WHERE clause for identifying the field in question.
*/
-- (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database
+- (NSString *)argumentForRow:(NSUInteger)rowIndex ofTable:(NSString *)tableForColumn andDatabase:(NSString *)database includeBlobs:(BOOL)includeBlobs
{
NSArray *dataRow;
NSDictionary *theRow;
@@ -1693,21 +1725,27 @@
for(field in columnsForFieldTableName) {
id aValue = [dataRow objectAtIndex:[[field objectForKey:@"datacolumnindex"] integerValue]];
if ([aValue isKindOfClass:[NSNull class]] || [aValue isNSNull]) {
- [fieldIDQueryStr appendFormat:@"%@ IS NULL", [[field objectForKey:@"org_name"] backtickQuotedString]];
+ [fieldIDQueryStr appendFormat:@"%@ IS NULL AND ", [[field objectForKey:@"org_name"] backtickQuotedString]];
} else {
- [fieldIDQueryStr appendFormat:@"%@=", [[field objectForKey:@"org_name"] backtickQuotedString]];
- if ([[field objectForKey:@"typegrouping"] isEqualToString:@"textdata"])
- [fieldIDQueryStr appendFormat:@"'%@'", [mySQLConnection prepareString:aValue]];
- else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"blobdata"])
- [fieldIDQueryStr appendFormat:@"X'%@'", [mySQLConnection prepareBinaryData:aValue]];
- else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"integer"])
- [fieldIDQueryStr appendFormat:@"%@", [aValue description]];
- else
- [fieldIDQueryStr appendFormat:@"'%@'", [mySQLConnection prepareString:aValue]];
+ 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"]) {
+ if(includeBlobs) {
+ [fieldIDQueryStr appendFormat:@"%@=X'%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareBinaryData:aValue]];
+ }
+ }
+ else if ([[field objectForKey:@"typegrouping"] isEqualToString:@"integer"]) {
+ [fieldIDQueryStr appendFormat:@"%@=%@ AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [aValue description]];
+ }
+ else {
+ [fieldIDQueryStr appendFormat:@"%@='%@' AND ", [[field objectForKey:@"org_name"] backtickQuotedString], [mySQLConnection prepareString:aValue]];
+ }
}
-
- [fieldIDQueryStr appendString:@" AND "];
}
+
// Remove last " AND "
if([fieldIDQueryStr length]>12)
[fieldIDQueryStr replaceCharactersInRange:NSMakeRange([fieldIDQueryStr length]-5,5) withString:@")"];
@@ -1830,11 +1868,11 @@
// Resolve the original column name if AS was used
NSString *columnName = [columnDefinition objectForKey:@"org_name"];
- // NSString *fieldIDQueryString = [self argumentForRow:rowIndex ofTable:tableForColumn];
- fieldIDQueryString = [self argumentForRow:rowIndex ofTable:tableForColumn andDatabase:[columnDefinition objectForKey:@"db"]];
+ // Check if the IDstring identifies the current field bijectively and get the WHERE clause
+ NSArray *editStatus = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]];
+ fieldIDQueryString = [editStatus objectAtIndex:1];
+ NSInteger numberOfPossibleUpdateRows = [[editStatus objectAtIndex:0] integerValue];
- // Check if the IDstring identifies the current field bijectively
- NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]];
if(numberOfPossibleUpdateRows == 1) {
NSString *newObject = nil;
@@ -1895,7 +1933,7 @@
} else {
SPBeginAlertSheet(NSLocalizedString(@"Error", @"error"), NSLocalizedString(@"OK", @"OK button"), nil, nil, [tableDocumentInstance parentWindow], self, nil, nil,
[NSString stringWithFormat:NSLocalizedString(@"Updating field content failed. Couldn't identify field origin unambiguously (%ld match%@). It's very likely that while editing this field of table `%@` was changed.", @"message of panel when error while updating field to db after enabling it"),
- (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?@"es":@"", [columnDefinition objectForKey:@"org_table"]]);
+ (numberOfPossibleUpdateRows<1)?0:numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?@"es":@"", [columnDefinition objectForKey:@"org_table"]]);
}
@@ -2181,7 +2219,6 @@
if ( aTableView == customQueryView ) {
NSDictionary *columnDefinition;
- BOOL isFieldEditable = NO;
BOOL isBlob = NO;
// Retrieve the column defintion
@@ -2199,52 +2236,6 @@
else
isBlob = NO;
- // Check if the clicked table field is editable
- NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]];
- isFieldEditable = (numberOfPossibleUpdateRows == 1) ? YES : NO;
- NSPoint pos = [NSEvent mouseLocation];
- pos.y -= 20;
- switch(numberOfPossibleUpdateRows) {
- case -1:
- isFieldEditable = NO;
- fieldIDQueryString = nil;
- [SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb
- atLocation:pos
- ofType:@"text"];
- isFieldEditable = NO;
- // Allow to display blobs even it's not editable
- if(!isBlob && [multipleLineEditingButton state] == NSOffState)
- return NO;
- break;
-
- case 0:
- [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, [columnDefinition objectForKey:@"org_table"]]
- atLocation:pos
- ofType:@"text"];
- isFieldEditable = NO;
- // Allow to display blobs even it's not editable
- if(!isBlob && [multipleLineEditingButton state] == NSOffState)
- return NO;
- break;
-
- case 1:
- isFieldEditable = YES;
- if(!isBlob && [multipleLineEditingButton state] == NSOffState)
- return YES;
- break;
-
- default:
- [SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""]
- atLocation:pos
- ofType:@"text"];
- isFieldEditable = NO;
- // Allow to display blobs even it's not editable
- if(!isBlob && [multipleLineEditingButton state] == NSOffState)
- return NO;
-
- }
-
-
if ([multipleLineEditingButton state] == NSOnState || isBlob) {
SPFieldEditorController *fieldEditor = [[SPFieldEditorController alloc] init];
@@ -2253,6 +2244,9 @@
editedRow = rowIndex;
editedScrollViewRect = [customQueryScrollView documentVisibleRect];
+ NSArray *editStatus = [self fieldEditStatusForRow:rowIndex andColumn:[aTableColumn identifier]];
+ isFieldEditable = ([[editStatus objectAtIndex:0] integerValue] == 1) ? YES : NO;
+
// Set max text length
if ([[columnDefinition objectForKey:@"typegrouping"] isEqualToString:@"string"]
&& [columnDefinition valueForKey:@"char_length"])
@@ -2283,7 +2277,7 @@
return NO;
}
- return isFieldEditable;
+ return YES;
} else {
return YES;
@@ -3373,11 +3367,12 @@
if ((self = [super init])) {
usedQuery = [[NSString stringWithString:@""] retain];
-
+ fieldIDQueryString = nil;
sortField = nil;
isDesc = NO;
sortColumn = nil;
selectionButtonCanBeEnabled = NO;
+ isFieldEditable = NO;
cqColumnDefinition = nil;
favoritesManager = nil;
@@ -3415,7 +3410,7 @@
prefs = [NSUserDefaults standardUserDefaults];
- kCellEditorErrorNoMatch = NSLocalizedString(@"Field is not editable. No matching record found. Reload data, check encoding, or try to add a primary key field or more fields in your SELECT statement for table '%@' to identify field origin unambiguously.", @"Custom Query result editing error - could not identify original row");
+ kCellEditorErrorNoMatch = NSLocalizedString(@"Field is not editable. No matching record found.\nReload data, check encoding, or try to add\na primary key field or more fields\nin your SELECT statement for table '%@'\nto identify field origin unambiguously.", @"Custom Query result editing error - could not identify original row");
kCellEditorErrorNoMultiTabDb = NSLocalizedString(@"Field is not editable. Field has no or multiple table or database origin(s).",@"field is not editable due to no table/database");
kCellEditorErrorTooManyMatches = NSLocalizedString(@"Field is not editable. Couldn't identify field origin unambiguously (%ld match%@).", @"Custom Query result editing error - could not match row being edited uniquely");
@@ -3466,6 +3461,7 @@
NSUInteger row, column;
NSDictionary *columnDefinition = nil;
+ BOOL shouldBeginEditing = NO;
row = [customQueryView editedRow];
column = [customQueryView editedColumn];
@@ -3480,7 +3476,8 @@
if(!columnDefinition) return NO;
- NSInteger numberOfPossibleUpdateRows = [self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([customQueryView tableColumns], column) identifier]];
+ NSArray *editStatus = [self fieldEditStatusForRow:row andColumn:[NSArrayObjectAtIndex([customQueryView tableColumns], column) identifier]];
+ NSInteger numberOfPossibleUpdateRows = [[editStatus objectAtIndex:0] integerValue];
NSPoint pos = [[tableDocumentInstance parentWindow] convertBaseToScreen:[customQueryView convertPoint:[customQueryView frameOfCellAtColumn:column row:row].origin toView:nil]];
pos.y -= 20;
switch(numberOfPossibleUpdateRows) {
@@ -3488,23 +3485,24 @@
[SPTooltip showWithObject:kCellEditorErrorNoMultiTabDb
atLocation:pos
ofType:@"text"];
- return NO;
+ shouldBeginEditing = NO;
break;
case 0:
[SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorNoMatch, [columnDefinition objectForKey:@"org_table"]]
atLocation:pos
ofType:@"text"];
- return NO;
+ shouldBeginEditing = NO;
break;
case 1:
+ shouldBeginEditing = YES;
break;
default:
[SPTooltip showWithObject:[NSString stringWithFormat:kCellEditorErrorTooManyMatches, (long)numberOfPossibleUpdateRows, (numberOfPossibleUpdateRows>1)?NSLocalizedString(@"es", @"Plural suffix for row count, eg 4 match*es*"):@""]
atLocation:pos
ofType:@"text"];
- return NO;
+ shouldBeginEditing = NO;
}
NSString *fieldType;
@@ -3518,8 +3516,10 @@
else
isBlob = NO;
- // Check if current edited field is a blob
- if (isBlob)
+ isFieldEditable = shouldBeginEditing;
+
+ // Check if current edited field is a blob or should be displayed in field editor sheet
+ if (isBlob || [multipleLineEditingButton state] == NSOnState)
{
// Cancel editing
[control abortEditing];
@@ -3537,7 +3537,7 @@
// Set editing color to black for NULL values while editing
[fieldEditor setTextColor:[NSColor blackColor]];
- return YES;
+ return shouldBeginEditing;
}