diff --git a/src/sql/azdata.d.ts b/src/sql/azdata.d.ts index c287466080..b82b08d9aa 100644 --- a/src/sql/azdata.d.ts +++ b/src/sql/azdata.d.ts @@ -285,7 +285,7 @@ declare module 'azdata' { password: string; authenticationType: string; savePassword: boolean; - groupFullName: string; + groupFullName?: string; groupId: string; providerName: string; saveProfile: boolean; @@ -834,7 +834,7 @@ declare module 'azdata' { export interface IResultMessage { batchId?: number; isError: boolean; - time: string; + time?: string; message: string; } diff --git a/src/sql/platform/common/pathUtilities.ts b/src/sql/platform/common/pathUtilities.ts index 88d42276ba..8cf6c84044 100644 --- a/src/sql/platform/common/pathUtilities.ts +++ b/src/sql/platform/common/pathUtilities.ts @@ -11,7 +11,7 @@ import { Schemas } from 'vs/base/common/network'; export const FILE_SCHEMA: string = 'file'; -export function resolveCurrentDirectory(uri: string, rootPath: string): string | undefined { +export function resolveCurrentDirectory(uri: string, rootPath?: string): string | undefined { let sqlUri = URI.parse(uri); let currentDirectory: string | undefined; @@ -30,7 +30,7 @@ export function resolveCurrentDirectory(uri: string, rootPath: string): string | return currentDirectory; } -export function resolveFilePath(uri: string, filePath: string, rootPath: string): string | undefined { +export function resolveFilePath(uri: string, filePath: string, rootPath?: string): string | undefined { let currentDirectory = resolveCurrentDirectory(uri, rootPath); if (currentDirectory) { return normalize(join(currentDirectory, filePath)); diff --git a/src/sql/platform/connection/common/connectionConfig.ts b/src/sql/platform/connection/common/connectionConfig.ts index 363df01241..e8a97aa54c 100644 --- a/src/sql/platform/connection/common/connectionConfig.ts +++ b/src/sql/platform/connection/common/connectionConfig.ts @@ -18,7 +18,7 @@ const CONNECTIONS_CONFIG_KEY = 'datasource.connections'; export interface ISaveGroupResult { groups: IConnectionProfileGroup[]; - newGroupId: string; + newGroupId?: string; } /** @@ -37,7 +37,9 @@ export class ConnectionConfig { public getAllGroups(): IConnectionProfileGroup[] { let allGroups: IConnectionProfileGroup[] = []; - let { user, workspace } = this.configurationService.inspect(GROUPS_CONFIG_KEY); + const config = this.configurationService.inspect(GROUPS_CONFIG_KEY); + let { user } = config; + const { workspace } = config; if (user) { if (workspace) { @@ -109,7 +111,7 @@ export class ConnectionConfig { let result = this.saveGroup(groups, profile.groupFullName, undefined, undefined); groups = result.groups; - return this.configurationService.updateValue(GROUPS_CONFIG_KEY, groups, ConfigurationTarget.USER).then(() => result.newGroupId); + return this.configurationService.updateValue(GROUPS_CONFIG_KEY, groups, ConfigurationTarget.USER).then(() => result.newGroupId!); } } @@ -129,7 +131,7 @@ export class ConnectionConfig { let result = this.saveGroup(groups, profileGroup.name, profileGroup.color, profileGroup.description); groups = result.groups; - return this.configurationService.updateValue(GROUPS_CONFIG_KEY, groups, ConfigurationTarget.USER).then(() => result.newGroupId); + return this.configurationService.updateValue(GROUPS_CONFIG_KEY, groups, ConfigurationTarget.USER).then(() => result.newGroupId!); } } } @@ -138,18 +140,22 @@ export class ConnectionConfig { let configs = this.configurationService.inspect(CONNECTIONS_CONFIG_KEY); let profiles: IConnectionProfileStore[]; if (configs) { + let fromConfig: IConnectionProfileStore[] | undefined; if (configTarget === ConfigurationTarget.USER) { - profiles = configs.user; + fromConfig = configs.user; } else if (configTarget === ConfigurationTarget.WORKSPACE) { - profiles = configs.workspace; + fromConfig = configs.workspace || []; } - if (profiles) { + if (fromConfig) { + profiles = fromConfig; if (this.fixConnectionIds(profiles)) { this.configurationService.updateValue(CONNECTIONS_CONFIG_KEY, profiles, configTarget); } } else { profiles = []; } + } else { + profiles = []; } return profiles; @@ -315,7 +321,7 @@ export class ConnectionConfig { } } - public saveGroup(groups: IConnectionProfileGroup[], groupFullName: string, color: string, description: string): ISaveGroupResult { + public saveGroup(groups: IConnectionProfileGroup[], groupFullName?: string, color?: string, description?: string): ISaveGroupResult { let groupNames = ConnectionProfileGroup.getGroupFullNameParts(groupFullName); return this.saveGroupInTree(groups, undefined, groupNames, color, description, 0); } @@ -348,21 +354,21 @@ export class ConnectionConfig { return sameGroupName; } - private saveGroupInTree(groupTree: IConnectionProfileGroup[], parentId: string, groupNames: string[], color: string, description: string, index: number): ISaveGroupResult { + private saveGroupInTree(groupTree: IConnectionProfileGroup[], parentId: string | undefined, groupNames: string[], color: string | undefined, description: string | undefined, index: number): ISaveGroupResult { if (!groupTree) { groupTree = []; } - let newGroupId: string; + let newGroupId: string | undefined; if (index < groupNames.length) { let groupName: string = groupNames[index]; - let newGroup: IConnectionProfileGroup = { + let newGroup = { // workaround to make this work properly name: groupName, id: undefined, parentId: parentId, color: color, description: description - }; + } as IConnectionProfileGroup; let found = groupTree.find(group => this.isSameGroupName(group, newGroup)); if (found) { if (index === groupNames.length - 1) { diff --git a/src/sql/platform/connection/common/connectionProfile.ts b/src/sql/platform/connection/common/connectionProfile.ts index 85782ffc65..a7c67f758c 100644 --- a/src/sql/platform/connection/common/connectionProfile.ts +++ b/src/sql/platform/connection/common/connectionProfile.ts @@ -25,7 +25,7 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa public parent?: ConnectionProfileGroup; private _id: string; public savePassword: boolean; - private _groupName: string; + private _groupName?: string; public groupId: string; public saveProfile: boolean; @@ -119,11 +119,11 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa this.options['registeredServerDescription'] = value; } - public get groupFullName(): string { + public get groupFullName(): string | undefined { return this._groupName; } - public set groupFullName(value: string) { + public set groupFullName(value: string | undefined) { this._groupName = value; } @@ -214,15 +214,12 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa return !profile.databaseName || profile.databaseName.trim() === ''; } - public static fromIConnectionProfile(capabilitiesService: ICapabilitiesService, profile: azdata.IConnectionProfile) { - if (profile) { - if (profile instanceof ConnectionProfile) { - return profile; - } else { - return new ConnectionProfile(capabilitiesService, profile); - } + public static fromIConnectionProfile(capabilitiesService: ICapabilitiesService, profile: azdata.IConnectionProfile): ConnectionProfile { + if (profile instanceof ConnectionProfile) { + return profile; + } else { + return new ConnectionProfile(capabilitiesService, profile); } - return undefined; } public static createFromStoredProfile(profile: interfaces.IConnectionProfileStore, capabilitiesService: ICapabilitiesService): ConnectionProfile { @@ -244,24 +241,18 @@ export class ConnectionProfile extends ProviderConnectionInfo implements interfa public static convertToProfileStore( capabilitiesService: ICapabilitiesService, - connectionProfile: interfaces.IConnectionProfile): interfaces.IConnectionProfileStore | undefined { - if (connectionProfile) { - let connectionInfo = ConnectionProfile.fromIConnectionProfile(capabilitiesService, connectionProfile); - if (connectionInfo) { - let profile: interfaces.IConnectionProfileStore = { - options: {}, - groupId: connectionProfile.groupId, - providerName: connectionInfo.providerName, - savePassword: connectionInfo.savePassword, - id: connectionInfo.id - }; + connectionProfile: interfaces.IConnectionProfile): interfaces.IConnectionProfileStore { + let connectionInfo = ConnectionProfile.fromIConnectionProfile(capabilitiesService, connectionProfile); + let profile: interfaces.IConnectionProfileStore = { + options: {}, + groupId: connectionProfile.groupId, + providerName: connectionInfo.providerName, + savePassword: connectionInfo.savePassword, + id: connectionInfo.id + }; - profile.options = connectionInfo.options; + profile.options = connectionInfo.options; - return profile; - } - } - - return undefined; + return profile; } } diff --git a/src/sql/platform/connection/common/connectionProfileGroup.ts b/src/sql/platform/connection/common/connectionProfileGroup.ts index 3e8c815749..de885dbacf 100644 --- a/src/sql/platform/connection/common/connectionProfileGroup.ts +++ b/src/sql/platform/connection/common/connectionProfileGroup.ts @@ -5,13 +5,14 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProfile'; import { Disposable } from 'vs/base/common/lifecycle'; +import { isUndefinedOrNull } from 'vs/base/common/types'; export interface IConnectionProfileGroup { id: string; parentId?: string; name: string; - color: string; - description: string; + color?: string; + description?: string; } export class ConnectionProfileGroup extends Disposable implements IConnectionProfileGroup { @@ -22,10 +23,10 @@ export class ConnectionProfileGroup extends Disposable implements IConnectionPro private _isRenamed: boolean; public constructor( public name: string, - public parent: ConnectionProfileGroup, + public parent: ConnectionProfileGroup | undefined, public id: string, - public color: string, - public description: string + public color?: string, + public description?: string ) { super(); this.parentId = parent ? parent.id : undefined; @@ -150,7 +151,7 @@ export class ConnectionProfileGroup extends Disposable implements IConnectionPro }); } - public getParent(): ConnectionProfileGroup { + public getParent(): ConnectionProfileGroup | undefined { return this.parent; } @@ -167,7 +168,7 @@ export class ConnectionProfileGroup extends Disposable implements IConnectionPro return isAncestor; } - public static getGroupFullNameParts(groupFullName: string): string[] { + public static getGroupFullNameParts(groupFullName?: string): string[] { groupFullName = groupFullName ? groupFullName : ''; let groupNames: string[] = groupFullName.split(ConnectionProfileGroup.GroupNameSeparator); groupNames = groupNames.filter(g => !!g); @@ -185,13 +186,19 @@ export class ConnectionProfileGroup extends Disposable implements IConnectionPro name === ConnectionProfileGroup.GroupNameSeparator); } - public static sameGroupName(name1: string, name2: string): boolean { - let sameGroupName: boolean = - (!name1 && !name2) || - name1.toUpperCase() === name2.toUpperCase() || - (ConnectionProfileGroup.isRoot(name1) && ConnectionProfileGroup.isRoot(name2)); - - return sameGroupName; + public static sameGroupName(name1?: string, name2?: string): boolean { + const isName1Undefined = isUndefinedOrNull(name1); + const isName2Undefined = isUndefinedOrNull(name2); + if (isName1Undefined && isName2Undefined) { + return true; + } + if ((isName1Undefined && !isName2Undefined) || !isName1Undefined && isName2Undefined) { + return false; + } + if (name1!.toUpperCase() === name2!.toUpperCase()) { + return true; + } + return ConnectionProfileGroup.isRoot(name1!) && ConnectionProfileGroup.isRoot(name2!); } public static getConnectionsInGroup(group: ConnectionProfileGroup): ConnectionProfile[] { diff --git a/src/sql/platform/connection/common/connectionStatusManager.ts b/src/sql/platform/connection/common/connectionStatusManager.ts index b70d6c04bb..437ef23333 100644 --- a/src/sql/platform/connection/common/connectionStatusManager.ts +++ b/src/sql/platform/connection/common/connectionStatusManager.ts @@ -27,7 +27,7 @@ export class ConnectionStatusManager { this._connections = {}; } - public findConnection(uri: string): ConnectionManagementInfo { + public findConnection(uri: string): ConnectionManagementInfo | undefined { if (uri in this._connections) { return this._connections[uri]; } else { @@ -39,7 +39,7 @@ export class ConnectionStatusManager { return Object.values(this._connections).find((connection: ConnectionManagementInfo) => connection.connectionProfile.id === profileId); } - public findConnectionProfile(connectionProfile: IConnectionProfile): ConnectionManagementInfo { + public findConnectionProfile(connectionProfile: IConnectionProfile): ConnectionManagementInfo | undefined { let id = Utils.generateUri(connectionProfile); return this.findConnection(id); } @@ -65,7 +65,7 @@ export class ConnectionStatusManager { } } - public getConnectionProfile(id: string): ConnectionProfile { + public getConnectionProfile(id: string): ConnectionProfile | undefined { let connectionInfoForId = this.findConnection(id); return connectionInfoForId ? connectionInfoForId.connectionProfile : undefined; } @@ -178,7 +178,7 @@ export class ConnectionStatusManager { return ownerUriToReturn; } - public onConnectionChanged(changedConnInfo: azdata.ChangedConnectionInfo): IConnectionProfile { + public onConnectionChanged(changedConnInfo: azdata.ChangedConnectionInfo): IConnectionProfile | undefined { let connection = this._connections[changedConnInfo.connectionUri]; if (connection && connection.connectionProfile) { connection.connectionProfile.serverName = changedConnInfo.connection.serverName; @@ -190,14 +190,14 @@ export class ConnectionStatusManager { } private isSharedSession(fileUri: string): boolean { - return fileUri && fileUri.startsWith('vsls:'); + return !!(fileUri && fileUri.startsWith('vsls:')); } public isConnected(id: string): boolean { if (this.isSharedSession(id)) { return true; } - return (id in this._connections && this._connections[id].connectionId && !!this._connections[id].connectionId); + return !!(id in this._connections && this._connections[id].connectionId && !!this._connections[id].connectionId); } public isConnecting(id: string): boolean { @@ -205,7 +205,7 @@ export class ConnectionStatusManager { } public isDefaultTypeUri(uri: string): boolean { - return uri && uri.startsWith(Utils.uriPrefixes.default); + return !!(uri && uri.startsWith(Utils.uriPrefixes.default)); } public getProviderIdFromUri(ownerUri: string): string { diff --git a/src/sql/platform/connection/common/connectionStore.ts b/src/sql/platform/connection/common/connectionStore.ts index 8c4f3d79d6..62db993a88 100644 --- a/src/sql/platform/connection/common/connectionStore.ts +++ b/src/sql/platform/connection/common/connectionStore.ts @@ -29,7 +29,7 @@ const CRED_PROFILE_USER = 'Profile'; * @export */ export class ConnectionStore { - private groupIdMap = new ReverseLookUpMap(); + private groupIdMap = new ReverseLookUpMap(); private connectionConfig = new ConnectionConfig(this.configurationService, this.capabilitiesService); private mru: Array; @@ -57,8 +57,7 @@ export class ConnectionStore { * @returns formatted string with server, DB and username */ private formatCredentialId(connectionProfile: IConnectionProfile, itemType?: string): string { - const connectionProfileInstance: ConnectionProfile = ConnectionProfile.fromIConnectionProfile( - this.capabilitiesService, connectionProfile); + const connectionProfileInstance = ConnectionProfile.fromIConnectionProfile(this.capabilitiesService, connectionProfile); const cred: string[] = [CRED_PREFIX]; if (!itemType) { itemType = CRED_PROFILE_USER; @@ -74,12 +73,8 @@ export class ConnectionStore { * @param connection profile */ public isPasswordRequired(connection: IConnectionProfile): boolean { - if (connection) { - const connectionProfile = ConnectionProfile.fromIConnectionProfile(this.capabilitiesService, connection); - return connectionProfile.isPasswordRequired(); - } else { - return false; - } + const connectionProfile = ConnectionProfile.fromIConnectionProfile(this.capabilitiesService, connection); + return connectionProfile.isPasswordRequired(); } public addSavedPassword(credentialsItem: IConnectionProfile): Promise<{ profile: IConnectionProfile, savedCred: boolean }> { @@ -162,34 +157,26 @@ export class ConnectionStore { private convertConfigValuesToConnectionProfiles(configValues: IConnectionProfile[]): ConnectionProfile[] { return configValues.map(c => { - if (c) { - const connectionProfile = new ConnectionProfile(this.capabilitiesService, c); - if (connectionProfile.saveProfile) { - if (!connectionProfile.groupFullName && connectionProfile.groupId) { - connectionProfile.groupFullName = this.getGroupFullName(connectionProfile.groupId); - } - if (!connectionProfile.groupId && connectionProfile.groupFullName) { - connectionProfile.groupId = this.getGroupId(connectionProfile.groupFullName); - } else if (!connectionProfile.groupId && !connectionProfile.groupFullName) { - connectionProfile.groupId = this.getGroupId(''); - } + const connectionProfile = new ConnectionProfile(this.capabilitiesService, c); + if (connectionProfile.saveProfile) { + if (!connectionProfile.groupFullName && connectionProfile.groupId) { + connectionProfile.groupFullName = this.getGroupFullName(connectionProfile.groupId); + } + if (!connectionProfile.groupId && connectionProfile.groupFullName) { + connectionProfile.groupId = this.getGroupId(connectionProfile.groupFullName); + } else if (!connectionProfile.groupId && !connectionProfile.groupFullName) { + connectionProfile.groupId = this.getGroupId(''); } - return connectionProfile; - } else { - return undefined; } + return connectionProfile; }); } public getProfileWithoutPassword(conn: IConnectionProfile): ConnectionProfile { - if (conn) { - let savedConn: ConnectionProfile = ConnectionProfile.fromIConnectionProfile(this.capabilitiesService, conn); - savedConn = savedConn.withoutPassword(); + let savedConn = ConnectionProfile.fromIConnectionProfile(this.capabilitiesService, conn); + savedConn = savedConn.withoutPassword(); - return savedConn; - } else { - return undefined; - } + return savedConn; } /** @@ -221,7 +208,7 @@ export class ConnectionStore { } private addToConnectionList(conn: IConnectionProfile, list: ConnectionProfile[]): IConnectionProfile[] { - const savedProfile: ConnectionProfile = this.getProfileWithoutPassword(conn); + const savedProfile = this.getProfileWithoutPassword(conn); // Remove the connection from the list if it already exists list = list.filter(value => { @@ -239,7 +226,7 @@ export class ConnectionStore { } private removeFromConnectionList(conn: IConnectionProfile, list: ConnectionProfile[]): IConnectionProfile[] { - const savedProfile: ConnectionProfile = this.getProfileWithoutPassword(conn); + const savedProfile = this.getProfileWithoutPassword(conn); // Remove the connection from the list if it already exists list = list.filter(value => { @@ -286,7 +273,7 @@ export class ConnectionStore { } public getConnectionProfileGroups(withoutConnections?: boolean, providers?: string[]): ConnectionProfileGroup[] { - let profilesInConfiguration: ConnectionProfile[]; + let profilesInConfiguration: ConnectionProfile[] | undefined; if (!withoutConnections) { profilesInConfiguration = this.connectionConfig.getConnections(true); if (providers && providers.length > 0) { @@ -295,10 +282,10 @@ export class ConnectionStore { } const groups = this.connectionConfig.getAllGroups(); - return this.convertToConnectionGroup(groups, profilesInConfiguration, undefined); + return this.convertToConnectionGroup(groups, profilesInConfiguration); } - private convertToConnectionGroup(groups: IConnectionProfileGroup[], connections: ConnectionProfile[], parent: ConnectionProfileGroup = undefined): ConnectionProfileGroup[] { + private convertToConnectionGroup(groups: IConnectionProfileGroup[], connections?: ConnectionProfile[], parent?: ConnectionProfileGroup): ConnectionProfileGroup[] { const result: ConnectionProfileGroup[] = []; const children = groups.filter(g => g.parentId === (parent ? parent.id : undefined)); if (children) { @@ -307,7 +294,7 @@ export class ConnectionStore { this.addGroupFullNameToMap(group.id, connectionGroup.fullName); if (connections) { let connectionsForGroup = connections.filter(conn => conn.groupId === connectionGroup.id); - let conns = []; + let conns: ConnectionProfile[] = []; connectionsForGroup.forEach((conn) => { conn.groupFullName = connectionGroup.fullName; conns.push(conn); @@ -359,7 +346,7 @@ export class ConnectionStore { return this.connectionConfig.changeGroupIdForConnection(source, targetGroupId).then(); } - private addGroupFullNameToMap(groupId: string, groupFullName: string): void { + private addGroupFullNameToMap(groupId: string, groupFullName?: string): void { if (groupId) { this.groupIdMap.set(groupId, groupFullName); } @@ -373,7 +360,7 @@ export class ConnectionStore { // Load the cache this.getConnectionProfileGroups(true); } - return this.groupIdMap.get(groupId); + return this.groupIdMap.get(groupId)!; } private getGroupId(groupFullName: string): string { @@ -385,6 +372,6 @@ export class ConnectionStore { // Load the cache this.getConnectionProfileGroups(true); } - return this.groupIdMap.reverseGet(key); + return this.groupIdMap.reverseGet(key)!; } } diff --git a/src/sql/platform/connection/common/utils.ts b/src/sql/platform/connection/common/utils.ts index b0916a6067..efa2bf09e5 100644 --- a/src/sql/platform/connection/common/utils.ts +++ b/src/sql/platform/connection/common/utils.ts @@ -115,7 +115,7 @@ export function generateUriWithPrefix(connection: IConnectionProfile, prefix: st return uri; } -export function findProfileInGroup(og: IConnectionProfile, groups: ConnectionProfileGroup[]): ConnectionProfile { +export function findProfileInGroup(og: IConnectionProfile, groups: ConnectionProfileGroup[]): ConnectionProfile | undefined { for (let group of groups) { for (let conn of group.connections) { if (conn.id === og.id) { diff --git a/src/sql/platform/query/common/gridDataProvider.ts b/src/sql/platform/query/common/gridDataProvider.ts index d7243b2dd0..d1969233df 100644 --- a/src/sql/platform/query/common/gridDataProvider.ts +++ b/src/sql/platform/query/common/gridDataProvider.ts @@ -34,7 +34,7 @@ export interface IGridDataProvider { shouldRemoveNewLines(): boolean; - getColumnHeaders(range: Slick.Range): string[]; + getColumnHeaders(range: Slick.Range): string[] | undefined; readonly canSerialize: boolean; diff --git a/src/sql/platform/query/common/queryManagement.ts b/src/sql/platform/query/common/queryManagement.ts index 71c251009c..c3611e9aec 100644 --- a/src/sql/platform/query/common/queryManagement.ts +++ b/src/sql/platform/query/common/queryManagement.ts @@ -29,16 +29,16 @@ export interface IQueryManagementService { getRegisteredProviders(): string[]; registerRunner(runner: QueryRunner, uri: string): void; - cancelQuery(ownerUri: string): Thenable; - runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable; - runQueryStatement(ownerUri: string, line: number, column: number): Thenable; - runQueryString(ownerUri: string, queryString: string): Thenable; - runQueryAndReturn(ownerUri: string, queryString: string): Thenable; - parseSyntax(ownerUri: string, query: string): Thenable; - getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable; - disposeQuery(ownerUri: string): Thenable; - saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable; - setQueryExecutionOptions(uri: string, options: azdata.QueryExecutionOptions): Thenable; + cancelQuery(ownerUri: string): Promise; + runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise; + runQueryStatement(ownerUri: string, line: number, column: number): Promise; + runQueryString(ownerUri: string, queryString: string): Promise; + runQueryAndReturn(ownerUri: string, queryString: string): Promise; + parseSyntax(ownerUri: string, query: string): Promise; + getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise; + disposeQuery(ownerUri: string): Promise; + saveResults(requestParams: azdata.SaveResultsRequestParams): Promise; + setQueryExecutionOptions(uri: string, options: azdata.QueryExecutionOptions): Promise; // Callbacks onQueryComplete(result: azdata.QueryExecuteCompleteNotificationResult): void; @@ -52,42 +52,42 @@ export interface IQueryManagementService { onEditSessionReady(ownerUri: string, success: boolean, message: string): void; // Edit Data Functions - initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable; - disposeEdit(ownerUri: string): Thenable; - updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable; - commitEdit(ownerUri): Thenable; - createRow(ownerUri: string): Thenable; - deleteRow(ownerUri: string, rowId: number): Thenable; - revertCell(ownerUri: string, rowId: number, columnId: number): Thenable; - revertRow(ownerUri: string, rowId: number): Thenable; - getEditRows(rowData: azdata.EditSubsetParams): Thenable; + initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise; + disposeEdit(ownerUri: string): Promise; + updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise; + commitEdit(ownerUri: string): Promise; + createRow(ownerUri: string): Promise; + deleteRow(ownerUri: string, rowId: number): Promise; + revertCell(ownerUri: string, rowId: number, columnId: number): Promise; + revertRow(ownerUri: string, rowId: number): Promise; + getEditRows(rowData: azdata.EditSubsetParams): Promise; } /* * An object that can handle basic request-response actions related to queries */ export interface IQueryRequestHandler { - cancelQuery(ownerUri: string): Thenable; - runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable; - runQueryStatement(ownerUri: string, line: number, column: number): Thenable; - runQueryString(ownerUri: string, queryString: string): Thenable; - runQueryAndReturn(ownerUri: string, queryString: string): Thenable; - parseSyntax(ownerUri: string, query: string): Thenable; - getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable; - disposeQuery(ownerUri: string): Thenable; - saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable; - setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable; + cancelQuery(ownerUri: string): Promise; + runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise; + runQueryStatement(ownerUri: string, line: number, column: number): Promise; + runQueryString(ownerUri: string, queryString: string): Promise; + runQueryAndReturn(ownerUri: string, queryString: string): Promise; + parseSyntax(ownerUri: string, query: string): Promise; + getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise; + disposeQuery(ownerUri: string): Promise; + saveResults(requestParams: azdata.SaveResultsRequestParams): Promise; + setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Promise; // Edit Data actions - initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable; - disposeEdit(ownerUri: string): Thenable; - updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable; - commitEdit(ownerUri): Thenable; - createRow(ownerUri: string): Thenable; - deleteRow(ownerUri: string, rowId: number): Thenable; - revertCell(ownerUri: string, rowId: number, columnId: number): Thenable; - revertRow(ownerUri: string, rowId: number): Thenable; - getEditRows(rowData: azdata.EditSubsetParams): Thenable; + initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise; + disposeEdit(ownerUri: string): Promise; + updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise; + commitEdit(ownerUri: string): Promise; + createRow(ownerUri: string): Promise; + deleteRow(ownerUri: string, rowId: number): Promise; + revertCell(ownerUri: string, rowId: number, columnId: number): Promise; + revertRow(ownerUri: string, rowId: number): Promise; + getEditRows(rowData: azdata.EditSubsetParams): Promise; } export class QueryManagementService implements IQueryManagementService { @@ -117,7 +117,7 @@ export class QueryManagementService implements IQueryManagementService { // _handlerCallbackQueue will be non-empty. Run all handlers in the queue first // so that notifications are handled in order they arrived while (this._handlerCallbackQueue.length > 0) { - let handler = this._handlerCallbackQueue.shift(); + let handler = this._handlerCallbackQueue.shift()!; handler(runner); } @@ -141,7 +141,7 @@ export class QueryManagementService implements IQueryManagementService { private _notify(ownerUri: string, sendNotification: (runner: QueryRunner) => void): void { let runner = this._queryRunners.get(ownerUri); - this.enqueueOrRun(sendNotification, runner); + this.enqueueOrRun(sendNotification, runner!); } public addQueryRequestHandler(queryType: string, handler: IQueryRequestHandler): IDisposable { @@ -181,7 +181,7 @@ export class QueryManagementService implements IQueryManagementService { TelemetryUtils.addTelemetry(this._telemetryService, this.logService, eventName, data); } - private _runAction(uri: string, action: (handler: IQueryRequestHandler) => Thenable, fallBackToDefaultProvider: boolean = false): Thenable { + private _runAction(uri: string, action: (handler: IQueryRequestHandler) => Promise, fallBackToDefaultProvider: boolean = false): Promise { let providerId: string = this._connectionService.getProviderIdFromUri(uri); if (!providerId && fallBackToDefaultProvider) { @@ -199,58 +199,58 @@ export class QueryManagementService implements IQueryManagementService { } } - public cancelQuery(ownerUri: string): Thenable { + public cancelQuery(ownerUri: string): Promise { this.addTelemetry(TelemetryKeys.CancelQuery, ownerUri); return this._runAction(ownerUri, (runner) => { return runner.cancelQuery(ownerUri); }); } - public runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable { + public runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise { this.addTelemetry(TelemetryKeys.RunQuery, ownerUri, runOptions); return this._runAction(ownerUri, (runner) => { return runner.runQuery(ownerUri, selection, runOptions); }); } - public runQueryStatement(ownerUri: string, line: number, column: number): Thenable { + public runQueryStatement(ownerUri: string, line: number, column: number): Promise { this.addTelemetry(TelemetryKeys.RunQueryStatement, ownerUri); return this._runAction(ownerUri, (runner) => { return runner.runQueryStatement(ownerUri, line, column); }); } - public runQueryString(ownerUri: string, queryString: string): Thenable { + public runQueryString(ownerUri: string, queryString: string): Promise { this.addTelemetry(TelemetryKeys.RunQueryString, ownerUri); return this._runAction(ownerUri, (runner) => { return runner.runQueryString(ownerUri, queryString); }); } - public runQueryAndReturn(ownerUri: string, queryString: string): Thenable { + public runQueryAndReturn(ownerUri: string, queryString: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.runQueryAndReturn(ownerUri, queryString); }); } - public parseSyntax(ownerUri: string, query: string): Thenable { + public parseSyntax(ownerUri: string, query: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.parseSyntax(ownerUri, query); }); } - public getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable { + public getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise { return this._runAction(rowData.ownerUri, (runner) => { return runner.getQueryRows(rowData); }); } - public disposeQuery(ownerUri: string): Thenable { + public disposeQuery(ownerUri: string): Promise { this._queryRunners.delete(ownerUri); return this._runAction(ownerUri, (runner) => { return runner.disposeQuery(ownerUri); }); } - public setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { + public setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Promise { return this._runAction(ownerUri, (runner) => { return runner.setQueryExecutionOptions(ownerUri, options); }, true); } - public saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable { + public saveResults(requestParams: azdata.SaveResultsRequestParams): Promise { return this._runAction(requestParams.ownerUri, (runner) => { return runner.saveResults(requestParams); }); @@ -292,7 +292,7 @@ export class QueryManagementService implements IQueryManagementService { } // Edit Data Functions - public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable { + public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.initializeEdit(ownerUri, schemaName, objectName, objectType, rowLimit, queryString); }); @@ -304,49 +304,49 @@ export class QueryManagementService implements IQueryManagementService { }); } - public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { + public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.updateCell(ownerUri, rowId, columnId, newValue); }); } - public commitEdit(ownerUri: string): Thenable { + public commitEdit(ownerUri: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.commitEdit(ownerUri); }); } - public createRow(ownerUri: string): Thenable { + public createRow(ownerUri: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.createRow(ownerUri); }); } - public deleteRow(ownerUri: string, rowId: number): Thenable { + public deleteRow(ownerUri: string, rowId: number): Promise { return this._runAction(ownerUri, (runner) => { return runner.deleteRow(ownerUri, rowId); }); } - public disposeEdit(ownerUri: string): Thenable { + public disposeEdit(ownerUri: string): Promise { return this._runAction(ownerUri, (runner) => { return runner.disposeEdit(ownerUri); }); } - public revertCell(ownerUri: string, rowId: number, columnId: number): Thenable { + public revertCell(ownerUri: string, rowId: number, columnId: number): Promise { return this._runAction(ownerUri, (runner) => { return runner.revertCell(ownerUri, rowId, columnId); }); } - public revertRow(ownerUri: string, rowId: number): Thenable { + public revertRow(ownerUri: string, rowId: number): Promise { return this._runAction(ownerUri, (runner) => { return runner.revertRow(ownerUri, rowId); }); } - public getEditRows(rowData: azdata.EditSubsetParams): Thenable { + public getEditRows(rowData: azdata.EditSubsetParams): Promise { return this._runAction(rowData.ownerUri, (runner) => { return runner.getEditRows(rowData); }); diff --git a/src/sql/platform/query/common/queryModel.ts b/src/sql/platform/query/common/queryModel.ts index d488f7607e..51d299c6aa 100644 --- a/src/sql/platform/query/common/queryModel.ts +++ b/src/sql/platform/query/common/queryModel.ts @@ -49,14 +49,12 @@ export interface IQueryEvent { export interface IQueryModelService { _serviceBrand: undefined; - getQueryRunner(uri: string): QueryRunner; + getQueryRunner(uri: string): QueryRunner | undefined; - getConfig(): Promise<{ [key: string]: any }>; - getShortcuts(): Promise; - getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Thenable; - runQuery(uri: string, selection: ISelectionData, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void; - runQueryStatement(uri: string, selection: ISelectionData, queryInput: QueryInput): void; - runQueryString(uri: string, selection: string, queryInput: QueryInput); + getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Promise; + runQuery(uri: string, selection: ISelectionData | undefined, queryInput: QueryInput, runOptions?: ExecutionPlanOptions): void; + runQueryStatement(uri: string, selection: ISelectionData | undefined, queryInput: QueryInput): void; + runQueryString(uri: string, selection: string | undefined, queryInput: QueryInput): void; cancelQuery(input: QueryRunner | string): void; disposeQuery(uri: string): void; isRunningQuery(uri: string): boolean; @@ -80,16 +78,16 @@ export interface IQueryModelService { // Edit Data Functions initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): void; - disposeEdit(ownerUri: string): Thenable; - updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable; - commitEdit(ownerUri): Thenable; - createRow(ownerUri: string): Thenable; - deleteRow(ownerUri: string, rowId: number): Thenable; - revertCell(ownerUri: string, rowId: number, columnId: number): Thenable; - revertRow(ownerUri: string, rowId: number): Thenable; - getEditRows(ownerUri: string, rowStart: number, numberOfRows: number): Thenable; + disposeEdit(ownerUri: string): Promise; + updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise; + commitEdit(ownerUri: string): Promise; + createRow(ownerUri: string): Promise; + deleteRow(ownerUri: string, rowId: number): Promise; + revertCell(ownerUri: string, rowId: number, columnId: number): Promise; + revertRow(ownerUri: string, rowId: number): Promise; + getEditRows(ownerUri: string, rowStart: number, numberOfRows: number): Promise; - _getQueryInfo(uri: string): QueryInfo; + _getQueryInfo(uri: string): QueryInfo | undefined; // Edit Data Callbacks onEditSessionReady: Event; } diff --git a/src/sql/platform/query/common/queryModelService.ts b/src/sql/platform/query/common/queryModelService.ts index f7afe2df08..aa4eb674e7 100644 --- a/src/sql/platform/query/common/queryModelService.ts +++ b/src/sql/platform/query/common/queryModelService.ts @@ -36,7 +36,7 @@ export class QueryInfo { public queryEventQueue: QueryEvent[]; public selection: Array; public queryInput: QueryInput; - public selectionSnippet: string; + public selectionSnippet?: string; // Notes if the angular components have obtained the DataService. If not, all messages sent // via the data service will be lost. @@ -85,7 +85,10 @@ export class QueryModelService implements IQueryModelService { // IQUERYMODEL ///////////////////////////////////////////////////////// public getDataService(uri: string): DataService { - let dataService = this._getQueryInfo(uri).dataService; + let dataService: DataService | undefined; + if (this._queryInfoMap.has(uri)) { + dataService = this._getQueryInfo(uri)!.dataService; + } if (!dataService) { throw new Error('Could not find data service for uri: ' + uri); } @@ -119,40 +122,44 @@ export class QueryModelService implements IQueryModelService { * angular is listening for them. */ public onAngularLoaded(uri: string) { - let info = this._getQueryInfo(uri); - info.dataServiceReady = true; - this._sendQueuedEvents(uri); + if (this._queryInfoMap.has(uri)) { + let info = this._getQueryInfo(uri)!; + info.dataServiceReady = true; + this._sendQueuedEvents(uri); + } } /** * Get more data rows from the current resultSets from the service layer */ - public getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Thenable { - return this._getQueryInfo(uri).queryRunner.getQueryRows(rowStart, numberOfRows, batchId, resultId).then(results => { - return results.resultSubset; - }); + public getQueryRows(uri: string, rowStart: number, numberOfRows: number, batchId: number, resultId: number): Promise { + if (this._queryInfoMap.has(uri)) { + return this._getQueryInfo(uri)!.queryRunner.getQueryRows(rowStart, numberOfRows, batchId, resultId).then(results => { + return results.resultSubset; + }); + } else { + return Promise.resolve(undefined); + } } - public getEditRows(uri: string, rowStart: number, numberOfRows: number): Thenable { - return this._queryInfoMap.get(uri).queryRunner.getEditRows(rowStart, numberOfRows).then(results => { - return results; - }); - } - - public getConfig(): Promise<{ [key: string]: any }> { - return undefined; - } - - public getShortcuts(): Promise { - return undefined; + public getEditRows(uri: string, rowStart: number, numberOfRows: number): Promise { + if (this._queryInfoMap.has(uri)) { + return this._queryInfoMap.get(uri)!.queryRunner.getEditRows(rowStart, numberOfRows).then(results => { + return results; + }); + } else { + return Promise.resolve(undefined); + } } public copyResults(uri: string, selection: Slick.Range[], batchId: number, resultId: number, includeHeaders?: boolean): void { - this._queryInfoMap.get(uri).queryRunner.copyResults(selection, batchId, resultId, includeHeaders); + if (this._queryInfoMap.has(uri)) { + this._queryInfoMap.get(uri)!.queryRunner.copyResults(selection, batchId, resultId, includeHeaders); + } } public setEditorSelection(uri: string, index: number): void { - let info: QueryInfo = this._queryInfoMap.get(uri); + let info = this._queryInfoMap.get(uri); if (info && info.queryInput) { info.queryInput.updateSelection(info.selection[index]); } @@ -174,7 +181,7 @@ export class QueryModelService implements IQueryModelService { public isRunningQuery(uri: string): boolean { return !this._queryInfoMap.has(uri) ? false - : this._getQueryInfo(uri).queryRunner.isExecuting; + : this._getQueryInfo(uri)!.queryRunner.isExecuting; } /** @@ -204,11 +211,11 @@ export class QueryModelService implements IQueryModelService { private doRunQuery(uri: string, selection: azdata.ISelectionData | string, queryInput: QueryInput, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): void { // Reuse existing query runner if it exists - let queryRunner: QueryRunner; + let queryRunner: QueryRunner | undefined; let info: QueryInfo; if (this._queryInfoMap.has(uri)) { - info = this._getQueryInfo(uri); + info = this._getQueryInfo(uri)!; let existingRunner: QueryRunner = info.queryRunner; // If the query is already in progress, don't attempt to send it @@ -365,11 +372,11 @@ export class QueryModelService implements IQueryModelService { } public cancelQuery(input: QueryRunner | string): void { - let queryRunner: QueryRunner; + let queryRunner: QueryRunner | undefined; if (typeof input === 'string') { if (this._queryInfoMap.has(input)) { - queryRunner = this._getQueryInfo(input).queryRunner; + queryRunner = this._getQueryInfo(input)!.queryRunner; } } else { queryRunner = input; @@ -391,7 +398,7 @@ export class QueryModelService implements IQueryModelService { severity: Severity.Error, message: strings.format(LocalizedConstants.msgCancelQueryFailed, error) }); - this._fireQueryEvent(queryRunner.uri, 'complete', 0); + this._fireQueryEvent(queryRunner!.uri, 'complete', 0); }); } @@ -415,7 +422,7 @@ export class QueryModelService implements IQueryModelService { let info: QueryInfo; if (this._queryInfoMap.has(ownerUri)) { - info = this._getQueryInfo(ownerUri); + info = this._getQueryInfo(ownerUri)!; let existingRunner: QueryRunner = info.queryRunner; // If the initialization is already in progress @@ -522,16 +529,16 @@ export class QueryModelService implements IQueryModelService { // TODO: Implement query cancellation service } - public disposeEdit(ownerUri: string): Thenable { + public disposeEdit(ownerUri: string): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { return queryRunner.disposeEdit(ownerUri); } - return Promise.resolve(null); + return Promise.resolve(); } - public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { + public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { @@ -543,10 +550,10 @@ export class QueryModelService implements IQueryModelService { return Promise.reject(error); }); } - return Promise.resolve(null); + return Promise.resolve(undefined); } - public commitEdit(ownerUri): Thenable { + public commitEdit(ownerUri: string): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { @@ -558,49 +565,49 @@ export class QueryModelService implements IQueryModelService { return Promise.reject(error); }); } - return Promise.resolve(null); + return Promise.resolve(); } - public createRow(ownerUri: string): Thenable { + public createRow(ownerUri: string): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { return queryRunner.createRow(ownerUri); } - return Promise.resolve(null); + return Promise.resolve(undefined); } - public deleteRow(ownerUri: string, rowId: number): Thenable { + public deleteRow(ownerUri: string, rowId: number): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { return queryRunner.deleteRow(ownerUri, rowId); } - return Promise.resolve(null); + return Promise.resolve(); } - public revertCell(ownerUri: string, rowId: number, columnId: number): Thenable { + public revertCell(ownerUri: string, rowId: number, columnId: number): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { return queryRunner.revertCell(ownerUri, rowId, columnId); } - return Promise.resolve(null); + return Promise.resolve(undefined); } - public revertRow(ownerUri: string, rowId: number): Thenable { + public revertRow(ownerUri: string, rowId: number): Promise { // Get existing query runner let queryRunner = this.internalGetQueryRunner(ownerUri); if (queryRunner) { return queryRunner.revertRow(ownerUri, rowId); } - return Promise.resolve(null); + return Promise.resolve(); } - public getQueryRunner(ownerUri): QueryRunner { - let queryRunner: QueryRunner = undefined; + public getQueryRunner(ownerUri: string): QueryRunner | undefined { + let queryRunner: QueryRunner | undefined = undefined; if (this._queryInfoMap.has(ownerUri)) { - queryRunner = this._getQueryInfo(ownerUri).queryRunner; + queryRunner = this._getQueryInfo(ownerUri)!.queryRunner; } // return undefined if not found or is already executing return queryRunner; @@ -608,13 +615,13 @@ export class QueryModelService implements IQueryModelService { // PRIVATE METHODS ////////////////////////////////////////////////////// - private internalGetQueryRunner(ownerUri): QueryRunner { - let queryRunner: QueryRunner = undefined; + private internalGetQueryRunner(ownerUri: string): QueryRunner | undefined { + let queryRunner: QueryRunner | undefined; if (this._queryInfoMap.has(ownerUri)) { - let existingRunner = this._getQueryInfo(ownerUri).queryRunner; + let existingRunner = this._getQueryInfo(ownerUri)!.queryRunner; // If the query is not already executing then set it up if (!existingRunner.isExecuting) { - queryRunner = this._getQueryInfo(ownerUri).queryRunner; + queryRunner = this._getQueryInfo(ownerUri)!.queryRunner; } } // return undefined if not found or is already executing @@ -622,7 +629,7 @@ export class QueryModelService implements IQueryModelService { } private _fireGridContentEvent(uri: string, type: string): void { - let info: QueryInfo = this._getQueryInfo(uri); + let info = this._getQueryInfo(uri); if (info && info.dataServiceReady) { let service: DataService = this.getDataService(uri); @@ -635,29 +642,29 @@ export class QueryModelService implements IQueryModelService { } private _fireQueryEvent(uri: string, type: string, data?: any) { - let info: QueryInfo = this._getQueryInfo(uri); + let info = this._getQueryInfo(uri); - if (info.dataServiceReady) { + if (info && info.dataServiceReady) { let service: DataService = this.getDataService(uri); service.queryEventObserver.next({ type: type, data: data }); - } else { + } else if (info) { let queueItem: QueryEvent = { type: type, data: data }; info.queryEventQueue.push(queueItem); } } private _sendQueuedEvents(uri: string): void { - let info: QueryInfo = this._getQueryInfo(uri); - while (info.queryEventQueue.length > 0) { - let event: QueryEvent = info.queryEventQueue.shift(); + let info = this._getQueryInfo(uri); + while (info && info.queryEventQueue.length > 0) { + let event = info.queryEventQueue.shift()!; this._fireQueryEvent(uri, event.type, event.data); } } - public _getQueryInfo(uri: string): QueryInfo { + public _getQueryInfo(uri: string): QueryInfo | undefined { return this._queryInfoMap.get(uri); } diff --git a/src/sql/platform/query/common/queryRunner.ts b/src/sql/platform/query/common/queryRunner.ts index 1cfbc6fe34..3d6e81910f 100644 --- a/src/sql/platform/query/common/queryRunner.ts +++ b/src/sql/platform/query/common/queryRunner.ts @@ -55,7 +55,7 @@ export default class QueryRunner extends Disposable { private _isQueryPlan: boolean = false; public get isQueryPlan(): boolean { return this._isQueryPlan; } private _planXml = new Deferred(); - public get planXml(): Thenable { return this._planXml.promise; } + public get planXml(): Promise { return this._planXml.promise; } private _onMessage = this._register(new Emitter()); public get onMessage(): Event { return this._onMessage.event; } // this is the only way typemoq can moq this... needs investigation @todo anthonydresser 5/2/2019 @@ -87,12 +87,12 @@ export default class QueryRunner extends Disposable { private _onVisualize = this._register(new Emitter()); public readonly onVisualize = this._onVisualize.event; - private _queryStartTime: Date; - public get queryStartTime(): Date { + private _queryStartTime?: Date; + public get queryStartTime(): Date | undefined { return this._queryStartTime; } - private _queryEndTime: Date; - public get queryEndTime(): Date { + private _queryEndTime?: Date; + public get queryEndTime(): Date | undefined { return this._queryEndTime; } @@ -135,7 +135,7 @@ export default class QueryRunner extends Disposable { /** * Cancels the running query, if there is one */ - public cancelQuery(): Thenable { + public cancelQuery(): Promise { return this._queryManagementService.cancelQuery(this.uri); } @@ -143,21 +143,25 @@ export default class QueryRunner extends Disposable { * Runs the query with the provided query * @param input Query string to execute */ - public runQuery(input: string, runOptions?: azdata.ExecutionPlanOptions): Thenable; + public runQuery(input: string, runOptions?: azdata.ExecutionPlanOptions): Promise; /** * Runs the query by pulling the query from the document using the provided selection data * @param input selection data */ - public runQuery(input: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable; - public runQuery(input, runOptions?: azdata.ExecutionPlanOptions): Thenable { - return this.doRunQuery(input, false, runOptions); + public runQuery(input: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise; + public runQuery(input: string | azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise { + if (types.isString(input)) { + return this.doRunQuery(input, false, runOptions); + } else { + return this.doRunQuery(input, false, runOptions); + } } /** * Runs the current SQL statement by pulling the query from the document using the provided selection data * @param input selection data */ - public runQueryStatement(input: azdata.ISelectionData): Thenable { + public runQueryStatement(input: azdata.ISelectionData): Promise { return this.doRunQuery(input, true); } @@ -165,11 +169,11 @@ export default class QueryRunner extends Disposable { * Implementation that runs the query with the provided query * @param input Query string to execute */ - private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable; - private doRunQuery(input: azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable; - private doRunQuery(input, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Thenable { + private doRunQuery(input: string, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise; + private doRunQuery(input: azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise; + private doRunQuery(input: string | azdata.ISelectionData, runCurrentStatement: boolean, runOptions?: azdata.ExecutionPlanOptions): Promise { if (this.isExecuting) { - return Promise.resolve(undefined); + return Promise.resolve(); } this._planXml = new Deferred(); this._batchSets = []; @@ -177,7 +181,7 @@ export default class QueryRunner extends Disposable { this._queryStartTime = undefined; this._queryEndTime = undefined; this._messages = []; - if (types.isObject(input) || types.isUndefinedOrNull(input)) { + if (isSelectionOrUndefined(input)) { // Update internal state to show that we're executing the query this._resultLineOffset = input ? input.startLine : 0; this._resultColumnOffset = input ? input.startColumn : 0; @@ -191,7 +195,7 @@ export default class QueryRunner extends Disposable { return runCurrentStatement ? this._queryManagementService.runQueryStatement(this.uri, input.startLine, input.startColumn).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e)) : this._queryManagementService.runQuery(this.uri, input, runOptions).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e)); - } else if (types.isString(input)) { + } else { // Update internal state to show that we're executing the query this._isExecuting = true; this._totalElapsedMilliseconds = 0; @@ -199,8 +203,6 @@ export default class QueryRunner extends Disposable { this._onQueryStart.fire(); return this._queryManagementService.runQueryString(this.uri, input).then(() => this.handleSuccessRunQueryResult(), e => this.handleFailureRunQueryResult(e)); - } else { - return Promise.reject('Unknown input'); } } @@ -329,7 +331,7 @@ export default class QueryRunner extends Disposable { if (this._batchSets.length > 0) { batchSet = this._batchSets[0]; } else { - batchSet = { + batchSet = { id: 0, selection: undefined, hasError: false, @@ -399,7 +401,7 @@ export default class QueryRunner extends Disposable { */ public handleMessage(obj: azdata.QueryExecuteMessageParams): void { let message = obj.message; - message.time = new Date(message.time).toLocaleTimeString(); + message.time = new Date(message.time!).toLocaleTimeString(); this._messages.push(message); // Send the message to the results pane @@ -409,7 +411,7 @@ export default class QueryRunner extends Disposable { /** * Get more data rows from the current resultSets from the service layer */ - public getQueryRows(rowStart: number, numberOfRows: number, batchIndex: number, resultSetIndex: number): Thenable { + public getQueryRows(rowStart: number, numberOfRows: number, batchIndex: number, resultSetIndex: number): Promise { let rowData: azdata.QueryExecuteSubsetParams = { ownerUri: this.uri, resultSetIndex: resultSetIndex, @@ -430,7 +432,7 @@ export default class QueryRunner extends Disposable { /* * Handle a session ready event for Edit Data */ - public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable { + public initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise { // Update internal state to show that we're executing the query this._isExecuting = true; this._totalElapsedMilliseconds = 0; @@ -454,7 +456,7 @@ export default class QueryRunner extends Disposable { * @param rowStart The index of the row to start returning (inclusive) * @param numberOfRows The number of rows to return */ - public getEditRows(rowStart: number, numberOfRows: number): Thenable { + public getEditRows(rowStart: number, numberOfRows: number): Promise { const self = this; let rowData: azdata.EditSubsetParams = { ownerUri: this.uri, @@ -488,35 +490,35 @@ export default class QueryRunner extends Disposable { this._onEditSessionReady.fire({ ownerUri, success, message }); } - public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { + public updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise { return this._queryManagementService.updateCell(ownerUri, rowId, columnId, newValue); } - public commitEdit(ownerUri): Thenable { + public commitEdit(ownerUri: string): Promise { return this._queryManagementService.commitEdit(ownerUri); } - public createRow(ownerUri: string): Thenable { + public createRow(ownerUri: string): Promise { return this._queryManagementService.createRow(ownerUri).then(result => { return result; }); } - public deleteRow(ownerUri: string, rowId: number): Thenable { + public deleteRow(ownerUri: string, rowId: number): Promise { return this._queryManagementService.deleteRow(ownerUri, rowId); } - public revertCell(ownerUri: string, rowId: number, columnId: number): Thenable { + public revertCell(ownerUri: string, rowId: number, columnId: number): Promise { return this._queryManagementService.revertCell(ownerUri, rowId, columnId).then(result => { return result; }); } - public revertRow(ownerUri: string, rowId: number): Thenable { + public revertRow(ownerUri: string, rowId: number): Promise { return this._queryManagementService.revertRow(ownerUri, rowId); } - public disposeEdit(ownerUri: string): Thenable { + public disposeEdit(ownerUri: string): Promise { return this._queryManagementService.disposeEdit(ownerUri); } @@ -530,7 +532,7 @@ export default class QueryRunner extends Disposable { } public dispose() { - this._batchSets = undefined; + this._batchSets = undefined!; super.dispose(); } @@ -551,8 +553,8 @@ export default class QueryRunner extends Disposable { } - public getColumnHeaders(batchId: number, resultId: number, range: Slick.Range): string[] { - let headers: string[] = undefined; + public getColumnHeaders(batchId: number, resultId: number, range: Slick.Range): string[] | undefined { + let headers: string[] | undefined = undefined; let batchSummary: azdata.BatchSummary = this._batchSets[batchId]; if (batchSummary !== undefined) { let resultSetSummary = batchSummary.resultSetSummaries[resultId]; @@ -612,7 +614,7 @@ export class QueryGridDataProvider implements IGridDataProvider { ) { } - getRowData(rowStart: number, numberOfRows: number): Thenable { + getRowData(rowStart: number, numberOfRows: number): Promise { return this.queryRunner.getQueryRows(rowStart, numberOfRows, this.batchId, this.resultSetId); } @@ -637,7 +639,7 @@ export class QueryGridDataProvider implements IGridDataProvider { shouldRemoveNewLines(): boolean { return shouldRemoveNewLines(this._configurationService); } - getColumnHeaders(range: Slick.Range): string[] { + getColumnHeaders(range: Slick.Range): string[] | undefined { return this.queryRunner.getColumnHeaders(this.batchId, this.resultSetId, range); } @@ -645,7 +647,7 @@ export class QueryGridDataProvider implements IGridDataProvider { return true; } - serializeResults(format: SaveFormat, selection: Slick.Range[]): Thenable { + serializeResults(format: SaveFormat, selection: Slick.Range[]): Promise { return this.queryRunner.serializeResults(this.batchId, this.resultSetId, format, selection); } } @@ -670,3 +672,7 @@ export function shouldRemoveNewLines(configurationService: IConfigurationService let removeNewLines = configurationService.getValue('sql.copyRemoveNewLine'); return !!removeNewLines; } + +function isSelectionOrUndefined(input: string | azdata.ISelectionData | undefined): input is azdata.ISelectionData | undefined { + return types.isObject(input) || types.isUndefinedOrNull(input); +} diff --git a/src/sql/sqlops.d.ts b/src/sql/sqlops.d.ts index aba9d0c353..1f3a607c27 100644 --- a/src/sql/sqlops.d.ts +++ b/src/sql/sqlops.d.ts @@ -215,7 +215,7 @@ declare module 'sqlops' { password: string; authenticationType: string; savePassword: boolean; - groupFullName: string; + groupFullName?: string; groupId: string; providerName: string; saveProfile: boolean; diff --git a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts index 97eb6628f3..52f8da455a 100644 --- a/src/sql/workbench/api/browser/mainThreadDataProtocol.ts +++ b/src/sql/workbench/api/browser/mainThreadDataProtocol.ts @@ -97,71 +97,71 @@ export class MainThreadDataProtocol extends Disposable implements MainThreadData public $registerQueryProvider(providerId: string, handle: number): Promise { const self = this; this._queryManagementService.addQueryRequestHandler(providerId, { - cancelQuery(ownerUri: string): Thenable { - return self._proxy.$cancelQuery(handle, ownerUri); + cancelQuery(ownerUri: string): Promise { + return Promise.resolve(self._proxy.$cancelQuery(handle, ownerUri)); }, - runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Thenable { - return self._proxy.$runQuery(handle, ownerUri, selection, runOptions); + runQuery(ownerUri: string, selection: azdata.ISelectionData, runOptions?: azdata.ExecutionPlanOptions): Promise { + return Promise.resolve(self._proxy.$runQuery(handle, ownerUri, selection, runOptions)); }, - runQueryStatement(ownerUri: string, line: number, column: number): Thenable { - return self._proxy.$runQueryStatement(handle, ownerUri, line, column); + runQueryStatement(ownerUri: string, line: number, column: number): Promise { + return Promise.resolve(self._proxy.$runQueryStatement(handle, ownerUri, line, column)); }, - runQueryString(ownerUri: string, queryString: string): Thenable { - return self._proxy.$runQueryString(handle, ownerUri, queryString); + runQueryString(ownerUri: string, queryString: string): Promise { + return Promise.resolve(self._proxy.$runQueryString(handle, ownerUri, queryString)); }, - runQueryAndReturn(ownerUri: string, queryString: string): Thenable { - return self._proxy.$runQueryAndReturn(handle, ownerUri, queryString); + runQueryAndReturn(ownerUri: string, queryString: string): Promise { + return Promise.resolve(self._proxy.$runQueryAndReturn(handle, ownerUri, queryString)); }, - parseSyntax(ownerUri: string, query: string): Thenable { - return self._proxy.$parseSyntax(handle, ownerUri, query); + parseSyntax(ownerUri: string, query: string): Promise { + return Promise.resolve(self._proxy.$parseSyntax(handle, ownerUri, query)); }, - getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Thenable { - return self._proxy.$getQueryRows(handle, rowData); + getQueryRows(rowData: azdata.QueryExecuteSubsetParams): Promise { + return Promise.resolve(self._proxy.$getQueryRows(handle, rowData)); }, - setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Thenable { - return self._proxy.$setQueryExecutionOptions(handle, ownerUri, options); + setQueryExecutionOptions(ownerUri: string, options: azdata.QueryExecutionOptions): Promise { + return Promise.resolve(self._proxy.$setQueryExecutionOptions(handle, ownerUri, options)); }, - disposeQuery(ownerUri: string): Thenable { - return self._proxy.$disposeQuery(handle, ownerUri); + disposeQuery(ownerUri: string): Promise { + return Promise.resolve(self._proxy.$disposeQuery(handle, ownerUri)); }, - saveResults(requestParams: azdata.SaveResultsRequestParams): Thenable { + saveResults(requestParams: azdata.SaveResultsRequestParams): Promise { let saveResultsFeatureInfo = self._serializationService.getSaveResultsFeatureMetadataProvider(requestParams.ownerUri); if (saveResultsFeatureInfo && saveResultsFeatureInfo.enabled) { - return self._proxy.$saveResults(handle, requestParams); + return Promise.resolve(self._proxy.$saveResults(handle, requestParams)); } else if (saveResultsFeatureInfo && !saveResultsFeatureInfo.enabled) { - return self._serializationService.disabledSaveAs(); + return Promise.resolve(self._serializationService.disabledSaveAs()); } else { - return self._serializationService.saveAs(requestParams.resultFormat, requestParams.filePath, undefined, true); + return Promise.resolve(self._serializationService.saveAs(requestParams.resultFormat, requestParams.filePath, undefined, true)); } }, - initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Thenable { - return self._proxy.$initializeEdit(handle, ownerUri, schemaName, objectName, objectType, rowLimit, queryString); + initializeEdit(ownerUri: string, schemaName: string, objectName: string, objectType: string, rowLimit: number, queryString: string): Promise { + return Promise.resolve(self._proxy.$initializeEdit(handle, ownerUri, schemaName, objectName, objectType, rowLimit, queryString)); }, - updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Thenable { - return self._proxy.$updateCell(handle, ownerUri, rowId, columnId, newValue); + updateCell(ownerUri: string, rowId: number, columnId: number, newValue: string): Promise { + return Promise.resolve(self._proxy.$updateCell(handle, ownerUri, rowId, columnId, newValue)); }, - commitEdit(ownerUri): Thenable { - return self._proxy.$commitEdit(handle, ownerUri); + commitEdit(ownerUri): Promise { + return Promise.resolve(self._proxy.$commitEdit(handle, ownerUri)); }, - createRow(ownerUri: string): Thenable { - return self._proxy.$createRow(handle, ownerUri); + createRow(ownerUri: string): Promise { + return Promise.resolve(self._proxy.$createRow(handle, ownerUri)); }, - deleteRow(ownerUri: string, rowId: number): Thenable { - return self._proxy.$deleteRow(handle, ownerUri, rowId); + deleteRow(ownerUri: string, rowId: number): Promise { + return Promise.resolve(self._proxy.$deleteRow(handle, ownerUri, rowId)); }, - disposeEdit(ownerUri: string): Thenable { - return self._proxy.$disposeEdit(handle, ownerUri); + disposeEdit(ownerUri: string): Promise { + return Promise.resolve(self._proxy.$disposeEdit(handle, ownerUri)); }, - revertCell(ownerUri: string, rowId: number, columnId: number): Thenable { - return self._proxy.$revertCell(handle, ownerUri, rowId, columnId); + revertCell(ownerUri: string, rowId: number, columnId: number): Promise { + return Promise.resolve(self._proxy.$revertCell(handle, ownerUri, rowId, columnId)); }, - revertRow(ownerUri: string, rowId: number): Thenable { - return self._proxy.$revertRow(handle, ownerUri, rowId); + revertRow(ownerUri: string, rowId: number): Promise { + return Promise.resolve(self._proxy.$revertRow(handle, ownerUri, rowId)); }, - getEditRows(rowData: azdata.EditSubsetParams): Thenable { - return self._proxy.$getEditRows(handle, rowData); + getEditRows(rowData: azdata.EditSubsetParams): Promise { + return Promise.resolve(self._proxy.$getEditRows(handle, rowData)); } }); diff --git a/src/sql/workbench/parts/editData/browser/editData.component.ts b/src/sql/workbench/parts/editData/browser/editData.component.ts index c530f8cdb1..068e70a0ca 100644 --- a/src/sql/workbench/parts/editData/browser/editData.component.ts +++ b/src/sql/workbench/parts/editData/browser/editData.component.ts @@ -207,31 +207,29 @@ export class EditDataComponent extends GridParentComponent implements OnInit, On // Setup a function for generating a promise to lookup result subsets this.loadDataFunction = (offset: number, count: number): Promise<{}[]> => { - return new Promise<{}[]>((resolve, reject) => { - self.dataService.getEditRows(offset, count).subscribe(result => { - let gridData = result.subset.map(r => { - let dataWithSchema = {}; - // skip the first column since its a number column - for (let i = 1; i < this.dataSet.columnDefinitions.length; i++) { - dataWithSchema[this.dataSet.columnDefinitions[i].field] = { - displayValue: r.cells[i - 1].displayValue, - ariaLabel: escape(r.cells[i - 1].displayValue), - isNull: r.cells[i - 1].isNull - }; - } - return dataWithSchema; - }); - - // should add null row? - if (offset + count > this.dataSet.totalRows - 1) { - gridData.push(this.dataSet.columnDefinitions.reduce((p, c) => { - p[c.field] = 'NULL'; - return p; - }, {})); + return self.dataService.getEditRows(offset, count).then(result => { + let gridData = result.subset.map(r => { + let dataWithSchema = {}; + // skip the first column since its a number column + for (let i = 1; i < this.dataSet.columnDefinitions.length; i++) { + dataWithSchema[this.dataSet.columnDefinitions[i].field] = { + displayValue: r.cells[i - 1].displayValue, + ariaLabel: escape(r.cells[i - 1].displayValue), + isNull: r.cells[i - 1].isNull + }; } - - resolve(gridData); + return dataWithSchema; }); + + // should add null row? + if (offset + count > this.dataSet.totalRows - 1) { + gridData.push(this.dataSet.columnDefinitions.reduce((p, c) => { + p[c.field] = 'NULL'; + return p; + }, {})); + } + + return gridData; }); }; } diff --git a/src/sql/workbench/parts/grid/common/dataService.ts b/src/sql/workbench/parts/grid/common/dataService.ts index 1aff8b3fc3..95863f611c 100644 --- a/src/sql/workbench/parts/grid/common/dataService.ts +++ b/src/sql/workbench/parts/grid/common/dataService.ts @@ -40,13 +40,8 @@ export class DataService { * @param rowStart The row to start retrieving from (inclusive) * @param numberOfRows The maximum number of rows to return */ - getEditRows(rowStart: number, numberOfRows: number): Observable { - const self = this; - return Observable.create(function (observer: Observer) { - self._queryModel.getEditRows(self._uri, rowStart, numberOfRows).then(results => { - observer.next(results); - }); - }); + getEditRows(rowStart: number, numberOfRows: number): Promise { + return this._queryModel.getEditRows(this._uri, rowStart, numberOfRows); } updateCell(rowId: number, columnId: number, newValue: string): Thenable { diff --git a/src/sql/workbench/parts/query/common/gridPanelState.ts b/src/sql/workbench/parts/query/common/gridPanelState.ts index ffb2b83d34..87a7c7da4d 100644 --- a/src/sql/workbench/parts/query/common/gridPanelState.ts +++ b/src/sql/workbench/parts/query/common/gridPanelState.ts @@ -30,7 +30,7 @@ export class GridTableState extends Disposable { /* The top row of the current scroll */ public scrollPositionY = 0; public scrollPositionX = 0; - public columnSizes: number[] = undefined; + public columnSizes?: number[] = undefined; public selection: Slick.Range[]; public activeCell: Slick.Cell; diff --git a/src/sql/workbench/parts/query/common/queryInput.ts b/src/sql/workbench/parts/query/common/queryInput.ts index 19e537b44d..ce7804875b 100644 --- a/src/sql/workbench/parts/query/common/queryInput.ts +++ b/src/sql/workbench/parts/query/common/queryInput.ts @@ -276,12 +276,12 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec } // State update funtions - public runQuery(selection: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void { + public runQuery(selection?: ISelectionData, executePlanOptions?: ExecutionPlanOptions): void { this._queryModelService.runQuery(this.uri, selection, this, executePlanOptions); this.state.executing = true; } - public runQueryStatement(selection: ISelectionData): void { + public runQueryStatement(selection?: ISelectionData): void { this._queryModelService.runQueryStatement(this.uri, selection, this); this.state.executing = true; } @@ -316,7 +316,7 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec let isRunningQuery = this._queryModelService.isRunningQuery(this.uri); if (!isRunningQuery && params && params.runQueryOnCompletion) { - let selection: ISelectionData = params ? params.querySelection : undefined; + let selection: ISelectionData | undefined = params ? params.querySelection : undefined; if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeCurrentQuery) { this.runQueryStatement(selection); } else if (params.runQueryOnCompletion === RunQueryOnConnectionMode.executeQuery) { @@ -361,6 +361,6 @@ export class QueryInput extends EditorInput implements IEncodingSupport, IConnec } public get isSharedSession(): boolean { - return this.uri && this.uri.startsWith('vsls:'); + return !!(this.uri && this.uri.startsWith('vsls:')); } } diff --git a/src/sql/workbench/parts/query/common/queryResultsInput.ts b/src/sql/workbench/parts/query/common/queryResultsInput.ts index b695616f5f..fc93fd2261 100644 --- a/src/sql/workbench/parts/query/common/queryResultsInput.ts +++ b/src/sql/workbench/parts/query/common/queryResultsInput.ts @@ -42,9 +42,9 @@ export class ResultsViewState { */ export class QueryResultsInput extends EditorInput { - private _state = new ResultsViewState(); + private _state?= new ResultsViewState(); - public get state(): ResultsViewState { + public get state(): ResultsViewState | undefined { return this._state; } @@ -53,7 +53,7 @@ export class QueryResultsInput extends EditorInput { } close() { - this.state.dispose(); + this.state!.dispose(); this._state = undefined; super.close(); } diff --git a/src/sql/workbench/parts/query/common/resultSerializer.ts b/src/sql/workbench/parts/query/common/resultSerializer.ts index bf22d5bcd0..ba8b0d164a 100644 --- a/src/sql/workbench/parts/query/common/resultSerializer.ts +++ b/src/sql/workbench/parts/query/common/resultSerializer.ts @@ -67,12 +67,12 @@ export class ResultSerializer { /** * Handle save request by getting filename from user and sending request to service */ - public saveResults(uri: string, saveRequest: ISaveRequest): Thenable { + public saveResults(uri: string, saveRequest: ISaveRequest): Promise { const self = this; return this.promptForFilepath(saveRequest.format, uri).then(filePath => { if (filePath) { if (!path.isAbsolute(filePath)) { - filePath = resolveFilePath(uri, filePath, this.rootPath); + filePath = resolveFilePath(uri, filePath, this.rootPath)!; } let saveResultsParams = this.getParameters(uri, filePath, saveRequest.batchIndex, saveRequest.resultSetNumber, saveRequest.format, saveRequest.selection ? saveRequest.selection[0] : undefined); let sendRequest = () => this.sendSaveRequestToService(saveResultsParams); @@ -98,9 +98,9 @@ export class ResultSerializer { return this.promptForFilepath(format, uri).then(filePath => { if (filePath) { if (!path.isAbsolute(filePath)) { - filePath = resolveFilePath(uri, filePath, this.rootPath); + filePath = resolveFilePath(uri, filePath, this.rootPath)!; } - return self.doSave(filePath, format, () => sendRequest(filePath)); + return self.doSave(filePath, format, () => sendRequest(filePath!)); } return Promise.resolve(); }); @@ -117,10 +117,10 @@ export class ResultSerializer { private get outputChannel(): IOutputChannel { this.ensureOutputChannelExists(); - return this._outputService.getChannel(ConnectionConstants.outputChannelName); + return this._outputService.getChannel(ConnectionConstants.outputChannelName)!; } - private get rootPath(): string { + private get rootPath(): string | undefined { return getRootPath(this._contextService); } @@ -129,7 +129,7 @@ export class ResultSerializer { } - private promptForFilepath(format: SaveFormat, resourceUri: string): Thenable { + private promptForFilepath(format: SaveFormat, resourceUri: string): Promise { let filepathPlaceHolder = prevSavePath ? path.dirname(prevSavePath) : resolveCurrentDirectory(resourceUri, this.rootPath); if (filepathPlaceHolder) { filepathPlaceHolder = path.join(filepathPlaceHolder, this.getResultsDefaultFilename(format)); @@ -171,7 +171,7 @@ export class ResultSerializer { private getResultsFileExtension(format: SaveFormat): FileFilter[] { let fileFilters = new Array(); - let fileFilter: { extensions: string[]; name: string } = { extensions: undefined, name: undefined }; + let fileFilter: { extensions: string[]; name: string } = Object.create(null); switch (format) { case SaveFormat.CSV: @@ -211,7 +211,7 @@ export class ResultSerializer { } else if (format === SaveFormat.XML) { saveResultsParams = this.getConfigForXml(); } - return saveResultsParams; + return saveResultsParams!; // this could be unsafe } @@ -280,7 +280,7 @@ export class ResultSerializer { } - private getParameters(uri: string, filePath: string, batchIndex: number, resultSetNo: number, format: string, selection: Slick.Range): SaveResultsRequestParams { + private getParameters(uri: string, filePath: string, batchIndex: number, resultSetNo: number, format: string, selection?: Slick.Range): SaveResultsRequestParams { let saveResultsParams = this.getBasicSaveParameters(format); saveResultsParams.filePath = filePath; saveResultsParams.ownerUri = uri; @@ -298,8 +298,8 @@ export class ResultSerializer { /** * Check if a range of cells were selected. */ - private isSelected(selection: Slick.Range): boolean { - return (selection && !((selection.fromCell === selection.toCell) && (selection.fromRow === selection.toRow))); + private isSelected(selection?: Slick.Range): selection is Slick.Range { + return !!(selection && !((selection.fromCell === selection.toCell) && (selection.fromRow === selection.toRow))); } diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json index 28d1fd5abf..1257bbaf64 100644 --- a/src/tsconfig.strictNullChecks.json +++ b/src/tsconfig.strictNullChecks.json @@ -17,12 +17,14 @@ // "./vs/platform/**/*.ts", "./sql/base/**/*.ts", "./sql/editor/**/*.ts", + "./sql/platform/accounts/common/**/*.ts", "./sql/platform/angularEventing/**/*.ts", "./sql/platform/backup/**/*.ts", "./sql/platform/browser/**/*.ts", "./sql/platform/capabilities/**/*.ts", "./sql/platform/clipboard/**/*.ts", "./sql/platform/common/**/*.ts", + "./sql/platform/connection/common/**/*.ts", "./sql/platform/credentials/**/*.ts", "./sql/platform/errorMessage/**/*.ts", "./sql/platform/fileBrowser/**/*.ts", @@ -31,6 +33,7 @@ "./sql/platform/modelComponents/**/*.ts", "./sql/platform/notebooks/**/*.ts", "./sql/platform/oAuth/**/*.ts", + "./sql/platform/query/common/gridDataProvider.ts", "./sql/platform/scripting/**/*.ts", "./sql/platform/serialization/**/*.ts", "./sql/platform/serverGroup/**/*.ts",