From fe17955fa11483d25aad5f05cefe99df71422dcb Mon Sep 17 00:00:00 2001 From: Karl Burtram Date: Thu, 16 May 2019 16:31:30 -0700 Subject: [PATCH] Add support for setting query options in settings and through API (#5484) Initial query execution options PR. This is the second in a set of query editor extensibility improvements I'm making. The PRs include (1) bug fix for webview in query tab (2) dynamic toolbars and (3) fix query event sequencing and event metadata info. --- extensions/mssql/package.json | 2 +- extensions/mssql/src/config.json | 2 +- extensions/mssql/yarn.lock | 6 +- src/sql/azdata.proposed.d.ts | 15 ++- .../connection/common/connectionManagement.ts | 2 + .../common/connectionManagementService.ts | 5 + .../platform/query/common/queryManagement.ts | 13 ++- src/sql/platform/query/common/queryRunner.ts | 62 +++++----- .../workbench/api/node/extHostDataProtocol.ts | 8 ++ .../workbench/api/node/extHostQueryEditor.ts | 22 ++-- .../api/node/mainThreadDataProtocol.ts | 3 + .../api/node/mainThreadQueryEditor.ts | 9 +- .../workbench/api/node/sqlExtHost.api.impl.ts | 7 +- .../workbench/api/node/sqlExtHost.protocol.ts | 5 + .../parts/query/browser/query.contribution.ts | 110 ++++++++++++++++++ .../connectionManagementService.test.ts | 7 ++ .../stubs/connectionManagementService.test.ts | 4 + 17 files changed, 222 insertions(+), 60 deletions(-) diff --git a/extensions/mssql/package.json b/extensions/mssql/package.json index 19ffd2b219..8794e7db19 100644 --- a/extensions/mssql/package.json +++ b/extensions/mssql/package.json @@ -20,7 +20,7 @@ "dependencies": { "buffer-stream-reader": "^0.1.1", "bytes": "^3.1.0", - "dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.2.16", + "dataprotocol-client": "github:Microsoft/sqlops-dataprotocolclient#0.3.0", "error-ex": "^1.3.2", "figures": "^2.0.0", "find-remove": "1.2.1", diff --git a/extensions/mssql/src/config.json b/extensions/mssql/src/config.json index 71882e01c5..0bb1506353 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.93", + "version": "1.5.0-alpha.95", "downloadFileNames": { "Windows_86": "win-x86-netcoreapp2.2.zip", "Windows_64": "win-x64-netcoreapp2.2.zip", diff --git a/extensions/mssql/yarn.lock b/extensions/mssql/yarn.lock index 0b66a92b76..d8dfcb8b75 100644 --- a/extensions/mssql/yarn.lock +++ b/extensions/mssql/yarn.lock @@ -170,9 +170,9 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.2.16": - version "0.2.16" - resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/3c4e70405022ab5333cf1505deddd643223db3de" +"dataprotocol-client@github:Microsoft/sqlops-dataprotocolclient#0.3.0": + version "0.3.0" + resolved "https://codeload.github.com/Microsoft/sqlops-dataprotocolclient/tar.gz/21487d15a5f753ba885ce1e489abc0af03487544" dependencies: vscode-languageclient "3.5.1" diff --git a/src/sql/azdata.proposed.d.ts b/src/sql/azdata.proposed.d.ts index 21e016260b..ba8f2e8f37 100644 --- a/src/sql/azdata.proposed.d.ts +++ b/src/sql/azdata.proposed.d.ts @@ -740,6 +740,10 @@ declare module 'azdata' { flavor: string; } + export interface QueryExecutionOptions { + options: Map; + } + export interface QueryProvider extends DataProvider { cancelQuery(ownerUri: string): Thenable; runQuery(ownerUri: string, selection: ISelectionData, runOptions?: ExecutionPlanOptions): Thenable; @@ -750,6 +754,7 @@ declare module 'azdata' { getQueryRows(rowData: QueryExecuteSubsetParams): Thenable; disposeQuery(ownerUri: string): Thenable; saveResults(requestParams: SaveResultsRequestParams): Thenable; + setQueryExecutionOptions(ownerUri: string, options: QueryExecutionOptions): Thenable; // Notifications registerOnQueryComplete(handler: (result: QueryExecuteCompleteNotificationResult) => any): void; @@ -3884,11 +3889,8 @@ declare module 'azdata' { uri: string; - // get the document's execution options - getOptions(): Map; - // set the document's execution options - setOptions(options: Map): void; + setExecutionOptions(options: Map): Thenable; // tab content is build using the modelview UI builder APIs // probably should rename DialogTab class since it is useful outside dialogs @@ -3913,7 +3915,10 @@ declare module 'azdata' { */ export function registerQueryEventListener(listener: queryeditor.QueryEventListener): void; - export function getQueryDocument(fileUri: string): queryeditor.QueryDocument; + /** + * Get a QueryDocument object for a file URI + */ + export function getQueryDocument(fileUri: string): Thenable; } /** diff --git a/src/sql/platform/connection/common/connectionManagement.ts b/src/sql/platform/connection/common/connectionManagement.ts index 01e13177c6..ac3d5ac6fa 100644 --- a/src/sql/platform/connection/common/connectionManagement.ts +++ b/src/sql/platform/connection/common/connectionManagement.ts @@ -191,6 +191,8 @@ export interface IConnectionManagementService { getConnectionInfo(fileUri: string): ConnectionManagementInfo; + getDefaultProviderId(): string; + /** * Cancels the connection */ diff --git a/src/sql/platform/connection/common/connectionManagementService.ts b/src/sql/platform/connection/common/connectionManagementService.ts index f949328a5f..70694e9856 100644 --- a/src/sql/platform/connection/common/connectionManagementService.ts +++ b/src/sql/platform/connection/common/connectionManagementService.ts @@ -760,6 +760,11 @@ export class ConnectionManagementService extends Disposable implements IConnecti } } + public getDefaultProviderId(): string { + let defaultProvider = WorkbenchUtils.getSqlConfigValue(this._configurationService, Constants.defaultEngine); + return defaultProvider && this._providers.has(defaultProvider) ? defaultProvider : undefined; + } + private async fillInAzureTokenIfNeeded(connection: IConnectionProfile): Promise { if (connection.authenticationType !== Constants.azureMFA || connection.options['azureAccountToken']) { return true; diff --git a/src/sql/platform/query/common/queryManagement.ts b/src/sql/platform/query/common/queryManagement.ts index 656d315578..cf28cadc52 100644 --- a/src/sql/platform/query/common/queryManagement.ts +++ b/src/sql/platform/query/common/queryManagement.ts @@ -36,6 +36,7 @@ export interface IQueryManagementService { getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable; disposeQuery(ownerUri: string): Thenable; saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable; + setQueryExecutionOptions(uri: string, options: azdata.QueryExecutionOptions): Thenable; // Callbacks onQueryComplete(result: azdata.QueryExecuteCompleteNotificationResult): void; @@ -73,6 +74,7 @@ export interface IQueryRequestHandler { getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable; disposeQuery(ownerUri: string): Thenable; saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable; + setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable; // Edit Data actions initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable; @@ -177,9 +179,13 @@ export class QueryManagementService implements IQueryManagementService { TelemetryUtils.addTelemetry(this._telemetryService, this.logService, eventName, data); } - private _runAction(uri: string, action: (handler: IQueryRequestHandler) => Thenable): Thenable { + private _runAction(uri: string, action: (handler: IQueryRequestHandler) => Thenable, fallBackToDefaultProvider: boolean = false): Thenable { let providerId: string = this._connectionService.getProviderIdFromUri(uri); + if (!providerId && fallBackToDefaultProvider) { + providerId = this._connectionService.getDefaultProviderId(); + } + if (!providerId) { return Promise.reject(new Error('Connection is required in order to interact with queries')); } @@ -236,6 +242,11 @@ export class QueryManagementService implements IQueryManagementService { return runner.disposeQuery(ownerUri); }); } + public setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { + return this._runAction(ownerUri, (runner) => { + return runner.setQueryExecutionOptions(ownerUri, options); + }, true); + } public saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable { return this._runAction(requestParams.ownerUri, (runner) => { diff --git a/src/sql/platform/query/common/queryRunner.ts b/src/sql/platform/query/common/queryRunner.ts index f2639d5672..a474151823 100644 --- a/src/sql/platform/query/common/queryRunner.ts +++ b/src/sql/platform/query/common/queryRunner.ts @@ -50,7 +50,7 @@ export default class QueryRunner extends Disposable { private _messages: IQueryMessage[] = []; private registered = false; - private _isQueryPlan: boolean; + private _isQueryPlan: boolean = false; public get isQueryPlan(): boolean { return this._isQueryPlan; } private _planXml = new Deferred(); public get planXml(): Thenable { return this._planXml.promise; } @@ -180,12 +180,6 @@ export default class QueryRunner extends Disposable { this._totalElapsedMilliseconds = 0; // TODO issue #228 add statusview callbacks here - if (runOptions && (runOptions.displayActualQueryPlan || runOptions.displayEstimatedQueryPlan)) { - this._isQueryPlan = true; - } else { - this._isQueryPlan = false; - } - this._onQueryStart.fire(); // Send the request to execute the query @@ -335,16 +329,15 @@ export default class QueryRunner extends Disposable { batchSet = this._batchSets[resultSet.batchId]; } // handle getting queryPlanxml if we need too - if (this.isQueryPlan) { - // check if this result has show plan, this needs work, it won't work for any other provider - let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan'); - if (hasShowPlan) { - this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => { - if (e.resultSubset.rows) { - this._planXml.resolve(e.resultSubset.rows[0][0].displayValue); - } - }); - } + // check if this result has show plan, this needs work, it won't work for any other provider + let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan'); + if (hasShowPlan) { + this._isQueryPlan = true; + this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => { + if (e.resultSubset.rows) { + this._planXml.resolve(e.resultSubset.rows[0][0].displayValue); + } + }); } // we will just ignore the set if we already have it // ideally this should never happen @@ -362,25 +355,24 @@ export default class QueryRunner extends Disposable { let batchSet: azdata.BatchSummary; batchSet = this._batchSets[resultSet.batchId]; // handle getting queryPlanxml if we need too - if (this.isQueryPlan) { - // check if this result has show plan, this needs work, it won't work for any other provider - let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan'); - if (hasShowPlan) { - this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => { - if (e.resultSubset.rows) { - let planXmlString = e.resultSubset.rows[0][0].displayValue; - this._planXml.resolve(e.resultSubset.rows[0][0].displayValue); - // fire query plan available event if execution is completed - if (result.resultSetSummary.complete) { - this._onQueryPlanAvailable.fire({ - providerId: 'MSSQL', - fileUri: result.ownerUri, - planXml: planXmlString - }); - } + // check if this result has show plan, this needs work, it won't work for any other provider + let hasShowPlan = !!result.resultSetSummary.columnInfo.find(e => e.columnName === 'Microsoft SQL Server 2005 XML Showplan'); + if (hasShowPlan) { + this._isQueryPlan = true; + this.getQueryRows(0, 1, result.resultSetSummary.batchId, result.resultSetSummary.id).then(e => { + if (e.resultSubset.rows) { + let planXmlString = e.resultSubset.rows[0][0].displayValue; + this._planXml.resolve(e.resultSubset.rows[0][0].displayValue); + // fire query plan available event if execution is completed + if (result.resultSetSummary.complete) { + this._onQueryPlanAvailable.fire({ + providerId: 'MSSQL', + fileUri: result.ownerUri, + planXml: planXmlString + }); } - }); - } + } + }); } if (batchSet) { // Store the result set in the batch and emit that a result set has completed diff --git a/src/sql/workbench/api/node/extHostDataProtocol.ts b/src/sql/workbench/api/node/extHostDataProtocol.ts index bc3860b3c5..4b4cc19b26 100644 --- a/src/sql/workbench/api/node/extHostDataProtocol.ts +++ b/src/sql/workbench/api/node/extHostDataProtocol.ts @@ -260,6 +260,14 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape { return this._resolveProvider(handle).runQueryAndReturn(ownerUri, queryString); } + $setQueryExecutionOptions(handle: number, ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { + if (this._resolveProvider(handle).setQueryExecutionOptions) { + return this._resolveProvider(handle).setQueryExecutionOptions(ownerUri, options); + } else { + return new Promise((r) => r()); + } + } + $parseSyntax(handle: number, ownerUri: string, query: string): Thenable { return this._resolveProvider(handle).parseSyntax(ownerUri, query); } diff --git a/src/sql/workbench/api/node/extHostQueryEditor.ts b/src/sql/workbench/api/node/extHostQueryEditor.ts index c5c3045ae4..4762c382ed 100644 --- a/src/sql/workbench/api/node/extHostQueryEditor.ts +++ b/src/sql/workbench/api/node/extHostQueryEditor.ts @@ -15,17 +15,14 @@ class ExtHostQueryDocument implements azdata.queryeditor.QueryDocument { private _proxy: MainThreadQueryEditorShape) { } - // get the document's execution options - getOptions(): Map { - return undefined; + public setExecutionOptions(options: Map): Thenable { + let executionOptions: azdata.QueryExecutionOptions = { + options: options + }; + return this._proxy.$setQueryExecutionOptions(this.uri, executionOptions); } - // set the document's execution optionsß - setOptions(options: Map): void { - - } - - createQueryTab(tab: azdata.window.DialogTab): void { + public createQueryTab(tab: azdata.window.DialogTab): void { this._proxy.$createQueryTab(this.uri, tab.title, tab.content); } } @@ -63,4 +60,11 @@ export class ExtHostQueryEditor implements ExtHostQueryEditorShape { listener.onQueryEvent(event.type, new ExtHostQueryDocument('MSSQL', fileUri, this._proxy), planXml); } } + + public $getQueryDocument(fileUri: string): Thenable { + return new Promise((resolve) => { + resolve(new ExtHostQueryDocument('MSSQL', fileUri, this._proxy)); + }); + } + } diff --git a/src/sql/workbench/api/node/mainThreadDataProtocol.ts b/src/sql/workbench/api/node/mainThreadDataProtocol.ts index 70fc252d10..e34a2090a3 100644 --- a/src/sql/workbench/api/node/mainThreadDataProtocol.ts +++ b/src/sql/workbench/api/node/mainThreadDataProtocol.ts @@ -127,6 +127,9 @@ export class MainThreadDataProtocol implements MainThreadDataProtocolShape { getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable { return self._proxy.$getQueryRows(handle, rowData); }, + setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { + return self._proxy.$setQueryExecutionOptions(handle, ownerUri, options); + }, disposeQuery(ownerUri: string): Thenable { return self._proxy.$disposeQuery(handle, ownerUri); }, diff --git a/src/sql/workbench/api/node/mainThreadQueryEditor.ts b/src/sql/workbench/api/node/mainThreadQueryEditor.ts index e4642d8f1c..a825187f6b 100644 --- a/src/sql/workbench/api/node/mainThreadQueryEditor.ts +++ b/src/sql/workbench/api/node/mainThreadQueryEditor.ts @@ -7,11 +7,12 @@ import { SqlExtHostContext, SqlMainContext, ExtHostQueryEditorShape, MainThreadQ import { IExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; import { IConnectionManagementService, IConnectionCompletionOptions, ConnectionType, RunQueryOnConnectionMode } from 'sql/platform/connection/common/connectionManagement'; -import { IQueryEditorService } from 'sql/workbench/services/queryEditor/common/queryEditorService'; import { QueryEditor } from 'sql/workbench/parts/query/browser/queryEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { dispose, IDisposable } from 'vs/base/common/lifecycle'; import { IQueryModelService, IQueryEvent } from 'sql/platform/query/common/queryModel'; +import { IQueryManagementService } from 'sql/platform/query/common/queryManagement'; +import * as azdata from 'azdata'; @extHostNamedCustomer(SqlMainContext.MainThreadQueryEditor) export class MainThreadQueryEditor implements MainThreadQueryEditorShape { @@ -22,7 +23,7 @@ export class MainThreadQueryEditor implements MainThreadQueryEditorShape { constructor( extHostContext: IExtHostContext, @IConnectionManagementService private _connectionManagementService: IConnectionManagementService, - @IQueryEditorService private _queryEditorService: IQueryEditorService, + @IQueryManagementService private _queryManagementService: IQueryManagementService, @IQueryModelService private _queryModelService: IQueryModelService, @IEditorService private _editorService: IEditorService ) { @@ -96,4 +97,8 @@ export class MainThreadQueryEditor implements MainThreadQueryEditorShape { } } } + + public $setQueryExecutionOptions(fileUri: string, options: azdata.QueryExecutionOptions): Thenable { + return this._queryManagementService.setQueryExecutionOptions(fileUri, options); + } } diff --git a/src/sql/workbench/api/node/sqlExtHost.api.impl.ts b/src/sql/workbench/api/node/sqlExtHost.api.impl.ts index f977dd30fd..c51c000ea2 100644 --- a/src/sql/workbench/api/node/sqlExtHost.api.impl.ts +++ b/src/sql/workbench/api/node/sqlExtHost.api.impl.ts @@ -41,6 +41,7 @@ import { ExtHostConfiguration, ExtHostConfigProvider } from 'vs/workbench/api/co import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage'; import * as extHostTypes from 'vs/workbench/api/common/extHostTypes'; import { ISchemeTransformer } from 'vs/workbench/api/common/extHostLanguageFeatures'; +import { AzureResource } from 'sql/platform/accounts/common/interfaces'; export interface ISqlExtensionApiFactory { vsCodeFactory(extension: IExtensionDescription, registry: ExtensionDescriptionRegistry, configProvider: ExtHostConfigProvider): typeof vscode; @@ -462,8 +463,8 @@ export function createApiFactory( extHostQueryEditor.$registerQueryInfoListener('MSSQL', listener); }, - getQueryDocument(fileUri: string): azdata.queryeditor.QueryDocument { - return undefined; + getQueryDocument(fileUri: string): Thenable { + return extHostQueryEditor.$getQueryDocument(fileUri); } }; @@ -662,7 +663,7 @@ export function createApiFactory( extHostDataProvider.$onEditSessionReady(provider.handle, ownerUri, success, message); }); - return extHostDataProvider.$registerQueryProvider(provider); + return extHostDataProvider.$registerQueryProvider(provider); }; let registerObjectExplorerProvider = (provider: sqlops.ObjectExplorerProvider): vscode.Disposable => { diff --git a/src/sql/workbench/api/node/sqlExtHost.protocol.ts b/src/sql/workbench/api/node/sqlExtHost.protocol.ts index 39165b542f..74a1e8ea40 100644 --- a/src/sql/workbench/api/node/sqlExtHost.protocol.ts +++ b/src/sql/workbench/api/node/sqlExtHost.protocol.ts @@ -173,6 +173,10 @@ export abstract class ExtHostDataProtocolShape { * Gets a subset of rows in a result set in order to display in the UI */ $getQueryRows(handle: number, rowData: azdata.QueryExecuteSubsetParams): Thenable { throw ni(); } + /** + * Sets the query execution options for a query editor document + */ + $setQueryExecutionOptions(handle: number, ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { throw ni(); } /** * Disposes the cached information regarding a query @@ -793,6 +797,7 @@ export interface MainThreadQueryEditorShape extends IDisposable { $connect(fileUri: string, connectionId: string): Thenable; $runQuery(fileUri: string): void; $createQueryTab(fileUri: string, title: string, content: string): void; + $setQueryExecutionOptions(fileUri: string, options: azdata.QueryExecutionOptions): Thenable; $registerQueryInfoListener(handle: number, providerId: string): void; } diff --git a/src/sql/workbench/parts/query/browser/query.contribution.ts b/src/sql/workbench/parts/query/browser/query.contribution.ts index 5b8e2e4126..2e13e4e6c1 100644 --- a/src/sql/workbench/parts/query/browser/query.contribution.ts +++ b/src/sql/workbench/parts/query/browser/query.contribution.ts @@ -404,6 +404,116 @@ let registryProperties = { 'type': 'boolean', 'default': false, 'description': localize('mssql.intelliSense.lowerCaseSuggestions', 'Should IntelliSense suggestions be lowercase') + }, + 'mssql.query.rowCount': { + 'type': 'number', + 'default': 0, + 'description': localize('mssql.query.setRowCount', 'Maximum number of rows to return before the server stops processing your query.') + }, + 'mssql.query.textSize': { + 'type': 'number', + 'default': 2147483647, + 'description': localize('mssql.query.textSize', 'Maximum size of text and ntext data returned from a SELECT statement') + }, + 'mssql.query.executionTimeout': { + 'type': 'number', + 'default': 0, + 'description': localize('mssql.query.executionTimeout', 'An execution time-out of 0 indicates an unlimited wait (no time-out)') + }, + 'mssql.query.noCount': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.noCount', 'Enable SET NOCOUNT option') + }, + 'mssql.query.noExec': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.noExec', 'Enable SET NOEXEC option') + }, + 'mssql.query.parseOnly': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.parseOnly', 'Enable SET PARSEONLY option') + }, + 'mssql.query.arithAbort': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.arithAbort', 'Enable SET ARITHABORT option') + }, + 'mssql.query.statisticsTime': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.statisticsTime', 'Enable SET STATISTICS TIME option') + }, + 'mssql.query.statisticsIO': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.statisticsIO', 'Enable SET STATISTICS IO option') + }, + 'mssql.query.xactAbortOn': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.xactAbortOn', 'Enable SET XACT_ABORT ON option') + }, + 'mssql.query.transactionIsolationLevel': { + 'enum': ['READ COMMITTED', 'READ UNCOMMITTED', 'REPEATABLE READ', 'SERIALIZABLE'], + 'default': 'READ COMMITTED', + 'description': localize('mssql.query.transactionIsolationLevel', 'Enable SET TRANSACTION ISOLATION LEVEL option') + }, + 'mssql.query.deadlockPriority': { + 'enum': ['Normal', 'Low'], + 'default': 'Normal', + 'description': localize('mssql.query.deadlockPriority', 'Enable SET DEADLOCK_PRIORITY option') + }, + 'mssql.query.lockTimeout': { + 'type': 'number', + 'default': -1, + 'description': localize('mssql.query.lockTimeout', 'Enable SET LOCK TIMEOUT option (in milliseconds)') + }, + 'mssql.query.queryGovernorCostLimit': { + 'type': 'number', + 'default': -1, + 'description': localize('mssql.query.queryGovernorCostLimit', 'Enable SET QUERY_GOVERNOR_COST_LIMIT') + }, + 'mssql.query.ansiDefaults': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.ansiDefaults', 'Enable SET ANSI_DEFAULTS') + }, + 'mssql.query.quotedIdentifier': { + 'type': 'boolean', + 'default': true, + 'description': localize('mssql.query.quotedIdentifier', 'Enable SET QUOTED_IDENTIFIER') + }, + 'mssql.query.ansiNullDefaultOn': { + 'type': 'boolean', + 'default': true, + 'description': localize('mssql.query.ansiNullDefaultOn', 'Enable SET ANSI_NULL_DFLT_ON') + }, + 'mssql.query.implicitTransactions': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.implicitTransactions', 'Enable SET IMPLICIT_TRANSACTIONS') + }, + 'mssql.query.cursorCloseOnCommit': { + 'type': 'boolean', + 'default': false, + 'description': localize('mssql.query.cursorCloseOnCommit', 'Enable SET CURSOR_CLOSE_ON_COMMIT') + }, + 'mssql.query.ansiPadding': { + 'type': 'boolean', + 'default': true, + 'description': localize('mssql.query.ansiPadding', 'Enable SET ANSI_PADDING') + }, + 'mssql.query.ansiWarnings': { + 'type': 'boolean', + 'default': true, + 'description': localize('mssql.query.ansiWarnings', 'Enable SET ANSI_WARNINGS') + }, + 'mssql.query.ansiNulls': { + 'type': 'boolean', + 'default': true, + 'description': localize('mssql.query.ansiNulls', 'Enable SET ANSI_NULLS') } }; diff --git a/src/sqltest/parts/connection/connectionManagementService.test.ts b/src/sqltest/parts/connection/connectionManagementService.test.ts index a24f103887..8999b57bf0 100644 --- a/src/sqltest/parts/connection/connectionManagementService.test.ts +++ b/src/sqltest/parts/connection/connectionManagementService.test.ts @@ -73,6 +73,7 @@ suite('SQL ConnectionManagementService tests', () => { let connectionManagementService: ConnectionManagementService; let configResult: { [key: string]: any } = {}; + configResult['defaultEngine'] = 'MSSQL'; let handleFirewallRuleResult: IHandleFirewallRuleResult; let resolveHandleFirewallRuleDialog: boolean; let isFirewallRuleAdded: boolean; @@ -316,6 +317,12 @@ suite('SQL ConnectionManagementService tests', () => { }); }); + test('getDefaultProviderId is MSSQL', done => { + let defaultProvider = connectionManagementService.getDefaultProviderId(); + assert.equal(defaultProvider, 'MSSQL', `Default provider is not equal to MSSQL`); + done(); + }); + /* Andresse 10/5/17 commented this test out since it was only working before my changes by the chance of how Promises work If we want to continue to test this, the connection logic needs to be rewritten to actually wait for everything to be done before it resolves */ // test('connect should show dashboard given options with showDashboard set to true', done => { diff --git a/src/sqltest/stubs/connectionManagementService.test.ts b/src/sqltest/stubs/connectionManagementService.test.ts index 19effabca3..6cb3963119 100644 --- a/src/sqltest/stubs/connectionManagementService.test.ts +++ b/src/sqltest/stubs/connectionManagementService.test.ts @@ -287,4 +287,8 @@ export class TestConnectionManagementService implements IConnectionManagementSer getConnectionIconId(connectionId: string): string { return undefined; } + + getDefaultProviderId(): string { + return undefined; + } } \ No newline at end of file