mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Add ability to change source and target to Schema Compare (#6026)
* add ability to change source and target * addressing comments * fixes after rebasing * add check for user * bump extension version
This commit is contained in:
@@ -39,6 +39,7 @@ if (context.RunTest) {
|
|||||||
let source: azdata.SchemaCompareEndpointInfo = {
|
let source: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
packageFilePath: dacpac1,
|
packageFilePath: dacpac1,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
@@ -46,6 +47,7 @@ if (context.RunTest) {
|
|||||||
let target: azdata.SchemaCompareEndpointInfo = {
|
let target: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
packageFilePath: dacpac2,
|
packageFilePath: dacpac2,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
@@ -86,6 +88,7 @@ if (context.RunTest) {
|
|||||||
let source: azdata.SchemaCompareEndpointInfo = {
|
let source: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Database,
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
packageFilePath: '',
|
packageFilePath: '',
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: server.serverName,
|
serverName: server.serverName,
|
||||||
databaseName: sourceDB,
|
databaseName: sourceDB,
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
@@ -93,6 +96,7 @@ if (context.RunTest) {
|
|||||||
let target: azdata.SchemaCompareEndpointInfo = {
|
let target: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Database,
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
packageFilePath: '',
|
packageFilePath: '',
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: server.serverName,
|
serverName: server.serverName,
|
||||||
databaseName: targetDB,
|
databaseName: targetDB,
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
@@ -137,6 +141,7 @@ if (context.RunTest) {
|
|||||||
let source: azdata.SchemaCompareEndpointInfo = {
|
let source: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
packageFilePath: dacpac1,
|
packageFilePath: dacpac1,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
@@ -144,6 +149,7 @@ if (context.RunTest) {
|
|||||||
let target: azdata.SchemaCompareEndpointInfo = {
|
let target: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Database,
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
packageFilePath: '',
|
packageFilePath: '',
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: server.serverName,
|
serverName: server.serverName,
|
||||||
databaseName: targetDB,
|
databaseName: targetDB,
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "schema-compare",
|
"name": "schema-compare",
|
||||||
"displayName": "%displayName%",
|
"displayName": "%displayName%",
|
||||||
"description": "%description%",
|
"description": "%description%",
|
||||||
"version": "0.3.0",
|
"version": "0.4.0",
|
||||||
"publisher": "Microsoft",
|
"publisher": "Microsoft",
|
||||||
"preview": true,
|
"preview": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
import * as azdata from 'azdata';
|
import * as azdata from 'azdata';
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { SchemaCompareDialog } from '../dialogs/schemaCompareDialog';
|
import { SchemaCompareResult } from '../schemaCompareResult';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main controller class that initializes the extension
|
* The main controller class that initializes the extension
|
||||||
@@ -32,7 +32,7 @@ export default class MainController implements vscode.Disposable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private initializeSchemaCompareDialog(): void {
|
private initializeSchemaCompareDialog(): void {
|
||||||
azdata.tasks.registerTask('schemaCompare.start', (profile: azdata.IConnectionProfile) => new SchemaCompareDialog().openDialog(profile));
|
azdata.tasks.registerTask('schemaCompare.start', (profile: azdata.IConnectionProfile) => new SchemaCompareResult().start(profile));
|
||||||
}
|
}
|
||||||
|
|
||||||
public dispose(): void {
|
public dispose(): void {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { SchemaCompareResult } from '../schemaCompareResult';
|
|||||||
import { isNullOrUndefined } from 'util';
|
import { isNullOrUndefined } from 'util';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { Telemetry } from '../telemetry';
|
import { Telemetry } from '../telemetry';
|
||||||
|
import { getEndpointName } from '../utils';
|
||||||
|
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
const OkButtonText: string = localize('schemaCompareDialog.ok', 'Ok');
|
const OkButtonText: string = localize('schemaCompareDialog.ok', 'Ok');
|
||||||
@@ -26,6 +27,11 @@ const ServerDropdownLabel: string = localize('schemaCompareDialog.serverDropdown
|
|||||||
const DatabaseDropdownLabel: string = localize('schemaCompareDialog.databaseDropdownTitle', 'Database');
|
const DatabaseDropdownLabel: string = localize('schemaCompareDialog.databaseDropdownTitle', 'Database');
|
||||||
const NoActiveConnectionsLabel: string = localize('schemaCompare.noActiveConnectionsText', 'No active connections');
|
const NoActiveConnectionsLabel: string = localize('schemaCompare.noActiveConnectionsText', 'No active connections');
|
||||||
const SchemaCompareLabel: string = localize('schemaCompare.dialogTitle', 'Schema Compare');
|
const SchemaCompareLabel: string = localize('schemaCompare.dialogTitle', 'Schema Compare');
|
||||||
|
const differentSourceMessage: string = localize('schemaCompareDialog.differentSourceMessage', 'A different source schema has been selected. Compare to see the comparison?');
|
||||||
|
const differentTargetMessage: string = localize('schemaCompareDialog.differentTargetMessage', 'A different target schema has been selected. Compare to see the comparison?');
|
||||||
|
const differentSourceTargetMessage: string = localize('schemaCompareDialog.differentSourceTargetMessage', 'Different source and target schemas have been selected. Compare to see the comparison?');
|
||||||
|
const YesButtonText: string = localize('schemaCompareDialog.Yes', 'Yes');
|
||||||
|
const NoButtonText: string = localize('schemaCompareDialog.No', 'No');
|
||||||
const titleFontSize: number = 13;
|
const titleFontSize: number = 13;
|
||||||
|
|
||||||
export class SchemaCompareDialog {
|
export class SchemaCompareDialog {
|
||||||
@@ -51,10 +57,16 @@ export class SchemaCompareDialog {
|
|||||||
private formBuilder: azdata.FormBuilder;
|
private formBuilder: azdata.FormBuilder;
|
||||||
private sourceIsDacpac: boolean;
|
private sourceIsDacpac: boolean;
|
||||||
private targetIsDacpac: boolean;
|
private targetIsDacpac: boolean;
|
||||||
private database: string;
|
|
||||||
private connectionId: string;
|
private connectionId: string;
|
||||||
private sourceDbEditable: string;
|
private sourceDbEditable: string;
|
||||||
private taregtDbEditable: string;
|
private taregtDbEditable: string;
|
||||||
|
private previousSource: azdata.SchemaCompareEndpointInfo;
|
||||||
|
private previousTarget: azdata.SchemaCompareEndpointInfo;
|
||||||
|
|
||||||
|
constructor(private schemaCompareResult: SchemaCompareResult) {
|
||||||
|
this.previousSource = schemaCompareResult.sourceEndpointInfo;
|
||||||
|
this.previousTarget = schemaCompareResult.targetEndpointInfo;
|
||||||
|
}
|
||||||
|
|
||||||
protected initializeDialog(): void {
|
protected initializeDialog(): void {
|
||||||
this.schemaCompareTab = azdata.window.createTab(SchemaCompareLabel);
|
this.schemaCompareTab = azdata.window.createTab(SchemaCompareLabel);
|
||||||
@@ -62,22 +74,14 @@ export class SchemaCompareDialog {
|
|||||||
this.dialog.content = [this.schemaCompareTab];
|
this.dialog.content = [this.schemaCompareTab];
|
||||||
}
|
}
|
||||||
|
|
||||||
public async openDialog(context: any, dialogName?: string): Promise<void> {
|
public async openDialog(): Promise<void> {
|
||||||
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
|
// connection to use if schema compare wasn't launched from a database or no previous source/target
|
||||||
if (profile) {
|
let connection = await azdata.connection.getCurrentConnection();
|
||||||
this.database = profile.databaseName;
|
if (connection) {
|
||||||
this.connectionId = profile.id;
|
this.connectionId = connection.connectionId;
|
||||||
} else {
|
|
||||||
let connection = await azdata.connection.getCurrentConnection();
|
|
||||||
if (connection) {
|
|
||||||
this.connectionId = connection.connectionId;
|
|
||||||
this.database = undefined;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let event = dialogName ? dialogName : null;
|
this.dialog = azdata.window.createModelViewDialog(SchemaCompareLabel);
|
||||||
this.dialog = azdata.window.createModelViewDialog(SchemaCompareLabel, event);
|
|
||||||
|
|
||||||
this.initializeDialog();
|
this.initializeDialog();
|
||||||
|
|
||||||
this.dialog.okButton.label = OkButtonText;
|
this.dialog.okButton.label = OkButtonText;
|
||||||
@@ -91,25 +95,21 @@ export class SchemaCompareDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async execute(): Promise<void> {
|
protected async execute(): Promise<void> {
|
||||||
let sourceName: string;
|
|
||||||
let targetName: string;
|
|
||||||
|
|
||||||
let sourceEndpointInfo: azdata.SchemaCompareEndpointInfo;
|
|
||||||
if (this.sourceIsDacpac) {
|
if (this.sourceIsDacpac) {
|
||||||
sourceName = this.sourceTextBox.value;
|
this.schemaCompareResult.sourceEndpointInfo = {
|
||||||
sourceEndpointInfo = {
|
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
packageFilePath: this.sourceTextBox.value
|
packageFilePath: this.sourceTextBox.value
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
sourceName = (this.sourceServerDropdown.value as ConnectionDropdownValue).name + '.' + (<azdata.CategoryValue>this.sourceDatabaseDropdown.value).name;
|
|
||||||
let ownerUri = await azdata.connection.getUriForConnection((this.sourceServerDropdown.value as ConnectionDropdownValue).connection.connectionId);
|
let ownerUri = await azdata.connection.getUriForConnection((this.sourceServerDropdown.value as ConnectionDropdownValue).connection.connectionId);
|
||||||
|
|
||||||
sourceEndpointInfo = {
|
this.schemaCompareResult.sourceEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Database,
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
|
serverDisplayName: (this.sourceServerDropdown.value as ConnectionDropdownValue).displayName,
|
||||||
serverName: (this.sourceServerDropdown.value as ConnectionDropdownValue).name,
|
serverName: (this.sourceServerDropdown.value as ConnectionDropdownValue).name,
|
||||||
databaseName: (<azdata.CategoryValue>this.sourceDatabaseDropdown.value).name,
|
databaseName: (<azdata.CategoryValue>this.sourceDatabaseDropdown.value).name,
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
@@ -117,22 +117,21 @@ export class SchemaCompareDialog {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetEndpointInfo: azdata.SchemaCompareEndpointInfo;
|
|
||||||
if (this.targetIsDacpac) {
|
if (this.targetIsDacpac) {
|
||||||
targetName = this.targetTextBox.value;
|
this.schemaCompareResult.targetEndpointInfo = {
|
||||||
targetEndpointInfo = {
|
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
packageFilePath: this.targetTextBox.value
|
packageFilePath: this.targetTextBox.value
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
targetName = (this.targetServerDropdown.value as ConnectionDropdownValue).name + '.' + (<azdata.CategoryValue>this.targetDatabaseDropdown.value).name;
|
|
||||||
let ownerUri = await azdata.connection.getUriForConnection((this.targetServerDropdown.value as ConnectionDropdownValue).connection.connectionId);
|
let ownerUri = await azdata.connection.getUriForConnection((this.targetServerDropdown.value as ConnectionDropdownValue).connection.connectionId);
|
||||||
|
|
||||||
targetEndpointInfo = {
|
this.schemaCompareResult.targetEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Database,
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
|
serverDisplayName: (this.targetServerDropdown.value as ConnectionDropdownValue).displayName,
|
||||||
serverName: (this.targetServerDropdown.value as ConnectionDropdownValue).name,
|
serverName: (this.targetServerDropdown.value as ConnectionDropdownValue).name,
|
||||||
databaseName: (<azdata.CategoryValue>this.targetDatabaseDropdown.value).name,
|
databaseName: (<azdata.CategoryValue>this.targetDatabaseDropdown.value).name,
|
||||||
ownerUri: ownerUri,
|
ownerUri: ownerUri,
|
||||||
@@ -144,8 +143,39 @@ export class SchemaCompareDialog {
|
|||||||
'sourceIsDacpac': this.sourceIsDacpac.toString(),
|
'sourceIsDacpac': this.sourceIsDacpac.toString(),
|
||||||
'targetIsDacpac': this.targetIsDacpac.toString()
|
'targetIsDacpac': this.targetIsDacpac.toString()
|
||||||
});
|
});
|
||||||
let schemaCompareResult = new SchemaCompareResult(sourceName, targetName, sourceEndpointInfo, targetEndpointInfo);
|
|
||||||
schemaCompareResult.start();
|
// update source and target values that are displayed
|
||||||
|
this.schemaCompareResult.updateSourceAndTarget();
|
||||||
|
|
||||||
|
const sourceEndpointChanged = this.endpointChanged(this.previousSource, this.schemaCompareResult.sourceEndpointInfo);
|
||||||
|
const targetEndpointChanged = this.endpointChanged(this.previousTarget, this.schemaCompareResult.targetEndpointInfo);
|
||||||
|
|
||||||
|
// show recompare message if it isn't the initial population of source and target
|
||||||
|
if (this.previousSource && this.previousTarget
|
||||||
|
&& (sourceEndpointChanged || targetEndpointChanged)) {
|
||||||
|
this.schemaCompareResult.setButtonsForRecompare();
|
||||||
|
|
||||||
|
let message = differentSourceMessage;
|
||||||
|
if (sourceEndpointChanged && targetEndpointChanged) {
|
||||||
|
message = differentSourceTargetMessage;
|
||||||
|
} else if (targetEndpointChanged) {
|
||||||
|
message = differentTargetMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
vscode.window.showWarningMessage(message, YesButtonText, NoButtonText).then((result) => {
|
||||||
|
if (result === YesButtonText) {
|
||||||
|
this.schemaCompareResult.startCompare();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private endpointChanged(previousEndpoint: azdata.SchemaCompareEndpointInfo, updatedEndpoint: azdata.SchemaCompareEndpointInfo): boolean {
|
||||||
|
if (previousEndpoint && updatedEndpoint) {
|
||||||
|
return getEndpointName(previousEndpoint).toLowerCase() !== getEndpointName(updatedEndpoint).toLowerCase()
|
||||||
|
|| previousEndpoint.serverDisplayName.toLocaleLowerCase() !== updatedEndpoint.serverDisplayName.toLowerCase();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async cancel(): Promise<void> {
|
protected async cancel(): Promise<void> {
|
||||||
@@ -154,6 +184,7 @@ export class SchemaCompareDialog {
|
|||||||
private initializeSchemaCompareTab(): void {
|
private initializeSchemaCompareTab(): void {
|
||||||
this.schemaCompareTab.registerContent(async view => {
|
this.schemaCompareTab.registerContent(async view => {
|
||||||
this.sourceTextBox = view.modelBuilder.inputBox().withProperties({
|
this.sourceTextBox = view.modelBuilder.inputBox().withProperties({
|
||||||
|
value: this.schemaCompareResult.sourceEndpointInfo ? this.schemaCompareResult.sourceEndpointInfo.packageFilePath : '',
|
||||||
width: 275
|
width: 275
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
@@ -162,6 +193,7 @@ export class SchemaCompareDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.targetTextBox = view.modelBuilder.inputBox().withProperties({
|
this.targetTextBox = view.modelBuilder.inputBox().withProperties({
|
||||||
|
value: this.schemaCompareResult.targetEndpointInfo ? this.schemaCompareResult.targetEndpointInfo.packageFilePath : '',
|
||||||
width: 275
|
width: 275
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
@@ -185,8 +217,8 @@ export class SchemaCompareDialog {
|
|||||||
await this.populateDatabaseDropdown((this.targetServerDropdown.value as ConnectionDropdownValue).connection.connectionId, true);
|
await this.populateDatabaseDropdown((this.targetServerDropdown.value as ConnectionDropdownValue).connection.connectionId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sourceDacpacComponent = await this.createFileBrowser(view, false);
|
this.sourceDacpacComponent = await this.createFileBrowser(view, false, this.schemaCompareResult.sourceEndpointInfo);
|
||||||
this.targetDacpacComponent = await this.createFileBrowser(view, true);
|
this.targetDacpacComponent = await this.createFileBrowser(view, true, this.schemaCompareResult.targetEndpointInfo);
|
||||||
|
|
||||||
let sourceRadioButtons = await this.createSourceRadiobuttons(view);
|
let sourceRadioButtons = await this.createSourceRadiobuttons(view);
|
||||||
let targetRadioButtons = await this.createTargetRadiobuttons(view);
|
let targetRadioButtons = await this.createTargetRadiobuttons(view);
|
||||||
@@ -194,63 +226,60 @@ export class SchemaCompareDialog {
|
|||||||
this.sourceNoActiveConnectionsText = await this.createNoActiveConnectionsText(view);
|
this.sourceNoActiveConnectionsText = await this.createNoActiveConnectionsText(view);
|
||||||
this.targetNoActiveConnectionsText = await this.createNoActiveConnectionsText(view);
|
this.targetNoActiveConnectionsText = await this.createNoActiveConnectionsText(view);
|
||||||
|
|
||||||
// if schema compare was launched from a db context menu, set that db as the source
|
let sourceComponents = [];
|
||||||
if (this.database) {
|
let targetComponents = [];
|
||||||
this.formBuilder = <azdata.FormBuilder>view.modelBuilder.formContainer()
|
|
||||||
.withFormItems([
|
// start source and target with either dacpac or database selection based on what the previous value was
|
||||||
{
|
if (this.schemaCompareResult.sourceEndpointInfo && this.schemaCompareResult.sourceEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
title: SourceTitle,
|
sourceComponents = [
|
||||||
components: [
|
sourceRadioButtons,
|
||||||
sourceRadioButtons,
|
this.sourceServerComponent,
|
||||||
this.sourceServerComponent,
|
this.sourceDatabaseComponent
|
||||||
this.sourceDatabaseComponent
|
];
|
||||||
]
|
|
||||||
}, {
|
|
||||||
title: TargetTitle,
|
|
||||||
components: [
|
|
||||||
targetRadioButtons,
|
|
||||||
this.targetDacpacComponent
|
|
||||||
]
|
|
||||||
}
|
|
||||||
], {
|
|
||||||
horizontal: true,
|
|
||||||
titleFontSize: titleFontSize
|
|
||||||
})
|
|
||||||
.withLayout({
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px 10px 0 30px'
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
this.formBuilder = <azdata.FormBuilder>view.modelBuilder.formContainer()
|
sourceComponents = [
|
||||||
.withFormItems([
|
sourceRadioButtons,
|
||||||
{
|
this.sourceDacpacComponent,
|
||||||
title: SourceTitle,
|
];
|
||||||
components: [
|
|
||||||
sourceRadioButtons,
|
|
||||||
this.sourceDacpacComponent,
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
title: TargetTitle,
|
|
||||||
components: [
|
|
||||||
targetRadioButtons,
|
|
||||||
this.targetDacpacComponent
|
|
||||||
]
|
|
||||||
}
|
|
||||||
], {
|
|
||||||
horizontal: true,
|
|
||||||
titleFontSize: titleFontSize
|
|
||||||
})
|
|
||||||
.withLayout({
|
|
||||||
width: '100%',
|
|
||||||
padding: '10px 10px 0 30px'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.schemaCompareResult.targetEndpointInfo && this.schemaCompareResult.targetEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
|
targetComponents = [
|
||||||
|
targetRadioButtons,
|
||||||
|
this.targetServerComponent,
|
||||||
|
this.targetDatabaseComponent
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
targetComponents = [
|
||||||
|
targetRadioButtons,
|
||||||
|
this.targetDacpacComponent,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.formBuilder = <azdata.FormBuilder>view.modelBuilder.formContainer()
|
||||||
|
.withFormItems([
|
||||||
|
{
|
||||||
|
title: SourceTitle,
|
||||||
|
components: sourceComponents
|
||||||
|
}, {
|
||||||
|
title: TargetTitle,
|
||||||
|
components: targetComponents
|
||||||
|
}
|
||||||
|
], {
|
||||||
|
horizontal: true,
|
||||||
|
titleFontSize: titleFontSize
|
||||||
|
})
|
||||||
|
.withLayout({
|
||||||
|
width: '100%',
|
||||||
|
padding: '10px 10px 0 30px'
|
||||||
|
});
|
||||||
|
|
||||||
let formModel = this.formBuilder.component();
|
let formModel = this.formBuilder.component();
|
||||||
await view.initializeModel(formModel);
|
await view.initializeModel(formModel);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createFileBrowser(view: azdata.ModelView, isTarget: boolean): Promise<azdata.FormComponent> {
|
private async createFileBrowser(view: azdata.ModelView, isTarget: boolean, endpoint: azdata.SchemaCompareEndpointInfo): Promise<azdata.FormComponent> {
|
||||||
let currentTextbox = isTarget ? this.targetTextBox : this.sourceTextBox;
|
let currentTextbox = isTarget ? this.targetTextBox : this.sourceTextBox;
|
||||||
if (isTarget) {
|
if (isTarget) {
|
||||||
this.targetFileButton = view.modelBuilder.button().withProperties({
|
this.targetFileButton = view.modelBuilder.button().withProperties({
|
||||||
@@ -265,13 +294,16 @@ export class SchemaCompareDialog {
|
|||||||
let currentButton = isTarget ? this.targetFileButton : this.sourceFileButton;
|
let currentButton = isTarget ? this.targetFileButton : this.sourceFileButton;
|
||||||
|
|
||||||
currentButton.onDidClick(async (click) => {
|
currentButton.onDidClick(async (click) => {
|
||||||
|
// file browser should open where the current dacpac is or the appropriate default folder
|
||||||
let rootPath = vscode.workspace.rootPath ? vscode.workspace.rootPath : os.homedir();
|
let rootPath = vscode.workspace.rootPath ? vscode.workspace.rootPath : os.homedir();
|
||||||
|
let defaultUri = endpoint && endpoint.packageFilePath && existsSync(endpoint.packageFilePath) ? endpoint.packageFilePath : rootPath;
|
||||||
|
|
||||||
let fileUris = await vscode.window.showOpenDialog(
|
let fileUris = await vscode.window.showOpenDialog(
|
||||||
{
|
{
|
||||||
canSelectFiles: true,
|
canSelectFiles: true,
|
||||||
canSelectFolders: false,
|
canSelectFolders: false,
|
||||||
canSelectMany: false,
|
canSelectMany: false,
|
||||||
defaultUri: vscode.Uri.file(rootPath),
|
defaultUri: vscode.Uri.file(defaultUri),
|
||||||
openLabel: localize('schemaCompare.openFile', 'Open'),
|
openLabel: localize('schemaCompare.openFile', 'Open'),
|
||||||
filters: {
|
filters: {
|
||||||
'dacpac Files': ['dacpac'],
|
'dacpac Files': ['dacpac'],
|
||||||
@@ -330,7 +362,8 @@ export class SchemaCompareDialog {
|
|||||||
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
|
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.database) {
|
// if source is currently a db, show it in the server and db dropdowns
|
||||||
|
if (this.schemaCompareResult.sourceEndpointInfo && this.schemaCompareResult.sourceEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
databaseRadioButton.checked = true;
|
databaseRadioButton.checked = true;
|
||||||
this.sourceIsDacpac = false;
|
this.sourceIsDacpac = false;
|
||||||
} else {
|
} else {
|
||||||
@@ -384,8 +417,15 @@ export class SchemaCompareDialog {
|
|||||||
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
|
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
|
||||||
});
|
});
|
||||||
|
|
||||||
dacpacRadioButton.checked = true;
|
// if target is currently a db, show it in the server and db dropdowns
|
||||||
this.targetIsDacpac = true;
|
if (this.schemaCompareResult.targetEndpointInfo && this.schemaCompareResult.targetEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
|
databaseRadioButton.checked = true;
|
||||||
|
this.targetIsDacpac = false;
|
||||||
|
} else {
|
||||||
|
dacpacRadioButton.checked = true;
|
||||||
|
this.targetIsDacpac = true;
|
||||||
|
}
|
||||||
|
|
||||||
let flexRadioButtonsModel = view.modelBuilder.flexContainer()
|
let flexRadioButtonsModel = view.modelBuilder.flexContainer()
|
||||||
.withLayout({ flexFlow: 'column' })
|
.withLayout({ flexFlow: 'column' })
|
||||||
.withItems([dacpacRadioButton, databaseRadioButton]
|
.withItems([dacpacRadioButton, databaseRadioButton]
|
||||||
@@ -463,7 +503,7 @@ export class SchemaCompareDialog {
|
|||||||
|
|
||||||
protected async populateServerDropdown(isTarget: boolean): Promise<void> {
|
protected async populateServerDropdown(isTarget: boolean): Promise<void> {
|
||||||
let currentDropdown = isTarget ? this.targetServerDropdown : this.sourceServerDropdown;
|
let currentDropdown = isTarget ? this.targetServerDropdown : this.sourceServerDropdown;
|
||||||
let values = await this.getServerValues();
|
let values = await this.getServerValues(isTarget);
|
||||||
|
|
||||||
if (values && values.length > 0) {
|
if (values && values.length > 0) {
|
||||||
currentDropdown.updateProperties({
|
currentDropdown.updateProperties({
|
||||||
@@ -473,13 +513,14 @@ export class SchemaCompareDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getServerValues(): Promise<{ connection: azdata.connection.Connection, displayName: string, name: string }[]> {
|
protected async getServerValues(isTarget: boolean): Promise<{ connection: azdata.connection.Connection, displayName: string, name: string }[]> {
|
||||||
let cons = await azdata.connection.getActiveConnections();
|
let cons = await azdata.connection.getActiveConnections();
|
||||||
// This user has no active connections
|
// This user has no active connections
|
||||||
if (!cons || cons.length === 0) {
|
if (!cons || cons.length === 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let endpointInfo = isTarget ? this.schemaCompareResult.targetEndpointInfo : this.schemaCompareResult.sourceEndpointInfo;
|
||||||
// reverse list so that most recent connections are first
|
// reverse list so that most recent connections are first
|
||||||
cons.reverse();
|
cons.reverse();
|
||||||
|
|
||||||
@@ -488,10 +529,6 @@ export class SchemaCompareDialog {
|
|||||||
let values = cons.map(c => {
|
let values = cons.map(c => {
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (c.connectionId === this.connectionId) {
|
|
||||||
idx = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
let usr = c.options.user;
|
let usr = c.options.user;
|
||||||
let srv = c.options.server;
|
let srv = c.options.server;
|
||||||
|
|
||||||
@@ -500,10 +537,24 @@ export class SchemaCompareDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let finalName = `${srv} (${usr})`;
|
let finalName = `${srv} (${usr})`;
|
||||||
|
if (endpointInfo) {
|
||||||
|
console.error('finalname: ' + finalName + ' endpointname: ' + endpointInfo.serverDisplayName);
|
||||||
|
}
|
||||||
|
// use previously selected server or current connection if there is one
|
||||||
|
if (endpointInfo && endpointInfo.serverName !== null
|
||||||
|
&& c.options.server.toLowerCase() === endpointInfo.serverName.toLowerCase()
|
||||||
|
&& finalName.toLowerCase() === endpointInfo.serverDisplayName.toLowerCase()) {
|
||||||
|
idx = count;
|
||||||
|
}
|
||||||
|
else if (c.connectionId === this.connectionId) {
|
||||||
|
idx = count;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
connection: c,
|
connection: c,
|
||||||
displayName: finalName,
|
displayName: finalName,
|
||||||
name: srv
|
name: srv,
|
||||||
|
user: usr
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -569,7 +620,7 @@ export class SchemaCompareDialog {
|
|||||||
let currentDropdown = isTarget ? this.targetDatabaseDropdown : this.sourceDatabaseDropdown;
|
let currentDropdown = isTarget ? this.targetDatabaseDropdown : this.sourceDatabaseDropdown;
|
||||||
currentDropdown.updateProperties({ values: [], value: null });
|
currentDropdown.updateProperties({ values: [], value: null });
|
||||||
|
|
||||||
let values = await this.getDatabaseValues(connectionId);
|
let values = await this.getDatabaseValues(connectionId, isTarget);
|
||||||
if (values && values.length > 0) {
|
if (values && values.length > 0) {
|
||||||
currentDropdown.updateProperties({
|
currentDropdown.updateProperties({
|
||||||
values: values,
|
values: values,
|
||||||
@@ -578,13 +629,17 @@ export class SchemaCompareDialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getDatabaseValues(connectionId: string): Promise<{ displayName, name }[]> {
|
protected async getDatabaseValues(connectionId: string, isTarget: boolean): Promise<{ displayName, name }[]> {
|
||||||
|
let endpointInfo = isTarget ? this.schemaCompareResult.targetEndpointInfo : this.schemaCompareResult.sourceEndpointInfo;
|
||||||
|
|
||||||
let idx = -1;
|
let idx = -1;
|
||||||
let count = -1;
|
let count = -1;
|
||||||
let values = (await azdata.connection.listDatabases(connectionId)).map(db => {
|
let values = (await azdata.connection.listDatabases(connectionId)).map(db => {
|
||||||
count++;
|
count++;
|
||||||
// if schema compare was launched from a db context menu, set that db at the top of the dropdown
|
|
||||||
if (this.database && db === this.database) {
|
// put currently selected db at the top of the dropdown if there is one
|
||||||
|
if (endpointInfo && endpointInfo.databaseName !== null
|
||||||
|
&& db === endpointInfo.databaseName) {
|
||||||
idx = count;
|
idx = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import * as os from 'os';
|
|||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import { SchemaCompareOptionsDialog } from './dialogs/schemaCompareOptionsDialog';
|
import { SchemaCompareOptionsDialog } from './dialogs/schemaCompareOptionsDialog';
|
||||||
import { Telemetry } from './telemetry';
|
import { Telemetry } from './telemetry';
|
||||||
import { getTelemetryErrorType } from './utils';
|
import { getTelemetryErrorType, getEndpointName } from './utils';
|
||||||
|
import { SchemaCompareDialog } from './dialogs/schemaCompareDialog';
|
||||||
const localize = nls.loadMessageBundle();
|
const localize = nls.loadMessageBundle();
|
||||||
const diffEditorTitle = localize('schemaCompare.CompareDetailsTitle', 'Compare Details');
|
const diffEditorTitle = localize('schemaCompare.CompareDetailsTitle', 'Compare Details');
|
||||||
const applyConfirmation = localize('schemaCompare.ApplyConfirmation', 'Are you sure you want to update the target?');
|
const applyConfirmation = localize('schemaCompare.ApplyConfirmation', 'Are you sure you want to update the target?');
|
||||||
@@ -40,6 +41,8 @@ export class SchemaCompareResult {
|
|||||||
private optionsButton: azdata.ButtonComponent;
|
private optionsButton: azdata.ButtonComponent;
|
||||||
private generateScriptButton: azdata.ButtonComponent;
|
private generateScriptButton: azdata.ButtonComponent;
|
||||||
private applyButton: azdata.ButtonComponent;
|
private applyButton: azdata.ButtonComponent;
|
||||||
|
private selectSourceButton: azdata.ButtonComponent;
|
||||||
|
private selectTargetButton: azdata.ButtonComponent;
|
||||||
private SchemaCompareActionMap: Map<Number, string>;
|
private SchemaCompareActionMap: Map<Number, string>;
|
||||||
private comparisonResult: azdata.SchemaCompareResult;
|
private comparisonResult: azdata.SchemaCompareResult;
|
||||||
private sourceNameComponent: azdata.TableComponent;
|
private sourceNameComponent: azdata.TableComponent;
|
||||||
@@ -50,18 +53,37 @@ export class SchemaCompareResult {
|
|||||||
private originalSourceExcludes = new Map<string, azdata.DiffEntry>();
|
private originalSourceExcludes = new Map<string, azdata.DiffEntry>();
|
||||||
private originalTargetExcludes = new Map<string, azdata.DiffEntry>();
|
private originalTargetExcludes = new Map<string, azdata.DiffEntry>();
|
||||||
private sourceTargetSwitched = false;
|
private sourceTargetSwitched = false;
|
||||||
|
private sourceName: string;
|
||||||
|
private targetName: string;
|
||||||
|
|
||||||
constructor(private sourceName: string, private targetName: string, private sourceEndpointInfo: azdata.SchemaCompareEndpointInfo, private targetEndpointInfo: azdata.SchemaCompareEndpointInfo) {
|
public sourceEndpointInfo: azdata.SchemaCompareEndpointInfo;
|
||||||
|
public targetEndpointInfo: azdata.SchemaCompareEndpointInfo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
this.SchemaCompareActionMap = new Map<Number, string>();
|
this.SchemaCompareActionMap = new Map<Number, string>();
|
||||||
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Delete] = localize('schemaCompare.deleteAction', 'Delete');
|
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Delete] = localize('schemaCompare.deleteAction', 'Delete');
|
||||||
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Change] = localize('schemaCompare.changeAction', 'Change');
|
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Change] = localize('schemaCompare.changeAction', 'Change');
|
||||||
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Add] = localize('schemaCompare.addAction', 'Add');
|
this.SchemaCompareActionMap[azdata.SchemaUpdateAction.Add] = localize('schemaCompare.addAction', 'Add');
|
||||||
|
|
||||||
this.editor = azdata.workspace.createModelViewEditor(localize('schemaCompare.Title', 'Schema Compare'), { retainContextWhenHidden: true, supportsSave: true, resourceName: schemaCompareResourceName });
|
this.editor = azdata.workspace.createModelViewEditor(localize('schemaCompare.Title', 'Schema Compare'), { retainContextWhenHidden: true, supportsSave: true, resourceName: schemaCompareResourceName });
|
||||||
this.GetDefaultDeploymentOptions();
|
}
|
||||||
|
|
||||||
|
public async start(context: any) {
|
||||||
|
// if schema compare was launched from a db, set that as the source
|
||||||
|
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
|
||||||
|
if (profile) {
|
||||||
|
let ownerUri = await azdata.connection.getUriForConnection((profile.id));
|
||||||
|
this.sourceEndpointInfo = {
|
||||||
|
endpointType: azdata.SchemaCompareEndpointType.Database,
|
||||||
|
serverDisplayName: `${profile.serverName} ${profile.userName}`,
|
||||||
|
serverName: profile.serverName,
|
||||||
|
databaseName: profile.databaseName,
|
||||||
|
ownerUri: ownerUri,
|
||||||
|
packageFilePath: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
this.editor.registerContent(async view => {
|
this.editor.registerContent(async view => {
|
||||||
|
|
||||||
this.differencesTable = view.modelBuilder.table().withProperties({
|
this.differencesTable = view.modelBuilder.table().withProperties({
|
||||||
data: [],
|
data: [],
|
||||||
height: 300
|
height: 300
|
||||||
@@ -93,7 +115,8 @@ export class SchemaCompareResult {
|
|||||||
this.createGenerateScriptButton(view);
|
this.createGenerateScriptButton(view);
|
||||||
this.createApplyButton(view);
|
this.createApplyButton(view);
|
||||||
this.createOptionsButton(view);
|
this.createOptionsButton(view);
|
||||||
this.resetButtons(true);
|
this.createSourceAndTargetButtons(view);
|
||||||
|
this.resetButtons(false); // disable buttons because source and target aren't both selected yet
|
||||||
|
|
||||||
let toolBar = view.modelBuilder.toolbarContainer();
|
let toolBar = view.modelBuilder.toolbarContainer();
|
||||||
toolBar.addToolbarItems([{
|
toolBar.addToolbarItems([{
|
||||||
@@ -123,12 +146,13 @@ export class SchemaCompareResult {
|
|||||||
value: localize('schemaCompare.switchLabel', '➔')
|
value: localize('schemaCompare.switchLabel', '➔')
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
|
this.sourceName = this.sourceEndpointInfo ? `${this.sourceEndpointInfo.serverName}.${this.sourceEndpointInfo.databaseName}` : ' ';
|
||||||
this.sourceNameComponent = view.modelBuilder.table().withProperties({
|
this.sourceNameComponent = view.modelBuilder.table().withProperties({
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
value: sourceName,
|
value: this.sourceName,
|
||||||
headerCssClass: 'no-borders',
|
headerCssClass: 'no-borders',
|
||||||
toolTip: sourceName
|
toolTip: this.sourceName
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}).component();
|
}).component();
|
||||||
@@ -136,18 +160,20 @@ export class SchemaCompareResult {
|
|||||||
this.targetNameComponent = view.modelBuilder.table().withProperties({
|
this.targetNameComponent = view.modelBuilder.table().withProperties({
|
||||||
columns: [
|
columns: [
|
||||||
{
|
{
|
||||||
value: targetName,
|
value: ' ',
|
||||||
headerCssClass: 'no-borders',
|
headerCssClass: 'no-borders',
|
||||||
toolTip: targetName
|
toolTip: ''
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
sourceTargetLabels.addItem(sourceLabel, { CSSStyles: { 'width': '55%', 'margin-left': '15px', 'font-size': 'larger', 'font-weight': 'bold' } });
|
sourceTargetLabels.addItem(sourceLabel, { CSSStyles: { 'width': '55%', 'margin-left': '15px', 'font-size': 'larger', 'font-weight': 'bold' } });
|
||||||
sourceTargetLabels.addItem(targetLabel, { CSSStyles: { 'width': '45%', 'font-size': 'larger', 'font-weight': 'bold' } });
|
sourceTargetLabels.addItem(targetLabel, { CSSStyles: { 'width': '45%', 'font-size': 'larger', 'font-weight': 'bold' } });
|
||||||
this.sourceTargetFlexLayout.addItem(this.sourceNameComponent, { CSSStyles: { 'width': '45%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
this.sourceTargetFlexLayout.addItem(this.sourceNameComponent, { CSSStyles: { 'width': '40%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(this.selectSourceButton, { CSSStyles: { 'margin-top': '10px' } });
|
||||||
this.sourceTargetFlexLayout.addItem(arrowLabel, { CSSStyles: { 'width': '10%', 'font-size': 'larger', 'text-align-last': 'center' } });
|
this.sourceTargetFlexLayout.addItem(arrowLabel, { CSSStyles: { 'width': '10%', 'font-size': 'larger', 'text-align-last': 'center' } });
|
||||||
this.sourceTargetFlexLayout.addItem(this.targetNameComponent, { CSSStyles: { 'width': '45%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
this.sourceTargetFlexLayout.addItem(this.targetNameComponent, { CSSStyles: { 'width': '40%', 'height': '25px', 'margin-top': '10px', 'margin-left': '15px' } });
|
||||||
|
this.sourceTargetFlexLayout.addItem(this.selectTargetButton, { CSSStyles: { 'margin-top': '10px' } });
|
||||||
|
|
||||||
this.loader = view.modelBuilder.loadingComponent().component();
|
this.loader = view.modelBuilder.loadingComponent().component();
|
||||||
this.waitText = view.modelBuilder.text().withProperties({
|
this.waitText = view.modelBuilder.text().withProperties({
|
||||||
@@ -155,7 +181,7 @@ export class SchemaCompareResult {
|
|||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.startText = view.modelBuilder.text().withProperties({
|
this.startText = view.modelBuilder.text().withProperties({
|
||||||
value: localize('schemaCompare.startText', 'Press Compare to start Schema Comparison.')
|
value: localize('schemaCompare.startText', 'To compare two schemas, first select a source schema and target schema, then press Compare.')
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.noDifferencesLabel = view.modelBuilder.text().withProperties({
|
this.noDifferencesLabel = view.modelBuilder.text().withProperties({
|
||||||
@@ -175,10 +201,33 @@ export class SchemaCompareResult {
|
|||||||
|
|
||||||
await view.initializeModel(this.flexModel);
|
await view.initializeModel(this.flexModel);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await this.GetDefaultDeploymentOptions();
|
||||||
|
this.editor.openEditor();
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(): void {
|
// update source and target name to display
|
||||||
this.editor.openEditor();
|
public updateSourceAndTarget() {
|
||||||
|
this.sourceName = getEndpointName(this.sourceEndpointInfo);
|
||||||
|
this.targetName = getEndpointName(this.targetEndpointInfo);
|
||||||
|
|
||||||
|
this.sourceNameComponent.updateProperty('columns', [
|
||||||
|
{
|
||||||
|
value: this.sourceName,
|
||||||
|
headerCssClass: 'no-borders',
|
||||||
|
toolTip: this.sourceName
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
this.targetNameComponent.updateProperty('columns', [
|
||||||
|
{
|
||||||
|
value: this.targetName,
|
||||||
|
headerCssClass: 'no-borders',
|
||||||
|
toolTip: this.targetName
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// reset buttons to before comparison state
|
||||||
|
this.resetButtons(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// only for test
|
// only for test
|
||||||
@@ -525,10 +574,7 @@ export class SchemaCompareResult {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// disable apply and generate script buttons because the results are no longer valid after applying the changes
|
// disable apply and generate script buttons because the results are no longer valid after applying the changes
|
||||||
this.generateScriptButton.enabled = false;
|
this.setButtonsForRecompare();
|
||||||
this.generateScriptButton.title = reCompareToRefeshMessage;
|
|
||||||
this.applyButton.enabled = false;
|
|
||||||
this.applyButton.title = reCompareToRefeshMessage;
|
|
||||||
|
|
||||||
const service = await SchemaCompareResult.getService('MSSQL');
|
const service = await SchemaCompareResult.getService('MSSQL');
|
||||||
const result = await service.schemaComparePublishChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
|
const result = await service.schemaComparePublishChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
|
||||||
@@ -572,6 +618,13 @@ export class SchemaCompareResult {
|
|||||||
this.applyButton.title = applyEnabledMessage;
|
this.applyButton.title = applyEnabledMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setButtonsForRecompare(): void {
|
||||||
|
this.generateScriptButton.enabled = false;
|
||||||
|
this.applyButton.enabled = false;
|
||||||
|
this.generateScriptButton.title = reCompareToRefeshMessage;
|
||||||
|
this.applyButton.title = reCompareToRefeshMessage;
|
||||||
|
}
|
||||||
|
|
||||||
private createSwitchButton(view: azdata.ModelView): void {
|
private createSwitchButton(view: azdata.ModelView): void {
|
||||||
this.switchButton = view.modelBuilder.button().withProperties({
|
this.switchButton = view.modelBuilder.button().withProperties({
|
||||||
label: localize('schemaCompare.switchDirectionButton', 'Switch direction'),
|
label: localize('schemaCompare.switchDirectionButton', 'Switch direction'),
|
||||||
@@ -615,6 +668,30 @@ export class SchemaCompareResult {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private createSourceAndTargetButtons(view: azdata.ModelView): void {
|
||||||
|
this.selectSourceButton = view.modelBuilder.button().withProperties({
|
||||||
|
label: '•••',
|
||||||
|
title: localize('schemaCompare.sourceButtonTitle', 'Select Source')
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.selectSourceButton.onDidClick(() => {
|
||||||
|
Telemetry.sendTelemetryEvent('SchemaCompareSelectSource');
|
||||||
|
let dialog = new SchemaCompareDialog(this);
|
||||||
|
dialog.openDialog();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectTargetButton = view.modelBuilder.button().withProperties({
|
||||||
|
label: '•••',
|
||||||
|
title: localize('schemaCompare.targetButtonTitle', 'Select Target')
|
||||||
|
}).component();
|
||||||
|
|
||||||
|
this.selectTargetButton.onDidClick(() => {
|
||||||
|
Telemetry.sendTelemetryEvent('SchemaCompareSelectTarget');
|
||||||
|
let dialog = new SchemaCompareDialog(this);
|
||||||
|
dialog.openDialog();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private setButtonStatesForNoChanges(enableButtons: boolean): void {
|
private setButtonStatesForNoChanges(enableButtons: boolean): void {
|
||||||
// generate script and apply can only be enabled if the target is a database
|
// generate script and apply can only be enabled if the target is a database
|
||||||
if (this.targetEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
if (this.targetEndpointInfo.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
|
|||||||
@@ -14,19 +14,19 @@ import { SchemaCompareTestService } from './testSchemaCompareService';
|
|||||||
|
|
||||||
// Mock test data
|
// Mock test data
|
||||||
const mockConnectionProfile: azdata.IConnectionProfile = {
|
const mockConnectionProfile: azdata.IConnectionProfile = {
|
||||||
connectionName: 'My Connection',
|
connectionName: 'My Connection',
|
||||||
serverName: 'My Server',
|
serverName: 'My Server',
|
||||||
databaseName: 'My Server',
|
databaseName: 'My Server',
|
||||||
userName: 'My User',
|
userName: 'My User',
|
||||||
password: 'My Pwd',
|
password: 'My Pwd',
|
||||||
authenticationType: 'SqlLogin',
|
authenticationType: 'SqlLogin',
|
||||||
savePassword: false,
|
savePassword: false,
|
||||||
groupFullName: 'My groupName',
|
groupFullName: 'My groupName',
|
||||||
groupId: 'My GroupId',
|
groupId: 'My GroupId',
|
||||||
providerName: 'My Server',
|
providerName: 'My Server',
|
||||||
saveProfile: true,
|
saveProfile: true,
|
||||||
id: 'My Id',
|
id: 'My Id',
|
||||||
options: null
|
options: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const mocksource: string = 'source.dacpac';
|
const mocksource: string = 'source.dacpac';
|
||||||
@@ -34,6 +34,7 @@ const mocktarget: string = 'target.dacpac';
|
|||||||
|
|
||||||
const mockSourceEndpoint: azdata.SchemaCompareEndpointInfo = {
|
const mockSourceEndpoint: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
@@ -42,16 +43,18 @@ const mockSourceEndpoint: azdata.SchemaCompareEndpointInfo = {
|
|||||||
|
|
||||||
const mockTargetEndpoint: azdata.SchemaCompareEndpointInfo = {
|
const mockTargetEndpoint: azdata.SchemaCompareEndpointInfo = {
|
||||||
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
endpointType: azdata.SchemaCompareEndpointType.Dacpac,
|
||||||
|
serverDisplayName: '',
|
||||||
serverName: '',
|
serverName: '',
|
||||||
databaseName: '',
|
databaseName: '',
|
||||||
ownerUri: '',
|
ownerUri: '',
|
||||||
packageFilePath: mocktarget
|
packageFilePath: mocktarget
|
||||||
};
|
};
|
||||||
|
|
||||||
describe('SchemaCompareDialog.openDialog', function(): void {
|
describe('SchemaCompareDialog.openDialog', function (): void {
|
||||||
it('Should be correct when created.', async function(): Promise<void> {
|
it('Should be correct when created.', async function (): Promise<void> {
|
||||||
let dialog = new SchemaCompareDialog();
|
let schemaCompareResult = new SchemaCompareResult();
|
||||||
await dialog.openDialog(mockConnectionProfile);
|
let dialog = new SchemaCompareDialog(schemaCompareResult);
|
||||||
|
await dialog.openDialog();
|
||||||
|
|
||||||
should(dialog.dialog.title).equal('Schema Compare');
|
should(dialog.dialog.title).equal('Schema Compare');
|
||||||
should(dialog.dialog.okButton.label).equal('Ok');
|
should(dialog.dialog.okButton.label).equal('Ok');
|
||||||
@@ -59,17 +62,19 @@ describe('SchemaCompareDialog.openDialog', function(): void {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('SchemaCompareResult.start', function(): void {
|
describe('SchemaCompareResult.start', function (): void {
|
||||||
it('Should be correct when created.', async function(): Promise<void> {
|
it('Should be correct when created.', async function (): Promise<void> {
|
||||||
let sc = new SchemaCompareTestService();
|
let sc = new SchemaCompareTestService();
|
||||||
azdata.dataprotocol.registerSchemaCompareServicesProvider(sc);
|
azdata.dataprotocol.registerSchemaCompareServicesProvider(sc);
|
||||||
|
|
||||||
let result = new SchemaCompareResult(mocksource, mocktarget, mockSourceEndpoint, mockTargetEndpoint);
|
let result = new SchemaCompareResult();
|
||||||
|
await result.start(null);
|
||||||
let promise = new Promise(resolve => setTimeout(resolve, 3000)); // to ensure comparision result view is initialized
|
let promise = new Promise(resolve => setTimeout(resolve, 3000)); // to ensure comparision result view is initialized
|
||||||
await promise;
|
await promise;
|
||||||
await result.start();
|
|
||||||
|
|
||||||
should(result.getComparisonResult() === undefined);
|
should(result.getComparisonResult() === undefined);
|
||||||
|
result.sourceEndpointInfo = mockSourceEndpoint;
|
||||||
|
result.targetEndpointInfo = mockTargetEndpoint;
|
||||||
await result.execute();
|
await result.execute();
|
||||||
|
|
||||||
should(result.getComparisonResult() !== undefined);
|
should(result.getComparisonResult() !== undefined);
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ export class SchemaCompareTestService implements azdata.SchemaCompareServicesPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
schemaCompareGetDefaultOptions(): Thenable<azdata.SchemaCompareOptionsResult> {
|
schemaCompareGetDefaultOptions(): Thenable<azdata.SchemaCompareOptionsResult> {
|
||||||
throw new Error('Method not implemented.');
|
let result: azdata.SchemaCompareOptionsResult = {
|
||||||
|
defaultDeploymentOptions: undefined,
|
||||||
|
success: true,
|
||||||
|
errorMessage: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
return Promise.resolve(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
schemaCompareIncludeExcludeNode(operationId: string, diffEntry: azdata.DiffEntry, IncludeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
schemaCompareIncludeExcludeNode(operationId: string, diffEntry: azdata.DiffEntry, IncludeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
*--------------------------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------------------------*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
import * as azdata from 'azdata';
|
||||||
|
|
||||||
export interface IPackageInfo {
|
export interface IPackageInfo {
|
||||||
name: string;
|
name: string;
|
||||||
@@ -31,4 +32,20 @@ export function getTelemetryErrorType(msg: string): string {
|
|||||||
else {
|
else {
|
||||||
return 'Other';
|
return 'Other';
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the appropriate endpoint name depending on if the endpoint is a dacpac or a database
|
||||||
|
* @param endpoint endpoint to get the name of
|
||||||
|
*/
|
||||||
|
export function getEndpointName(endpoint: azdata.SchemaCompareEndpointInfo): string {
|
||||||
|
if (!endpoint) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (endpoint.endpointType === azdata.SchemaCompareEndpointType.Database) {
|
||||||
|
return `${endpoint.serverName}.${endpoint.databaseName}`;
|
||||||
|
} else {
|
||||||
|
return endpoint.packageFilePath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
1
src/sql/azdata.proposed.d.ts
vendored
1
src/sql/azdata.proposed.d.ts
vendored
@@ -1747,6 +1747,7 @@ declare module 'azdata' {
|
|||||||
export interface SchemaCompareEndpointInfo {
|
export interface SchemaCompareEndpointInfo {
|
||||||
endpointType: SchemaCompareEndpointType;
|
endpointType: SchemaCompareEndpointType;
|
||||||
packageFilePath: string;
|
packageFilePath: string;
|
||||||
|
serverDisplayName: string;
|
||||||
serverName: string;
|
serverName: string;
|
||||||
databaseName: string;
|
databaseName: string;
|
||||||
ownerUri: string;
|
ownerUri: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user