Implement a no sync rule (#7216)

* implement a no sync rule

* fix linting disable

* fix unused imports

* exclude more testing

* clean up fs usage

* clean up more fs usage

* remove duplicate of code

* fix compile errors
This commit is contained in:
Anthony Dresser
2019-09-17 13:32:42 -07:00
committed by GitHub
parent 4d62983680
commit 28d453fced
31 changed files with 305 additions and 201 deletions

View File

@@ -64,7 +64,7 @@
},
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^10.14.8",
"@types/node": "^10.14.8",
"mocha": "^5.2.0",
"should": "^13.2.1",
"typemoq": "^2.1.0",

View File

@@ -9,8 +9,7 @@ import * as azdata from 'azdata';
import * as vscode from 'vscode';
import * as os from 'os';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { isNullOrUndefined } from 'util';
import { existsSync } from 'fs';
import { promises as fs } from 'fs';
import { Telemetry } from '../telemetry';
import { getEndpointName } from '../utils';
import * as mssql from '../../../mssql';
@@ -35,6 +34,15 @@ const YesButtonText: string = localize('schemaCompareDialog.Yes', 'Yes');
const NoButtonText: string = localize('schemaCompareDialog.No', 'No');
const titleFontSize: number = 13;
async function exists(path: string): Promise<boolean> {
try {
await fs.access(path);
return true;
} catch (e) {
return false;
}
}
export class SchemaCompareDialog {
public dialog: azdata.window.Dialog;
public dialogName: string;
@@ -194,8 +202,8 @@ export class SchemaCompareDialog {
ariaLabel: localize('schemaCompareDialog.sourceTextBox', "Source file")
}).component();
this.sourceTextBox.onTextChanged((e) => {
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.sourceTextBox.onTextChanged(async (e) => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.targetTextBox = view.modelBuilder.inputBox().withProperties({
@@ -204,8 +212,8 @@ export class SchemaCompareDialog {
ariaLabel: localize('schemaCompareDialog.targetTextBox', "Target file")
}).component();
this.targetTextBox.onTextChanged(() => {
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.targetTextBox.onTextChanged(async () => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.sourceServerComponent = await this.createSourceServerDropdown(view);
@@ -307,7 +315,7 @@ export class SchemaCompareDialog {
currentButton.onDidClick(async (click) => {
// file browser should open where the current dacpac is or the appropriate default folder
let rootPath = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].name : os.homedir();
let defaultUri = endpoint && endpoint.packageFilePath && existsSync(endpoint.packageFilePath) ? endpoint.packageFilePath : rootPath;
let defaultUri = endpoint && endpoint.packageFilePath && await exists(endpoint.packageFilePath) ? endpoint.packageFilePath : rootPath;
let fileUris = await vscode.window.showOpenDialog(
{
@@ -351,17 +359,17 @@ export class SchemaCompareDialog {
}).component();
// show dacpac file browser
dacpacRadioButton.onDidClick(() => {
dacpacRadioButton.onDidClick(async () => {
this.sourceIsDacpac = true;
this.formBuilder.removeFormItem(this.sourceNoActiveConnectionsText);
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.insertFormItem(this.sourceDacpacComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns or 'No active connections' text
databaseRadioButton.onDidClick(() => {
databaseRadioButton.onDidClick(async () => {
this.sourceIsDacpac = false;
if ((this.sourceServerDropdown.value as ConnectionDropdownValue)) {
this.formBuilder.insertFormItem(this.sourceServerComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
@@ -370,7 +378,7 @@ export class SchemaCompareDialog {
this.formBuilder.insertFormItem(this.sourceNoActiveConnectionsText, 2, { horizontal: true, titleFontSize: titleFontSize });
}
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// if source is currently a db, show it in the server and db dropdowns
@@ -408,17 +416,17 @@ export class SchemaCompareDialog {
}).component();
// show dacpac file browser
dacpacRadioButton.onDidClick(() => {
dacpacRadioButton.onDidClick(async () => {
this.targetIsDacpac = true;
this.formBuilder.removeFormItem(this.targetNoActiveConnectionsText);
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.addFormItem(this.targetDacpacComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns or 'No active connections' text
databaseRadioButton.onDidClick(() => {
databaseRadioButton.onDidClick(async () => {
this.targetIsDacpac = false;
this.formBuilder.removeFormItem(this.targetDacpacComponent);
if ((this.targetServerDropdown.value as ConnectionDropdownValue)) {
@@ -427,7 +435,7 @@ export class SchemaCompareDialog {
} else {
this.formBuilder.addFormItem(this.targetNoActiveConnectionsText, { horizontal: true, titleFontSize: titleFontSize });
}
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// if target is currently a db, show it in the server and db dropdowns
@@ -450,18 +458,18 @@ export class SchemaCompareDialog {
};
}
private shouldEnableOkayButton(): boolean {
private async shouldEnableOkayButton(): Promise<boolean> {
let sourcefilled = (this.sourceIsDacpac && this.existsDacpac(this.sourceTextBox.value))
let sourcefilled = (this.sourceIsDacpac && await this.existsDacpac(this.sourceTextBox.value))
|| (!this.sourceIsDacpac && !isNullOrUndefined(this.sourceDatabaseDropdown.value) && this.sourceDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.sourceDbEditable)) !== -1);
let targetfilled = (this.targetIsDacpac && this.existsDacpac(this.targetTextBox.value))
let targetfilled = (this.targetIsDacpac && await this.existsDacpac(this.targetTextBox.value))
|| (!this.targetIsDacpac && !isNullOrUndefined(this.targetDatabaseDropdown.value) && this.targetDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.targetDbEditable)) !== -1);
return sourcefilled && targetfilled;
}
private existsDacpac(filename: string): boolean {
return !isNullOrUndefined(filename) && existsSync(filename) && (filename.toLocaleLowerCase().endsWith('.dacpac'));
private async existsDacpac(filename: string): Promise<boolean> {
return !isNullOrUndefined(filename) && await exists(filename) && (filename.toLocaleLowerCase().endsWith('.dacpac'));
}
protected async createSourceServerDropdown(view: azdata.ModelView): Promise<azdata.FormComponent> {
@@ -596,9 +604,9 @@ export class SchemaCompareDialog {
ariaLabel: localize('schemaCompareDialog.sourceDatabaseDropdown', "Source Database")
}
).component();
this.sourceDatabaseDropdown.onValueChanged((value) => {
this.sourceDatabaseDropdown.onValueChanged(async (value) => {
this.sourceDbEditable = value;
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
return {
@@ -615,9 +623,9 @@ export class SchemaCompareDialog {
ariaLabel: localize('schemaCompareDialog.targetDatabaseDropdown', "Target Database")
}
).component();
this.targetDatabaseDropdown.onValueChanged((value) => {
this.targetDatabaseDropdown.onValueChanged(async (value) => {
this.targetDbEditable = value;
this.dialog.okButton.enabled = this.shouldEnableOkayButton();
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
return {
@@ -684,3 +692,7 @@ export class SchemaCompareDialog {
interface ConnectionDropdownValue extends azdata.CategoryValue {
connection: azdata.connection.ConnectionProfile;
}
function isNullOrUndefined(val: any): boolean {
return val === null || val === undefined;
}