aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-10-23 22:18:53 +0000
committerBibiko <bibiko@eva.mpg.de>2010-10-23 22:18:53 +0000
commitc965b60b6ec45f56aa406296b5c35f48360f175a (patch)
tree68570c4682d74094247970ff6b1513bd07cefd95 /Source
parenta24ef7bf96e86d8e9ad7ee3ac9147dfca5cb810d (diff)
downloadsequelpro-c965b60b6ec45f56aa406296b5c35f48360f175a.tar.gz
sequelpro-c965b60b6ec45f56aa406296b5c35f48360f175a.tar.bz2
sequelpro-c965b60b6ec45f56aa406296b5c35f48360f175a.zip
• CSV Import Field Mapper Sheet
- added the possibility to apply any sql function while importing set via "Add value or expression" sheet eg concat('$2', '$1', length('$3')) whereby $1 $2 $3 are the placeholder for the csv file columns 1 2 3 [first column starts with 1] • fixed ' escaping issue in MCPConnection
Diffstat (limited to 'Source')
-rw-r--r--Source/SPConstants.h1
-rw-r--r--Source/SPConstants.m1
-rw-r--r--Source/SPDataImport.m92
-rw-r--r--Source/SPFieldMapperController.h4
-rw-r--r--Source/SPFieldMapperController.m84
5 files changed, 169 insertions, 13 deletions
diff --git a/Source/SPConstants.h b/Source/SPConstants.h
index 0992cc1b..fd8c3af6 100644
--- a/Source/SPConstants.h
+++ b/Source/SPConstants.h
@@ -352,6 +352,7 @@ extern NSString *SPBlobTextEditorSpellCheckingEnabled;
extern NSString *SPUniqueSchemaDelimiter;
extern NSString *SPLastImportIntoNewTableEncoding;
extern NSString *SPLastImportIntoNewTableType;
+extern NSString *SPGlobalValueHistory;
// URLs
diff --git a/Source/SPConstants.m b/Source/SPConstants.m
index b84c174f..3dadf8c4 100644
--- a/Source/SPConstants.m
+++ b/Source/SPConstants.m
@@ -179,6 +179,7 @@ NSString *SPBlobTextEditorSpellCheckingEnabled = @"BlobTextEditorSpellChecking
NSString *SPUniqueSchemaDelimiter = @"￸"; // U+FFF8
NSString *SPLastImportIntoNewTableEncoding = @"LastImportIntoNewTableEncoding";
NSString *SPLastImportIntoNewTableType = @"LastImportIntoNewTableType";
+NSString *SPGlobalValueHistory = @"GlobalValueHistory";
// URLs
NSString *SPDonationsURL = @"http://www.sequelpro.com/donate.html";
diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m
index a1051c8c..61698b46 100644
--- a/Source/SPDataImport.m
+++ b/Source/SPDataImport.m
@@ -1259,6 +1259,7 @@
NSInteger mapColumn;
id cellData;
NSInteger mappingArrayCount = [fieldMappingArray count];
+ NSString *re = @"(?<!\\\\)\\$(\\d+)";
for (i = 0; i < mappingArrayCount; i++) {
@@ -1275,8 +1276,34 @@
// Append the data
// - check for global values
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
- // Global variables are coming wrapped in ' ' if there're not marked as SQL
- [setString appendString:NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ NSMutableString *globalVar = [NSMutableString string];
+ if([NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn) isKindOfClass:[NSNull class]]) {
+ [globalVar setString:@"NULL"];
+ } else {
+ [globalVar setString:NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ // Global variables are coming wrapped in ' ' if there're not marked as SQL.
+ // If global variable contains column placeholders $1 etc. replace them.
+ if([globalVar rangeOfString:@"$"].length && [globalVar isMatchedByRegex:re]) {
+ while([globalVar isMatchedByRegex:re]) {
+ [globalVar flushCachedRegexData];
+ NSRange aRange = [globalVar rangeOfRegex:re capture:0L];
+ NSInteger colIndex = [[globalVar substringWithRange:[globalVar rangeOfRegex:re capture:1L]] integerValue];
+ if(colIndex > 0 && colIndex <= [csvRowArray count]) {
+ NSString *colStr = NSArrayObjectAtIndex(csvRowArray, colIndex-1);
+ // escape column string for ' or " if the char just before $… is a " or '
+ if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '\'')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]];
+ else if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '"')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
+ else
+ [globalVar replaceCharactersInRange:aRange withString:colStr];
+ } else {
+ [globalVar replaceCharactersInRange:aRange withString:@""];
+ }
+ }
+ }
+ }
+ [setString appendString:globalVar];
} else {
cellData = NSArrayObjectAtIndex(csvRowArray, mapColumn);
@@ -1299,8 +1326,34 @@
// Append the data
// - check for global values
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
- // Global variables are coming wrapped in ' ' if there're not marked as SQL
- [whereString appendFormat:@"=%@", NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ NSMutableString *globalVar = [NSMutableString string];
+ if([NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn) isKindOfClass:[NSNull class]]) {
+ [globalVar setString:@"NULL"];
+ } else {
+ [globalVar setString:NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ // Global variables are coming wrapped in ' ' if there're not marked as SQL.
+ // If global variable contains column placeholders $1 etc. replace them.
+ if([globalVar rangeOfString:@"$"].length && [globalVar isMatchedByRegex:re]) {
+ while([globalVar isMatchedByRegex:re]) {
+ [globalVar flushCachedRegexData];
+ NSRange aRange = [globalVar rangeOfRegex:re capture:0L];
+ NSInteger colIndex = [[globalVar substringWithRange:[globalVar rangeOfRegex:re capture:1L]] integerValue];
+ if(colIndex > 0 && colIndex <= [csvRowArray count]) {
+ NSString *colStr = NSArrayObjectAtIndex(csvRowArray, colIndex-1);
+ // escape column string for ' or " if the char just before $… is a " or '
+ if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '\'')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]];
+ else if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '"')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
+ else
+ [globalVar replaceCharactersInRange:aRange withString:colStr];
+ } else {
+ [globalVar replaceCharactersInRange:aRange withString:@""];
+ }
+ }
+ }
+ }
+ [whereString appendFormat:@"=%@", globalVar];
} else {
cellData = NSArrayObjectAtIndex(csvRowArray, mapColumn);
@@ -1331,6 +1384,7 @@
NSInteger mapColumn;
id cellData;
NSInteger mappingArrayCount = [fieldMappingArray count];
+ NSString *re = @"(?<!\\\\)\\$(\\d+)";
for (i = 0; i < mappingArrayCount; i++) {
@@ -1344,8 +1398,34 @@
// Append the data
// - check for global values
if(fieldMappingArrayHasGlobalVariables && mapColumn >= numberOfImportDataColumns) {
- // Global variables are coming wrapped in ' ' if there're not marked as SQL
- [valueString appendString:NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ NSMutableString *globalVar = [NSMutableString string];
+ if([NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn) isKindOfClass:[NSNull class]]) {
+ [globalVar setString:@"NULL"];
+ } else {
+ [globalVar setString:NSArrayObjectAtIndex(fieldMappingGlobalValueArray, mapColumn)];
+ // Global variables are coming wrapped in ' ' if there're not marked as SQL.
+ // If global variable contains column placeholders $1 etc. replace them.
+ if([globalVar rangeOfString:@"$"].length && [globalVar isMatchedByRegex:re]) {
+ while([globalVar isMatchedByRegex:re]) {
+ [globalVar flushCachedRegexData];
+ NSRange aRange = [globalVar rangeOfRegex:re capture:0L];
+ NSInteger colIndex = [[globalVar substringWithRange:[globalVar rangeOfRegex:re capture:1L]] integerValue];
+ if(colIndex > 0 && colIndex <= [csvRowArray count]) {
+ NSString *colStr = NSArrayObjectAtIndex(csvRowArray, colIndex-1);
+ // escape column string for ' or " if the char just before $… is a " or '
+ if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '\'')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]];
+ else if(aRange.location && [globalVar characterAtIndex:aRange.location-1] == '"')
+ [globalVar replaceCharactersInRange:aRange withString:[colStr stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]];
+ else
+ [globalVar replaceCharactersInRange:aRange withString:colStr];
+ } else {
+ [globalVar replaceCharactersInRange:aRange withString:@""];
+ }
+ }
+ }
+ }
+ [valueString appendString:globalVar];
} else {
cellData = NSArrayObjectAtIndex(csvRowArray, mapColumn);
diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h
index 33b4a400..8a70df90 100644
--- a/Source/SPFieldMapperController.h
+++ b/Source/SPFieldMapperController.h
@@ -62,6 +62,8 @@
IBOutlet NSButton *removeGlobalValueButton;
IBOutlet NSButton *insertNULLValueButton;
IBOutlet id replaceAfterSavingCheckBox;
+ IBOutlet NSPopUpButton *insertPullDownButton;
+ IBOutlet NSMenu *recentGlobalValueMenu;
IBOutlet id ignoreCheckBox;
IBOutlet id ignoreUpdateCheckBox;
@@ -175,6 +177,8 @@
- (IBAction)insertNULLValue:(id)sender;
- (IBAction)closeGlobalValuesSheet:(id)sender;
- (IBAction)advancedCheckboxValidation:(id)sender;
+- (IBAction)insertPulldownValue:(id)sender;
+- (IBAction)insertRecentGlobalValue:(id)sender;
- (IBAction)newTable:(id)sender;
- (IBAction)newTableInfo:(id)sender;
diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m
index 1787c6f2..10afade0 100644
--- a/Source/SPFieldMapperController.m
+++ b/Source/SPFieldMapperController.m
@@ -280,10 +280,8 @@
{
NSMutableArray *globals = [NSMutableArray array];
for(NSInteger i=0; i < [fieldMappingGlobalValues count]; i++)
- if([[fieldMappingGlobalValuesSQLMarked objectAtIndex:i] boolValue])
+ if([[fieldMappingGlobalValuesSQLMarked objectAtIndex:i] boolValue] || [[fieldMappingGlobalValues objectAtIndex:i] isKindOfClass:[NSNull class]])
[globals addObject:[fieldMappingGlobalValues objectAtIndex:i]];
- else if([[fieldMappingGlobalValues objectAtIndex:i] isKindOfClass:[NSNull class]])
- [globals addObject:[NSString stringWithFormat:@"'%@'", [fieldMappingGlobalValues objectAtIndex:i]]];
else
[globals addObject:[NSString stringWithFormat:@"'%@'", [[fieldMappingGlobalValues objectAtIndex:i] stringByReplacingOccurrencesOfString:@"'" withString:@"\\'"]]];
@@ -1053,6 +1051,35 @@
{
addGlobalSheetIsOpen = YES;
+ // Init insert pulldown menu
+
+ // Remove all dynamic menu items
+ while([insertPullDownButton numberOfItems] > 5)
+ [insertPullDownButton removeItemAtIndex:[insertPullDownButton numberOfItems]-1];
+
+ // Add recent global value menu
+ if([prefs objectForKey:SPGlobalValueHistory] && [[prefs objectForKey:SPGlobalValueHistory] isKindOfClass:[NSArray class]] && [[prefs objectForKey:SPGlobalValueHistory] count])
+ for(id item in [prefs objectForKey:SPGlobalValueHistory])
+ [recentGlobalValueMenu addItemWithTitle:item action:@selector(insertRecentGlobalValue:) keyEquivalent:@""];
+
+ // Add column placeholder
+ NSInteger i = 0;
+ if([fieldMappingImportArray count] && [[fieldMappingImportArray objectAtIndex:0] count]) {
+ for(id item in [fieldMappingImportArray objectAtIndex:0]) {
+ i++;
+ if ([item isNSNull]) {
+ [insertPullDownButton addItemWithTitle:[NSString stringWithFormat:@"%i. <%@>", i, [prefs objectForKey:SPNullValue]]];
+ } else if ([item isSPNotLoaded]) {
+ [insertPullDownButton addItemWithTitle:[NSString stringWithFormat:@"%i. <%@>", i, @"DEFAULT"]];
+ } else {
+ if([item length] > 20)
+ [insertPullDownButton addItemWithTitle:[NSString stringWithFormat:@"%i. %@…", i, [item substringToIndex:20]]];
+ else
+ [insertPullDownButton addItemWithTitle:[NSString stringWithFormat:@"%i. %@", i, item]];
+ }
+ }
+ }
+
[NSApp beginSheet:globalValuesSheet
modalForWindow:[self window]
modalDelegate:self
@@ -1221,6 +1248,27 @@
}
}
+- (IBAction)insertPulldownValue:(id)sender
+{
+
+ if([globalValuesTableView numberOfSelectedRows] != 1 || [globalValuesTableView editedRow] < 0) return;
+
+ NSInteger index = [sender indexOfItem:[sender selectedItem]] - 4;
+ if([[[NSApp keyWindow] firstResponder] respondsToSelector:@selector(insertText:)])
+ [[[NSApp keyWindow] firstResponder] insertText:[NSString stringWithFormat:@"$%ld", index]];
+
+}
+
+- (IBAction)insertRecentGlobalValue:(id)sender
+{
+
+ if([globalValuesTableView numberOfSelectedRows] != 1 || [globalValuesTableView editedRow] < 0) return;
+
+ if([[[NSApp keyWindow] firstResponder] respondsToSelector:@selector(insertText:)])
+ [[[NSApp keyWindow] firstResponder] insertText:[sender title]];
+
+}
+
#pragma mark -
#pragma mark Others
@@ -1782,14 +1830,36 @@
}
[self validateImportButton];
}
- // Refresh table
- // [aTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.01];
}
else if(aTableView == globalValuesTableView) {
- if ([[aTableColumn identifier] isEqualToString:@"global_value"])
+ if ([[aTableColumn identifier] isEqualToString:@"global_value"]) {
+
[fieldMappingGlobalValues replaceObjectAtIndex:(numberOfImportColumns + rowIndex) withObject:anObject];
- else if ([[aTableColumn identifier] isEqualToString:@"sql"])
+
+ // If anObject contains $1 etc. enable SQL checkbox
+ if([anObject isMatchedByRegex:@"(?<!\\\\)\\$\\d+"])
+ [fieldMappingGlobalValuesSQLMarked replaceObjectAtIndex:(numberOfImportColumns + rowIndex) withObject:[NSNumber numberWithInteger:1]];
+
+ // Store anObject as recent global value if it's new
+ NSMutableArray *recents = [NSMutableArray array];
+ if([prefs objectForKey:SPGlobalValueHistory] && [[prefs objectForKey:SPGlobalValueHistory] isKindOfClass:[NSArray class]] && [[prefs objectForKey:SPGlobalValueHistory] count])
+ [recents setArray:[prefs objectForKey:SPGlobalValueHistory]];
+ if([recents containsObject:anObject])
+ [recents removeObject:anObject];
+ [recents insertObject:anObject atIndex:0];
+ while([recents count] > 20)
+ [recents removeObjectAtIndex:[recents count]-1];
+ if([recents count])
+ [prefs setObject:recents forKey:SPGlobalValueHistory];
+
+ // Re-init recent menu
+ [recentGlobalValueMenu removeAllItems];
+ for(id item in recents)
+ [recentGlobalValueMenu addItemWithTitle:item action:@selector(insertRecentGlobalValue:) keyEquivalent:@""];
+
+ } else if ([[aTableColumn identifier] isEqualToString:@"sql"]) {
[fieldMappingGlobalValuesSQLMarked replaceObjectAtIndex:(numberOfImportColumns + rowIndex) withObject:anObject];
+ }
}
}