From 233156c7449eb0377396836f5550e076b5fbd5c0 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Tue, 30 Oct 2018 16:17:14 -0700 Subject: [PATCH 01/15] fix missing footer for backup dialog (#3056) @MattIrv Thanks for helping out --- src/sql/base/browser/ui/modal/media/modal.css | 16 +++++----------- .../backup/media/backupDialog.css | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/src/sql/base/browser/ui/modal/media/modal.css b/src/sql/base/browser/ui/modal/media/modal.css index f639771d95..abe53a1d80 100644 --- a/src/sql/base/browser/ui/modal/media/modal.css +++ b/src/sql/base/browser/ui/modal/media/modal.css @@ -66,14 +66,11 @@ } .monaco-shell .modal.flyout-dialog .modal-body, -.monaco-shell .modal.flyout-dialog .angular-modal-body { - margin-bottom: auto; - height: 100%; -} - +.monaco-shell .modal.flyout-dialog .angular-modal-body, /* Style for body and footer in modal dialog. This should be applied to dialog created with angular component. */ .monaco-shell .modal.flyout-dialog .modal-body-and-footer { - height: 100%; + flex: 1 1; + overflow: hidden; } /* modl body content style(excluding dialogErrorMessage section) for angulr component dialog */ @@ -85,6 +82,8 @@ .modal.flyout-dialog .angular-form { height: 100%; + display: flex; + flex-direction: column; } .modal.flyout-dialog .dialog-label { @@ -105,10 +104,6 @@ padding-left: 4px; } -.modal.flyout-dialog .modal-body { - overflow-y: auto; -} - .vs-dark.monaco-shell .modal.flyout-dialog .input { background-color: #3C3C3C; } @@ -187,7 +182,6 @@ .modal.flyout-dialog .dialog-message-header { overflow: hidden; - overflow-y: hidden; display: flex; flex-direction: row; } diff --git a/src/sql/parts/disasterRecovery/backup/media/backupDialog.css b/src/sql/parts/disasterRecovery/backup/media/backupDialog.css index 8ec1f1c1c2..e338fcec04 100644 --- a/src/sql/parts/disasterRecovery/backup/media/backupDialog.css +++ b/src/sql/parts/disasterRecovery/backup/media/backupDialog.css @@ -17,7 +17,7 @@ } .backup-dialog { - height: calc(100% - 15px) + height: 100% } .backup-dialog .advanced-main-header { From 18671b7cca3bfc9954236734e832701e19a0f138 Mon Sep 17 00:00:00 2001 From: Ryan Date: Wed, 31 Oct 2018 13:03:02 -0400 Subject: [PATCH 02/15] Add query plan theme support (#2991) (#3031) Add monaco-editor and monaco-editor-hover to output otherwise backgrounds collide. --- src/sql/parts/grid/load/css/qp.css | 10 +++------- src/sql/parts/queryPlan/queryPlan.ts | 4 ++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sql/parts/grid/load/css/qp.css b/src/sql/parts/grid/load/css/qp.css index e91aa988c3..48a9fee1ce 100644 --- a/src/sql/parts/grid/load/css/qp.css +++ b/src/sql/parts/grid/load/css/qp.css @@ -1,8 +1,7 @@ div.qp-node { - background-color: #FFFFCC; margin: 2px; padding: 2px; - border: 1px solid black; + border: 1px solid; } div.qp-statement-header { margin: 2px; @@ -33,8 +32,7 @@ div[class|='qp-icon'] { .qp-tt { top: 4em; left: 2em; - border: 1px solid black; - background-color: #FFFFEE; + border: 1px solid; padding: 2px; width: 30em; } @@ -56,7 +54,7 @@ div[class|='qp-icon'] { .qp-tt td, .qp-tt th { font-size: 11px; - border-bottom: solid 1px Black; + border-bottom: solid 1px; padding: 1px; } @@ -204,8 +202,6 @@ div.qp-node:hover .qp-tt { .qp-root { display: table; position: relative; - background-color: #fff; - color: #000; } .qp-root svg { diff --git a/src/sql/parts/queryPlan/queryPlan.ts b/src/sql/parts/queryPlan/queryPlan.ts index 390b600ebb..216727cf1a 100644 --- a/src/sql/parts/queryPlan/queryPlan.ts +++ b/src/sql/parts/queryPlan/queryPlan.ts @@ -93,6 +93,10 @@ export class QueryPlan { QP.showPlan(this.container, this._xml, { jsTooltips: false }); + this.container.querySelectorAll('div.qp-tt').forEach(toolTip=>{ + toolTip.classList.add('monaco-editor'); + toolTip.classList.add('monaco-editor-hover'); + }); } public get xml(): string { From 7f66087d8c7758c07bf0735194f03aafebb47548 Mon Sep 17 00:00:00 2001 From: David Shiflet Date: Wed, 31 Oct 2018 13:05:37 -0400 Subject: [PATCH 03/15] Add a command line interface for connecting to a SQL Server (#3047) * Add switches for server, database, user, integrated auth * Refactor into new commandline service * Open query editor when passed server on command line * Add tests --- .../parts/commandLine/common/commandLine.ts | 17 ++ .../commandLine/common/commandLineService.ts | 77 ++++++++ .../common/connectionManagementService.ts | 36 ++-- .../commandLine/commandLineService.test.ts | 176 ++++++++++++++++++ .../environment/common/environment.ts | 7 + src/vs/platform/environment/node/argv.ts | 19 +- .../workbench/electron-browser/workbench.ts | 8 +- 7 files changed, 318 insertions(+), 22 deletions(-) create mode 100644 src/sql/parts/commandLine/common/commandLine.ts create mode 100644 src/sql/parts/commandLine/common/commandLineService.ts create mode 100644 src/sqltest/parts/commandLine/commandLineService.test.ts diff --git a/src/sql/parts/commandLine/common/commandLine.ts b/src/sql/parts/commandLine/common/commandLine.ts new file mode 100644 index 0000000000..4290a6308b --- /dev/null +++ b/src/sql/parts/commandLine/common/commandLine.ts @@ -0,0 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; +import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; +export interface ICommandLineProcessing { + _serviceBrand: any; + /** + * Interprets the various Azure Data Studio-specific command line switches and + * performs the requisite tasks such as connecting to a server + */ + processCommandLine() : void; +} + +export const ICommandLineProcessing = createDecorator('commandLineService'); \ No newline at end of file diff --git a/src/sql/parts/commandLine/common/commandLineService.ts b/src/sql/parts/commandLine/common/commandLineService.ts new file mode 100644 index 0000000000..08c6f9dc50 --- /dev/null +++ b/src/sql/parts/commandLine/common/commandLineService.ts @@ -0,0 +1,77 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; +import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile'; +import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine'; +import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement'; +import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import * as Constants from 'sql/parts/connection/common/constants'; +import { IQueryEditorService } from 'sql/parts/query/common/queryEditorService'; +import * as platform from 'vs/platform/registry/common/platform'; +import { ConnectionProviderProperties, IConnectionProviderRegistry, Extensions as ConnectionProviderExtensions } from 'sql/workbench/parts/connection/common/connectionProviderExtension'; +import * as TaskUtilities from 'sql/workbench/common/taskUtilities'; +import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; + +export class CommandLineService implements ICommandLineProcessing { + private _connectionProfile : ConnectionProfile; + private _showConnectionDialog: boolean; + + constructor( + @IConnectionManagementService private _connectionManagementService : IConnectionManagementService, + @ICapabilitiesService private _capabilitiesService : ICapabilitiesService, + @IEnvironmentService private _environmentService : IEnvironmentService, + @IQueryEditorService private _queryEditorService : IQueryEditorService, + @IObjectExplorerService private _objectExplorerService : IObjectExplorerService, + @IEditorService private _editorService : IEditorService, + ) + { + let profile = null; + if (this._environmentService && this._environmentService.args.server) { + profile = new ConnectionProfile(_capabilitiesService, null); + // We want connection store to use any matching password it finds + profile.savePassword = true; + profile.providerName = Constants.mssqlProviderName; + profile.serverName = _environmentService.args.server; + profile.databaseName = _environmentService.args.database ? _environmentService.args.database : ''; + profile.userName = _environmentService.args.user ? _environmentService.args.user : ''; + profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin'; + profile.connectionName = ''; + profile.setOptionValue('applicationName', Constants.applicationName); + profile.setOptionValue('databaseDisplayName', profile.databaseName); + profile.setOptionValue('groupId', profile.groupId); + } + this._connectionProfile = profile; + const registry = platform.Registry.as(ConnectionProviderExtensions.ConnectionProviderContributions); + let sqlProvider = registry.getProperties( Constants.mssqlProviderName); + // We can't connect to object explorer until the MSSQL connection provider is registered + if (sqlProvider) { + this.processCommandLine(); + } else { + registry.onNewProvider(e => { + if (e.id === Constants.mssqlProviderName) + { + this.processCommandLine(); + } + }); + } + } + public _serviceBrand: any; + public processCommandLine(): void { + if (!this._connectionProfile && !this._connectionManagementService.hasRegisteredServers()) { + // prompt the user for a new connection on startup if no profiles are registered + this._connectionManagementService.showConnectionDialog(); + } else if (this._connectionProfile) { + this._connectionManagementService.connectIfNotConnected(this._connectionProfile, 'connection') + .then(result => TaskUtilities.newQuery(this._connectionProfile, + this._connectionManagementService, + this._queryEditorService, + this._objectExplorerService, + this._editorService)) + .catch(() => {}); + } + } +} \ No newline at end of file diff --git a/src/sql/parts/connection/common/connectionManagementService.ts b/src/sql/parts/connection/common/connectionManagementService.ts index 80f466fa9e..5d925f59b9 100644 --- a/src/sql/parts/connection/common/connectionManagementService.ts +++ b/src/sql/parts/connection/common/connectionManagementService.ts @@ -77,7 +77,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti private _onConnectRequestSent = new Emitter(); private _onConnectionChanged = new Emitter(); private _onLanguageFlavorChanged = new Emitter(); - private _connectionGlobalStatus = new ConnectionGlobalStatus(this._statusBarService); private _configurationEditService: ConfigurationEditingService; @@ -124,16 +123,6 @@ export class ConnectionManagementService extends Disposable implements IConnecti 100 /* High Priority */ )); - if (_capabilitiesService && Object.keys(_capabilitiesService.providers).length > 0 && !this.hasRegisteredServers()) { - // prompt the user for a new connection on startup if no profiles are registered - this.showConnectionDialog(); - } else if (_capabilitiesService && !this.hasRegisteredServers()) { - _capabilitiesService.onCapabilitiesRegistered(e => { - // prompt the user for a new connection on startup if no profiles are registered - this.showConnectionDialog(); - }); - } - const registry = platform.Registry.as(ConnectionProviderExtensions.ConnectionProviderContributions); let providerRegistration = (p: { id: string, properties: ConnectionProviderProperties }) => { @@ -282,29 +271,30 @@ export class ConnectionManagementService extends Disposable implements IConnecti * @param options to use after the connection is complete */ private tryConnect(connection: IConnectionProfile, owner: IConnectableInput, options?: IConnectionCompletionOptions): Promise { + let self = this; return new Promise((resolve, reject) => { // Load the password if it's not already loaded - this._connectionStore.addSavedPassword(connection).then(result => { + self._connectionStore.addSavedPassword(connection).then(result => { let newConnection = result.profile; let foundPassword = result.savedCred; // If there is no password, try to load it from an existing connection - if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection)) { - let existingConnection = this._connectionStatusManager.findConnectionProfile(connection); + if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection)) { + let existingConnection = self._connectionStatusManager.findConnectionProfile(connection); if (existingConnection && existingConnection.connectionProfile) { newConnection.password = existingConnection.connectionProfile.password; foundPassword = true; } } // If the password is required and still not loaded show the dialog - if (!foundPassword && this._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) { - resolve(this.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options)); + if (!foundPassword && self._connectionStore.isPasswordRequired(newConnection) && !newConnection.password) { + resolve(self.showConnectionDialogOnError(connection, owner, { connected: false, errorMessage: undefined, callStack: undefined, errorCode: undefined }, options)); } else { // Try to connect - this.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => { + self.connectWithOptions(newConnection, owner.uri, options, owner).then(connectionResult => { if (!connectionResult.connected && !connectionResult.errorHandled) { // If connection fails show the dialog - resolve(this.showConnectionDialogOnError(connection, owner, connectionResult, options)); + resolve(self.showConnectionDialogOnError(connection, owner, connectionResult, options)); } else { //Resolve with the connection result resolve(connectionResult); @@ -390,7 +380,15 @@ export class ConnectionManagementService extends Disposable implements IConnecti if (this._connectionStatusManager.isConnected(ownerUri)) { resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); } else { - this.connect(connection, ownerUri).then(connectionResult => { + const options: IConnectionCompletionOptions = { + // Should saving the connection be a command line switch? + saveTheConnection : true, + showConnectionDialogOnError : true, + showDashboard : purpose === 'dashboard', + params : undefined, + showFirewallRuleOnError : true, + }; + this.connect(connection, ownerUri, options).then(connectionResult => { if (connectionResult && connectionResult.connected) { resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); } else { diff --git a/src/sqltest/parts/commandLine/commandLineService.test.ts b/src/sqltest/parts/commandLine/commandLineService.test.ts new file mode 100644 index 0000000000..f00d529cc9 --- /dev/null +++ b/src/sqltest/parts/commandLine/commandLineService.test.ts @@ -0,0 +1,176 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; +import * as Constants from 'sql/parts/connection/common/constants'; +import * as Utils from 'sql/parts/connection/common/utils'; +import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; +import * as sqlops from 'sqlops'; + +import { TPromise } from 'vs/base/common/winjs.base'; +import * as assert from 'assert'; +import * as TypeMoq from 'typemoq'; + +import { ConnectionProfile } from 'sql/parts/connection/common/connectionProfile'; +import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService'; +import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; +import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment'; +import { CapabilitiesService, ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService'; +import { CapabilitiesTestService } from 'sqltest/stubs/capabilitiesTestService'; +import { QueryEditorService } from 'sql/parts/query/services/queryEditorService'; +import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; +import { ObjectExplorerService } from 'sql/parts/objectExplorer/common/objectExplorerService'; +import { + IConnectionManagementService, IConnectionDialogService, INewConnectionParams, + ConnectionType, IConnectableInput, IConnectionCompletionOptions, IConnectionCallbacks, + IConnectionParams, IConnectionResult, IServerGroupController, IServerGroupDialogCallbacks, + RunQueryOnConnectionMode +} from 'sql/parts/connection/common/connectionManagement'; +import { ConnectionStore } from 'sql/parts/connection/common/connectionStore'; +import { TestConnectionManagementService } from 'sqltest/stubs/connectionManagementService.test'; + + +class TestParsedArgs implements ParsedArgs{ + [arg: string]: any; + _: string[]; + aad?: boolean; + add?: boolean; + database?:string; + debugBrkPluginHost?: string; + debugBrkSearch?: string; + debugId?: string; + debugPluginHost?: string; + debugSearch?: string; + diff?: boolean; + 'disable-crash-reporter'?: string; + 'disable-extension'?: string | string[]; + 'disable-extensions'?: boolean; + 'disable-restore-windows'?: boolean; + 'disable-telemetry'?: boolean; + 'disable-updates'?: string; + 'driver'?: string; + 'enable-proposed-api'?: string | string[]; + 'export-default-configuration'?: string; + 'extensions-dir'?: string; + extensionDevelopmentPath?: string; + extensionTestsPath?: string; + 'file-chmod'?: boolean; + 'file-write'?: boolean; + 'folder-uri'?: string | string[]; + goto?: boolean; + help?: boolean; + 'install-extension'?: string | string[]; + 'install-source'?: string; + integrated?: boolean; + 'list-extensions'?: boolean; + locale?: string; + log?: string; + logExtensionHostCommunication?: boolean; + 'max-memory'?: number; + 'new-window'?: boolean; + 'open-url'?: boolean; + performance?: boolean; + 'prof-append-timers'?: string; + 'prof-startup'?: string; + 'prof-startup-prefix'?: string; + 'reuse-window'?: boolean; + server?: string; + 'show-versions'?: boolean; + 'skip-add-to-recently-opened'?: boolean; + 'skip-getting-started'?: boolean; + 'skip-release-notes'?: boolean; + status?: boolean; + 'sticky-quickopen'?: boolean; + 'uninstall-extension'?: string | string[]; + 'unity-launch'?: boolean; // Always open a new window, except if opening the first window or opening a file or folder as part of the launch. + 'upload-logs'?: string; + user?: string; + 'user-data-dir'?: string; + _urls?: string[]; + verbose?: boolean; + version?: boolean; + wait?: boolean; + waitMarkerFilePath?: string; +} +suite('commandLineService tests', () => { + + let capabilitiesService: CapabilitiesTestService; + let commandLineService : CommandLineService; + let environmentService : TypeMoq.Mock; + let queryEditorService : TypeMoq.Mock; + let editorService:TypeMoq.Mock; + let objectExplorerService : TypeMoq.Mock; + let connectionStore: TypeMoq.Mock; + + setup(() => { + capabilitiesService = new CapabilitiesTestService(); + connectionStore = TypeMoq.Mock.ofType(ConnectionStore); + }); + + function getCommandLineService(connectionManagementService : IConnectionManagementService, + environmentService? : IEnvironmentService, + capabilitiesService? : ICapabilitiesService + ) : CommandLineService + { + let service= new CommandLineService( + connectionManagementService, + capabilitiesService, + environmentService, + undefined, + undefined, + undefined + ); + return service; + } + + test('processCommandLine shows connection dialog by default', done => { + const connectionManagementService : TypeMoq.Mock + = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict); + + connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(); + connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => false); + connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .verifiable(TypeMoq.Times.never()); + let service = getCommandLineService(connectionManagementService.object); + service.processCommandLine(); + connectionManagementService.verifyAll(); + done(); + }); + + test('processCommandLine does nothing if registered servers exist and no server name is provided', done => { + const connectionManagementService : TypeMoq.Mock + = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict); + + connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never()); + connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true); + connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), TypeMoq.It.isAny())) + .verifiable(TypeMoq.Times.never()); + let service = getCommandLineService(connectionManagementService.object); + service.processCommandLine(); + connectionManagementService.verifyAll(); + done(); + }); + + test('processCommandLine opens a new connection if a server name is passed', done => { + const connectionManagementService : TypeMoq.Mock + = TypeMoq.Mock.ofType(TestConnectionManagementService, TypeMoq.MockBehavior.Strict); + + const environmentService : TypeMoq.Mock = TypeMoq.Mock.ofType(EnvironmentService); + const args : TestParsedArgs = new TestParsedArgs(); + args.server = 'myserver'; + args.database = 'mydatabase'; + environmentService.setup(e => e.args).returns(() => args).verifiable(TypeMoq.Times.atLeastOnce()); + connectionManagementService.setup((c) => c.showConnectionDialog()).verifiable(TypeMoq.Times.never()); + connectionManagementService.setup(c => c.hasRegisteredServers()).returns(() => true).verifiable(TypeMoq.Times.atMostOnce()); + connectionManagementService.setup(c => c.connectIfNotConnected(TypeMoq.It.isAny(), 'connection')) + .returns(() => new Promise((resolve, reject) => { reject('unused');})) + .verifiable(TypeMoq.Times.once()); + let service = getCommandLineService(connectionManagementService.object, environmentService.object, capabilitiesService); + service.processCommandLine(); + environmentService.verifyAll(); + connectionManagementService.verifyAll(); + done(); + }); +}); diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 2d07d986ee..3d5f67b51d 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -62,6 +62,13 @@ export interface ParsedArgs { 'upload-logs'?: string; 'driver'?: string; 'driver-verbose'?: boolean; + // {{SQL CARBON EDIT}} + aad?: boolean; + database?: string; + integrated?: boolean; + server?: string; + user?: string; + // {{SQL CARBON EDIT}} } export const IEnvironmentService = createDecorator('environmentService'); diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index dff9ea9cbc..bd15d92783 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -33,7 +33,12 @@ const options: minimist.Opts = { 'export-default-configuration', 'install-source', 'upload-logs', - 'driver' + 'driver', + // {{SQL CARBON EDIT}} + 'database', + 'server', + 'user', + // {{SQL CARBON EDIT}} ], boolean: [ 'help', @@ -66,7 +71,11 @@ const options: minimist.Opts = { 'status', 'file-write', 'file-chmod', - 'driver-verbose' + 'driver-verbose', + // {{SQL CARBON EDIT}} + 'aad', + 'integrated', + // {{SQL CARBON EDIT}} ], alias: { add: 'a', @@ -85,6 +94,12 @@ const options: minimist.Opts = { 'debugBrkPluginHost': 'inspect-brk-extensions', 'debugSearch': 'inspect-search', 'debugBrkSearch': 'inspect-brk-search', + // {{SQL CARBON EDIT}} + database: 'D', + integrated: 'E', + server: 'S', + user: 'U', + // {{SQL CARBON EDIT}} } }; diff --git a/src/vs/workbench/electron-browser/workbench.ts b/src/vs/workbench/electron-browser/workbench.ts index 87e4a81d9c..476853e9d8 100644 --- a/src/vs/workbench/electron-browser/workbench.ts +++ b/src/vs/workbench/electron-browser/workbench.ts @@ -172,6 +172,10 @@ import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService' import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay'; +// {{SQL CARBON EDIT}} +import { ICommandLineProcessing } from 'sql/parts/commandLine/common/commandLine'; +import { CommandLineService } from 'sql/parts/commandLine/common/commandLineService'; +// {{SQL CARBON EDIT}} interface WorkbenchParams { configuration: IWindowConfiguration; @@ -575,7 +579,9 @@ export class Workbench extends Disposable implements IPartService { serviceCollection.set(IAccountManagementService, accountManagementService); serviceCollection.set(IAccountPickerService, this.instantiationService.createInstance(AccountPickerService)); serviceCollection.set(IProfilerService, this.instantiationService.createInstance(ProfilerService)); - + // {{SQL CARBON EDIT}} + serviceCollection.set(ICommandLineProcessing, this.instantiationService.createInstance(CommandLineService)); + // {{SQL CARBON EDIT}} this._register(toDisposable(() => connectionManagementService.shutdown())); this._register(toDisposable(() => accountManagementService.shutdown())); this._register(toDisposable(() => capabilitiesService.shutdown())); From c0e9f1ca43b2ff91d91fcd69057d8674237b04e5 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Wed, 31 Oct 2018 13:00:23 -0700 Subject: [PATCH 04/15] Fix build break in previous Query Plan commit --- src/sql/parts/queryPlan/queryPlan.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/parts/queryPlan/queryPlan.ts b/src/sql/parts/queryPlan/queryPlan.ts index 216727cf1a..737daad64f 100644 --- a/src/sql/parts/queryPlan/queryPlan.ts +++ b/src/sql/parts/queryPlan/queryPlan.ts @@ -93,7 +93,7 @@ export class QueryPlan { QP.showPlan(this.container, this._xml, { jsTooltips: false }); - this.container.querySelectorAll('div.qp-tt').forEach(toolTip=>{ + (this.container.querySelectorAll('div.qp-tt')).forEach(toolTip=>{ toolTip.classList.add('monaco-editor'); toolTip.classList.add('monaco-editor-hover'); }); From 64f6cf67479809541540e73fcdde4418186ebb55 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Wed, 31 Oct 2018 13:16:38 -0700 Subject: [PATCH 05/15] Bump SQL Tools to 1.5.0-alpha.51 --- extensions/mssql/src/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/mssql/src/config.json b/extensions/mssql/src/config.json index 1e8bb179f7..4648509076 100644 --- a/extensions/mssql/src/config.json +++ b/extensions/mssql/src/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "1.5.0-alpha.48", + "version": "1.5.0-alpha.51", "downloadFileNames": { "Windows_86": "win-x86-netcoreapp2.2.zip", "Windows_64": "win-x64-netcoreapp2.2.zip", From 2238c42432e247a3f6c8154cc30d23af331b5b85 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Wed, 31 Oct 2018 13:22:08 -0700 Subject: [PATCH 06/15] fix for issue 2719 (#3060) --- src/sql/base/browser/ui/splitview/splitview.css | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sql/base/browser/ui/splitview/splitview.css b/src/sql/base/browser/ui/splitview/splitview.css index 763146127e..312f1519dc 100644 --- a/src/sql/base/browser/ui/splitview/splitview.css +++ b/src/sql/base/browser/ui/splitview/splitview.css @@ -89,10 +89,6 @@ -moz-transition-property: width; } -.hc-black .split-view-view .action-label { - background: none; -} - .hc-black .split-view-view > .header .action-label:before { top: 4px !important; } \ No newline at end of file From 56c2d165605625d0462dc5ac8c9ad625557ed3d8 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Wed, 31 Oct 2018 13:44:12 -0700 Subject: [PATCH 07/15] a few ux improvements (#3057) * style update * checkbox styler * casing update --- .../theme-carbon/themes/dark_carbon.json | 97 ++++++++++--------- .../theme-carbon/themes/light_carbon.json | 39 ++++---- src/sql/base/browser/ui/checkbox/checkbox.ts | 16 +++ src/sql/base/browser/ui/modal/modal.ts | 2 +- src/sql/common/theme/colors.ts | 1 + src/sql/common/theme/styler.ts | 7 ++ .../connectionDialog/connectionWidget.ts | 3 +- .../backup/backup.component.ts | 7 +- .../disasterRecovery/restore/restoreDialog.ts | 3 +- .../modelComponents/checkbox.component.ts | 6 +- 10 files changed, 111 insertions(+), 70 deletions(-) diff --git a/extensions/theme-carbon/themes/dark_carbon.json b/extensions/theme-carbon/themes/dark_carbon.json index 1f0285cc14..674c8b176d 100644 --- a/extensions/theme-carbon/themes/dark_carbon.json +++ b/extensions/theme-carbon/themes/dark_carbon.json @@ -4,66 +4,69 @@ "type": "dark", "colors": { - // base - "foreground": "#fffffe", - "focusBorder": "#0E639C", + // base + "foreground": "#fffffe", + "focusBorder": "#0078d7", "selection.background": "#3062d6", - //text colors - "textLinkForeground": "#30B4FF", - "textLinkActiveForeground": "#30B4FF", + //text colors + "textLinkForeground": "#30b4ff", + "textLinkActiveForeground": "#30b4ff", - //Button control - "button.background": "#00BCF2", - "button.foreground": "#212121", - "button.hoverBackground": "#0099BC", + //Button control + "button.background": "#0078d7cc", + "button.foreground": "#ffffff", + "button.hoverBackground": "#0078d7", - // TODO add support for these - // "button.secondaryBackground": "#c8c8c8", - // "button.secondaryHoverBackground": "#a6a6a6", - // "button.secondaryForeground": "#333333", - // "button.disabledBackground": "#444444" , - // "button.disabledForeground": "#888888" , + // TODO add support for these + // "button.secondaryBackground": "#c8c8c8", + // "button.secondaryHoverBackground": "#a6a6a6", + // "button.secondaryForeground": "#333333", + // "button.disabledBackground": "#444444" , + // "button.disabledForeground": "#888888" , - //Dropdown Control - "dropdown.background": "#212121", - "dropdown.foreground": "#fffffe", - "dropdown.border": "#888888", + //Checkbox + "checkbox.disabled.foreground": "#888888", - //Input Control - "input.background": "#212121", + //Dropdown Control + "dropdown.background": "#212121", + "dropdown.foreground": "#fffffe", + "dropdown.border": "#888888", + + //Input Control + "input.background": "#212121", "input.border": "#888888", "input.disabled.background": "#444444", "input.disabled.foreground": "#888888", - "inputOption.activeBorder": "#007ACC", - "input.placeholderForeground": "#888888", - "inputValidation.errorBackground": "#D02E00", - "inputValidation.errorBorder": "#D02E00", + "inputOption.activeBorder": "#0078d7", + "input.placeholderForeground": "#888888", + "inputValidation.errorBackground": "#b62e00", + "inputValidation.errorBorder": "#b62e00", - //List and trees - "list.activeSelectionBackground": "#3062d6", - "list.hoverBackground": "#444444", - "pickerGroup.border": "#00BCF2", + //List and trees + "list.activeSelectionBackground": "#3062d6", + "list.hoverBackground": "#444444", + "pickerGroup.border": "#0078d7", "activityBar.background": "#444444", "sideBar.background": "#333333", - "sideBarTitle.foreground": "#BBBBBB", - "input.placeholderForeground": "#A6A6A6", - "editorGroupHeader.tabsBackground": "#444444", - "editor.background": "#212121", - "editor.foreground": "#ffffff", - "editorWidget.background": "#444444", - "editorLink.activeForeground": "#30B4FF", - "editorGroup.border": "#333333", - "editorGroup.background": "#212121", - "editorIndentGuide.activeBackground": "#707070", - "tab.activeBackground": "#212121", - "tab.activeForeground": "#ffffff", - "tab.inactiveBackground": "#444444", - "tab.inactiveForeground": "#b6b6b6", + "sideBarTitle.foreground": "#bbbbbb", + "input.placeholderForeground": "#a6a6a6", + "editorGroupHeader.tabsBackground": "#444444", + "editor.background": "#212121", + "editor.foreground": "#ffffff", + "editorWidget.background": "#444444", + "editorLink.activeForeground": "#30b4ff", + "editorGroup.border": "#333333", + "editorGroup.background": "#212121", + "editorIndentGuide.activeBackground": "#707070", + "tab.activeBackground": "#212121", + "tab.activeForeground": "#ffffff", + "tab.inactiveBackground": "#444444", + "tab.inactiveForeground": "#b6b6b6", "tab.border": "#3c3c3c", - "panel.background": "#212121", - "panel.border": "#515151", - "panelTitle.activeForeground": "#ffffff", + "panel.background": "#212121", + "panel.border": "#515151", + "panelTitle.activeForeground": "#ffffff", "panelTitle.inactiveForeground": "#888888" }, "tokenColors": [ diff --git a/extensions/theme-carbon/themes/light_carbon.json b/extensions/theme-carbon/themes/light_carbon.json index fa2dc6183c..4db0a032b2 100644 --- a/extensions/theme-carbon/themes/light_carbon.json +++ b/extensions/theme-carbon/themes/light_carbon.json @@ -5,18 +5,18 @@ "colors": { // base "foreground": "#4a4a4a", - "focusBorder": "#00BCF2", - "selection.background": "#C9D0D9", + "focusBorder": "#0078d7", + "selection.background": "#c9d0d9", "widget.shadow": "#666666", // text colors - "textLinkForeground": "#3062D6", - "textLinkActiveForeground": "#3062D6", + "textLinkForeground": "#3062d6", + "textLinkActiveForeground": "#3062d6", //Button control - "button.background": "#00BCF2", - "button.foreground": "#212121", - "button.hoverBackground": "#0099BC", + "button.background": "#0078d7cc", + "button.foreground": "#ffffff", + "button.hoverBackground": "#0078d7", // TODO add support for these // "button.secondaryBackground": "#c8c8c8", @@ -25,35 +25,38 @@ // "button.disabledBackground": "#eaeaea", // "button.disabledForeground": "#888888", + //Checkbox + "checkbox.disabled.foreground": "#888888", + //Dropdown Control - "dropdown.background": "#fffffe", + "dropdown.background": "#ffffff", "dropdown.foreground": "#4a4a4a", - "dropdown.border": "#C8C8C8", + "dropdown.border": "#c8c8c8", //badge "badge.background": "#777777", "badge.foreground": "#ffffff", //Input Control - "input.background": "#fffffe", + "input.background": "#ffffff", "input.border": "#c8c8c8", "input.disabled.background": "#dcdcdc", "input.disabled.foreground": "#888888", "inputOption.activeBorder": "#666666", "input.placeholderForeground": "#767676", "inputValidation.errorBackground": "#ffeaea", - "inputValidation.errorBorder": "#f1897f", + "inputValidation.errorBorder": "#b62e00", //List and tree "list.activeSelectionBackground": "#3062d6", "list.hoverBackground": "#dcdcdc", - "pickerGroup.border": "#00BCF2", + "pickerGroup.border": "#0078d7", // Workbench: Activity Bar "activityBar.background": "#212121", // Workbench: Side Bar - "sideBar.background": "#EAEAEA", + "sideBar.background": "#eaeaea", "editorGroupHeader.tabsBackground": "#f4f4f4", "editor.background": "#fffffe", "editor.foreground": "#212121", @@ -64,15 +67,15 @@ "editorIndentGuide.activeBackground": "#939393", // Workbench: Tabs - "tab.activeBackground": "#FFFFFE", - "tab.activeForeground": "#4A4A4A", + "tab.activeBackground": "#ffffff", + "tab.activeForeground": "#4a4a4a", "tab.inactiveBackground": "#f4f4f4", "tab.inactiveForeground": "#707070", - "tab.border": "#EAEAEA", + "tab.border": "#eaeaea", "tab.unfocusedInactiveForeground": "#888888", "tab.unfocusedActiveForeground": "#212121", - "panel.background": "#FFFFFE", - "panel.border": "#C8C8C8", + "panel.background": "#ffffff", + "panel.border": "#c8c8c8", "panelTitle.activeForeground": "#212121", "panelTitle.inactiveForeground": "#757575" }, diff --git a/src/sql/base/browser/ui/checkbox/checkbox.ts b/src/sql/base/browser/ui/checkbox/checkbox.ts index f4a3d36dba..00064391c7 100644 --- a/src/sql/base/browser/ui/checkbox/checkbox.ts +++ b/src/sql/base/browser/ui/checkbox/checkbox.ts @@ -3,6 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { Color } from 'vs/base/common/color'; import { Event, Emitter } from 'vs/base/common/event'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Widget } from 'vs/base/browser/ui/widget'; @@ -15,9 +16,14 @@ export interface ICheckboxOptions { ariaLabel?: string; } +export interface ICheckboxStyles { + disabledCheckboxForeground?: Color; +} + export class Checkbox extends Widget { private _el: HTMLInputElement; private _label: HTMLSpanElement; + private disabledCheckboxForeground: Color; private _onChange = new Emitter(); public readonly onChange: Event = this._onChange.event; @@ -65,6 +71,7 @@ export class Checkbox extends Widget { public set enabled(val: boolean) { this._el.disabled = !val; + this.updateStyle(); } public get enabled(): boolean { @@ -90,4 +97,13 @@ export class Checkbox extends Widget { public enable(): void { this.enabled = true; } + + public style(styles: ICheckboxStyles): void { + this.disabledCheckboxForeground = styles.disabledCheckboxForeground; + this.updateStyle(); + } + + private updateStyle(): void { + this._label.style.color = !this.enabled && this.disabledCheckboxForeground ? this.disabledCheckboxForeground.toString() : 'inherit'; + } } diff --git a/src/sql/base/browser/ui/modal/modal.ts b/src/sql/base/browser/ui/modal/modal.ts index 44f8a153d3..016e9968ce 100644 --- a/src/sql/base/browser/ui/modal/modal.ts +++ b/src/sql/base/browser/ui/modal/modal.ts @@ -27,7 +27,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService'; export const MODAL_SHOWING_KEY = 'modalShowing'; export const MODAL_SHOWING_CONTEXT = new RawContextKey>(MODAL_SHOWING_KEY, []); -const INFO_ALT_TEXT = localize('infoAltText', 'Infomation'); +const INFO_ALT_TEXT = localize('infoAltText', 'Information'); const WARNING_ALT_TEXT = localize('warningAltText', 'Warning'); const ERROR_ALT_TEXT = localize('errorAltText', 'Error'); const SHOW_DETAILS_TEXT = localize('showMessageDetails', 'Show Details'); diff --git a/src/sql/common/theme/colors.ts b/src/sql/common/theme/colors.ts index eb42ca596d..0e9cd3638b 100644 --- a/src/sql/common/theme/colors.ts +++ b/src/sql/common/theme/colors.ts @@ -12,6 +12,7 @@ export const tableHeaderForeground = registerColor('table.headerForeground', { d export const disabledInputBackground = registerColor('input.disabled.background', { dark: '#444444', light: '#dcdcdc', hc: Color.black }, nls.localize('disabledInputBoxBackground', "Disabled Input box background.")); export const disabledInputForeground = registerColor('input.disabled.foreground', { dark: '#888888', light: '#888888', hc: foreground }, nls.localize('disabledInputBoxForeground', "Disabled Input box foreground.")); export const buttonFocusOutline = registerColor('button.focusOutline', { dark: '#eaeaea', light: '#666666', hc: null }, nls.localize('buttonFocusOutline', "Button outline color when focused.")); +export const disabledCheckboxForeground = registerColor('checkbox.disabled.foreground', { dark: '#888888', light: '#888888', hc: Color.black }, nls.localize('disabledCheckboxforeground', "Disabled checkbox foreground.")); export const listFocusAndSelectionBackground = registerColor('list.focusAndSelectionBackground', { dark: '#2c3295', light: '#2c3295', hc: null }, nls.localize('listFocusAndSelectionBackground', "List/Table background color for the selected and focus item when the list/table is active")); diff --git a/src/sql/common/theme/styler.ts b/src/sql/common/theme/styler.ts index df2b8e936f..d0a7936576 100644 --- a/src/sql/common/theme/styler.ts +++ b/src/sql/common/theme/styler.ts @@ -255,3 +255,10 @@ export function attachButtonStyler(widget: IThemable, themeService: IThemeServic buttonFocusOutline: (style && style.buttonFocusOutline) || sqlcolors.buttonFocusOutline }, widget); } + +export function attachCheckboxStyler(widget: IThemable, themeService: IThemeService, style?: { disabledCheckboxForeground?: cr.ColorIdentifier }) + : IDisposable { + return attachStyler(themeService, { + disabledCheckboxForeground: (style && style.disabledCheckboxForeground) || sqlcolors.disabledCheckboxForeground + }, widget); +} diff --git a/src/sql/parts/connection/connectionDialog/connectionWidget.ts b/src/sql/parts/connection/connectionDialog/connectionWidget.ts index 28880ade97..332f055a4e 100644 --- a/src/sql/parts/connection/connectionDialog/connectionWidget.ts +++ b/src/sql/parts/connection/connectionDialog/connectionWidget.ts @@ -17,7 +17,7 @@ import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import { ConnectionOptionSpecialType } from 'sql/workbench/api/common/sqlExtHostTypes'; import * as Constants from 'sql/parts/connection/common/constants'; import { ConnectionProfileGroup, IConnectionProfileGroup } from 'sql/parts/connection/common/connectionProfileGroup'; -import { attachInputBoxStyler, attachButtonStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler'; +import { attachButtonStyler, attachCheckboxStyler, attachEditableDropdownStyler, attachInputBoxStyler } from 'sql/common/theme/styler'; import { Dropdown } from 'sql/base/browser/ui/editableDropdown/dropdown'; import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement'; import { ICapabilitiesService } from 'sql/services/capabilities/capabilitiesService'; @@ -274,6 +274,7 @@ export class ConnectionWidget { this._toDispose.push(attachInputBoxStyler(this._passwordInputBox, this._themeService)); this._toDispose.push(styler.attachSelectBoxStyler(this._serverGroupSelectBox, this._themeService)); this._toDispose.push(attachButtonStyler(this._advancedButton, this._themeService)); + this._toDispose.push(attachCheckboxStyler(this._rememberPasswordCheckBox, this._themeService)); if (this._authTypeSelectBox) { // Theme styler diff --git a/src/sql/parts/disasterRecovery/backup/backup.component.ts b/src/sql/parts/disasterRecovery/backup/backup.component.ts index 909a0cc9fe..c6d5da6153 100644 --- a/src/sql/parts/disasterRecovery/backup/backup.component.ts +++ b/src/sql/parts/disasterRecovery/backup/backup.component.ts @@ -14,7 +14,7 @@ import { ModalFooterStyle } from 'sql/base/browser/ui/modal/modal'; import { CategoryView } from 'sql/base/browser/ui/modal/optionsDialog'; import { SelectBox } from 'sql/base/browser/ui/selectBox/selectBox'; import { SplitView } from 'sql/base/browser/ui/splitview/splitview'; -import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'sql/common/theme/styler'; +import { attachButtonStyler, attachListBoxStyler, attachInputBoxStyler, attachSelectBoxStyler, attachCheckboxStyler } from 'sql/common/theme/styler'; import { IConnectionProfile } from 'sql/parts/connection/common/interfaces'; import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants'; import { IBackupService, IBackupUiService, TaskExecutionMode } from 'sql/parts/disasterRecovery/backup/common/backupService'; @@ -523,6 +523,11 @@ export class BackupComponent { this._toDispose.push(attachInputBoxStyler(this.mediaNameBox, this.themeService)); this._toDispose.push(attachInputBoxStyler(this.mediaDescriptionBox, this.themeService)); this._toDispose.push(attachInputBoxStyler(this.backupRetainDaysBox, this.themeService)); + this._toDispose.push(attachCheckboxStyler(this.copyOnlyCheckBox, this.themeService)); + this._toDispose.push(attachCheckboxStyler(this.encryptCheckBox, this.themeService)); + this._toDispose.push(attachCheckboxStyler(this.verifyCheckBox, this.themeService)); + this._toDispose.push(attachCheckboxStyler(this.checksumCheckBox, this.themeService)); + this._toDispose.push(attachCheckboxStyler(this.continueOnErrorCheckBox, this.themeService)); this._toDispose.push(this.backupTypeSelectBox.onDidSelect(selected => this.onBackupTypeChanged())); this.addButtonClickHandler(this.addPathButton, () => this.onAddClick()); diff --git a/src/sql/parts/disasterRecovery/restore/restoreDialog.ts b/src/sql/parts/disasterRecovery/restore/restoreDialog.ts index 7b61e80710..39fc2a7757 100644 --- a/src/sql/parts/disasterRecovery/restore/restoreDialog.ts +++ b/src/sql/parts/disasterRecovery/restore/restoreDialog.ts @@ -33,7 +33,7 @@ import { Table } from 'sql/base/browser/ui/table/table'; import { TableDataView } from 'sql/base/browser/ui/table/tableDataView'; import * as DialogHelper from 'sql/base/browser/ui/modal/dialogHelper'; import { Modal } from 'sql/base/browser/ui/modal/modal'; -import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler } from 'sql/common/theme/styler'; +import { attachButtonStyler, attachModalDialogStyler, attachTableStyler, attachInputBoxStyler, attachSelectBoxStyler, attachEditableDropdownStyler, attachCheckboxStyler } from 'sql/common/theme/styler'; import * as TelemetryKeys from 'sql/common/telemetryKeys'; import * as BackupConstants from 'sql/parts/disasterRecovery/backup/constants'; import { RestoreViewModel, RestoreOptionParam, SouceDatabaseNamesParam } from 'sql/parts/disasterRecovery/restore/restoreViewModel'; @@ -532,6 +532,7 @@ export class RestoreDialog extends Modal { ariaLabel: label }); }); + this._register(attachCheckboxStyler(checkbox, this._themeService)); return checkbox; } diff --git a/src/sql/parts/modelComponents/checkbox.component.ts b/src/sql/parts/modelComponents/checkbox.component.ts index d8fe0ca504..b58744fd59 100644 --- a/src/sql/parts/modelComponents/checkbox.component.ts +++ b/src/sql/parts/modelComponents/checkbox.component.ts @@ -14,6 +14,8 @@ import { ComponentBase } from 'sql/parts/modelComponents/componentBase'; import { IComponent, IComponentDescriptor, IModelStore, ComponentEventType } from 'sql/parts/modelComponents/interfaces'; import { Checkbox, ICheckboxOptions } from 'sql/base/browser/ui/checkbox/checkbox'; import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service'; +import { attachCheckboxStyler } from 'sql/common/theme/styler'; +import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; @Component({ selector: 'modelview-checkbox', @@ -30,7 +32,8 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone constructor( @Inject(forwardRef(() => CommonServiceInterface)) private _commonService: CommonServiceInterface, @Inject(forwardRef(() => ChangeDetectorRef)) changeRef: ChangeDetectorRef, - @Inject(forwardRef(() => ElementRef)) el: ElementRef) { + @Inject(IWorkbenchThemeService) private themeService: IWorkbenchThemeService, + @Inject(forwardRef(() => ElementRef)) el: ElementRef,) { super(changeRef, el); } @@ -55,6 +58,7 @@ export default class CheckBoxComponent extends ComponentBase implements ICompone args: e }); })); + this._register(attachCheckboxStyler(this._input, this.themeService)); } } From 114d67b40819c559d671ff5e5decbec175b7c69e Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Wed, 31 Oct 2018 13:50:44 -0700 Subject: [PATCH 08/15] fixed null ref (#3061) --- extensions/import/src/wizard/flatFileWizard.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/import/src/wizard/flatFileWizard.ts b/extensions/import/src/wizard/flatFileWizard.ts index 386740028a..e0062eb271 100644 --- a/extensions/import/src/wizard/flatFileWizard.ts +++ b/extensions/import/src/wizard/flatFileWizard.ts @@ -31,7 +31,7 @@ export class FlatFileWizard { public async start(p: any, ...args: any[]) { let model = {}; - let profile = p.connectionProfile; + let profile = p ? p.connectionProfile : null; if (profile) { model.serverId = profile.id; model.database = profile.databaseName; From 8ce1013a260aacf107481f87e7eb8e3f7413209c Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Wed, 31 Oct 2018 15:23:24 -0700 Subject: [PATCH 09/15] Remove SQL Import dashboard tab (#3064) --- extensions/import/package.json | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/extensions/import/package.json b/extensions/import/package.json index fc7932a503..5eaedfb6d0 100644 --- a/extensions/import/package.json +++ b/extensions/import/package.json @@ -42,33 +42,6 @@ "mac": "ctrl+i" } ], - "dashboard.tabs": [ - { - "id": "flat-file-import", - "title": "Flat File Import", - "description": "The flat file importer.", - "container": { - "flat-file-import-container": {} - } - } - ], - "dashboard.containers": [ - { - "id": "flat-file-import-container", - "container": { - "widgets-container": [ - { - "name": "Tasks", - "widget": { - "tasks-widget": [ - "flatFileImport.start" - ] - } - } - ] - } - } - ], "menus": { "objectExplorer/item/context": [ { From f7dcaa38ff523ab7f49040368095a243c45945c4 Mon Sep 17 00:00:00 2001 From: Alan Ren Date: Wed, 31 Oct 2018 16:13:09 -0700 Subject: [PATCH 10/15] fix for issue 3065 (#3067) * fix for 3065 * remove the parameter, no need to save connection --- .../commandLine/common/commandLineService.ts | 36 +++++++++---------- .../common/connectionManagementService.ts | 11 +++--- 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/sql/parts/commandLine/common/commandLineService.ts b/src/sql/parts/commandLine/common/commandLineService.ts index 08c6f9dc50..e9d9c53935 100644 --- a/src/sql/parts/commandLine/common/commandLineService.ts +++ b/src/sql/parts/commandLine/common/commandLineService.ts @@ -17,18 +17,17 @@ import { IObjectExplorerService } from 'sql/parts/objectExplorer/common/objectEx import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; export class CommandLineService implements ICommandLineProcessing { - private _connectionProfile : ConnectionProfile; + private _connectionProfile: ConnectionProfile; private _showConnectionDialog: boolean; constructor( - @IConnectionManagementService private _connectionManagementService : IConnectionManagementService, - @ICapabilitiesService private _capabilitiesService : ICapabilitiesService, - @IEnvironmentService private _environmentService : IEnvironmentService, - @IQueryEditorService private _queryEditorService : IQueryEditorService, - @IObjectExplorerService private _objectExplorerService : IObjectExplorerService, - @IEditorService private _editorService : IEditorService, - ) - { + @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, + @ICapabilitiesService private _capabilitiesService: ICapabilitiesService, + @IEnvironmentService private _environmentService: IEnvironmentService, + @IQueryEditorService private _queryEditorService: IQueryEditorService, + @IObjectExplorerService private _objectExplorerService: IObjectExplorerService, + @IEditorService private _editorService: IEditorService, + ) { let profile = null; if (this._environmentService && this._environmentService.args.server) { profile = new ConnectionProfile(_capabilitiesService, null); @@ -38,7 +37,7 @@ export class CommandLineService implements ICommandLineProcessing { profile.serverName = _environmentService.args.server; profile.databaseName = _environmentService.args.database ? _environmentService.args.database : ''; profile.userName = _environmentService.args.user ? _environmentService.args.user : ''; - profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin'; + profile.authenticationType = _environmentService.args.integrated ? 'Integrated' : 'SqlLogin'; profile.connectionName = ''; profile.setOptionValue('applicationName', Constants.applicationName); profile.setOptionValue('databaseDisplayName', profile.databaseName); @@ -46,14 +45,13 @@ export class CommandLineService implements ICommandLineProcessing { } this._connectionProfile = profile; const registry = platform.Registry.as(ConnectionProviderExtensions.ConnectionProviderContributions); - let sqlProvider = registry.getProperties( Constants.mssqlProviderName); + let sqlProvider = registry.getProperties(Constants.mssqlProviderName); // We can't connect to object explorer until the MSSQL connection provider is registered if (sqlProvider) { this.processCommandLine(); } else { registry.onNewProvider(e => { - if (e.id === Constants.mssqlProviderName) - { + if (e.id === Constants.mssqlProviderName) { this.processCommandLine(); } }); @@ -64,14 +62,14 @@ export class CommandLineService implements ICommandLineProcessing { if (!this._connectionProfile && !this._connectionManagementService.hasRegisteredServers()) { // prompt the user for a new connection on startup if no profiles are registered this._connectionManagementService.showConnectionDialog(); - } else if (this._connectionProfile) { + } else if (this._connectionProfile) { this._connectionManagementService.connectIfNotConnected(this._connectionProfile, 'connection') .then(result => TaskUtilities.newQuery(this._connectionProfile, - this._connectionManagementService, - this._queryEditorService, - this._objectExplorerService, - this._editorService)) - .catch(() => {}); + this._connectionManagementService, + this._queryEditorService, + this._objectExplorerService, + this._editorService)) + .catch(() => { }); } } } \ No newline at end of file diff --git a/src/sql/parts/connection/common/connectionManagementService.ts b/src/sql/parts/connection/common/connectionManagementService.ts index 5d925f59b9..2d468afe31 100644 --- a/src/sql/parts/connection/common/connectionManagementService.ts +++ b/src/sql/parts/connection/common/connectionManagementService.ts @@ -381,12 +381,11 @@ export class ConnectionManagementService extends Disposable implements IConnecti resolve(this._connectionStatusManager.getOriginalOwnerUri(ownerUri)); } else { const options: IConnectionCompletionOptions = { - // Should saving the connection be a command line switch? - saveTheConnection : true, - showConnectionDialogOnError : true, - showDashboard : purpose === 'dashboard', - params : undefined, - showFirewallRuleOnError : true, + saveTheConnection: false, + showConnectionDialogOnError: true, + showDashboard: purpose === 'dashboard', + params: undefined, + showFirewallRuleOnError: true, }; this.connect(connection, ownerUri, options).then(connectionResult => { if (connectionResult && connectionResult.connected) { From ce7893c2e52e67bff2927891fd77cd9732d44f45 Mon Sep 17 00:00:00 2001 From: Aditya Bist Date: Wed, 31 Oct 2018 16:40:36 -0700 Subject: [PATCH 11/15] Agent/edit job logic (#3023) * lumped stepdata with jobdata in job dialog * fix bug with empty steps * added clumped and update steps and schedules from job dialog * edit data sends one call instead of multiple * cleaned code --- extensions/agent/src/data/alertData.ts | 31 +++++-- extensions/agent/src/data/jobData.ts | 17 +--- extensions/agent/src/data/jobStepData.ts | 20 ++--- extensions/agent/src/data/pickScheduleData.ts | 2 - extensions/agent/src/dialogs/alertDialog.ts | 21 +++-- extensions/agent/src/dialogs/jobDialog.ts | 83 +++++++++++-------- extensions/agent/src/dialogs/jobStepDialog.ts | 3 +- extensions/agent/src/mainController.ts | 19 +++-- .../parts/jobManagement/common/jobActions.ts | 8 +- .../jobManagement/views/jobsView.component.ts | 36 +++----- 10 files changed, 129 insertions(+), 111 deletions(-) diff --git a/extensions/agent/src/data/alertData.ts b/extensions/agent/src/data/alertData.ts index bcef62b4ea..295661b2cc 100644 --- a/extensions/agent/src/data/alertData.ts +++ b/extensions/agent/src/data/alertData.ts @@ -9,6 +9,7 @@ import * as vscode from 'vscode'; import * as sqlops from 'sqlops'; import { AgentUtils } from '../agentUtils'; import { IAgentDialogData, AgentDialogMode } from '../interfaces'; +import { JobData } from './jobData'; const localize = nls.loadMessageBundle(); @@ -45,8 +46,19 @@ export class AlertData implements IAgentDialogData { wmiEventNamespace: string; wmiEventQuery: string; - constructor(ownerUri:string, alertInfo: sqlops.AgentAlertInfo) { + private viaJobDialog: boolean; + private jobModel: JobData; + + constructor( + ownerUri:string, + alertInfo: sqlops.AgentAlertInfo, + jobModel?: JobData, + viaJobDialog: boolean = false + ) { this.ownerUri = ownerUri; + this.viaJobDialog = viaJobDialog; + this.jobModel = jobModel; + this.jobName = this.jobName ? this.jobName : this.jobModel.name; if (alertInfo) { this.dialogMode = AgentDialogMode.EDIT; @@ -60,7 +72,6 @@ export class AlertData implements IAgentDialogData { this.includeEventDescription = alertInfo.includeEventDescription.toString(); this.isEnabled = alertInfo.isEnabled; this.jobId = alertInfo.jobId; - this.jobName = alertInfo.jobName; this.lastOccurrenceDate = alertInfo.lastOccurrenceDate; this.lastResponseDate = alertInfo.lastResponseDate; this.messageId = alertInfo.messageId; @@ -82,10 +93,18 @@ export class AlertData implements IAgentDialogData { public async save() { let agentService = await AgentUtils.getAgentService(); - let result = this.dialogMode === AgentDialogMode.CREATE - ? await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo()) - : await agentService.updateAlert(this.ownerUri, this.originalName, this.toAgentAlertInfo()); - + let result: any; + // if it's called via the job dialog, add it to the + // job model + if (this.viaJobDialog) { + if (this.jobModel) { + Promise.resolve(this); + return; + } + } else { + // has to be a create alert + result = await agentService.createAlert(this.ownerUri, this.toAgentAlertInfo()); + } if (!result || !result.success) { vscode.window.showErrorMessage( localize('alertData.saveErrorMessage', "Alert update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown')); diff --git a/extensions/agent/src/data/jobData.ts b/extensions/agent/src/data/jobData.ts index 9f6f24cc87..1d512edd62 100644 --- a/extensions/agent/src/data/jobData.ts +++ b/extensions/agent/src/data/jobData.ts @@ -44,6 +44,7 @@ export class JobData implements IAgentDialogData { public jobSteps: sqlops.AgentJobStepInfo[]; public jobSchedules: sqlops.AgentJobScheduleInfo[]; public alerts: sqlops.AgentAlertInfo[]; + public jobId: string; constructor( ownerUri: string, @@ -62,6 +63,7 @@ export class JobData implements IAgentDialogData { this.jobSteps = jobInfo.JobSteps; this.jobSchedules = jobInfo.JobSchedules; this.alerts = jobInfo.Alerts; + this.jobId = jobInfo.jobId; } } @@ -115,7 +117,6 @@ export class JobData implements IAgentDialogData { let result = this.dialogMode === AgentDialogMode.CREATE ? await this._agentService.createJob(this.ownerUri, jobInfo) : await this._agentService.updateJob(this.ownerUri, this.originalName, jobInfo); - if (!result || !result.success) { vscode.window.showErrorMessage( localize('jobData.saveErrorMessage', "Job update failed '{0}'", result.errorMessage ? result.errorMessage : 'Unknown')); @@ -135,18 +136,6 @@ export class JobData implements IAgentDialogData { }; } - public addJobSchedule(schedule: sqlops.AgentJobScheduleInfo) { - if (this.jobSchedules) { - let existingSchedule = this.jobSchedules.find(item => item.name === schedule.name); - if (!existingSchedule) { - this.jobSchedules.push(schedule); - } - } else { - this.jobSchedules = []; - this.jobSchedules.push(schedule); - } - } - public toAgentJobInfo(): sqlops.AgentJobInfo { return { name: this.name, @@ -177,7 +166,7 @@ export class JobData implements IAgentDialogData { categoryType: 1, // LocalJob, hard-coding the value, corresponds to the target tab in SSMS lastRun: '', nextRun: '', - jobId: '' + jobId: this.jobId }; } } \ No newline at end of file diff --git a/extensions/agent/src/data/jobStepData.ts b/extensions/agent/src/data/jobStepData.ts index b84c73f566..a9624442f7 100644 --- a/extensions/agent/src/data/jobStepData.ts +++ b/extensions/agent/src/data/jobStepData.ts @@ -46,11 +46,13 @@ export class JobStepData implements IAgentDialogData { public retryInterval: number; public proxyName: string; private jobModel: JobData; + private viaJobDialog: boolean; - constructor(ownerUri:string, jobModel?: JobData) { + constructor(ownerUri:string, jobModel?: JobData, viaJobDialog: boolean = false) { this.ownerUri = ownerUri; this.jobName = jobModel.name; this.jobModel = jobModel; + this.viaJobDialog = viaJobDialog; } public async initialize() { @@ -59,18 +61,16 @@ export class JobStepData implements IAgentDialogData { public async save() { let agentService = await AgentUtils.getAgentService(); let result: any; - if (this.dialogMode === AgentDialogMode.CREATE) { - if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.CREATE) { - // create job -> create step + // if it's called via the job dialog, add it to the + // job model + if (this.viaJobDialog) { + if (this.jobModel) { Promise.resolve(this); return; - } else { - // edit job -> create step - result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this)); } - } else if (this.jobModel && this.jobModel.dialogMode === AgentDialogMode.EDIT) { - // edit job -> edit step - result = await agentService.updateJobStep(this.ownerUri, this.stepName, JobStepData.convertToAgentJobStepInfo(this)); + } else { + // has to be a create step + result = await agentService.createJobStep(this.ownerUri, JobStepData.convertToAgentJobStepInfo(this)); } if (!result || !result.success) { vscode.window.showErrorMessage( diff --git a/extensions/agent/src/data/pickScheduleData.ts b/extensions/agent/src/data/pickScheduleData.ts index 15ad4c0f34..d2a46bf729 100644 --- a/extensions/agent/src/data/pickScheduleData.ts +++ b/extensions/agent/src/data/pickScheduleData.ts @@ -29,8 +29,6 @@ export class PickScheduleData implements IAgentDialogData { } public async save() { - let agentService = await AgentUtils.getAgentService(); this.selectedSchedule.jobName = this.jobName; - let result = await agentService.createJobSchedule(this.ownerUri, this.selectedSchedule); } } diff --git a/extensions/agent/src/dialogs/alertDialog.ts b/extensions/agent/src/dialogs/alertDialog.ts index 1e7bfe8b5e..b10ba8e40e 100644 --- a/extensions/agent/src/dialogs/alertDialog.ts +++ b/extensions/agent/src/dialogs/alertDialog.ts @@ -12,6 +12,7 @@ import { AgentUtils } from '../agentUtils'; import { AlertData } from '../data/alertData'; import { OperatorDialog } from './operatorDialog'; import { JobDialog } from './jobDialog'; +import { JobData } from '../data/jobData'; const localize = nls.loadMessageBundle(); @@ -148,14 +149,23 @@ export class AlertDialog extends AgentDialog { private delayMinutesTextBox: sqlops.InputBoxComponent; private delaySecondsTextBox: sqlops.InputBoxComponent; - private jobs: string[]; private databases: string[]; + private jobModel: JobData; + public jobId: string; + public jobName: string; - constructor(ownerUri: string, alertInfo: sqlops.AgentAlertInfo = undefined, jobs: string[]) { + constructor( + ownerUri: string, + jobModel: JobData, + alertInfo: sqlops.AgentAlertInfo = undefined, + viaJobDialog: boolean = false + ) { super(ownerUri, - new AlertData(ownerUri, alertInfo), + new AlertData(ownerUri, alertInfo, jobModel, viaJobDialog), alertInfo ? AlertDialog.EditDialogTitle : AlertDialog.CreateDialogTitle); - this.jobs = jobs; + this.jobModel = jobModel; + this.jobId = this.jobId ? this.jobId : this.jobModel.jobId; + this.jobName = this.jobName ? this.jobName : this.jobModel.name; } protected async initializeDialog(dialog: sqlops.window.modelviewdialog.Dialog) { @@ -512,7 +522,8 @@ export class AlertDialog extends AgentDialog { protected updateModel() { this.model.name = this.nameTextBox.value; this.model.isEnabled = this.enabledCheckBox.checked; - + this.model.jobId = this.jobId; + this.model.jobName = this.jobName; this.model.alertType = this.getDropdownValue(this.typeDropDown); let databaseName = this.getDropdownValue(this.databaseDropDown); this.model.databaseName = (databaseName !== AlertDialog.AllDatabases) ? databaseName : undefined; diff --git a/extensions/agent/src/dialogs/jobDialog.ts b/extensions/agent/src/dialogs/jobDialog.ts index bf3523daf1..bbbce0f4a8 100644 --- a/extensions/agent/src/dialogs/jobDialog.ts +++ b/extensions/agent/src/dialogs/jobDialog.ts @@ -11,6 +11,7 @@ import { PickScheduleDialog } from './pickScheduleDialog'; import { AlertDialog } from './alertDialog'; import { AgentDialog } from './agentDialog'; import { AgentUtils } from '../agentUtils'; +import { JobStepData } from '../data/jobStepData'; const localize = nls.loadMessageBundle(); @@ -110,11 +111,19 @@ export class JobDialog extends AgentDialog { private newAlertButton: sqlops.ButtonComponent; private isEdit: boolean = false; + // Job objects + private steps: sqlops.AgentJobStepInfo[]; + private schedules: sqlops.AgentJobScheduleInfo[]; + private alerts: sqlops.AgentAlertInfo[] = []; + constructor(ownerUri: string, jobInfo: sqlops.AgentJobInfo = undefined) { super( ownerUri, new JobData(ownerUri, jobInfo), jobInfo ? JobDialog.EditDialogTitle : JobDialog.CreateDialogTitle); + this.steps = this.model.jobSteps ? this.model.jobSteps : []; + this.schedules = this.model.jobSchedules ? this.model.jobSchedules : []; + this.alerts = this.model.alerts ? this.model.alerts : []; this.isEdit = jobInfo ? true : false; } @@ -198,12 +207,7 @@ export class JobDialog extends AgentDialog { private initializeStepsTab() { this.stepsTab.registerContent(async view => { - let previewTag = view.modelBuilder.text() - .withProperties({ - value: 'Feature Preview' - }).component(); - let steps = this.model.jobSteps ? this.model.jobSteps : []; - let data = this.convertStepsToData(steps); + let data = this.steps ? this.convertStepsToData(this.steps) : []; this.stepsTable = view.modelBuilder.table() .withProperties({ columns: [ @@ -237,13 +241,11 @@ export class JobDialog extends AgentDialog { width: 80 }).component(); - let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model); + let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, null, true); stepDialog.onSuccess((step) => { - if (!this.model.jobSteps) { - this.model.jobSteps = []; - } - this.model.jobSteps.push(step); - this.stepsTable.data = this.convertStepsToData(this.model.jobSteps); + let stepInfo = JobStepData.convertToAgentJobStepInfo(step); + this.steps.push(stepInfo); + this.stepsTable.data = this.convertStepsToData(this.steps); }); this.newStepButton.onDidClick((e)=>{ if (this.nameTextBox.value && this.nameTextBox.value.length > 0) { @@ -277,7 +279,7 @@ export class JobDialog extends AgentDialog { this.deleteStepButton.enabled = true; this.editStepButton.enabled = true; this.editStepButton.onDidClick(() => { - let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData); + let stepDialog = new JobStepDialog(this.model.ownerUri, '' , this.model, stepData, true); stepDialog.openDialog(); }); @@ -287,7 +289,6 @@ export class JobDialog extends AgentDialog { agentService.deleteJobStep(this.ownerUri, stepData).then((result) => { if (result && result.success) { delete steps[rowNumber]; - this.model.jobSteps = steps; let data = this.convertStepsToData(steps); this.stepsTable.data = data; } @@ -299,10 +300,6 @@ export class JobDialog extends AgentDialog { let formModel = view.modelBuilder.formContainer() .withFormItems([{ - component: previewTag, - title: '' - }, - { component: this.stepsTable, title: this.JobStepsTopLabelString, actions: [this.moveStepUpButton, this.moveStepDownButton, this.newStepButton, this.editStepButton, this.deleteStepButton] @@ -313,10 +310,6 @@ export class JobDialog extends AgentDialog { private initializeAlertsTab() { this.alertsTab.registerContent(async view => { - let previewTag = view.modelBuilder.text() - .withProperties({ - value: 'Feature Preview' - }).component(); let alerts = this.model.alerts ? this.model.alerts : []; let data = this.convertAlertsToData(alerts); this.alertsTable = view.modelBuilder.table() @@ -327,7 +320,7 @@ export class JobDialog extends AgentDialog { this.AlertTypeLabelString ], data: data, - height: 430, + height: 750, width: 400 }).component(); @@ -336,18 +329,24 @@ export class JobDialog extends AgentDialog { width: 80 }).component(); - this.newAlertButton.onDidClick((e)=>{ - let alertDialog = new AlertDialog(this.model.ownerUri, null, []); - alertDialog.onSuccess((dialogModel) => { - }); - alertDialog.openDialog(); + let alertDialog = new AlertDialog(this.model.ownerUri, this.model, null, true); + alertDialog.onSuccess((alert) => { + let alertInfo = alert.toAgentAlertInfo(); + this.alerts.push(alertInfo); + this.alertsTable.data = this.convertAlertsToData(this.alerts); + }); + this.newAlertButton.onDidClick(()=>{ + if (this.nameTextBox.value && this.nameTextBox.value.length > 0) { + alertDialog.jobId = this.model.jobId; + alertDialog.jobName = this.model.name ? this.model.name : this.nameTextBox.value; + alertDialog.openDialog(); + } else { + this.dialog.message = { text: this.BlankJobNameErrorText }; + } }); let formModel = view.modelBuilder.formContainer() .withFormItems([{ - component: previewTag, - title: '' - }, { component: this.alertsTable, title: this.AlertsTopLabelString, actions: [this.newAlertButton] @@ -380,8 +379,11 @@ export class JobDialog extends AgentDialog { pickScheduleDialog.onSuccess((dialogModel) => { let selectedSchedule = dialogModel.selectedSchedule; if (selectedSchedule) { - selectedSchedule.jobName = this.model.name; - this.model.addJobSchedule(selectedSchedule); + let existingSchedule = this.schedules.find(item => item.name === selectedSchedule.name); + if (!existingSchedule) { + selectedSchedule.jobName = this.model.name ? this.model.name : this.nameTextBox.value; + this.schedules.push(selectedSchedule); + } this.populateScheduleTable(); } }); @@ -402,8 +404,7 @@ export class JobDialog extends AgentDialog { } private populateScheduleTable() { - let schedules = this.model.jobSchedules ? this.model.jobSchedules : []; - let data = this.convertSchedulesToData(schedules); + let data = this.convertSchedulesToData(this.schedules); if (data.length > 0) { this.schedulesTable.data = data; this.schedulesTable.height = 750; @@ -566,5 +567,17 @@ export class JobDialog extends AgentDialog { this.model.pageLevel = this.getActualConditionValue(this.pagerCheckBox, this.pagerConditionDropdown); this.model.eventLogLevel = this.getActualConditionValue(this.eventLogCheckBox, this.eventLogConditionDropdown); this.model.deleteLevel = this.getActualConditionValue(this.deleteJobCheckBox, this.deleteJobConditionDropdown); + if (!this.model.jobSteps) { + this.model.jobSteps = []; + } + this.model.jobSteps = this.steps; + if (!this.model.jobSchedules) { + this.model.jobSchedules = []; + } + this.model.jobSchedules = this.schedules; + if (!this.model.alerts) { + this.model.alerts = []; + } + this.model.alerts = this.alerts; } } \ No newline at end of file diff --git a/extensions/agent/src/dialogs/jobStepDialog.ts b/extensions/agent/src/dialogs/jobStepDialog.ts index da0ec4028b..614f49794c 100644 --- a/extensions/agent/src/dialogs/jobStepDialog.ts +++ b/extensions/agent/src/dialogs/jobStepDialog.ts @@ -118,9 +118,10 @@ export class JobStepDialog extends AgentDialog { server: string, jobModel: JobData, jobStepInfo?: sqlops.AgentJobStepInfo, + viaJobDialog: boolean = false ) { super(ownerUri, - jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel), + jobStepInfo ? JobStepData.convertToJobStepData(jobStepInfo, jobModel) : new JobStepData(ownerUri, jobModel, viaJobDialog), jobStepInfo ? JobStepDialog.EditDialogTitle : JobStepDialog.NewDialogTitle); this.stepId = jobStepInfo ? jobStepInfo.id : jobModel.jobSteps ? diff --git a/extensions/agent/src/mainController.ts b/extensions/agent/src/mainController.ts index af10fa01be..ce1ff93608 100644 --- a/extensions/agent/src/mainController.ts +++ b/extensions/agent/src/mainController.ts @@ -14,6 +14,7 @@ import { ProxyDialog } from './dialogs/proxyDialog'; import { JobStepDialog } from './dialogs/jobStepDialog'; import { PickScheduleDialog } from './dialogs/pickScheduleDialog'; import { JobData } from './data/jobData'; +import { AgentUtils } from './agentUtils'; const localize = nls.loadMessageBundle(); @@ -41,17 +42,23 @@ export class MainController { let dialog = new JobDialog(ownerUri, jobInfo); dialog.openDialog(); }); - vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobData: JobData, jobStepInfo: sqlops.AgentJobStepInfo) => { - let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo); - dialog.openDialog(); + vscode.commands.registerCommand('agent.openNewStepDialog', (ownerUri: string, server: string, jobInfo: sqlops.AgentJobInfo, jobStepInfo: sqlops.AgentJobStepInfo) => { + AgentUtils.getAgentService().then((agentService) => { + let jobData: JobData = new JobData(ownerUri, jobInfo, agentService); + let dialog = new JobStepDialog(ownerUri, server, jobData, jobStepInfo, false); + dialog.openDialog(); + }); }); vscode.commands.registerCommand('agent.openPickScheduleDialog', (ownerUri: string, jobName: string) => { let dialog = new PickScheduleDialog(ownerUri, jobName); dialog.showDialog(); }); - vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, alertInfo: sqlops.AgentAlertInfo, jobs: string[]) => { - let dialog = new AlertDialog(ownerUri, alertInfo, jobs); - dialog.openDialog(); + vscode.commands.registerCommand('agent.openAlertDialog', (ownerUri: string, jobInfo: sqlops.AgentJobInfo, alertInfo: sqlops.AgentAlertInfo) => { + AgentUtils.getAgentService().then((agentService) => { + let jobData: JobData = new JobData(ownerUri, jobInfo, agentService); + let dialog = new AlertDialog(ownerUri, jobData, alertInfo, false); + dialog.openDialog(); + }); }); vscode.commands.registerCommand('agent.openOperatorDialog', (ownerUri: string, operatorInfo: sqlops.AgentOperatorInfo) => { let dialog = new OperatorDialog(ownerUri, operatorInfo); diff --git a/src/sql/parts/jobManagement/common/jobActions.ts b/src/sql/parts/jobManagement/common/jobActions.ts index ef48595e69..1ec5c54fd9 100644 --- a/src/sql/parts/jobManagement/common/jobActions.ts +++ b/src/sql/parts/jobManagement/common/jobActions.ts @@ -219,14 +219,10 @@ export class NewStepAction extends Action { public run(context: JobHistoryComponent): TPromise { let ownerUri = context.ownerUri; - let jobName = context.agentJobInfo.name; let server = context.serverName; - let stepId = 0; - if (context.agentJobHistoryInfo && context.agentJobHistoryInfo.steps) { - stepId = context.agentJobHistoryInfo.steps.length + 1; - } + let jobInfo = context.agentJobInfo; return new TPromise((resolve, reject) => { - resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, jobName, server, stepId)); + resolve(this._commandService.executeCommand('agent.openNewStepDialog', ownerUri, server, jobInfo , null)); }); } } diff --git a/src/sql/parts/jobManagement/views/jobsView.component.ts b/src/sql/parts/jobManagement/views/jobsView.component.ts index e6e61ba465..ebaa2bb3bc 100644 --- a/src/sql/parts/jobManagement/views/jobsView.component.ts +++ b/src/sql/parts/jobManagement/views/jobsView.component.ts @@ -923,33 +923,17 @@ export class JobsViewComponent extends JobManagementView implements OnInit { let steps = this.jobSteps[jobId]; job[0].JobSteps = steps; } - let jobHistories = this.jobHistories[job[0].jobId]; - let schedules: sqlops.AgentJobScheduleInfo[] = this.jobSchedules[job[0].jobId]; - let alerts: sqlops.AgentAlertInfo[] = this.jobAlerts[job[0].jobId]; - if (jobHistories && jobHistories[jobHistories.length-1]) { - // add schedules - if (schedules && schedules.length > 0) { - if (!job[0].JobSchedules) { - job[0].JobSchedules = []; - } - if (job[0].JobSchedules.length !== schedules.length) { - job[0].JobSchedules = []; - schedules.forEach(schedule => { - job[0].JobSchedules.push(schedule); - }); - } - } - // add alerts - if (!job[0].Alerts) { - job[0].Alerts = []; - } - if (job[0].Alerts.length !== alerts.length) { - job[0].Alerts = []; - alerts.forEach(alert => { - job[0].Alerts.push(alert); - }); - } + // add schedules + if (this.jobSchedules && this.jobSchedules[jobId]) { + let schedules = this.jobSchedules[jobId]; + job[0].JobSchedules = schedules; + } + + // add alerts + if (this.jobAlerts && this.jobAlerts[jobId]) { + let alerts = this.jobAlerts[jobId]; + job[0].Alerts = alerts; } return job && job.length > 0 ? job[0] : undefined; } From cff21124da21e3963820b58c497e96b65c034c09 Mon Sep 17 00:00:00 2001 From: Anthony Dresser Date: Wed, 31 Oct 2018 20:27:40 -0700 Subject: [PATCH 12/15] Auto Scale Axis (#3070) * fix input to chart that was causes scales to not auto size * formatting * formatting * added comments --- .../parts/query/editor/charting/chartView.ts | 2 +- .../editor/charting/insights/graphInsight.ts | 45 ++++++++++++------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/sql/parts/query/editor/charting/chartView.ts b/src/sql/parts/query/editor/charting/chartView.ts index 728469c6be..0ae7471d44 100644 --- a/src/sql/parts/query/editor/charting/chartView.ts +++ b/src/sql/parts/query/editor/charting/chartView.ts @@ -326,7 +326,7 @@ export class ChartView extends Disposable implements IPanelView { this.optionDisposables.push(attachInputBoxStyler(numberInput, this._themeService)); break; case ControlType.dateInput: - let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'date' }); + let dateInput = new InputBox(optionContainer, this._contextViewService, { type: 'datetime-local' }); dateInput.value = value || ''; dateInput.onDidChange(e => { if (this.options[option.configEntry] !== e) { diff --git a/src/sql/parts/query/editor/charting/insights/graphInsight.ts b/src/sql/parts/query/editor/charting/insights/graphInsight.ts index b73ece6a38..d8cbe9e02c 100644 --- a/src/sql/parts/query/editor/charting/insights/graphInsight.ts +++ b/src/sql/parts/query/editor/charting/insights/graphInsight.ts @@ -19,7 +19,7 @@ import { ChartType, DataDirection, LegendPosition, DataType, IPointDataSet, cust const noneLineGraphs = [ChartType.Doughnut, ChartType.Pie]; -const timeSeriesScales = { +const timeSeriesScales: ChartJs.ChartOptions = { scales: { xAxes: [{ type: 'time', @@ -64,7 +64,7 @@ export class Graph implements IInsight { this._theme = e; this.data = this._data; }); - this._options = mixin(options, defaultOptions, false); + this.options = mixin(options, defaultOptions, false); let canvasContainer = document.createElement('div'); canvasContainer.style.width = '100%'; @@ -89,9 +89,12 @@ export class Graph implements IInsight { } public set data(data: IInsightData) { + if (!data) { + return; + } this._data = data; - let chartData: Array; let labels: Array; + let chartData: Array; if (this.options.dataDirection === DataDirection.Horizontal) { if (this.options.labelFirstColumn) { @@ -158,19 +161,19 @@ export class Graph implements IInsight { if (this.chartjs) { this.chartjs.data.datasets = chartData; this.chartjs.config.type = this.options.type; - this.chartjs.data.labels = labels; + // we don't want to include lables for timeSeries + this.chartjs.data.labels = this.originalType === 'timeSeries' ? [] : labels; this.chartjs.options = this.transformOptions(this.options); this.chartjs.update(0); } else { this.chartjs = new ChartJs(this.canvas.getContext('2d'), { data: { - labels: labels, + // we don't want to include lables for timeSeries + labels: this.originalType === 'timeSeries' ? [] : labels, datasets: chartData }, type: this.options.type, - options: { - maintainAspectRatio: false - } + options: this.transformOptions(this.options) }); } } @@ -197,15 +200,21 @@ export class Graph implements IInsight { display: options.xAxisLabel ? true : false }, ticks: { - fontColor: foreground, - max: options.xAxisMax, - min: options.xAxisMin + fontColor: foreground }, gridLines: { color: gridLines } }]; + if (options.xAxisMax) { + retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { max: options.xAxisMax } }] }, true, customMixin); + } + + if (options.xAxisMin) { + retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { min: options.xAxisMin } }] }, true, customMixin); + } + retval.scales.yAxes = [{ scaleLabel: { fontColor: foreground, @@ -213,22 +222,27 @@ export class Graph implements IInsight { display: options.yAxisLabel ? true : false }, ticks: { - fontColor: foreground, - max: options.yAxisMax, - min: options.yAxisMin + fontColor: foreground }, gridLines: { color: gridLines } }]; + if (options.yAxisMax) { + retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { max: options.yAxisMax } }] }, true, customMixin); + } + + if (options.yAxisMin) { + retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { min: options.yAxisMin } }] }, true, customMixin); + } + if (this.originalType === ChartType.TimeSeries) { retval = mixin(retval, timeSeriesScales, true, customMixin); if (options.xAxisMax) { retval = mixin(retval, { scales: { xAxes: [{ - type: 'time', time: { max: options.xAxisMax } @@ -241,7 +255,6 @@ export class Graph implements IInsight { retval = mixin(retval, { scales: { xAxes: [{ - type: 'time', time: { min: options.xAxisMin } From cbf6c06e4b1a2c613beab6b65d9393c44ccc8565 Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Wed, 31 Oct 2018 20:37:47 -0700 Subject: [PATCH 13/15] Bump SQL Tools to 1.5.0-alpha.52 --- extensions/mssql/src/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/mssql/src/config.json b/extensions/mssql/src/config.json index 4648509076..f4b626b481 100644 --- a/extensions/mssql/src/config.json +++ b/extensions/mssql/src/config.json @@ -1,6 +1,6 @@ { "downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}", - "version": "1.5.0-alpha.51", + "version": "1.5.0-alpha.52", "downloadFileNames": { "Windows_86": "win-x86-netcoreapp2.2.zip", "Windows_64": "win-x64-netcoreapp2.2.zip", From b6c9a3bb895deda985545f80e200af3d7708b48d Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 1 Nov 2018 15:06:58 -0700 Subject: [PATCH 14/15] Bump Azure Data Studio to 1.2.4 --- extensions/agent/package.json | 2 +- extensions/import/package.json | 2 +- extensions/profiler/package.json | 2 +- package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/agent/package.json b/extensions/agent/package.json index 1a3f5612f6..73773325e8 100644 --- a/extensions/agent/package.json +++ b/extensions/agent/package.json @@ -2,7 +2,7 @@ "name": "agent", "displayName": "SQL Server Agent", "description": "Manage and troubleshoot SQL Server Agent jobs", - "version": "0.34.0", + "version": "0.35.0", "publisher": "Microsoft", "preview": true, "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", diff --git a/extensions/import/package.json b/extensions/import/package.json index 5eaedfb6d0..871078cb7e 100644 --- a/extensions/import/package.json +++ b/extensions/import/package.json @@ -2,7 +2,7 @@ "name": "import", "displayName": "SQL Server Import", "description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.", - "version": "0.3.0", + "version": "0.4.0", "publisher": "Microsoft", "preview": true, "engines": { diff --git a/extensions/profiler/package.json b/extensions/profiler/package.json index 3924d69b70..f2cdd86357 100644 --- a/extensions/profiler/package.json +++ b/extensions/profiler/package.json @@ -2,7 +2,7 @@ "name": "profiler", "displayName": "SQL Server Profiler", "description": "SQL Server Profiler for Azure Data Studio", - "version": "0.2.0", + "version": "0.3.0", "publisher": "Microsoft", "preview": true, "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", diff --git a/package.json b/package.json index 559b3e90da..3abb6216c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "azuredatastudio", - "version": "1.2.3", + "version": "1.2.4", "distro": "8c3e97e3425cc9814496472ab73e076de2ba99ee", "author": { "name": "Microsoft Corporation" From 00cd772cbc6eda1bf77c99473fcd016ad37275cd Mon Sep 17 00:00:00 2001 From: Kevin Cunnane Date: Fri, 2 Nov 2018 14:26:03 -0700 Subject: [PATCH 15/15] Snippets: fix sqlCreateTable, remove database refs & use dbo schema (#3094) - Fixed issues with sqlCreateTable snippet, which meant it couldn't effectively be used to tab through all fields and then hit execute without errors. Specifically fixed bugs where types like NVARCHAR were incorrectly escaped and the Id part of a column was outside the name section, both causing intellisense & execution breaks - Changed SchemaName to dbo. This helps hit the "80% case" where objects are in the most common schema - Removed DatabaseName from most snippets. The core issue is this requires you to manually type the exact database name into the snippet which is really hard. We should consider having separate "with Database" snippets or support SQLCMD variables which would let us default to the current database without needing users to manually type them in as alternatives, but having basic snippets just work on current DB is important. --- extensions/mssql/snippets/mssql.json | 98 ++++++++++++++-------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/extensions/mssql/snippets/mssql.json b/extensions/mssql/snippets/mssql.json index aa4ba3852d..6d1a64275a 100644 --- a/extensions/mssql/snippets/mssql.json +++ b/extensions/mssql/snippets/mssql.json @@ -42,18 +42,18 @@ "Create a new Table": { "prefix": "sqlCreateTable", "body": [ - "-- Create a new table called '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", + "-- Create a new table called '[${1:TableName}]' in schema '[${2:dbo}]'", "-- Drop the table if it already exists", - "IF OBJECT_ID('[${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]', 'U') IS NOT NULL", - "DROP TABLE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", + "IF OBJECT_ID('[${2:dbo}].[${1:TableName}]', 'U') IS NOT NULL", + "DROP TABLE [${2:dbo}].[${1:TableName}]", "GO", - "-- Create the table in the specified database and schema", - "CREATE TABLE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", + "-- Create the table in the specified schema", + "CREATE TABLE [${2:dbo}].[${1:TableName}]", "(", - "\t[${4:ColumnName}]Id INT NOT NULL PRIMARY KEY, -- Primary Key column", - "\t[${5:ColumnName1}] [NVARCHAR](50) NOT NULL,", - "\t[${6:ColumnName2}] [NVARCHAR](50) NOT NULL", - "\t-- Specify more columns here", + "\t[${3:Id}] INT NOT NULL PRIMARY KEY, -- Primary Key column", + "\t[${4:ColumnName2}] ${5:NVARCHAR(50)} NOT NULL,", + "\t[${6:ColumnName3}] ${7:NVARCHAR(50)} NOT NULL", + "\t$0-- Specify more columns here", ");", "GO" ], @@ -64,10 +64,10 @@ "Drop a Table": { "prefix": "sqlDropTable", "body": [ - "-- Drop a table called '${3:TableName}' in schema '${2:SchemaName}' in Database '${1:DatabaseName}'", + "-- Drop a table called '${1:TableName}' in schema '${2:dbo}'", "-- Drop the table if it already exists", - "IF OBJECT_ID('[${1:DatabaseName}].[${2:SchemaName}].[${3:TableName}]', 'U') IS NOT NULL", - "DROP TABLE [${1:DatabaseName}].[${2:SchemaName}].[${3:TableName}]", + "IF OBJECT_ID('[${2:dbo}].[${1:TableName}]', 'U') IS NOT NULL", + "DROP TABLE [${2:dbo}].[${1:TableName}]", "GO" ], "description": "Drop a Table" @@ -76,9 +76,9 @@ "Add a new column to a Table": { "prefix": "sqlAddColumn", "body": [ - "-- Add a new column '[${1:NewColumnName}]' to table '[${2:TableName}]' in schema '[${3:SchemaName}]' in database '[${4:DatabaseName}]'", - "ALTER TABLE [${4:DatabaseName}].[${3:SchemaName}].[${2:TableName}]", - "\tADD [${1:NewColumnName}] /*new_column_name*/ ${5:int} /*new_column_datatype*/ ${6:NULL} /*new_column_nullability*/", + "-- Add a new column '[${1:NewColumnName}]' to table '[${2:TableName}]' in schema '[${3:dbo}]'", + "ALTER TABLE [${3:dbo}].[${2:TableName}]", + "\tADD [${1:NewColumnName}] /*new_column_name*/ ${4:int} /*new_column_datatype*/ ${5:NULL} /*new_column_nullability*/", "GO" ], "description": "Add a new column to a Table" @@ -87,8 +87,8 @@ "Drop a column from a Table": { "prefix": "sqlDropColumn", "body": [ - "-- Drop '[${1:ColumnName}]' from table '[${2:TableName}]' in schema '[${3:SchemaName}]' in database '[${4:DatabaseName}]'", - "ALTER TABLE [${4:DatabaseName}].[${3:SchemaName}].[${2:TableName}]", + "-- Drop '[${1:ColumnName}]' from table '[${2:TableName}]' in schema '[${3:dbo}]'", + "ALTER TABLE [${3:dbo}].[${2:TableName}]", "\tDROP COLUMN [${1:ColumnName}]", "GO" ], @@ -98,9 +98,9 @@ "Select rows from a Table or a View": { "prefix": "sqlSelect", "body": [ - "-- Select rows from a Table or View '[${1:TableOrViewName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", - "SELECT * FROM [${3:DatabaseName}].[${2:SchemaName}].[${1:TableOrViewName}]", - "WHERE ${4:/* add search conditions here */}", + "-- Select rows from a Table or View '[${1:TableOrViewName}]' in schema '[${2:dbo}]'", + "SELECT * FROM [${2:dbo}].[${1:TableOrViewName}]", + "WHERE ${3:/* add search conditions here */}", "GO" ], "description": "Select rows from a Table or a View" @@ -109,17 +109,17 @@ "Insert rows into a Table": { "prefix": "sqlInsertRows", "body": [ - "-- Insert rows into table '${1:TableName}' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", - "INSERT INTO [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", + "-- Insert rows into table '${1:TableName}' in schema '[${2:dbo}]'", + "INSERT INTO [${2:dbo}].[${1:TableName}]", "( -- Columns to insert data into", - " ${4:[ColumnName1], [ColumnName2], [ColumnName3]}", + " ${3:[ColumnName1], [ColumnName2], [ColumnName3]}", ")", "VALUES", "( -- First row: values for the columns in the list above", - " ${5:ColumnValue1, ColumnValue2, ColumnValue3}", + " ${4:ColumnValue1, ColumnValue2, ColumnValue3}", "),", "( -- Second row: values for the columns in the list above", - " ${6:ColumnValue1, ColumnValue2, ColumnValue3}", + " ${5:ColumnValue1, ColumnValue2, ColumnValue3}", ")", "-- Add more rows here", "GO" @@ -130,9 +130,9 @@ "Delete rows from a Table": { "prefix": "sqlDeleteRows", "body": [ - "-- Delete rows from table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", - "DELETE FROM [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", - "WHERE ${4:/* add search conditions here */}", + "-- Delete rows from table '[${1:TableName}]' in schema '[${2:dbo}]'", + "DELETE FROM [${2:dbo}].[${1:TableName}]", + "WHERE ${3:/* add search conditions here */}", "GO" ], "description": "Delete rows from a Table" @@ -141,13 +141,13 @@ "Update rows in a Table": { "prefix": "sqlUpdateRows", "body": [ - "-- Update rows in table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", - "UPDATE [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}]", + "-- Update rows in table '[${1:TableName}]' in schema '[${2:dbo}]'", + "UPDATE [${2:dbo}].[${1:TableName}]", "SET", - "\t[${4:ColumnName1}] = ${5:ColumnValue1},", - "\t[${6:ColumnName2}] = ${7:ColumnValue2}", + "\t[${3:ColumnName1}] = ${4:ColumnValue1},", + "\t[${5:ColumnName2}] = ${6:ColumnValue2}", "\t-- Add more columns and values here", - "WHERE ${8:/* add search conditions here */}", + "WHERE ${7:/* add search conditions here */}", "GO" ], "description": "Update rows in a Table" @@ -156,27 +156,27 @@ "Create a stored procedure": { "prefix": "sqlCreateStoredProc", "body": [ - "-- Create a new stored procedure called '${1:StoredProcedureName}' in schema '${2:SchemaName}'", + "-- Create a new stored procedure called '${1:StoredProcedureName}' in schema '${2:dbo}'", "-- Drop the stored procedure if it already exists", "IF EXISTS (", "SELECT *", "\tFROM INFORMATION_SCHEMA.ROUTINES", - "WHERE SPECIFIC_SCHEMA = N'${2:SchemaName}'", + "WHERE SPECIFIC_SCHEMA = N'${2:dbo}'", "\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'", ")", - "DROP PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", + "DROP PROCEDURE ${2:dbo}.${1:StoredProcedureName}", "GO", "-- Create the stored procedure in the specified schema", - "CREATE PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", - "\t$3@param1 /*parameter name*/ int /*datatype_for_param1*/ = 0, /*default_value_for_param1*/", - "\t$4@param2 /*parameter name*/ int /*datatype_for_param1*/ = 0 /*default_value_for_param2*/", + "CREATE PROCEDURE ${2:dbo}.${1:StoredProcedureName}", + "\t$3@param1 /*parameter name*/ $4int /*datatype_for_param1*/ = 0, /*default_value_for_param1*/", + "\t$5@param2 /*parameter name*/ $6int /*datatype_for_param1*/ = 0 /*default_value_for_param2*/", "-- add more stored procedure parameters here", "AS", "\t-- body of the stored procedure", "\tSELECT @param1, @param2", "GO", "-- example to execute the stored procedure we just created", - "EXECUTE ${2:SchemaName}.${1:StoredProcedureName} 1 /*value_for_param1*/, 2 /*value_for_param2*/", + "EXECUTE ${2:dbo}.${1:StoredProcedureName} 1 /*value_for_param1*/, 2 /*value_for_param2*/", "GO" ], "description": "Create a stored procedure" @@ -185,14 +185,14 @@ "Drop a stored procedure": { "prefix": "sqlDropStoredProc", "body": [ - "-- Drop the stored procedure called '${1:StoredProcedureName}' in schema '${2:SchemaName}'", + "-- Drop the stored procedure called '${1:StoredProcedureName}' in schema '${2:dbo}'", "IF EXISTS (", "SELECT *", "\tFROM INFORMATION_SCHEMA.ROUTINES", - "WHERE SPECIFIC_SCHEMA = N'${2:SchemaName}'", + "WHERE SPECIFIC_SCHEMA = N'${2:dbo}'", "\tAND SPECIFIC_NAME = N'${1:StoredProcedureName}'", ")", - "DROP PROCEDURE ${2:SchemaName}.${1:StoredProcedureName}", + "DROP PROCEDURE ${2:dbo}.${1:StoredProcedureName}", "GO" ], "description": "Drop a stored procedure" @@ -241,7 +241,7 @@ "Declare a cursor": { "prefix": "sqlCursor", "body": [ - "-- Declare a cursor for a Table or a View '${1:TableOrViewName}' in schema '${2:SchemaName}'", + "-- Declare a cursor for a Table or a View '${1:TableOrViewName}' in schema '${2:dbo}'", "DECLARE @ColumnName1 NVARCHAR(50), @ColumnName2 NVARCHAR(50)", "", "DECLARE db_cursor CURSOR FOR", @@ -304,8 +304,8 @@ "prefix": "sqlCreateIndex", "body": [ "-- Create a nonclustered index with or without a unique constraint", - "-- Or create a clustered index on table '[${1:TableName}]' in schema '[${2:SchemaName}]' in database '[${3:DatabaseName}]'", - "CREATE ${5:/*UNIQUE or CLUSTERED*/} INDEX IX_${4:IndexName} ON [${3:DatabaseName}].[${2:SchemaName}].[${1:TableName}] ([${6:ColumnName1}] DESC /*Change sort order as needed*/", + "-- Or create a clustered index on table '[${1:TableName}]' in schema '[${2:dbo}]' in database '[${3:DatabaseName}]'", + "CREATE ${5:/*UNIQUE or CLUSTERED*/} INDEX IX_${4:IndexName} ON [${3:DatabaseName}].[${2:dbo}].[${1:TableName}] ([${6:ColumnName1}] DESC /*Change sort order as needed*/", "GO" ], "description": "Create a new Index" @@ -319,13 +319,13 @@ "IF OBJECT_ID('tempDB..#${1:TableName}', 'U') IS NOT NULL", "DROP TABLE #${1:TableName}", "GO", - "-- Create the temporary table from a physical table called '${4:TableName}' in schema '${3:SchemaName}' in database '${2:DatabaseName}'", + "-- Create the temporary table from a physical table called '${4:TableName}' in schema '${3:dbo}' in database '${2:DatabaseName}'", "SELECT *", "INTO #${1:TableName}", - "FROM [${2:DatabaseName}].[${3:[SchemaName}].[${4:TableName}]", + "FROM [${2:DatabaseName}].[${3:[dbo}].[${4:TableName}]", "WHERE ${5:/* add search conditions here */}" ], "description": "Create a new Temporary Table" - }, + } }