diff options
author | Bibiko <bibiko@eva.mpg.de> | 2010-09-03 10:53:26 +0000 |
---|---|---|
committer | Bibiko <bibiko@eva.mpg.de> | 2010-09-03 10:53:26 +0000 |
commit | ca60d2e7bdec4763489e79ff4c457c32cd1f57db (patch) | |
tree | 85ba4e228f51ec6975833d3e2a8a7b0860f0df8e | |
parent | 4aaa7dda2d01afbebb9f7c2a6ba8537a3206858a (diff) | |
download | sequelpro-ca60d2e7bdec4763489e79ff4c457c32cd1f57db.tar.gz sequelpro-ca60d2e7bdec4763489e79ff4c457c32cd1f57db.tar.bz2 sequelpro-ca60d2e7bdec4763489e79ff4c457c32cd1f57db.zip |
• finished the first implementation of CSV Import into new table
note:What else is needed for such an import? table encoding settings? ... has to be discussed
-rw-r--r-- | Interfaces/English.lproj/DataMigrationDialog.xib | 71 | ||||
-rw-r--r-- | Source/SPDataImport.h | 1 | ||||
-rw-r--r-- | Source/SPDataImport.m | 39 | ||||
-rw-r--r-- | Source/SPFieldMapperController.h | 4 | ||||
-rw-r--r-- | Source/SPFieldMapperController.m | 182 | ||||
-rw-r--r-- | Source/SPTableView.m | 10 | ||||
-rw-r--r-- | Source/SPTablesList.m | 2 |
7 files changed, 259 insertions, 50 deletions
diff --git a/Interfaces/English.lproj/DataMigrationDialog.xib b/Interfaces/English.lproj/DataMigrationDialog.xib index 9306af15..97194022 100644 --- a/Interfaces/English.lproj/DataMigrationDialog.xib +++ b/Interfaces/English.lproj/DataMigrationDialog.xib @@ -12,7 +12,7 @@ </object> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <bool key="EncodedWithXMLCoder">YES</bool> - <integer value="144"/> + <integer value="13"/> </object> <object class="NSArray" key="IBDocument.PluginDependencies"> <bool key="EncodedWithXMLCoder">YES</bool> @@ -280,7 +280,6 @@ </object> <int key="NSResizingMask">3</int> <bool key="NSIsResizeable">YES</bool> - <bool key="NSIsEditable">YES</bool> <reference key="NSTableView" ref="678921094"/> </object> <object class="NSTableColumn" id="283787363"> @@ -332,7 +331,6 @@ <bool key="NSUsesItemFromMenu">YES</bool> <bool key="NSAltersState">YES</bool> </object> - <bool key="NSIsEditable">YES</bool> <reference key="NSTableView" ref="678921094"/> </object> <object class="NSTableColumn" id="185178480"> @@ -1860,30 +1858,6 @@ <int key="connectionID">69</int> </object> <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">fieldMapperTableView</string> - <reference key="source" ref="1001"/> - <reference key="destination" ref="678921094"/> - </object> - <int key="connectionID">70</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">delegate</string> - <reference key="source" ref="678921094"/> - <reference key="destination" ref="1001"/> - </object> - <int key="connectionID">71</int> - </object> - <object class="IBConnectionRecord"> - <object class="IBOutletConnection" key="connection"> - <string key="label">dataSource</string> - <reference key="source" ref="678921094"/> - <reference key="destination" ref="1001"/> - </object> - <int key="connectionID">72</int> - </object> - <object class="IBConnectionRecord"> <object class="IBActionConnection" key="connection"> <string key="label">closeSheet:</string> <reference key="source" ref="1001"/> @@ -2363,6 +2337,30 @@ </object> <int key="connectionID">409</int> </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">dataSource</string> + <reference key="source" ref="678921094"/> + <reference key="destination" ref="1001"/> + </object> + <int key="connectionID">410</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">delegate</string> + <reference key="source" ref="678921094"/> + <reference key="destination" ref="1001"/> + </object> + <int key="connectionID">411</int> + </object> + <object class="IBConnectionRecord"> + <object class="IBOutletConnection" key="connection"> + <string key="label">fieldMapperTableView</string> + <reference key="source" ref="1001"/> + <reference key="destination" ref="678921094"/> + </object> + <int key="connectionID">413</int> + </object> </object> <object class="IBMutableOrderedSet" key="objectRecords"> <object class="NSArray" key="orderedObjects"> @@ -3471,6 +3469,7 @@ <string>405.IBPluginDependency</string> <string>406.IBPluginDependency</string> <string>41.IBPluginDependency</string> + <string>42.CustomClassName</string> <string>42.IBPluginDependency</string> <string>42.ImportedFromIB2</string> <string>43.IBPluginDependency</string> @@ -3501,9 +3500,9 @@ <object class="NSMutableArray" key="dict.values"> <bool key="EncodedWithXMLCoder">YES</bool> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{827, 351}, {522, 348}}</string> + <string>{{749, 497}, {522, 348}}</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> - <string>{{827, 351}, {522, 348}}</string> + <string>{{749, 497}, {522, 348}}</string> <integer value="1"/> <string>{{387, 725}, {432, 282}}</string> <boolean value="NO"/> @@ -3730,6 +3729,7 @@ <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> + <string>SPTableView</string> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> <integer value="1"/> <string>com.apple.InterfaceBuilder.CocoaPlugin</string> @@ -3774,7 +3774,7 @@ </object> </object> <nil key="sourceID"/> - <int key="maxID">409</int> + <int key="maxID">413</int> </object> <object class="IBClassDescriber" key="IBDocument.Classes"> <object class="NSMutableArray" key="referencedPartialClassDescriptions"> @@ -4596,6 +4596,7 @@ <string>rowUpButton</string> <string>skipexistingRowsCheckBox</string> <string>tableTargetPopup</string> + <string>tablesListInstance</string> <string>theDelegate</string> </object> <object class="NSMutableArray" key="dict.values"> @@ -4614,7 +4615,7 @@ <string>id</string> <string>id</string> <string>id</string> - <string>NSTableView</string> + <string>id</string> <string>id</string> <string>NSPathControl</string> <string>id</string> @@ -4643,6 +4644,7 @@ <string>id</string> <string>NSPopUpButton</string> <string>id</string> + <string>id</string> </object> </object> <object class="NSMutableDictionary" key="toOneOutletInfosByName"> @@ -4691,6 +4693,7 @@ <string>rowUpButton</string> <string>skipexistingRowsCheckBox</string> <string>tableTargetPopup</string> + <string>tablesListInstance</string> <string>theDelegate</string> </object> <object class="NSMutableArray" key="dict.values"> @@ -4753,7 +4756,7 @@ </object> <object class="IBToOneOutletInfo"> <string key="name">fieldMapperTableView</string> - <string key="candidateClassName">NSTableView</string> + <string key="candidateClassName">id</string> </object> <object class="IBToOneOutletInfo"> <string key="name">fieldMappingImportArray</string> @@ -4864,6 +4867,10 @@ <string key="candidateClassName">NSPopUpButton</string> </object> <object class="IBToOneOutletInfo"> + <string key="name">tablesListInstance</string> + <string key="candidateClassName">id</string> + </object> + <object class="IBToOneOutletInfo"> <string key="name">theDelegate</string> <string key="candidateClassName">id</string> </object> diff --git a/Source/SPDataImport.h b/Source/SPDataImport.h index 9a9dedf5..97ba134f 100644 --- a/Source/SPDataImport.h +++ b/Source/SPDataImport.h @@ -94,6 +94,7 @@ BOOL csvImportMethodHasTail; BOOL insertRemainingRowsAfterUpdate; BOOL importMethodIsUpdate; + BOOL importIntoNewTable; NSUInteger exportMode; NSUserDefaults *prefs; diff --git a/Source/SPDataImport.m b/Source/SPDataImport.m index c9b5664b..efc85bbc 100644 --- a/Source/SPDataImport.m +++ b/Source/SPDataImport.m @@ -76,8 +76,10 @@ fieldMappingImportArrayIsPreview = NO; fieldMappingArrayHasGlobalVariables = NO; importMethodIsUpdate = NO; + importIntoNewTable = NO; insertRemainingRowsAfterUpdate = NO; numberOfImportDataColumns = 0; + selectedTableTarget = nil; prefs = nil; lastFilename = nil; @@ -1074,15 +1076,34 @@ document:tableDocumentInstance notificationName:@"Import Finished"]; - // If the table selected for import is also selected in the content view, - // update the content view - on the main thread to avoid crashes. - if ([tablesListInstance tableName] && [selectedTableTarget isEqualToString:[tablesListInstance tableName]]) { - if ([[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent]) { - [tableContentInstance performSelectorOnMainThread:@selector(reloadTable:) withObject:nil waitUntilDone:YES]; - } else { - [tablesListInstance setContentRequiresReload:YES]; + + if(importIntoNewTable) { + + // Select the new table + + // Update current database tables + [tablesListInstance performSelectorOnMainThread:@selector(updateTables:) withObject:self waitUntilDone:YES]; + + // Re-query the structure of all databases in the background + [NSThread detachNewThreadSelector:@selector(queryDbStructureWithUserInfo:) toTarget:mySQLConnection withObject:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], @"forceUpdate", nil]]; + + // Select the new table + [tablesListInstance selectItemWithName:selectedTableTarget]; + + } else { + + // If import was done into a new table or the table selected for import is also selected in the content view, + // update the content view - on the main thread to avoid crashes. + if ([tablesListInstance tableName] && [selectedTableTarget isEqualToString:[tablesListInstance tableName]]) { + if ([[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableContent]) { + [tableContentInstance performSelectorOnMainThread:@selector(reloadTable:) withObject:nil waitUntilDone:YES]; + } else { + [tablesListInstance setContentRequiresReload:YES]; + } } + } + } /** @@ -1165,13 +1186,14 @@ // Get mapping settings and preset some global variables fieldMapperOperator = [[NSArray arrayWithArray:[fieldMapperController fieldMapperOperator]] retain]; fieldMappingArray = [[NSArray arrayWithArray:[fieldMapperController fieldMappingArray]] retain]; - selectedTableTarget = [NSString stringWithString:[fieldMapperController selectedTableTarget]]; + selectedTableTarget = [[NSString stringWithString:[fieldMapperController selectedTableTarget]] retain]; selectedImportMethod = [NSString stringWithString:[fieldMapperController selectedImportMethod]]; fieldMappingTableColumnNames = [[NSArray arrayWithArray:[fieldMapperController fieldMappingTableColumnNames]] retain]; fieldMappingGlobalValueArray = [[NSArray arrayWithArray:[fieldMapperController fieldMappingGlobalValueArray]] retain]; fieldMappingTableDefaultValues = [[NSArray arrayWithArray:[fieldMapperController fieldMappingTableDefaultValues]] retain]; csvImportHeaderString = [[NSString stringWithString:[fieldMapperController importHeaderString]] retain]; csvImportTailString = [[NSString stringWithString:[fieldMapperController onupdateString]] retain]; + importIntoNewTable = [fieldMapperController importIntoNewTable]; fieldMappingArrayHasGlobalVariables = [fieldMapperController globalValuesInUsage]; csvImportMethodHasTail = ([csvImportTailString length] == 0) ? NO : YES; insertRemainingRowsAfterUpdate = [fieldMapperController insertRemainingRowsAfterUpdate]; @@ -1475,6 +1497,7 @@ if (fieldMappingImportArray) [fieldMappingImportArray release]; if (lastFilename) [lastFilename release]; if (prefs) [prefs release]; + if(selectedTableTarget) [selectedTableTarget release]; for (id retainedObject in nibObjectsToRelease) [retainedObject release]; diff --git a/Source/SPFieldMapperController.h b/Source/SPFieldMapperController.h index 15efd595..da5b6ca2 100644 --- a/Source/SPFieldMapperController.h +++ b/Source/SPFieldMapperController.h @@ -24,12 +24,13 @@ #import <Cocoa/Cocoa.h> #import <MCPKit/MCPKit.h> +#import "SPTableView.h" @class SPTextView; @interface SPFieldMapperController : NSWindowController { - IBOutlet NSTableView *fieldMapperTableView; + IBOutlet id fieldMapperTableView; IBOutlet id fieldMapperTableScrollView; IBOutlet NSTableView *globalValuesTableView; IBOutlet NSPopUpButton *tableTargetPopup; @@ -138,6 +139,7 @@ - (BOOL)importFieldNamesHeader; - (BOOL)insertRemainingRowsAfterUpdate; - (BOOL)globalValuesInUsage; +- (BOOL)importIntoNewTable; - (NSString*)onupdateString; - (NSString*)importHeaderString; diff --git a/Source/SPFieldMapperController.m b/Source/SPFieldMapperController.m index 1018ff4e..b9f41935 100644 --- a/Source/SPFieldMapperController.m +++ b/Source/SPFieldMapperController.m @@ -77,6 +77,8 @@ prefs = [NSUserDefaults standardUserDefaults]; tablesListInstance = [theDelegate valueForKeyPath:@"tablesListInstance"]; + [fieldMapperTableView setDelegate:self]; + [fieldMapperTableView setDataSource:self]; } @@ -218,7 +220,11 @@ - (NSString*)selectedTableTarget { + + if(newTableMode) return [newTableNameTextField stringValue]; + return ([tableTargetPopup titleOfSelectedItem] == nil) ? @"" : [tableTargetPopup titleOfSelectedItem]; + } - (NSArray*)fieldMapperOperator @@ -259,6 +265,11 @@ return NO; } +- (BOOL)importIntoNewTable +{ + return newTableMode; +} + - (NSArray*)fieldMappingTableColumnNames { return fieldMappingTableColumnNames; @@ -318,6 +329,38 @@ - (IBAction)closeSheet:(id)sender { + + // Try to create the new TABLE + if(newTableMode && [sender tag] == 1) { + + [[self window] endEditingFor:nil]; + + NSMutableString *createString = [NSMutableString string]; + [createString appendFormat:@"CREATE TABLE %@ (\n", [[newTableNameTextField stringValue] backtickQuotedString]]; + NSInteger columnIndex = 0; + NSInteger numberOfColumns = [fieldMappingTableColumnNames count]; + for(columnIndex = 0; columnIndex < numberOfColumns; columnIndex++) { + [createString appendFormat:@"\t%@ %@", [[fieldMappingTableColumnNames objectAtIndex:columnIndex] backtickQuotedString], [fieldMappingTableTypes objectAtIndex:columnIndex]]; + if(columnIndex < numberOfColumns-1) [createString appendString:@", \n"]; + } + [createString appendString:@")"]; + [mySQLConnection queryString:createString]; + + if ([mySQLConnection queryErrored]) { + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error adding new table", @"error adding new table message") + defaultButton:NSLocalizedString(@"OK", @"OK button") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"An error occurred while trying to add the new table '%@' by\n\n%@.\n\nMySQL said: %@", @"error adding new table informative message"), [newTableNameTextField stringValue], createString, [mySQLConnection getLastErrorMessage]]]; + + [alert setAlertStyle:NSCriticalAlertStyle]; + [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:nil contextInfo:nil]; + return; + } + + } + + [advancedReplaceView setHidden:YES]; [advancedUpdateView setHidden:YES]; [advancedInsertView setHidden:YES]; @@ -1026,13 +1069,22 @@ BOOL enableImportButton = YES; if(newTableMode) { - [importButton setTitle:@"Not Yet"]; - [importButton setEnabled:NO]; - return; if(![tablesListInstance isTableNameValid:[newTableNameTextField stringValue] forType:SPTableTypeTable ignoringSelectedTable:NO]) { [importButton setEnabled:NO]; return; } + for(NSString* fieldName in fieldMappingTableColumnNames) { + if(![fieldName length]) { + [importButton setEnabled:NO]; + return; + } + } + for(NSString* fieldType in fieldMappingTableTypes) { + if(![fieldType length]) { + [importButton setEnabled:NO]; + return; + } + } } if([[self selectedImportMethod] isEqualToString:@"UPDATE"]) { @@ -1316,7 +1368,7 @@ [self validateImportButton]; } // Refresh table - [aTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.01]; + // [aTableView performSelector:@selector(reloadData) withObject:nil afterDelay:0.01]; } else if(aTableView == globalValuesTableView) { if ([[aTableColumn identifier] isEqualToString:@"global_value"]) @@ -1337,17 +1389,131 @@ } + +/* + * Trap the enter, escape, tab and arrow keys, overriding default behaviour and continuing/ending editing, + * only within the current row of the tableView only in newTableMode. + */ +- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command +{ + + if(!newTableMode) return NO; + + NSUInteger row, column; + + row = [fieldMapperTableView editedRow]; + column = [fieldMapperTableView editedColumn]; + + // Trap tab key + // -- for handling of blob fields and to check if it's editable look at [[self delegate] control:textShouldBeginEditing:] + if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertTab:)] ) + { + [[control window] makeFirstResponder:control]; + + // Save the current line if it's the last field in the table + if ( [fieldMapperTableView numberOfColumns] - 1 == column) { + [fieldMapperTableView makeFirstResponder]; + } else { + // Select the next field for editing + [fieldMapperTableView editColumn:column+1 row:row withEvent:nil select:YES]; + } + + return YES; + } + + // Trap shift-tab key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertBacktab:)] ) + { + [[control window] makeFirstResponder:control]; + + // Save the current line if it's the last field in the table + if ( column < 1 ) { + [fieldMapperTableView makeFirstResponder]; + } else { + // Select the previous field for editing + [fieldMapperTableView editColumn:column-1 row:row withEvent:nil select:YES]; + } + + return YES; + } + + // Trap enter key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(insertNewline:)] ) + { + + // If newTableNameTextField is active enter key closes the sheet + if(control == newTableNameTextField) { + NSButton *b = [[[NSButton alloc] init] autorelease]; + [b setTag:1]; + [self closeSheet:b]; + return YES; + } + + [[self window] endEditingFor:nil]; + [[control window] makeFirstResponder:control]; + return YES; + + } + + // Trap down arrow key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveDown:)] ) + { + + NSUInteger newRow = row+1; + if (newRow>=[self numberOfRowsInTableView:fieldMapperTableView]) return YES; //check if we're already at the end of the list + + [[control window] makeFirstResponder:control]; + + [fieldMapperTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; + [fieldMapperTableView editColumn:column row:newRow withEvent:nil select:YES]; + return YES; + } + + // Trap up arrow key + else if ( [textView methodForSelector:command] == [textView methodForSelector:@selector(moveUp:)] ) + { + + if (row==0) return YES; //already at the beginning of the list + NSUInteger newRow = row-1; + + [[control window] makeFirstResponder:control]; + + [fieldMapperTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:newRow] byExtendingSelection:NO]; + [fieldMapperTableView editColumn:column row:newRow withEvent:nil select:YES]; + return YES; + } + + + // Trap the escape key + else if ( [[control window] methodForSelector:command] == [[control window] methodForSelector:@selector(cancelOperation:)] ) + { + + // Abort editing + [control abortEditing]; + + // Preserve the focus + [fieldMapperTableView makeFirstResponder]; + + return TRUE; + } + + return FALSE; + +} + #pragma mark - #pragma mark NSTextField delegates + +/* + * Validate some user input in newTableMode + */ - (void)controlTextDidChange:(NSNotification *)notification { - id object = [notification object]; + if(!newTableMode) return; - if (object == newTableNameTextField) { - [self validateImportButton]; - } + [self validateImportButton]; } diff --git a/Source/SPTableView.m b/Source/SPTableView.m index 8255f9c1..c19678db 100644 --- a/Source/SPTableView.m +++ b/Source/SPTableView.m @@ -87,9 +87,19 @@ - (void)keyDown:(NSEvent *)theEvent { + // Check if ENTER or RETURN is hit and edit the column. if([self numberOfSelectedRows] == 1 && ([theEvent keyCode] == 36 || [theEvent keyCode] == 76)) { + + // ENTER or RETURN closes the SPFieldMapperController sheet by sending an object with the tag 1 + if([[[[self delegate] class] description] isEqualToString:@"SPFieldMapperController"]) { + NSButton *b = [[[NSButton alloc] init] autorelease]; + [b setTag:1]; + [[self delegate] closeSheet:b]; + return; + } + if (![[[[self delegate] class] description] isEqualToString:@"SPCustomQuery"] && ![[[[self delegate] class] description] isEqualToString:@"SPQueryFavoriteManager"]){ diff --git a/Source/SPTablesList.m b/Source/SPTablesList.m index e3a5cdd3..8075f244 100644 --- a/Source/SPTablesList.m +++ b/Source/SPTablesList.m @@ -1656,7 +1656,7 @@ [mySQLConnection queryString:query]; if ([mySQLConnection queryErrored]) { - NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error while importing table", @"rror while importing table message") + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Error while importing table", @"error while importing table message") defaultButton:NSLocalizedString(@"OK", @"OK button") alternateButton:nil otherButton:nil |