diff --git a/extensions/sql-database-projects/src/controllers/projectController.ts b/extensions/sql-database-projects/src/controllers/projectController.ts index b7836c902c..dccca5aa07 100644 --- a/extensions/sql-database-projects/src/controllers/projectController.ts +++ b/extensions/sql-database-projects/src/controllers/projectController.ts @@ -20,7 +20,7 @@ import { PublishDatabaseDialog } from '../dialogs/publishDatabaseDialog'; import { Project, reservedProjectFolders, FileProjectEntry, SqlProjectReferenceProjectEntry, IDatabaseReferenceProjectEntry } from '../models/project'; import { SqlDatabaseProjectTreeViewProvider } from './databaseProjectTreeViewProvider'; import { FolderNode, FileNode } from '../models/tree/fileFolderTreeItem'; -import { IPublishSettings, IGenerateScriptSettings } from '../models/IPublishSettings'; +import { IDeploySettings } from '../models/IDeploySettings'; import { BaseProjectTreeItem } from '../models/tree/baseTreeItem'; import { ProjectRootTreeItem } from '../models/tree/projectTreeItem'; import { ImportDataModel } from '../models/api/import'; @@ -244,8 +244,8 @@ export class ProjectsController { if (utils.getAzdataApi()) { let publishDatabaseDialog = this.getPublishDialog(project); - publishDatabaseDialog.publish = async (proj, prof) => this.publishProjectCallback(proj, prof); - publishDatabaseDialog.generateScript = async (proj, prof) => this.publishProjectCallback(proj, prof); + publishDatabaseDialog.publish = async (proj, prof) => this.publishOrScriptProject(proj, prof, true); + publishDatabaseDialog.generateScript = async (proj, prof) => this.publishOrScriptProject(proj, prof, false); publishDatabaseDialog.readPublishProfile = async (profileUri) => readPublishProfile(profileUri); publishDatabaseDialog.openDialog(); @@ -257,7 +257,14 @@ export class ProjectsController { } } - public async publishProjectCallback(project: Project, settings: IPublishSettings | IGenerateScriptSettings): Promise { + /** + * Builds and either deploys or generates a deployment script for the specified project. + * @param project The project to deploy + * @param settings The settings used to configure the deployment + * @param publish Whether to publish the deployment or just generate a script + * @returns The DacFx result of the deployment + */ + public async publishOrScriptProject(project: Project, settings: IDeploySettings, publish: boolean): Promise { const telemetryProps: Record = {}; const telemetryMeasures: Record = {}; const buildStartTime = new Date().getTime(); @@ -298,17 +305,16 @@ export class ProjectsController { try { const azdataApi = utils.getAzdataApi(); - if ((settings).upgradeExisting) { + if (publish) { telemetryProps.publishAction = 'deploy'; if (azdataApi) { - result = await (dacFxService as mssql.IDacFxService).deployDacpac(tempPath, settings.databaseName, (settings).upgradeExisting, settings.connectionUri, azdataApi.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); + result = await (dacFxService as mssql.IDacFxService).deployDacpac(tempPath, settings.databaseName, true, settings.connectionUri, azdataApi.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); } else { // TODO@chgagnon Fix typing - result = await (dacFxService as mssqlVscode.IDacFxService).deployDacpac(tempPath, settings.databaseName, (settings).upgradeExisting, settings.connectionUri, azdataApi!.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); + result = await (dacFxService as mssqlVscode.IDacFxService).deployDacpac(tempPath, settings.databaseName, true, settings.connectionUri, azdataApi!.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); } - } - else { + } else { telemetryProps.publishAction = 'generateScript'; if (azdataApi) { result = await (dacFxService as mssql.IDacFxService).generateDeployScript(tempPath, settings.databaseName, settings.connectionUri, azdataApi.TaskExecutionMode.script, settings.sqlCmdVariables, settings.deploymentOptions); diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts index 9e1bf2afed..6e848cf767 100644 --- a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts @@ -10,7 +10,7 @@ import * as utils from '../common/utils'; import { Project } from '../models/project'; import { SqlConnectionDataSource } from '../models/dataSources/sqlConnectionStringSource'; -import { IPublishSettings, IGenerateScriptSettings } from '../models/IPublishSettings'; +import { IDeploySettings } from '../models/IDeploySettings'; import { DeploymentOptions, SchemaObjectType } from '../../../mssql/src/mssql'; import { IconPathHelper } from '../common/iconHelper'; import { cssStyles } from '../common/uiConstants'; @@ -46,8 +46,8 @@ export class PublishDatabaseDialog { private toDispose: vscode.Disposable[] = []; - public publish: ((proj: Project, profile: IPublishSettings) => any) | undefined; - public generateScript: ((proj: Project, profile: IGenerateScriptSettings) => any) | undefined; + public publish: ((proj: Project, profile: IDeploySettings) => any) | undefined; + public generateScript: ((proj: Project, profile: IDeploySettings) => any) | undefined; public readPublishProfile: ((profileUri: vscode.Uri) => any) | undefined; constructor(private project: Project) { @@ -182,10 +182,9 @@ export class PublishDatabaseDialog { } public async publishClick(): Promise { - const settings: IPublishSettings = { + const settings: IDeploySettings = { databaseName: this.getTargetDatabaseName(), serverName: this.getServerName(), - upgradeExisting: true, connectionUri: await this.getConnectionUri(), sqlCmdVariables: this.getSqlCmdVariablesForPublish(), deploymentOptions: await this.getDeploymentOptions(), @@ -202,7 +201,7 @@ export class PublishDatabaseDialog { TelemetryReporter.sendActionEvent(TelemetryViews.SqlProjectPublishDialog, TelemetryActions.generateScriptClicked); const sqlCmdVars = this.getSqlCmdVariablesForPublish(); - const settings: IGenerateScriptSettings = { + const settings: IDeploySettings = { databaseName: this.getTargetDatabaseName(), serverName: this.getServerName(), connectionUri: await this.getConnectionUri(), @@ -213,9 +212,7 @@ export class PublishDatabaseDialog { utils.getAzdataApi()!.window.closeDialog(this.dialog); - if (this.generateScript) { - await this.generateScript!(this.project, settings); - } + await this.generateScript?.(this.project, settings); this.dispose(); } diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts index b729a1cc79..5c55bca81f 100644 --- a/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts @@ -5,7 +5,6 @@ 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'; @@ -188,17 +187,12 @@ export async function launchPublishDatabaseQuickpick(project: Project): Promise< // TODO@chgagnon: Get deployment options // 6. Generate script/publish - let settings: IPublishSettings | IGenerateScriptSettings = { - databaseName: databaseName, - serverName: '', // TODO@chgagnon: Get from connection profile - connectionUri: '', // TODO@chgagnon: Get from connection profile - sqlCmdVariables: undefined, // this.getSqlCmdVariablesForPublish(), - deploymentOptions: undefined, // await this.getDeploymentOptions(), - profileUsed: true, // this.profileUsed, - }; - - // TODO@chgagnon Consolidate creation of the settings into one place - if (action === constants.publish) { - (settings as IPublishSettings).upgradeExisting = true; - } + // let settings: IDeploySettings | IGenerateScriptSettings = { + // databaseName: databaseName, + // serverName: connectionProfile!.server, + // connectionUri: '', // TODO@chgagnon: Get from connection profile + // sqlCmdVariables: sqlCmdVariables, + // deploymentOptions: undefined, // await this.getDeploymentOptions(), + // profileUsed: !!publishProfile + // }; } diff --git a/extensions/sql-database-projects/src/models/IPublishSettings.ts b/extensions/sql-database-projects/src/models/IDeploySettings.ts similarity index 67% rename from extensions/sql-database-projects/src/models/IPublishSettings.ts rename to extensions/sql-database-projects/src/models/IDeploySettings.ts index bb3e378960..c124fede5b 100644 --- a/extensions/sql-database-projects/src/models/IPublishSettings.ts +++ b/extensions/sql-database-projects/src/models/IDeploySettings.ts @@ -5,17 +5,7 @@ import { DeploymentOptions } from '../../../mssql/src/mssql'; -export interface IPublishSettings { - databaseName: string; - serverName: string; - connectionUri: string; - upgradeExisting: boolean; - sqlCmdVariables?: Record; - deploymentOptions?: DeploymentOptions; - profileUsed?: boolean; -} - -export interface IGenerateScriptSettings { +export interface IDeploySettings { databaseName: string; serverName: string; connectionUri: string; diff --git a/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts b/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts index 3f19c7149a..a1848aa58c 100644 --- a/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts +++ b/extensions/sql-database-projects/src/test/dialogs/publishDatabaseDialog.test.ts @@ -15,7 +15,7 @@ import * as TypeMoq from 'typemoq'; import { PublishDatabaseDialog } from '../../dialogs/publishDatabaseDialog'; import { Project } from '../../models/project'; import { ProjectsController } from '../../controllers/projectController'; -import { IPublishSettings, IGenerateScriptSettings } from '../../models/IPublishSettings'; +import { IDeploySettings } from '../../models/IDeploySettings'; import { emptySqlDatabaseProjectTypeId } from '../../common/constants'; import { mockDacFxOptionsResult } from '../testContext'; @@ -70,13 +70,12 @@ describe('Publish Database Dialog', () => { dialog.setup(x => x.getServerName()).returns(() => 'MockServer'); dialog.callBase = true; - let profile: IPublishSettings | IGenerateScriptSettings | undefined; + let profile: IDeploySettings | undefined; - const expectedPublish: IPublishSettings = { + const expectedPublish: IDeploySettings = { databaseName: 'MockDatabaseName', serverName: 'MockServer', connectionUri: 'Mock|Connection|Uri', - upgradeExisting: true, sqlCmdVariables: { 'ProdDatabaseName': 'MyProdDatabase', 'BackupDatabaseName': 'MyBackupDatabase' @@ -90,7 +89,7 @@ describe('Publish Database Dialog', () => { should(profile).deepEqual(expectedPublish); - const expectedGenScript: IGenerateScriptSettings = { + const expectedGenScript: IDeploySettings = { databaseName: 'MockDatabaseName', serverName: 'MockServer', connectionUri: 'Mock|Connection|Uri', diff --git a/extensions/sql-database-projects/src/test/projectController.test.ts b/extensions/sql-database-projects/src/test/projectController.test.ts index 4d6f78fba8..3bc73651a3 100644 --- a/extensions/sql-database-projects/src/test/projectController.test.ts +++ b/extensions/sql-database-projects/src/test/projectController.test.ts @@ -23,7 +23,6 @@ import { promises as fs } from 'fs'; import { createContext, TestContext, mockDacFxResult, mockConnectionProfile } from './testContext'; import { Project, reservedProjectFolders, SystemDatabase, FileProjectEntry, SystemDatabaseReferenceProjectEntry } from '../models/project'; import { PublishDatabaseDialog } from '../dialogs/publishDatabaseDialog'; -import { IPublishSettings, IGenerateScriptSettings } from '../models/IPublishSettings'; import { ProjectRootTreeItem } from '../models/tree/projectTreeItem'; import { FolderNode, FileNode } from '../models/tree/fileFolderTreeItem'; import { BaseProjectTreeItem } from '../models/tree/baseTreeItem'; @@ -386,12 +385,12 @@ describe('ProjectsController', function (): void { let projController = TypeMoq.Mock.ofType(ProjectsController); projController.callBase = true; projController.setup(x => x.getPublishDialog(TypeMoq.It.isAny())).returns(() => publishDialog.object); - projController.setup(x => x.publishProjectCallback(TypeMoq.It.isAny(), TypeMoq.It.is((_): _ is IPublishSettings => true))).returns(() => { + projController.setup(x => x.publishOrScriptProject(TypeMoq.It.isAny(), TypeMoq.It.isAny(), true)).returns(() => { holler = publishHoller; return Promise.resolve(undefined); }); - projController.setup(x => x.publishProjectCallback(TypeMoq.It.isAny(), TypeMoq.It.is((_): _ is IGenerateScriptSettings => true))).returns(() => { + projController.setup(x => x.publishOrScriptProject(TypeMoq.It.isAny(), TypeMoq.It.isAny(), false)).returns(() => { holler = generateHoller; return Promise.resolve(undefined); }); @@ -430,7 +429,7 @@ describe('ProjectsController', function (): void { const proj = await testUtils.createTestProject(baselines.openProjectFileBaseline); - await projController.object.publishProjectCallback(proj, { connectionUri: '', databaseName: '' , serverName: ''}); + await projController.object.publishOrScriptProject(proj, { connectionUri: '', databaseName: '' , serverName: ''}, false); should(builtDacpacPath).not.equal('', 'built dacpac path should be set'); should(publishedDacpacPath).not.equal('', 'published dacpac path should be set');