aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPDatabaseViewController.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPDatabaseViewController.m')
-rw-r--r--Source/SPDatabaseViewController.m641
1 files changed, 0 insertions, 641 deletions
diff --git a/Source/SPDatabaseViewController.m b/Source/SPDatabaseViewController.m
deleted file mode 100644
index 8f0e8c38..00000000
--- a/Source/SPDatabaseViewController.m
+++ /dev/null
@@ -1,641 +0,0 @@
-//
-// SPDatabaseViewController.m
-// sequel-pro
-//
-// Created by Rowan Beentje on October 31, 2010.
-// Copyright (c) 2010 Arboreal. All rights reserved.
-//
-// Permission is hereby granted, free of charge, to any person
-// obtaining a copy of this software and associated documentation
-// files (the "Software"), to deal in the Software without
-// restriction, including without limitation the rights to use,
-// copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following
-// conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-// More info at <https://github.com/sequelpro/sequelpro>
-
-#ifndef SP_CODA /* headers */
-#import "SPAppController.h"
-#import "SPBundleHTMLOutputController.h"
-#endif
-#import "SPCopyTable.h"
-#import "SPDatabaseViewController.h"
-#import "SPHistoryController.h"
-#import "SPTableContent.h"
-#import "SPTableData.h"
-#import "SPTablesList.h"
-#import "SPTableTriggers.h"
-#import "SPThreadAdditions.h"
-#import "SPTableRelations.h"
-#ifdef SP_CODA /* headers */
-#import "SPTableStructure.h"
-#import "SPTableStructureLoading.h"
-#endif
-
-#import <SPMySQL/SPMySQL.h>
-
-@interface SPDatabaseDocument (SPDatabaseViewControllerPrivateAPI)
-
-- (void)_loadTabTask:(NSNumber *)tabViewItemIndexNumber;
-- (void)_loadTableTask;
-
-@end
-
-@implementation SPDatabaseDocument (SPDatabaseViewController)
-
-#pragma mark -
-#pragma mark Getters
-
-#ifndef SP_CODA /* getters */
-/**
- * Returns the master database view, containing the tables list and views for
- * table setup and contents.
- */
-- (NSView *)databaseView
-{
- return parentView;
-}
-#endif
-
-/**
- * Returns the name of the currently selected table/view/procedure/function.
- */
-- (NSString *)table
-{
- return selectedTableName;
-}
-
-/**
- * Returns the currently selected table type, or -1 if no table or multiple tables are selected
- */
-- (SPTableType)tableType
-{
- return selectedTableType;
-}
-
-/**
- * Returns YES if table source has already been loaded
- */
-- (BOOL)structureLoaded
-{
- return structureLoaded;
-}
-
-/**
- * Returns YES if table content has already been loaded
- */
-- (BOOL)contentLoaded
-{
- return contentLoaded;
-}
-
-/**
- * Returns YES if table status has already been loaded
- */
-- (BOOL)statusLoaded
-{
- return statusLoaded;
-}
-
-#ifndef SP_CODA /* toolbar ibactions */
-
-#pragma mark -
-#pragma mark Tab view control and delegate methods
-
-//WARNING: Might be called from code in background threads
-- (IBAction)viewStructure:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![[self onMainThread] couldCommitCurrentViewActions]) {
- [[mainToolbar onMainThread] setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [[tableTabView onMainThread] selectTabViewItemAtIndex:0];
- [[mainToolbar onMainThread] setSelectedItemIdentifier:SPMainToolbarTableStructure];
- [spHistoryControllerInstance updateHistoryEntries];
-
- [prefs setInteger:SPStructureViewMode forKey:SPLastViewMode];
-}
-
-- (IBAction)viewContent:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![self couldCommitCurrentViewActions]) {
- [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [tableTabView selectTabViewItemAtIndex:1];
- [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableContent];
- [spHistoryControllerInstance updateHistoryEntries];
-
- [prefs setInteger:SPContentViewMode forKey:SPLastViewMode];
-}
-
-- (IBAction)viewQuery:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![self couldCommitCurrentViewActions]) {
- [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [tableTabView selectTabViewItemAtIndex:2];
- [mainToolbar setSelectedItemIdentifier:SPMainToolbarCustomQuery];
- [spHistoryControllerInstance updateHistoryEntries];
-
- // Set the focus on the text field
- [parentWindow makeFirstResponder:customQueryTextView];
-
- [prefs setInteger:SPQueryEditorViewMode forKey:SPLastViewMode];
-}
-
-- (IBAction)viewStatus:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![self couldCommitCurrentViewActions]) {
- [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [tableTabView selectTabViewItemAtIndex:3];
- [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableInfo];
- [spHistoryControllerInstance updateHistoryEntries];
-
- if ([[self table] length]) {
- [extendedTableInfoInstance loadTable:[self table]];
- }
-
- [parentWindow makeFirstResponder:[extendedTableInfoInstance valueForKeyPath:@"tableCreateSyntaxTextView"]];
-
- [prefs setInteger:SPTableInfoViewMode forKey:SPLastViewMode];
-}
-
-- (IBAction)viewRelations:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![self couldCommitCurrentViewActions]) {
- [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [tableTabView selectTabViewItemAtIndex:4];
- [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableRelations];
- [spHistoryControllerInstance updateHistoryEntries];
-
- [prefs setInteger:SPRelationsViewMode forKey:SPLastViewMode];
-}
-
-- (IBAction)viewTriggers:(id)sender
-{
- // Cancel the selection if currently editing a view and unable to save
- if (![self couldCommitCurrentViewActions]) {
- [mainToolbar setSelectedItemIdentifier:*SPViewModeToMainToolbarMap[[prefs integerForKey:SPLastViewMode]]];
- return;
- }
-
- [tableTabView selectTabViewItemAtIndex:5];
- [mainToolbar setSelectedItemIdentifier:SPMainToolbarTableTriggers];
- [spHistoryControllerInstance updateHistoryEntries];
-
- [prefs setInteger:SPTriggersViewMode forKey:SPLastViewMode];
-}
-#endif
-
-/**
- * Mark the structure tab for refresh when it's next switched to,
- * or reload the view if it's currently active
- */
-- (void)setStructureRequiresReload:(BOOL)reload
-{
- BOOL reloadRequired = reload;
-
-#ifndef SP_CODA
- if ([self currentlySelectedView] == SPTableViewStructure) {
- reloadRequired = NO;
- }
-#endif
-
- if (reloadRequired && selectedTableName) {
- [tableSourceInstance loadTable:selectedTableName];
- }
- else {
- structureLoaded = !reload;
- }
-}
-
-/**
- * Mark the content tab for refresh when it's next switched to,
- * or reload the view if it's currently active
- */
-- (void)setContentRequiresReload:(BOOL)reload
-{
- if (reload && selectedTableName
-#ifndef SP_CODA /* check which tab is selected */
- && [self currentlySelectedView] == SPTableViewContent
-#endif
- ) {
- [tableContentInstance loadTable:selectedTableName];
- }
- else {
- contentLoaded = !reload;
- }
-}
-
-/**
- * Mark the extended tab info for refresh when it's next switched to,
- * or reload the view if it's currently active
- */
-- (void)setStatusRequiresReload:(BOOL)reload
-{
- if (reload && selectedTableName
-#ifndef SP_CODA /* check which tab is selected */
- && [self currentlySelectedView] == SPTableViewStatus
-#endif
- ) {
- [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName];
- }
- else {
- statusLoaded = !reload;
- }
-}
-
-/**
- * Mark the relations tab for refresh when it's next switched to,
- * or reload the view if it's currently active
- */
-- (void)setRelationsRequiresReload:(BOOL)reload
-{
- if (reload && selectedTableName
-#ifndef SP_CODA /* check which tab is selected */
- && [self currentlySelectedView] == SPTableViewRelations
-#endif
- ) {
- [[tableRelationsInstance onMainThread] refreshRelations:self];
- }
- else {
- relationsLoaded = !reload;
- }
-}
-
-#ifndef SP_CODA /* !!! respond to tab change */
-/**
- * Triggers a task to update the newly selected tab view, ensuring
- * the data is fully loaded and up-to-date.
- */
-- (void)tabView:(NSTabView *)aTabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem
-{
- [self startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), [self table]]];
-
- // We can't pass aTabView or tabViewItem UI objects to a bg thread, but since the change should already
- // be done in *did*SelectTabViewItem we can just ask the tab view for the current selection index and use that
- SPTableViewType newView = [self currentlySelectedView];
-
- if ([NSThread isMainThread]) {
- [NSThread detachNewThreadWithName:SPCtxt(@"SPDatabaseViewController view load task",self)
- target:self
- selector:@selector(_loadTabTask:)
- object:@(newView)];
- }
- else {
- [self _loadTabTask:@(newView)];
- }
-}
-#endif
-
-#pragma mark -
-#pragma mark Table control
-
-/**
- * Loads a specified table into the database view, and ensures it's selected in
- * the tables list. Passing a table name of nil will deselect any currently selected
- * table, but will leave multiple selections intact.
- * If this method is supplied with the currently selected name, a reload rather than
- * a load will be triggered.
- */
-- (void)loadTable:(NSString *)aTable ofType:(SPTableType)aTableType
-{
- // Ensure a connection is still present
- if (![mySQLConnection isConnected]) return;
-
- // If the supplied table name was nil, clear the views.
- if (!aTable) {
-
- // Update the selected table name and type
- if (selectedTableName) SPClear(selectedTableName);
-
- selectedTableType = SPTableTypeNone;
-
- // Clear the views
- [[tablesListInstance onMainThread] setSelectionState:nil];
- [tableSourceInstance loadTable:nil];
- [tableContentInstance loadTable:nil];
-#ifndef SP_CODA /* [extendedTableInfoInstance loadTable:] */
- [[extendedTableInfoInstance onMainThread] loadTable:nil];
- [[tableTriggersInstance onMainThread] resetInterface];
- [[tableRelationsInstance onMainThread] refreshRelations:self];
-#endif
- structureLoaded = NO;
- contentLoaded = NO;
- statusLoaded = NO;
- triggersLoaded = NO;
- relationsLoaded = NO;
-
-#ifndef SP_CODA
- // Update the window title
- [self updateWindowTitle:self];
-
- // Add a history entry
- [spHistoryControllerInstance updateHistoryEntries];
-#endif
-
- // Notify listeners of the table change
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-
- return;
- }
-
- BOOL isReloading = (selectedTableName && [selectedTableName isEqualToString:aTable]);
-
- // Store the new name
- if (selectedTableName) [selectedTableName release];
-
- selectedTableName = [[NSString alloc] initWithString:aTable];
- selectedTableType = aTableType;
-
- // Start a task
- if (isReloading) {
- [self startTaskWithDescription:NSLocalizedString(@"Reloading...", @"Reloading table task string")];
- }
- else {
- [self startTaskWithDescription:[NSString stringWithFormat:NSLocalizedString(@"Loading %@...", @"Loading table task string"), aTable]];
- }
-
- // Update the tables list interface - also updates menus to reflect the selected table type
- [[tablesListInstance onMainThread] setSelectionState:[NSDictionary dictionaryWithObjectsAndKeys:aTable, @"name", [NSNumber numberWithInteger:aTableType], @"type", nil]];
-
- // If on the main thread, fire up a thread to deal with view changes and data loading;
- // if already on a background thread, make the changes on the existing thread.
- if ([NSThread isMainThread]) {
- [NSThread detachNewThreadWithName:SPCtxt(@"SPDatabaseViewController table load task",self)
- target:self
- selector:@selector(_loadTableTask)
- object:nil];
- }
- else {
- [self _loadTableTask];
- }
-}
-
-@end
-
-#pragma mark -
-
-@implementation SPDatabaseDocument (SPDatabaseViewControllerPrivateAPI)
-
-/**
- * In a threaded task, ensure that the supplied tab is loaded -
- * usually as a result of switching to it.
- */
-- (void)_loadTabTask:(NSNumber *)tabViewItemIndexNumber
-{
- NSAutoreleasePool *tabLoadPool = [[NSAutoreleasePool alloc] init];
-
- // If anything other than a single table or view is selected, don't proceed.
- if (![self table] || ([tablesListInstance tableType] != SPTableTypeTable && [tablesListInstance tableType] != SPTableTypeView))
- {
- [self endTask];
- [tabLoadPool drain];
- return;
- }
-
- // Get the tab view index and ensure the associated view is loaded
- SPTableViewType selectedTabViewIndex = [tabViewItemIndexNumber integerValue];
-
- switch (selectedTabViewIndex) {
- case SPTableViewStructure:
- if (!structureLoaded) {
- [tableSourceInstance loadTable:selectedTableName];
- structureLoaded = YES;
- }
- break;
- case SPTableViewContent:
- if (!contentLoaded) {
- [tableContentInstance loadTable:selectedTableName];
- contentLoaded = YES;
- }
- break;
-#ifndef SP_CODA /* case SPTableViewStatus: case SPTableViewTriggers: */
- case SPTableViewStatus:
- if (!statusLoaded) {
- [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName];
- statusLoaded = YES;
- }
- break;
- case SPTableViewTriggers:
- if (!triggersLoaded) {
- [[tableTriggersInstance onMainThread] loadTriggers];
- triggersLoaded = YES;
- }
- break;
- case SPTableViewRelations:
- if (!relationsLoaded) {
- [[tableRelationsInstance onMainThread] refreshRelations:self];
- relationsLoaded = YES;
- }
- break;
-#endif
- }
-
- [self endTask];
-
- [tabLoadPool drain];
-}
-
-
-/**
- * In a threaded task, load the currently selected table/view/proc/function.
- */
-- (void)_loadTableTask
-{
- NSAutoreleasePool *loadPool = [[NSAutoreleasePool alloc] init];
- NSString *tableEncoding = nil;
-
-#ifndef SP_CODA /* Update the window title */
- // Update the window title
- [self updateWindowTitle:self];
-#endif
-
- // Reset table information caches and mark that all loaded views require their data reloading
- [tableDataInstance resetAllData];
-
- structureLoaded = NO;
- contentLoaded = NO;
- statusLoaded = NO;
- triggersLoaded = NO;
- relationsLoaded = NO;
-
- // Ensure status and details are fetched using UTF8
- NSString *previousEncoding = [mySQLConnection encoding];
- BOOL changeEncoding = ![previousEncoding isEqualToString:@"utf8"];
-
- if (changeEncoding) {
- [mySQLConnection storeEncodingForRestoration];
- [mySQLConnection setEncoding:@"utf8"];
- }
-
- // Cache status information on the working thread
- [tableDataInstance updateStatusInformationForCurrentTable];
-
- // Check the current encoding against the table encoding to see whether
- // an encoding change and reset is required. This also caches table information on
- // the working thread.
- if( selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable) {
-
- // tableEncoding == nil indicates that there was an error while retrieving table data
- tableEncoding = [tableDataInstance tableEncoding];
-
- // If encoding is set to Autodetect, update the connection character set encoding
- // based on the newly selected table's encoding - but only if it differs from the current encoding.
- if ([[[NSUserDefaults standardUserDefaults] objectForKey:SPDefaultEncoding] intValue] == SPEncodingAutodetect) {
- if (tableEncoding != nil && ![tableEncoding isEqualToString:previousEncoding]) {
- [self setConnectionEncoding:tableEncoding reloadingViews:NO];
- changeEncoding = NO;
- }
- }
- }
-
- if (changeEncoding) [mySQLConnection restoreStoredEncoding];
-
- // Notify listeners of the table change now that the state is fully set up.
- [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadWithName:SPTableChangedNotification object:self];
-
-#ifndef SP_CODA /* [spHistoryControllerInstance restoreViewStates] */
-
- // Restore view states as appropriate
- [spHistoryControllerInstance restoreViewStates];
-#endif
-
- // Load the currently selected view if looking at a table or view
- if (tableEncoding && (selectedTableType == SPTableTypeView || selectedTableType == SPTableTypeTable))
- {
-#ifndef SP_CODA /* load everything */
- NSInteger selectedTabViewIndex = [[self onMainThread] currentlySelectedView];
-
- switch (selectedTabViewIndex) {
- case SPTableViewStructure:
-#endif
- [tableSourceInstance loadTable:selectedTableName];
- structureLoaded = YES;
-#ifndef SP_CODA /* load everything */
- break;
- case SPTableViewContent:
-#endif
- [tableContentInstance loadTable:selectedTableName];
- contentLoaded = YES;
-#ifndef SP_CODA /* load everything */
- break;
- case SPTableViewStatus:
- [[extendedTableInfoInstance onMainThread] loadTable:selectedTableName];
- statusLoaded = YES;
- break;
- case SPTableViewTriggers:
- [[tableTriggersInstance onMainThread] loadTriggers];
- triggersLoaded = YES;
- break;
- case SPTableViewRelations:
- [[tableRelationsInstance onMainThread] refreshRelations:self];
- relationsLoaded = YES;
- break;
- }
-#endif
- }
-
- // Clear any views which haven't been loaded as they weren't visible. Note
- // that this should be done after reloading visible views, instead of clearing all
- // views, to reduce UI operations and avoid resetting state unnecessarily.
- // Some views (eg TableRelations) make use of the SPTableChangedNotification and
- // so don't require manual clearing.
- if (!structureLoaded) [tableSourceInstance loadTable:nil];
- if (!contentLoaded) [tableContentInstance loadTable:nil];
- if (!statusLoaded) [[extendedTableInfoInstance onMainThread] loadTable:nil];
- if (!triggersLoaded) [[tableTriggersInstance onMainThread] resetInterface];
-
- // If the table row counts an inaccurate and require updating, trigger an update - no
- // action will be performed if not necessary
- [tableDataInstance updateAccurateNumberOfRowsForCurrentTableForcingUpdate:NO];
-
-#ifndef SP_CODA /* show Create Table syntax */
- // Update the "Show Create Syntax" window if it's already opened
- // according to the selected table/view/proc/func
- if ([[[self onMainThread] getCreateTableSyntaxWindow] isVisible]) {
- [[self onMainThread] showCreateTableSyntax:self];
- }
-
- // Add a history entry
- [spHistoryControllerInstance updateHistoryEntries];
-#endif
- // Empty the loading pool and exit the thread
- [self endTask];
-
-#ifndef SP_CODA /* triggered commands */
- NSArray *triggeredCommands = [SPAppDelegate bundleCommandsForTrigger:SPBundleTriggerActionTableChanged];
-
- for(NSString* cmdPath in triggeredCommands)
- {
- NSArray *data = [cmdPath componentsSeparatedByString:@"|"];
- NSMenuItem *aMenuItem = [[[NSMenuItem alloc] init] autorelease];
- [aMenuItem setTag:0];
- [aMenuItem setToolTip:[data objectAtIndex:0]];
-
- // For HTML output check if corresponding window already exists
- BOOL stopTrigger = NO;
- if([(NSString*)[data objectAtIndex:2] length]) {
- BOOL correspondingWindowFound = NO;
- NSString *uuid = [data objectAtIndex:2];
- for(id win in [NSApp windows]) {
- if([[[[win delegate] class] description] isEqualToString:@"SPBundleHTMLOutputController"]) {
- if([[[win delegate] windowUUID] isEqualToString:uuid]) {
- correspondingWindowFound = YES;
- break;
- }
- }
- }
- if(!correspondingWindowFound) stopTrigger = YES;
- }
- if(!stopTrigger) {
- id firstResponder = [[NSApp keyWindow] firstResponder];
- if([[data objectAtIndex:1] isEqualToString:SPBundleScopeGeneral]) {
- [[SPAppDelegate onMainThread] executeBundleItemForApp:aMenuItem];
- }
- else if([[data objectAtIndex:1] isEqualToString:SPBundleScopeDataTable]) {
- if([[[firstResponder class] description] isEqualToString:@"SPCopyTable"])
- [[firstResponder onMainThread] executeBundleItemForDataTable:aMenuItem];
- }
- else if([[data objectAtIndex:1] isEqualToString:SPBundleScopeInputField]) {
- if([firstResponder isKindOfClass:[NSTextView class]])
- [[firstResponder onMainThread] executeBundleItemForInputField:aMenuItem];
- }
- }
- }
-#endif
-
- [loadPool drain];
-}
-
-@end