Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions extensions/mssql/src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,15 @@ export const build = "build";
export const sqlProjBuildTaskType = "sqlproj-build";
export const msBuildProblemMatcher = "$msCompile";
export const buildDirectory = "BuildDirectory";

// DacFx task names (as reported by SQL Tools Service)
export const taskNameExportBacpac = "Export bacpac";
export const taskNameExtractDacpac = "Extract dacpac";
export const taskNameImportBacpac = "Import bacpac";
export const taskNameDeployDacpac = "Deploy dacpac";

// DacFx operation IDs (as reported by SQL Tools Service via taskOperation field)
export const operationIdExportBacpac = "ExportOperation";
export const operationIdExtractDacpac = "ExtractOperation";
export const operationIdImportBacpac = "ImportOperation";
export const operationIdDeployDacpac = "DeployOperation";
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,16 @@ import {
DatabaseNameValidationError,
ConnectionMatcher,
} from "../models/utils";
import { PlatformInformation } from "../models/platform";
import { UserSurvey } from "../nps/userSurvey";
import { getErrorMessage } from "../utils/utils";

// File extension constants
export const DACPAC_EXTENSION = ".dacpac";
export const BACPAC_EXTENSION = ".bacpac";

// VS Code command constants
const REVEAL_FILE_IN_OS_COMMAND = "revealFileInOS";

// View ID constant for NPS survey
const DACPAC_DIALOG_VIEW_ID = "dacpacDialog";

/**
* Gets the OS-specific localized text for the "Reveal/Open" file button
* @returns The appropriate localized string based on the operating system
*/
function getRevealInOsButtonText(): string {
const platformInfo = new PlatformInformation(process.platform, process.arch, undefined);

if (platformInfo.isMacOS) {
return LocConstants.DacpacDialog.RevealInFinder;
} else if (platformInfo.isLinux) {
return LocConstants.DacpacDialog.OpenContainingFolder;
} else {
// Windows or any other platform
return LocConstants.DacpacDialog.RevealInExplorer;
}
}

/**
* Controller for the DacpacDialog webview.
* Manages DACPAC and BACPAC operations (Deploy, Extract, Import, Export) using the Data-tier Application Framework (DacFx).
Expand Down Expand Up @@ -352,10 +331,6 @@ export class DacpacDialogWebviewController extends ReactWebviewPanelController<
if (result.success) {
this.logger.verbose("Deploy DACPAC operation completed successfully");
activity.end(ActivityStatus.Succeeded);
// Show success notification for Deploy operation
void this.vscodeWrapper.showInformationMessage(
LocConstants.DacpacDialog.DeploySuccessWithDatabase(params.databaseName),
);
// Prompt user for NPS survey feedback
UserSurvey.getInstance().promptUserForNPSFeedback(
`${DACPAC_DIALOG_VIEW_ID}_deploy`,
Expand Down Expand Up @@ -417,22 +392,6 @@ export class DacpacDialogWebviewController extends ReactWebviewPanelController<
if (result.success) {
this.logger.verbose("Extract DACPAC operation completed successfully");
activity.end(ActivityStatus.Succeeded);
// Show success notification with OS-specific "Reveal/Open" button for Extract operation
const fileName = path.basename(params.packageFilePath);
const revealButtonText = getRevealInOsButtonText();
void this.vscodeWrapper
.showInformationMessage(
LocConstants.DacpacDialog.ExtractSuccessWithFile(fileName),
revealButtonText,
)
.then((selection) => {
if (selection === revealButtonText) {
void vscode.commands.executeCommand(
REVEAL_FILE_IN_OS_COMMAND,
vscode.Uri.file(params.packageFilePath),
);
}
});
// Prompt user for NPS survey feedback
UserSurvey.getInstance().promptUserForNPSFeedback(
`${DACPAC_DIALOG_VIEW_ID}_extract`,
Expand Down Expand Up @@ -492,10 +451,6 @@ export class DacpacDialogWebviewController extends ReactWebviewPanelController<
if (result.success) {
this.logger.verbose("Import BACPAC operation completed successfully");
activity.end(ActivityStatus.Succeeded);
// Show success notification for Import operation
void this.vscodeWrapper.showInformationMessage(
LocConstants.DacpacDialog.ImportSuccessWithDatabase(params.databaseName),
);
// Prompt user for NPS survey feedback
UserSurvey.getInstance().promptUserForNPSFeedback(
`${DACPAC_DIALOG_VIEW_ID}_import`,
Expand Down Expand Up @@ -555,22 +510,6 @@ export class DacpacDialogWebviewController extends ReactWebviewPanelController<
if (result.success) {
this.logger.verbose("Export BACPAC operation completed successfully");
activity.end(ActivityStatus.Succeeded);
// Show success notification with OS-specific "Reveal/Open" button for Export operation
const fileName = path.basename(params.packageFilePath);
const revealButtonText = getRevealInOsButtonText();
void this.vscodeWrapper
.showInformationMessage(
LocConstants.DacpacDialog.ExportSuccessWithFile(fileName),
revealButtonText,
)
.then((selection) => {
if (selection === revealButtonText) {
void vscode.commands.executeCommand(
REVEAL_FILE_IN_OS_COMMAND,
vscode.Uri.file(params.packageFilePath),
);
}
});
// Prompt user for NPS survey feedback
UserSurvey.getInstance().promptUserForNPSFeedback(
`${DACPAC_DIALOG_VIEW_ID}_export`,
Expand Down
6 changes: 5 additions & 1 deletion extensions/mssql/src/controllers/mainController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -564,8 +564,12 @@ export default class MainController implements vscode.Disposable {
this.sqlTasksService = new SqlTasksService(
SqlToolsServerClient.instance,
this._sqlDocumentService,
this._vscodeWrapper,
);
this.dacFxService = new DacFxService(
SqlToolsServerClient.instance,
this.sqlTasksService,
);
this.dacFxService = new DacFxService(SqlToolsServerClient.instance);
this.sqlProjectsService = new SqlProjectsService(SqlToolsServerClient.instance);
this.schemaCompareService = new SchemaCompareService(SqlToolsServerClient.instance);
this.tableExplorerService = new TableExplorerService(SqlToolsServerClient.instance);
Expand Down
77 changes: 76 additions & 1 deletion extensions/mssql/src/services/dacFxService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,84 @@ import SqlToolsServiceClient from "../languageservice/serviceclient";
import * as dacFxContracts from "../models/contracts/dacFx/dacFxContracts";
import * as mssql from "vscode-mssql";
import { ExtractTarget, TaskExecutionMode } from "../sharedInterfaces/schemaCompare";
import { SqlTasksService } from "./sqlTasksService";
import * as path from "path";
import * as vscode from "vscode";
import * as Constants from "../constants/constants";
import * as LocalizedConstants from "../constants/locConstants";
import { PlatformInformation } from "../models/platform";

export class DacFxService implements mssql.IDacFxService {
constructor(private _client: SqlToolsServiceClient) {}
constructor(
private _client: SqlToolsServiceClient,
sqlTasksService: SqlTasksService,
) {
this.registerTaskCompletionHandlers(sqlTasksService);
}

/**
* Register task completion handlers for dacpac operations
*/
private registerTaskCompletionHandlers(sqlTasksService: SqlTasksService): void {
const platformInfo = new PlatformInformation(process.platform, process.arch, undefined);

// Determine the OS-specific reveal button text
let revealButtonText: string;
if (platformInfo.isMacOS) {
revealButtonText = LocalizedConstants.DacpacDialog.RevealInFinder;
} else if (platformInfo.isLinux) {
revealButtonText = LocalizedConstants.DacpacDialog.OpenContainingFolder;
} else {
// Windows or any other platform
revealButtonText = LocalizedConstants.DacpacDialog.RevealInExplorer;
}

// Register handler for Export BACPAC operation
sqlTasksService.registerCompletionHandler({
operationName: Constants.operationIdExportBacpac,
getTargetLocation: (taskInfo) => taskInfo.targetLocation,
getSuccessMessage: (_taskInfo, targetLocation) => {
const fileName = path.basename(targetLocation);
return LocalizedConstants.DacpacDialog.ExportSuccessWithFile(fileName);
},
getActionButtonText: () => revealButtonText,
getActionCommand: () => "revealFileInOS",
getActionCommandArgs: (_taskInfo, targetLocation) => [vscode.Uri.file(targetLocation)],
});

// Register handler for Extract DACPAC operation
sqlTasksService.registerCompletionHandler({
operationName: Constants.operationIdExtractDacpac,
getTargetLocation: (taskInfo) => taskInfo.targetLocation,
getSuccessMessage: (_taskInfo, targetLocation) => {
const fileName = path.basename(targetLocation);
return LocalizedConstants.DacpacDialog.ExtractSuccessWithFile(fileName);
},
getActionButtonText: () => revealButtonText,
getActionCommand: () => "revealFileInOS",
getActionCommandArgs: (_taskInfo, targetLocation) => [vscode.Uri.file(targetLocation)],
});

// Register handler for Import BACPAC operation
sqlTasksService.registerCompletionHandler({
operationName: Constants.operationIdImportBacpac,
getTargetLocation: (taskInfo) => taskInfo.databaseName,
getSuccessMessage: (_taskInfo, databaseName) => {
return LocalizedConstants.DacpacDialog.ImportSuccessWithDatabase(databaseName);
},
// No action button for database operations
});

// Register handler for Deploy DACPAC operation
sqlTasksService.registerCompletionHandler({
operationName: Constants.operationIdDeployDacpac,
getTargetLocation: (taskInfo) => taskInfo.databaseName,
getSuccessMessage: (_taskInfo, databaseName) => {
return LocalizedConstants.DacpacDialog.DeploySuccessWithDatabase(databaseName);
},
// No action button for database operations
});
}

public exportBacpac(
databaseName: string,
Expand Down
Loading
Loading