mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-16 09:35:36 -05:00
Read publish profile using DacFX (#16110)
* Read publish profile using DacFX in VS Code * Fixes * complete promise on hide * comment
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { SqlTargetPlatform } from 'sqldbproj';
|
||||
import * as utils from '../common/utils';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -101,7 +102,7 @@ export const connectionRadioButtonLabel = localize('connectionRadioButtonLabel',
|
||||
export const dataSourceDropdownTitle = localize('dataSourceDropdownTitle', "Data source");
|
||||
export const noDataSourcesText = localize('noDataSourcesText', "No data sources in this project");
|
||||
export const loadProfilePlaceholderText = localize('loadProfilePlaceholderText', "Load profile...");
|
||||
export const profileReadError = localize('profileReadError', "Could not load the profile file.");
|
||||
export const profileReadError = (err: any) => localize('profileReadError', "Error loading the publish profile. {0}", utils.getErrorMessage(err));
|
||||
export const sqlCmdTableLabel = localize('sqlCmdTableLabel', "SQLCMD Variables");
|
||||
export const sqlCmdVariableColumn = localize('sqlCmdVariableColumn', "Name");
|
||||
export const sqlCmdValueColumn = localize('sqlCmdValueColumn', "Value");
|
||||
@@ -110,7 +111,8 @@ export const profile = localize('profile', "Profile");
|
||||
export const selectConnection = localize('selectConnection', "Select connection");
|
||||
export const server = localize('server', "Server");
|
||||
export const defaultUser = localize('default', "default");
|
||||
export const selectProfile = localize('selectProfile', "Select publish profile to load");
|
||||
export const selectProfileToUse = localize('selectProfileToUse', "Select publish profile to load");
|
||||
export const selectProfile = localize('selectProfile', "Select Profile");
|
||||
export const dontUseProfile = localize('dontUseProfile', "Don't use profile");
|
||||
export const browseForProfile = localize('browseForProfile', "Browse for profile");
|
||||
export const chooseAction = localize('chooseAction', "Choose action");
|
||||
|
||||
@@ -11,6 +11,7 @@ import * as path from 'path';
|
||||
import * as glob from 'fast-glob';
|
||||
import * as dataworkspace from 'dataworkspace';
|
||||
import * as mssql from '../../../mssql';
|
||||
import * as vscodeMssql from 'vscode-mssql';
|
||||
import { promises as fs } from 'fs';
|
||||
|
||||
/**
|
||||
@@ -251,6 +252,20 @@ export function getDataWorkspaceExtensionApi(): dataworkspace.IExtension {
|
||||
return extension.exports;
|
||||
}
|
||||
|
||||
export type IDacFxService = mssql.IDacFxService | vscodeMssql.IDacFxService;
|
||||
|
||||
export async function getDacFxService(): Promise<IDacFxService> {
|
||||
if (getAzdataApi()) {
|
||||
let ext = vscode.extensions.getExtension(mssql.extension.name) as vscode.Extension<mssql.IExtension>;
|
||||
const api = await ext.activate();
|
||||
return api.dacFx;
|
||||
} else {
|
||||
let ext = vscode.extensions.getExtension(vscodeMssql.extension.name) as vscode.Extension<vscodeMssql.IExtension>;
|
||||
const api = await ext.activate();
|
||||
return api.dacFx;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default deployment options from DacFx
|
||||
*/
|
||||
|
||||
@@ -26,7 +26,7 @@ import { ProjectRootTreeItem } from '../models/tree/projectTreeItem';
|
||||
import { ImportDataModel } from '../models/api/import';
|
||||
import { NetCoreTool, DotNetCommandOptions } from '../tools/netcoreTool';
|
||||
import { BuildHelper } from '../tools/buildHelper';
|
||||
import { PublishProfile, load } from '../models/publishProfile/publishProfile';
|
||||
import { readPublishProfile } from '../models/publishProfile/publishProfile';
|
||||
import { AddDatabaseReferenceDialog } from '../dialogs/addDatabaseReferenceDialog';
|
||||
import { ISystemDatabaseReferenceSettings, IDacpacReferenceSettings, IProjectReferenceSettings } from '../models/IDatabaseReferenceSettings';
|
||||
import { DatabaseReferenceTreeItem } from '../models/tree/databaseReferencesTreeItem';
|
||||
@@ -39,8 +39,6 @@ import { launchPublishDatabaseQuickpick } from '../dialogs/publishDatabaseQuickp
|
||||
|
||||
const maxTableLength = 10;
|
||||
|
||||
export type IDacFxService = mssql.IDacFxService | mssqlVscode.IDacFxService;
|
||||
|
||||
/**
|
||||
* Controller for managing lifecycle of projects
|
||||
*/
|
||||
@@ -242,9 +240,9 @@ export class ProjectsController {
|
||||
if (utils.getAzdataApi()) {
|
||||
let publishDatabaseDialog = this.getPublishDialog(project);
|
||||
|
||||
publishDatabaseDialog.publish = async (proj, prof) => await this.publishProjectCallback(proj, prof);
|
||||
publishDatabaseDialog.generateScript = async (proj, prof) => await this.publishProjectCallback(proj, prof);
|
||||
publishDatabaseDialog.readPublishProfile = async (profileUri) => await this.readPublishProfileCallback(profileUri);
|
||||
publishDatabaseDialog.publish = async (proj, prof) => this.publishProjectCallback(proj, prof);
|
||||
publishDatabaseDialog.generateScript = async (proj, prof) => this.publishProjectCallback(proj, prof);
|
||||
publishDatabaseDialog.readPublishProfile = async (profileUri) => readPublishProfile(profileUri);
|
||||
|
||||
publishDatabaseDialog.openDialog();
|
||||
|
||||
@@ -279,7 +277,7 @@ export class ProjectsController {
|
||||
const tempPath = path.join(os.tmpdir(), `${path.parse(dacpacPath).name}_${new Date().getTime()}${constants.sqlprojExtension}`);
|
||||
await fs.copyFile(dacpacPath, tempPath);
|
||||
|
||||
const dacFxService = await this.getDaxFxService();
|
||||
const dacFxService = await utils.getDacFxService();
|
||||
|
||||
let result: mssql.DacFxResult;
|
||||
telemetryProps.profileUsed = (settings.profileUsed ?? false).toString();
|
||||
@@ -349,17 +347,6 @@ export class ProjectsController {
|
||||
return result;
|
||||
}
|
||||
|
||||
public async readPublishProfileCallback(profileUri: vscode.Uri): Promise<PublishProfile> {
|
||||
try {
|
||||
const dacFxService = await this.getDaxFxService();
|
||||
const profile = await load(profileUri, dacFxService);
|
||||
return profile;
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(constants.profileReadError);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public async schemaCompare(treeNode: dataworkspace.WorkspaceTreeItem): Promise<void> {
|
||||
try {
|
||||
// check if schema compare extension is installed
|
||||
@@ -740,7 +727,7 @@ export class ProjectsController {
|
||||
|
||||
const streamingJobDefinition: string = (await fs.readFile(node.element.fileSystemUri.fsPath)).toString();
|
||||
|
||||
const dacFxService = await this.getDaxFxService();
|
||||
const dacFxService = await utils.getDacFxService();
|
||||
const actionStartTime = new Date().getTime();
|
||||
|
||||
const result: mssql.ValidateStreamingJobResult = await dacFxService.validateStreamingJob(dacpacPath, streamingJobDefinition);
|
||||
@@ -831,21 +818,6 @@ export class ProjectsController {
|
||||
}
|
||||
}
|
||||
|
||||
public async getDaxFxService(): Promise<IDacFxService> {
|
||||
if (utils.getAzdataApi()) {
|
||||
const ext: vscode.Extension<mssql.IExtension> = vscode.extensions.getExtension(mssql.extension.name)!;
|
||||
const extensionApi = await ext.activate();
|
||||
return extensionApi.dacFx;
|
||||
} else {
|
||||
const ext: vscode.Extension<mssqlVscode.IExtension> = vscode.extensions.getExtension(mssql.extension.name)!;
|
||||
const extensionApi = await ext.activate();
|
||||
return extensionApi.dacFx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private async promptForNewObjectName(itemType: templates.ProjectScriptType, _project: Project, folderPath: string, fileExtension?: string): Promise<string | undefined> {
|
||||
const suggestedName = itemType.friendlyName.replace(/\s+/g, '');
|
||||
let counter: number = 0;
|
||||
|
||||
@@ -622,6 +622,7 @@ export class PublishDatabaseDialog {
|
||||
export function promptForPublishProfile(defaultPath: string): Thenable<vscode.Uri[] | undefined> {
|
||||
return vscode.window.showOpenDialog(
|
||||
{
|
||||
title: constants.selectProfile,
|
||||
canSelectFiles: true,
|
||||
canSelectFolders: false,
|
||||
canSelectMany: false,
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as vscode from 'vscode';
|
||||
import * as constants from '../common/constants';
|
||||
import { IGenerateScriptSettings, IPublishSettings } from '../models/IPublishSettings';
|
||||
import { Project } from '../models/project';
|
||||
import { PublishProfile, readPublishProfile } from '../models/publishProfile/publishProfile';
|
||||
import { promptForPublishProfile } from './publishDatabaseDialog';
|
||||
|
||||
/**
|
||||
@@ -15,21 +16,57 @@ import { promptForPublishProfile } from './publishDatabaseDialog';
|
||||
export async function launchPublishDatabaseQuickpick(project: Project): Promise<void> {
|
||||
|
||||
// 1. Select publish settings file (optional)
|
||||
// TODO@chgagnon: Hook up to dacfx service
|
||||
const browseProfileOption = await vscode.window.showQuickPick(
|
||||
[constants.dontUseProfile, constants.browseForProfile],
|
||||
{ title: constants.selectProfile, ignoreFocusOut: true });
|
||||
if (!browseProfileOption) {
|
||||
return;
|
||||
}
|
||||
// Create custom quickpick so we can control stuff like displaying the loading indicator
|
||||
const quickPick = vscode.window.createQuickPick();
|
||||
quickPick.items = [{ label: constants.dontUseProfile }, { label: constants.browseForProfile }];
|
||||
quickPick.ignoreFocusOut = true;
|
||||
quickPick.title = constants.selectProfileToUse;
|
||||
const profilePicked = new Promise<PublishProfile | undefined>((resolve, reject) => {
|
||||
quickPick.onDidHide(() => {
|
||||
// If the quickpick is hidden that means the user cancelled or another quickpick came up - so we reject
|
||||
// here to be able to complete the promise being waited on below
|
||||
reject();
|
||||
});
|
||||
quickPick.onDidChangeSelection(async items => {
|
||||
if (items[0].label === constants.browseForProfile) {
|
||||
const locations = await promptForPublishProfile(project.projectFolderPath);
|
||||
if (!locations) {
|
||||
// Clear items so that this event will trigger again if they select the same item
|
||||
quickPick.selectedItems = [];
|
||||
quickPick.activeItems = [];
|
||||
// If the user cancels out of the file picker then just return and let them choose another option
|
||||
return;
|
||||
}
|
||||
let publishProfileUri = locations[0];
|
||||
try {
|
||||
// Show loading state while reading profile
|
||||
quickPick.busy = true;
|
||||
quickPick.enabled = false;
|
||||
const profile = await readPublishProfile(publishProfileUri);
|
||||
resolve(profile);
|
||||
} catch (err) {
|
||||
// readPublishProfile will handle displaying an error if one occurs
|
||||
// Clear items so that this event will trigger again if they select the same item
|
||||
quickPick.selectedItems = [];
|
||||
quickPick.activeItems = [];
|
||||
quickPick.busy = false;
|
||||
quickPick.enabled = true;
|
||||
|
||||
// let publishSettingsFile: vscode.Uri | undefined;
|
||||
if (browseProfileOption === constants.browseForProfile) {
|
||||
const locations = await promptForPublishProfile(project.projectFolderPath);
|
||||
if (!locations) {
|
||||
return;
|
||||
}
|
||||
// publishSettingsFile = locations[0];
|
||||
}
|
||||
} else {
|
||||
// Selected no profile so just continue on
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
quickPick.show();
|
||||
let publishProfile: PublishProfile | undefined = undefined;
|
||||
try {
|
||||
publishProfile = await profilePicked;
|
||||
} catch (err) {
|
||||
// User cancelled or another quickpick came up and hid the current one
|
||||
// so exit the flow.
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Select connection
|
||||
@@ -83,8 +120,9 @@ export async function launchPublishDatabaseQuickpick(project: Project): Promise<
|
||||
|
||||
|
||||
// 4. Modify sqlcmd vars
|
||||
// TODO@chgagnon: Concat ones from publish profile
|
||||
let sqlCmdVariables = Object.assign({}, project.sqlCmdVariables);
|
||||
// If a publish profile is provided then the values from there will overwrite the ones in the
|
||||
// project file (if they exist)
|
||||
let sqlCmdVariables = Object.assign({}, project.sqlCmdVariables, publishProfile?.sqlCmdVariables);
|
||||
|
||||
if (Object.keys(sqlCmdVariables).length > 0) {
|
||||
// Continually loop here, allowing the user to modify SQLCMD variables one
|
||||
@@ -123,7 +161,7 @@ export async function launchPublishDatabaseQuickpick(project: Project): Promise<
|
||||
sqlCmdVariables[sqlCmd.key] = newValue;
|
||||
}
|
||||
} else if (sqlCmd.isResetAllVars) {
|
||||
sqlCmdVariables = Object.assign({}, project.sqlCmdVariables);
|
||||
sqlCmdVariables = Object.assign({}, project.sqlCmdVariables, publishProfile?.sqlCmdVariables);
|
||||
} else if (sqlCmd.isDone) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8,11 +8,10 @@ import * as constants from '../../common/constants';
|
||||
import * as utils from '../../common/utils';
|
||||
import * as mssql from '../../../../mssql';
|
||||
import * as vscodeMssql from 'vscode-mssql';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import { promises as fs } from 'fs';
|
||||
import { Uri } from 'vscode';
|
||||
import { SqlConnectionDataSource } from '../dataSources/sqlConnectionStringSource';
|
||||
import { IDacFxService } from '../../controllers/projectController';
|
||||
|
||||
// only reading db name, connection string, and SQLCMD vars from profile for now
|
||||
export interface PublishProfile {
|
||||
@@ -24,10 +23,21 @@ export interface PublishProfile {
|
||||
options?: mssql.DeploymentOptions | vscodeMssql.DeploymentOptions;
|
||||
}
|
||||
|
||||
export async function readPublishProfile(profileUri: vscode.Uri): Promise<PublishProfile> {
|
||||
try {
|
||||
const dacFxService = await utils.getDacFxService();
|
||||
const profile = await load(profileUri, dacFxService);
|
||||
return profile;
|
||||
} catch (e) {
|
||||
vscode.window.showErrorMessage(constants.profileReadError(e));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parses the specified file to load publish settings
|
||||
*/
|
||||
export async function load(profileUri: Uri, dacfxService: IDacFxService): Promise<PublishProfile> {
|
||||
export async function load(profileUri: vscode.Uri, dacfxService: utils.IDacFxService): Promise<PublishProfile> {
|
||||
const profileText = await fs.readFile(profileUri.fsPath);
|
||||
const profileXmlDoc = new xmldom.DOMParser().parseFromString(profileText.toString());
|
||||
|
||||
@@ -67,17 +77,26 @@ async function readConnectionString(xmlDoc: any): Promise<{ connectionId: string
|
||||
const connectionProfile = dataSource.getConnectionProfile();
|
||||
|
||||
try {
|
||||
const azdataApi = utils.getAzdataApi();
|
||||
if (dataSource.integratedSecurity) {
|
||||
const connection = await utils.getAzdataApi()!.connection.connect(connectionProfile, false, false);
|
||||
connId = connection.connectionId;
|
||||
if (azdataApi) {
|
||||
const connection = await utils.getAzdataApi()!.connection.connect(connectionProfile, false, false);
|
||||
connId = connection.connectionId;
|
||||
} else {
|
||||
// TODO@chgagnon - hook up VS Code MSSQL
|
||||
}
|
||||
server = dataSource.server;
|
||||
username = constants.defaultUser;
|
||||
}
|
||||
else {
|
||||
const connection = await utils.getAzdataApi()!.connection.openConnectionDialog(undefined, connectionProfile);
|
||||
connId = connection.connectionId;
|
||||
server = connection.options['server'];
|
||||
username = connection.options['user'];
|
||||
if (azdataApi) {
|
||||
const connection = await utils.getAzdataApi()!.connection.openConnectionDialog(undefined, connectionProfile);
|
||||
connId = connection.connectionId;
|
||||
server = connection.options['server'];
|
||||
username = connection.options['user'];
|
||||
} else {
|
||||
// TODO@chgagnon - hook up VS Code MSSQL
|
||||
}
|
||||
}
|
||||
|
||||
targetConnection = `${server} (${username})`;
|
||||
|
||||
@@ -15,6 +15,7 @@ import * as templates from '../templates/templates';
|
||||
import * as testUtils from './testUtils';
|
||||
import * as constants from '../common/constants';
|
||||
import * as mssql from '../../../mssql';
|
||||
import * as utils from '../common/utils';
|
||||
|
||||
import { SqlDatabaseProjectTreeViewProvider } from '../controllers/databaseProjectTreeViewProvider';
|
||||
import { ProjectsController } from '../controllers/projectController';
|
||||
@@ -23,7 +24,6 @@ import { createContext, TestContext, mockDacFxResult, mockConnectionProfile } fr
|
||||
import { Project, reservedProjectFolders, SystemDatabase, FileProjectEntry, SystemDatabaseReferenceProjectEntry } from '../models/project';
|
||||
import { PublishDatabaseDialog } from '../dialogs/publishDatabaseDialog';
|
||||
import { IPublishSettings, IGenerateScriptSettings } from '../models/IPublishSettings';
|
||||
import { exists } from '../common/utils';
|
||||
import { ProjectRootTreeItem } from '../models/tree/projectTreeItem';
|
||||
import { FolderNode, FileNode } from '../models/tree/fileFolderTreeItem';
|
||||
import { BaseProjectTreeItem } from '../models/tree/baseTreeItem';
|
||||
@@ -198,10 +198,10 @@ describe('ProjectsController', function (): void {
|
||||
should(proj.postDeployScripts.length).equal(0);
|
||||
should(proj.noneDeployScripts.length).equal(0);
|
||||
|
||||
should(await exists(scriptEntry.fsUri.fsPath)).equal(false, 'script is supposed to be deleted');
|
||||
should(await exists(preDeployEntry.fsUri.fsPath)).equal(false, 'pre-deployment script is supposed to be deleted');
|
||||
should(await exists(postDeployEntry.fsUri.fsPath)).equal(false, 'post-deployment script is supposed to be deleted');
|
||||
should(await exists(noneEntry.fsUri.fsPath)).equal(false, 'none entry pre-deployment script is supposed to be deleted');
|
||||
should(await utils.exists(scriptEntry.fsUri.fsPath)).equal(false, 'script is supposed to be deleted');
|
||||
should(await utils.exists(preDeployEntry.fsUri.fsPath)).equal(false, 'pre-deployment script is supposed to be deleted');
|
||||
should(await utils.exists(postDeployEntry.fsUri.fsPath)).equal(false, 'post-deployment script is supposed to be deleted');
|
||||
should(await utils.exists(noneEntry.fsUri.fsPath)).equal(false, 'none entry pre-deployment script is supposed to be deleted');
|
||||
});
|
||||
|
||||
it('Should delete database references', async function (): Promise<void> {
|
||||
@@ -259,10 +259,10 @@ describe('ProjectsController', function (): void {
|
||||
should(proj.postDeployScripts.length).equal(0);
|
||||
should(proj.noneDeployScripts.length).equal(0);
|
||||
|
||||
should(await exists(scriptEntry.fsUri.fsPath)).equal(true, 'script is supposed to still exist on disk');
|
||||
should(await exists(preDeployEntry.fsUri.fsPath)).equal(true, 'pre-deployment script is supposed to still exist on disk');
|
||||
should(await exists(postDeployEntry.fsUri.fsPath)).equal(true, 'post-deployment script is supposed to still exist on disk');
|
||||
should(await exists(noneEntry.fsUri.fsPath)).equal(true, 'none entry pre-deployment script is supposed to still exist on disk');
|
||||
should(await utils.exists(scriptEntry.fsUri.fsPath)).equal(true, 'script is supposed to still exist on disk');
|
||||
should(await utils.exists(preDeployEntry.fsUri.fsPath)).equal(true, 'pre-deployment script is supposed to still exist on disk');
|
||||
should(await utils.exists(postDeployEntry.fsUri.fsPath)).equal(true, 'post-deployment script is supposed to still exist on disk');
|
||||
should(await utils.exists(noneEntry.fsUri.fsPath)).equal(true, 'none entry pre-deployment script is supposed to still exist on disk');
|
||||
});
|
||||
|
||||
it('Should delete folders with excluded items', async function (): Promise<void> {
|
||||
@@ -287,9 +287,9 @@ describe('ProjectsController', function (): void {
|
||||
|
||||
// Confirm result
|
||||
should(proj.files.some(x => x.relativePath === 'UpperFolder')).equal(false, 'UpperFolder should not be part of proj file any more');
|
||||
should(await exists(scriptEntry.fsUri.fsPath)).equal(false, 'script is supposed to be deleted from disk');
|
||||
should(await exists(lowerFolder.projectUri.fsPath)).equal(false, 'LowerFolder is supposed to be deleted from disk');
|
||||
should(await exists(upperFolder.projectUri.fsPath)).equal(false, 'UpperFolder is supposed to be deleted from disk');
|
||||
should(await utils.exists(scriptEntry.fsUri.fsPath)).equal(false, 'script is supposed to be deleted from disk');
|
||||
should(await utils.exists(lowerFolder.projectUri.fsPath)).equal(false, 'LowerFolder is supposed to be deleted from disk');
|
||||
should(await utils.exists(upperFolder.projectUri.fsPath)).equal(false, 'UpperFolder is supposed to be deleted from disk');
|
||||
});
|
||||
|
||||
it('Should reload correctly after changing sqlproj file', async function (): Promise<void> {
|
||||
@@ -426,8 +426,7 @@ describe('ProjectsController', function (): void {
|
||||
builtDacpacPath = await testUtils.createTestFile(fakeDacpacContents, 'output.dacpac');
|
||||
return builtDacpacPath;
|
||||
});
|
||||
|
||||
projController.setup(x => x.getDaxFxService()).returns(() => Promise.resolve(testContext.dacFxService.object));
|
||||
sinon.stub(utils, 'getDacFxService').resolves(testContext.dacFxService.object);
|
||||
|
||||
const proj = await testUtils.createTestProject(baselines.openProjectFileBaseline);
|
||||
|
||||
|
||||
@@ -11,9 +11,8 @@ import * as TypeMoq from 'typemoq';
|
||||
import * as baselines from './baselines/baselines';
|
||||
import * as testUtils from './testUtils';
|
||||
import * as constants from '../common/constants';
|
||||
import { ProjectsController } from '../controllers/projectController';
|
||||
import { TestContext, createContext, mockDacFxOptionsResult } from './testContext';
|
||||
import { load } from '../models/publishProfile/publishProfile';
|
||||
import { load, readPublishProfile } from '../models/publishProfile/publishProfile';
|
||||
|
||||
let testContext: TestContext;
|
||||
|
||||
@@ -81,10 +80,9 @@ describe('Publish profile tests', function (): void {
|
||||
it('Should throw error when connecting does not work', async function (): Promise<void> {
|
||||
await baselines.loadBaselines();
|
||||
let profilePath = await testUtils.createTestFile(baselines.publishProfileIntegratedSecurityBaseline, 'publishProfile.publish.xml');
|
||||
const projController = new ProjectsController();
|
||||
|
||||
sinon.stub(azdata.connection, 'connect').throws(new Error('Could not connect'));
|
||||
|
||||
await testUtils.shouldThrowSpecificError(async () => await projController.readPublishProfileCallback(vscode.Uri.file(profilePath)), constants.unableToCreatePublishConnection('Could not connect'));
|
||||
await testUtils.shouldThrowSpecificError(async () => await readPublishProfile(vscode.Uri.file(profilePath)), constants.unableToCreatePublishConnection('Could not connect'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ declare module 'vscode-mssql' {
|
||||
|
||||
|
||||
export const enum extension {
|
||||
name = 'Microsoft.mssql'
|
||||
name = 'ms-mssql.mssql'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +45,7 @@ declare module 'vscode-mssql' {
|
||||
validateStreamingJob(packageFilePath: string, createStreamingJobTsql: string): Thenable<ValidateStreamingJobResult>;
|
||||
}
|
||||
|
||||
export enum TaskExecutionMode {
|
||||
export const enum TaskExecutionMode {
|
||||
execute = 0,
|
||||
script = 1,
|
||||
executeAndScript = 2
|
||||
|
||||
Reference in New Issue
Block a user