mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
sql-database-projects dialog completion cleanup (#17525)
This commit is contained in:
@@ -6,7 +6,20 @@
|
|||||||
/**
|
/**
|
||||||
* Deferred promise
|
* Deferred promise
|
||||||
*/
|
*/
|
||||||
export interface Deferred<T> {
|
export class Deferred<T = void> {
|
||||||
resolve: (result: T | Promise<T>) => void;
|
promise: Promise<T>;
|
||||||
reject: (reason: any) => void;
|
resolve!: (value: T | PromiseLike<T>) => void;
|
||||||
|
reject!: (reason?: any) => void;
|
||||||
|
constructor() {
|
||||||
|
this.promise = new Promise<T>((resolve, reject) => {
|
||||||
|
this.resolve = resolve;
|
||||||
|
this.reject = reject;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
|
||||||
|
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
|
||||||
|
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult> {
|
||||||
|
return this.promise.then(onfulfilled, onrejected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export default class MainController implements vscode.Disposable {
|
|||||||
vscode.commands.registerCommand('sqlDatabaseProjects.properties', async (node: WorkspaceTreeItem) => { return vscode.window.showErrorMessage(`Properties not yet implemented: ${node.element.uri.path}`); }); // TODO
|
vscode.commands.registerCommand('sqlDatabaseProjects.properties', async (node: WorkspaceTreeItem) => { return vscode.window.showErrorMessage(`Properties not yet implemented: ${node.element.uri.path}`); }); // TODO
|
||||||
|
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.build', async (node: WorkspaceTreeItem) => { return this.projectsController.buildProject(node); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.build', async (node: WorkspaceTreeItem) => { return this.projectsController.buildProject(node); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.publish', async (node: WorkspaceTreeItem) => { this.projectsController.publishProject(node); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.publish', async (node: WorkspaceTreeItem) => { return this.projectsController.publishProject(node); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.schemaCompare', async (node: WorkspaceTreeItem) => { return this.projectsController.schemaCompare(node); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.schemaCompare', async (node: WorkspaceTreeItem) => { return this.projectsController.schemaCompare(node); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.createProjectFromDatabase', async (context: azdataType.IConnectionProfile | vscodeMssql.ITreeNodeInfo | undefined) => { return this.projectsController.createProjectFromDatabase(context); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.createProjectFromDatabase', async (context: azdataType.IConnectionProfile | vscodeMssql.ITreeNodeInfo | undefined) => { return this.projectsController.createProjectFromDatabase(context); });
|
||||||
vscode.commands.registerCommand('sqlDatabaseProjects.generateProjectFromOpenApiSpec', async () => { return this.projectsController.generateProjectFromOpenApiSpec(); });
|
vscode.commands.registerCommand('sqlDatabaseProjects.generateProjectFromOpenApiSpec', async () => { return this.projectsController.generateProjectFromOpenApiSpec(); });
|
||||||
|
|||||||
@@ -300,13 +300,13 @@ export class ProjectsController {
|
|||||||
* Builds and publishes a project
|
* Builds and publishes a project
|
||||||
* @param treeNode a treeItem in a project's hierarchy, to be used to obtain a Project
|
* @param treeNode a treeItem in a project's hierarchy, to be used to obtain a Project
|
||||||
*/
|
*/
|
||||||
public publishProject(treeNode: dataworkspace.WorkspaceTreeItem): PublishDatabaseDialog;
|
public async publishProject(treeNode: dataworkspace.WorkspaceTreeItem): Promise<void>;
|
||||||
/**
|
/**
|
||||||
* Builds and publishes a project
|
* Builds and publishes a project
|
||||||
* @param project Project to be built and published
|
* @param project Project to be built and published
|
||||||
*/
|
*/
|
||||||
public publishProject(project: Project): PublishDatabaseDialog;
|
public async publishProject(project: Project): Promise<void>;
|
||||||
public publishProject(context: Project | dataworkspace.WorkspaceTreeItem): PublishDatabaseDialog | undefined {
|
public async publishProject(context: Project | dataworkspace.WorkspaceTreeItem): Promise<void> {
|
||||||
const project: Project = this.getProjectFromContext(context);
|
const project: Project = this.getProjectFromContext(context);
|
||||||
if (utils.getAzdataApi()) {
|
if (utils.getAzdataApi()) {
|
||||||
let publishDatabaseDialog = this.getPublishDialog(project);
|
let publishDatabaseDialog = this.getPublishDialog(project);
|
||||||
@@ -317,10 +317,9 @@ export class ProjectsController {
|
|||||||
|
|
||||||
publishDatabaseDialog.openDialog();
|
publishDatabaseDialog.openDialog();
|
||||||
|
|
||||||
return publishDatabaseDialog;
|
return publishDatabaseDialog.waitForClose();
|
||||||
} else {
|
} else {
|
||||||
void launchPublishDatabaseQuickpick(project, this);
|
return launchPublishDatabaseQuickpick(project, this);
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
public currentReferenceType: ReferenceType | undefined;
|
public currentReferenceType: ReferenceType | undefined;
|
||||||
|
|
||||||
private toDispose: vscode.Disposable[] = [];
|
private toDispose: vscode.Disposable[] = [];
|
||||||
private initDialogComplete: Deferred<void> | undefined;
|
private initDialogComplete: Deferred = new Deferred();
|
||||||
private initDialogPromise: Promise<void> = new Promise<void>((resolve, reject) => this.initDialogComplete = { resolve, reject });
|
|
||||||
|
|
||||||
public addReference: ((proj: Project, settings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings) => any) | undefined;
|
public addReference: ((proj: Project, settings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings) => any) | undefined;
|
||||||
|
|
||||||
@@ -86,7 +85,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
this.dialog.cancelButton.label = constants.cancelButtonText;
|
this.dialog.cancelButton.label = constants.cancelButtonText;
|
||||||
|
|
||||||
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
||||||
await this.initDialogPromise;
|
await this.initDialogComplete.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dispose(): void {
|
private dispose(): void {
|
||||||
@@ -144,7 +143,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
await this.systemDatabaseRadioButton?.focus();
|
await this.systemDatabaseRadioButton?.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initDialogComplete?.resolve();
|
this.initDialogComplete.resolve();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,7 @@ export class CreateProjectFromDatabaseDialog {
|
|||||||
private formBuilder: azdataType.FormBuilder | undefined;
|
private formBuilder: azdataType.FormBuilder | undefined;
|
||||||
private connectionId: string | undefined;
|
private connectionId: string | undefined;
|
||||||
private toDispose: vscode.Disposable[] = [];
|
private toDispose: vscode.Disposable[] = [];
|
||||||
private initDialogComplete!: Deferred<void>;
|
private initDialogComplete: Deferred = new Deferred();
|
||||||
private initDialogPromise: Promise<void> = new Promise<void>((resolve, reject) => this.initDialogComplete = { resolve, reject });
|
|
||||||
|
|
||||||
public createProjectFromDatabaseCallback: ((model: ImportDataModel) => any) | undefined;
|
public createProjectFromDatabaseCallback: ((model: ImportDataModel) => any) | undefined;
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ export class CreateProjectFromDatabaseDialog {
|
|||||||
this.dialog.cancelButton.label = constants.cancelButtonText;
|
this.dialog.cancelButton.label = constants.cancelButtonText;
|
||||||
|
|
||||||
getAzdataApi()!.window.openDialog(this.dialog);
|
getAzdataApi()!.window.openDialog(this.dialog);
|
||||||
await this.initDialogPromise;
|
await this.initDialogComplete.promise;
|
||||||
|
|
||||||
if (this.profile) {
|
if (this.profile) {
|
||||||
await this.updateConnectionComponents(getConnectionName(this.profile), this.profile.id, this.profile.databaseName!);
|
await this.updateConnectionComponents(getConnectionName(this.profile), this.profile.id, this.profile.databaseName!);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { IconPathHelper } from '../common/iconHelper';
|
|||||||
import { cssStyles } from '../common/uiConstants';
|
import { cssStyles } from '../common/uiConstants';
|
||||||
import { getConnectionName } from './utils';
|
import { getConnectionName } from './utils';
|
||||||
import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry';
|
import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry';
|
||||||
|
import { Deferred } from '../common/promise';
|
||||||
|
|
||||||
interface DataSourceDropdownValue extends azdataType.CategoryValue {
|
interface DataSourceDropdownValue extends azdataType.CategoryValue {
|
||||||
dataSource: SqlConnectionDataSource;
|
dataSource: SqlConnectionDataSource;
|
||||||
@@ -44,6 +45,8 @@ export class PublishDatabaseDialog {
|
|||||||
private profileUsed: boolean = false;
|
private profileUsed: boolean = false;
|
||||||
private serverName: string | undefined;
|
private serverName: string | undefined;
|
||||||
|
|
||||||
|
private completionPromise: Deferred = new Deferred();
|
||||||
|
|
||||||
private toDispose: vscode.Disposable[] = [];
|
private toDispose: vscode.Disposable[] = [];
|
||||||
|
|
||||||
public publish: ((proj: Project, profile: IDeploySettings) => any) | undefined;
|
public publish: ((proj: Project, profile: IDeploySettings) => any) | undefined;
|
||||||
@@ -71,6 +74,13 @@ export class PublishDatabaseDialog {
|
|||||||
this.dialog.customButtons.push(generateScriptButton);
|
this.dialog.customButtons.push(generateScriptButton);
|
||||||
|
|
||||||
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
utils.getAzdataApi()!.window.openDialog(this.dialog);
|
||||||
|
// Complete the promise when we're done - we use a disposable here instead of a CloseValidator because we have custom buttons (generate script)
|
||||||
|
// which don't go through that logic.
|
||||||
|
this.toDispose.push({ dispose: () => { this.completionPromise.resolve(); } });
|
||||||
|
}
|
||||||
|
|
||||||
|
public waitForClose(): Promise<void> {
|
||||||
|
return this.completionPromise.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
private dispose(): void {
|
private dispose(): void {
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ describe('ProjectsController', function (): void {
|
|||||||
projController.callBase = true;
|
projController.callBase = true;
|
||||||
projController.setup(x => x.getPublishDialog(TypeMoq.It.isAny())).returns(() => publishDialog.object);
|
projController.setup(x => x.getPublishDialog(TypeMoq.It.isAny())).returns(() => publishDialog.object);
|
||||||
|
|
||||||
projController.object.publishProject(new Project('FakePath'));
|
void projController.object.publishProject(new Project('FakePath'));
|
||||||
should(opened).equal(true);
|
should(opened).equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -395,13 +395,15 @@ describe('ProjectsController', function (): void {
|
|||||||
return Promise.resolve(undefined);
|
return Promise.resolve(undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
let dialog = projController.object.publishProject(proj);
|
let dialogPromise = projController.object.publishProject(proj);
|
||||||
await dialog.publishClick();
|
await publishDialog.object.publishClick();
|
||||||
|
await dialogPromise;
|
||||||
|
|
||||||
should(holler).equal(publishHoller, 'executionCallback() is supposed to have been setup and called for Publish scenario');
|
should(holler).equal(publishHoller, 'executionCallback() is supposed to have been setup and called for Publish scenario');
|
||||||
|
|
||||||
dialog = projController.object.publishProject(proj);
|
dialogPromise = projController.object.publishProject(proj);
|
||||||
await dialog.generateScriptClick();
|
await publishDialog.object.generateScriptClick();
|
||||||
|
await dialogPromise;
|
||||||
|
|
||||||
should(holler).equal(generateHoller, 'executionCallback() is supposed to have been setup and called for GenerateScript scenario');
|
should(holler).equal(generateHoller, 'executionCallback() is supposed to have been setup and called for GenerateScript scenario');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user