mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Add DB Reference quickpick dialog (#16601)
* Add DB Reference quickpick dialog * pr comments & cleanup
This commit is contained in:
@@ -69,6 +69,7 @@ export const databaseReferencesNodeName = localize('databaseReferencesNodeName',
|
|||||||
export const sqlConnectionStringFriendly = localize('sqlConnectionStringFriendly', "SQL connection string");
|
export const sqlConnectionStringFriendly = localize('sqlConnectionStringFriendly', "SQL connection string");
|
||||||
export const yesString = localize('yesString', "Yes");
|
export const yesString = localize('yesString', "Yes");
|
||||||
export const noString = localize('noString', "No");
|
export const noString = localize('noString', "No");
|
||||||
|
export const noStringDefault = localize('noStringDefault', "No (default)");
|
||||||
export const okString = localize('okString', "Ok");
|
export const okString = localize('okString', "Ok");
|
||||||
export const selectString = localize('selectString', "Select");
|
export const selectString = localize('selectString', "Select");
|
||||||
export const dacpacFiles = localize('dacpacFiles', "dacpac Files");
|
export const dacpacFiles = localize('dacpacFiles', "dacpac Files");
|
||||||
@@ -79,6 +80,7 @@ export const objectType = localize('objectType', "Object Type");
|
|||||||
export const schema = localize('schema', "Schema");
|
export const schema = localize('schema', "Schema");
|
||||||
export const schemaObjectType = localize('schemaObjectType', "Schema/Object Type");
|
export const schemaObjectType = localize('schemaObjectType', "Schema/Object Type");
|
||||||
export const defaultProjectNameStarter = localize('defaultProjectNameStarter', "DatabaseProject");
|
export const defaultProjectNameStarter = localize('defaultProjectNameStarter', "DatabaseProject");
|
||||||
|
export const location = localize('location', "Location");
|
||||||
export const reloadProject = localize('reloadProject', "Would you like to reload your database project?");
|
export const reloadProject = localize('reloadProject', "Would you like to reload your database project?");
|
||||||
export function newObjectNamePrompt(objectType: string) { return localize('newObjectNamePrompt', 'New {0} name:', objectType); }
|
export function newObjectNamePrompt(objectType: string) { return localize('newObjectNamePrompt', 'New {0} name:', objectType); }
|
||||||
export function deleteConfirmation(toDelete: string) { return localize('deleteConfirmation', "Are you sure you want to delete {0}?", toDelete); }
|
export function deleteConfirmation(toDelete: string) { return localize('deleteConfirmation', "Are you sure you want to delete {0}?", toDelete); }
|
||||||
@@ -129,12 +131,10 @@ export const nameMustNotBeEmpty = localize('nameMustNotBeEmpty', "Name must not
|
|||||||
export const addDatabaseReferenceDialogName = localize('addDatabaseReferencedialogName', "Add database reference");
|
export const addDatabaseReferenceDialogName = localize('addDatabaseReferencedialogName', "Add database reference");
|
||||||
export const addDatabaseReferenceOkButtonText = localize('addDatabaseReferenceOkButtonText', "Add reference");
|
export const addDatabaseReferenceOkButtonText = localize('addDatabaseReferenceOkButtonText', "Add reference");
|
||||||
export const referenceRadioButtonsGroupTitle = localize('referenceRadioButtonsGroupTitle', "Type");
|
export const referenceRadioButtonsGroupTitle = localize('referenceRadioButtonsGroupTitle', "Type");
|
||||||
export const projectRadioButtonTitle = localize('projectRadioButtonTitle', "Project");
|
export const projectLabel = localize('projectLocString', "Project");
|
||||||
export const systemDatabaseRadioButtonTitle = localize('systemDatabaseRadioButtonTitle', "System database");
|
export const systemDatabase = localize('systemDatabase', "System database");
|
||||||
export const dacpacText = localize('dacpacText', "Data-tier application (.dacpac)");
|
export const dacpacText = localize('dacpacText', "Data-tier application (.dacpac)");
|
||||||
export const dacpacPlaceholder = localize('dacpacPlaceholder', "Select .dacpac");
|
export const selectDacpac = localize('selectDacpac', "Select .dacpac");
|
||||||
export const loadDacpacButton = localize('loadDacpacButton', "Select .dacpac");
|
|
||||||
export const locationDropdown = localize('locationDropdown', "Location");
|
|
||||||
export const sameDatabase = localize('sameDatabase', "Same database");
|
export const sameDatabase = localize('sameDatabase', "Same database");
|
||||||
export const differentDbSameServer = localize('differentDbSameServer', "Different database, same server");
|
export const differentDbSameServer = localize('differentDbSameServer', "Different database, same server");
|
||||||
export const differentDbDifferentServer = localize('differentDbDifferentServer', "Different database, different server");
|
export const differentDbDifferentServer = localize('differentDbDifferentServer', "Different database, different server");
|
||||||
@@ -153,6 +153,7 @@ export const otherServer = 'OtherServer';
|
|||||||
export const otherSeverVariable = 'OtherServer';
|
export const otherSeverVariable = 'OtherServer';
|
||||||
export const databaseProject = localize('databaseProject', "Database project");
|
export const databaseProject = localize('databaseProject', "Database project");
|
||||||
export const dacpacNotOnSameDrive = (projectLocation: string): string => { return localize('dacpacNotOnSameDrive', "Dacpac references need to be located on the same drive as the project file. The project file is located at {0}", projectLocation); };
|
export const dacpacNotOnSameDrive = (projectLocation: string): string => { return localize('dacpacNotOnSameDrive', "Dacpac references need to be located on the same drive as the project file. The project file is located at {0}", projectLocation); };
|
||||||
|
export const referenceType = localize('referenceType', "Reference type");
|
||||||
|
|
||||||
// Create Project From Database dialog strings
|
// Create Project From Database dialog strings
|
||||||
|
|
||||||
@@ -163,7 +164,6 @@ export const targetProject = localize('targetProject', "Target project");
|
|||||||
export const createProjectSettings = localize('createProjectSettings', "Settings");
|
export const createProjectSettings = localize('createProjectSettings', "Settings");
|
||||||
export const projectNameLabel = localize('projectNameLabel', "Name");
|
export const projectNameLabel = localize('projectNameLabel', "Name");
|
||||||
export const projectNamePlaceholderText = localize('projectNamePlaceholderText', "Enter project name");
|
export const projectNamePlaceholderText = localize('projectNamePlaceholderText', "Enter project name");
|
||||||
export const projectLocationLabel = localize('projectLocationLabel', "Location");
|
|
||||||
export const projectLocationPlaceholderText = localize('projectLocationPlaceholderText', "Select location to create project");
|
export const projectLocationPlaceholderText = localize('projectLocationPlaceholderText', "Select location to create project");
|
||||||
export const browseButtonText = localize('browseButtonText', "Browse folder");
|
export const browseButtonText = localize('browseButtonText', "Browse folder");
|
||||||
export const selectFolderStructure = localize('selectFolderStructure', "Select folder structure");
|
export const selectFolderStructure = localize('selectFolderStructure', "Select folder structure");
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import { DashboardData, PublishData, Status } from '../models/dashboardData/dash
|
|||||||
import { launchPublishDatabaseQuickpick } from '../dialogs/publishDatabaseQuickpick';
|
import { launchPublishDatabaseQuickpick } from '../dialogs/publishDatabaseQuickpick';
|
||||||
import { SqlTargetPlatform } from 'sqldbproj';
|
import { SqlTargetPlatform } from 'sqldbproj';
|
||||||
import { createNewProjectFromDatabaseWithQuickpick } from '../dialogs/createProjectFromDatabaseQuickpick';
|
import { createNewProjectFromDatabaseWithQuickpick } from '../dialogs/createProjectFromDatabaseQuickpick';
|
||||||
|
import { addDatabaseReferenceQuickpick } from '../dialogs/addDatabaseReferenceQuickpick';
|
||||||
|
|
||||||
const maxTableLength = 10;
|
const maxTableLength = 10;
|
||||||
|
|
||||||
@@ -53,6 +54,8 @@ export enum TaskExecutionMode {
|
|||||||
executeAndScript = 2
|
executeAndScript = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type AddDatabaseReferenceSettings = ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller for managing lifecycle of projects
|
* Controller for managing lifecycle of projects
|
||||||
*/
|
*/
|
||||||
@@ -672,15 +675,25 @@ export class ProjectsController {
|
|||||||
* Adds a database reference to the project
|
* Adds a database reference to the project
|
||||||
* @param context a treeItem in a project's hierarchy, to be used to obtain a Project
|
* @param context a treeItem in a project's hierarchy, to be used to obtain a Project
|
||||||
*/
|
*/
|
||||||
public async addDatabaseReference(context: Project | dataworkspace.WorkspaceTreeItem): Promise<AddDatabaseReferenceDialog> {
|
public async addDatabaseReference(context: Project | dataworkspace.WorkspaceTreeItem): Promise<AddDatabaseReferenceDialog | undefined> {
|
||||||
const project = this.getProjectFromContext(context);
|
const project = this.getProjectFromContext(context);
|
||||||
|
|
||||||
const addDatabaseReferenceDialog = this.getAddDatabaseReferenceDialog(project);
|
if (utils.getAzdataApi()) {
|
||||||
addDatabaseReferenceDialog.addReference = async (proj, prof) => await this.addDatabaseReferenceCallback(proj, prof, context as dataworkspace.WorkspaceTreeItem);
|
const addDatabaseReferenceDialog = this.getAddDatabaseReferenceDialog(project);
|
||||||
|
addDatabaseReferenceDialog.addReference = async (proj, settings) => await this.addDatabaseReferenceCallback(proj, settings, context as dataworkspace.WorkspaceTreeItem);
|
||||||
|
|
||||||
|
addDatabaseReferenceDialog.openDialog();
|
||||||
|
return addDatabaseReferenceDialog;
|
||||||
|
} else {
|
||||||
|
const settings = await addDatabaseReferenceQuickpick(project);
|
||||||
|
if (settings) {
|
||||||
|
await this.addDatabaseReferenceCallback(project, settings, context as dataworkspace.WorkspaceTreeItem);
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
addDatabaseReferenceDialog.openDialog();
|
|
||||||
|
|
||||||
return addDatabaseReferenceDialog;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -689,7 +702,7 @@ export class ProjectsController {
|
|||||||
* @param settings settings for the database reference
|
* @param settings settings for the database reference
|
||||||
* @param context a treeItem in a project's hierarchy, to be used to obtain a Project
|
* @param context a treeItem in a project's hierarchy, to be used to obtain a Project
|
||||||
*/
|
*/
|
||||||
public async addDatabaseReferenceCallback(project: Project, settings: ISystemDatabaseReferenceSettings | IDacpacReferenceSettings | IProjectReferenceSettings, context: dataworkspace.WorkspaceTreeItem): Promise<void> {
|
public async addDatabaseReferenceCallback(project: Project, settings: AddDatabaseReferenceSettings, context: dataworkspace.WorkspaceTreeItem): Promise<void> {
|
||||||
try {
|
try {
|
||||||
if ((<IProjectReferenceSettings>settings).projectName !== undefined) {
|
if ((<IProjectReferenceSettings>settings).projectName !== undefined) {
|
||||||
// get project path and guid
|
// get project path and guid
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
} else if (this.currentReferenceType === ReferenceType.systemDb) {
|
} else if (this.currentReferenceType === ReferenceType.systemDb) {
|
||||||
referenceSettings = {
|
referenceSettings = {
|
||||||
databaseName: <string>this.databaseNameTextbox?.value,
|
databaseName: <string>this.databaseNameTextbox?.value,
|
||||||
systemDb: <string>this.systemDatabaseDropdown?.value === constants.master ? SystemDatabase.master : SystemDatabase.msdb,
|
systemDb: getSystemDatabase(<string>this.systemDatabaseDropdown?.value),
|
||||||
suppressMissingDependenciesErrors: <boolean>this.suppressMissingDependenciesErrorsCheckbox?.checked
|
suppressMissingDependenciesErrors: <boolean>this.suppressMissingDependenciesErrorsCheckbox?.checked
|
||||||
};
|
};
|
||||||
} else { // this.currentReferenceType === ReferenceType.dacpac
|
} else { // this.currentReferenceType === ReferenceType.dacpac
|
||||||
@@ -192,7 +192,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
this.projectRadioButton = this.view!.modelBuilder.radioButton()
|
this.projectRadioButton = this.view!.modelBuilder.radioButton()
|
||||||
.withProps({
|
.withProps({
|
||||||
name: 'referenceType',
|
name: 'referenceType',
|
||||||
label: constants.projectRadioButtonTitle
|
label: constants.projectLabel
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.projectRadioButton.onDidClick(() => {
|
this.projectRadioButton.onDidClick(() => {
|
||||||
@@ -202,7 +202,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
this.systemDatabaseRadioButton = this.view!.modelBuilder.radioButton()
|
this.systemDatabaseRadioButton = this.view!.modelBuilder.radioButton()
|
||||||
.withProps({
|
.withProps({
|
||||||
name: 'referenceType',
|
name: 'referenceType',
|
||||||
label: constants.systemDatabaseRadioButtonTitle
|
label: constants.systemDatabase
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
this.systemDatabaseRadioButton.onDidClick(() => {
|
this.systemDatabaseRadioButton.onDidClick(() => {
|
||||||
@@ -307,7 +307,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
|
|
||||||
private createSystemDatabaseDropdown(): azdataType.FormComponent {
|
private createSystemDatabaseDropdown(): azdataType.FormComponent {
|
||||||
this.systemDatabaseDropdown = this.view!.modelBuilder.dropDown().withProps({
|
this.systemDatabaseDropdown = this.view!.modelBuilder.dropDown().withProps({
|
||||||
values: [constants.master, constants.msdb],
|
values: getSystemDbOptions(this.project),
|
||||||
ariaLabel: constants.databaseNameLabel
|
ariaLabel: constants.databaseNameLabel
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
@@ -315,11 +315,6 @@ export class AddDatabaseReferenceDialog {
|
|||||||
this.setDefaultDatabaseValues();
|
this.setDefaultDatabaseValues();
|
||||||
});
|
});
|
||||||
|
|
||||||
// only master is a valid system db reference for projects targetting Azure and DW
|
|
||||||
if (this.project.getProjectTargetVersion().toLowerCase().includes('azure') || this.project.getProjectTargetVersion().toLowerCase().includes('dw')) {
|
|
||||||
this.systemDatabaseDropdown.values?.splice(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
component: this.systemDatabaseDropdown,
|
component: this.systemDatabaseDropdown,
|
||||||
title: constants.databaseNameLabel
|
title: constants.databaseNameLabel
|
||||||
@@ -329,7 +324,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
private createDacpacTextbox(): azdataType.FormComponent {
|
private createDacpacTextbox(): azdataType.FormComponent {
|
||||||
this.dacpacTextbox = this.view!.modelBuilder.inputBox().withProps({
|
this.dacpacTextbox = this.view!.modelBuilder.inputBox().withProps({
|
||||||
ariaLabel: constants.dacpacText,
|
ariaLabel: constants.dacpacText,
|
||||||
placeHolder: constants.dacpacPlaceholder,
|
placeHolder: constants.selectDacpac,
|
||||||
width: '400px'
|
width: '400px'
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
@@ -351,25 +346,14 @@ export class AddDatabaseReferenceDialog {
|
|||||||
|
|
||||||
private createLoadDacpacButton(): azdataType.ButtonComponent {
|
private createLoadDacpacButton(): azdataType.ButtonComponent {
|
||||||
const loadDacpacButton = this.view!.modelBuilder.button().withProps({
|
const loadDacpacButton = this.view!.modelBuilder.button().withProps({
|
||||||
ariaLabel: constants.loadDacpacButton,
|
ariaLabel: constants.selectDacpac,
|
||||||
iconPath: IconPathHelper.folder_blue,
|
iconPath: IconPathHelper.folder_blue,
|
||||||
height: '18px',
|
height: '18px',
|
||||||
width: '18px'
|
width: '18px'
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
loadDacpacButton.onDidClick(async () => {
|
loadDacpacButton.onDidClick(async () => {
|
||||||
let fileUris = await vscode.window.showOpenDialog(
|
let fileUris = await promptDacpacLocation();
|
||||||
{
|
|
||||||
canSelectFiles: true,
|
|
||||||
canSelectFolders: false,
|
|
||||||
canSelectMany: false,
|
|
||||||
defaultUri: vscode.workspace.workspaceFolders ? (vscode.workspace.workspaceFolders as vscode.WorkspaceFolder[])[0].uri : undefined,
|
|
||||||
openLabel: constants.selectString,
|
|
||||||
filters: {
|
|
||||||
[constants.dacpacFiles]: ['dacpac'],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!fileUris || fileUris.length === 0) {
|
if (!fileUris || fileUris.length === 0) {
|
||||||
return;
|
return;
|
||||||
@@ -383,7 +367,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
|
|
||||||
private createLocationDropdown(): azdataType.FormComponent {
|
private createLocationDropdown(): azdataType.FormComponent {
|
||||||
this.locationDropdown = this.view!.modelBuilder.dropDown().withProps({
|
this.locationDropdown = this.view!.modelBuilder.dropDown().withProps({
|
||||||
ariaLabel: constants.locationDropdown,
|
ariaLabel: constants.location,
|
||||||
values: this.currentReferenceType === ReferenceType.systemDb ? constants.systemDbLocationDropdownValues : constants.locationDropdownValues
|
values: this.currentReferenceType === ReferenceType.systemDb ? constants.systemDbLocationDropdownValues : constants.locationDropdownValues
|
||||||
}).component();
|
}).component();
|
||||||
|
|
||||||
@@ -397,7 +381,7 @@ export class AddDatabaseReferenceDialog {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
component: this.locationDropdown,
|
component: this.locationDropdown,
|
||||||
title: constants.locationDropdown
|
title: constants.location
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,3 +614,31 @@ export class AddDatabaseReferenceDialog {
|
|||||||
return !!this.databaseNameTextbox?.value && !!this.serverNameTextbox?.value && !!this.serverVariableTextbox?.value;
|
return !!this.databaseNameTextbox?.value && !!this.serverNameTextbox?.value && !!this.serverVariableTextbox?.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSystemDbOptions(project: Project): string[] {
|
||||||
|
// only master is a valid system db reference for projects targeting Azure and DW
|
||||||
|
if (project.getProjectTargetVersion().toLowerCase().includes('azure') || project.getProjectTargetVersion().toLowerCase().includes('dw')) {
|
||||||
|
return [constants.master];
|
||||||
|
}
|
||||||
|
return [constants.master, constants.msdb];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getSystemDatabase(name: string): SystemDatabase {
|
||||||
|
return name === constants.master ? SystemDatabase.master : SystemDatabase.msdb;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function promptDacpacLocation(): Promise<vscode.Uri[] | undefined> {
|
||||||
|
return await vscode.window.showOpenDialog(
|
||||||
|
{
|
||||||
|
canSelectFiles: true,
|
||||||
|
canSelectFolders: false,
|
||||||
|
canSelectMany: false,
|
||||||
|
defaultUri: vscode.workspace.workspaceFolders ? (vscode.workspace.workspaceFolders as vscode.WorkspaceFolder[])[0].uri : undefined,
|
||||||
|
openLabel: constants.selectString,
|
||||||
|
title: constants.selectDacpac,
|
||||||
|
filters: {
|
||||||
|
[constants.dacpacFiles]: ['dacpac'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,277 @@
|
|||||||
|
/*---------------------------------------------------------------------------------------------
|
||||||
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||||
|
*--------------------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
import path = require('path');
|
||||||
|
import * as vscode from 'vscode';
|
||||||
|
import * as constants from '../common/constants';
|
||||||
|
import { getSqlProjectsInWorkspace, isValidSqlCmdVariableName, removeSqlCmdVariableFormatting } from '../common/utils';
|
||||||
|
import { AddDatabaseReferenceSettings } from '../controllers/projectController';
|
||||||
|
import { IDacpacReferenceSettings, IProjectReferenceSettings, ISystemDatabaseReferenceSettings } from '../models/IDatabaseReferenceSettings';
|
||||||
|
import { Project } from '../models/project';
|
||||||
|
import { getSystemDatabase, getSystemDbOptions, promptDacpacLocation } from './addDatabaseReferenceDialog';
|
||||||
|
|
||||||
|
interface DbServerValues {
|
||||||
|
dbName?: string,
|
||||||
|
dbVariable?: string,
|
||||||
|
serverName?: string,
|
||||||
|
serverVariable?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create flow for adding a database reference using only VS Code-native APIs such as QuickPick
|
||||||
|
* @param connectionInfo Optional connection info to use instead of prompting the user for a connection
|
||||||
|
*/
|
||||||
|
export async function addDatabaseReferenceQuickpick(project: Project): Promise<AddDatabaseReferenceSettings | undefined> {
|
||||||
|
|
||||||
|
const otherProjectsInWorkspace = (await getSqlProjectsInWorkspace()).filter(p => p.fsPath !== project.projectFilePath);
|
||||||
|
|
||||||
|
// 1. Prompt for reference type
|
||||||
|
// Only show project option if we have at least one other project in the workspace
|
||||||
|
const referenceTypes = otherProjectsInWorkspace.length > 0 ?
|
||||||
|
[constants.projectLabel, constants.systemDatabase, constants.dacpacText] :
|
||||||
|
[constants.systemDatabase, constants.dacpacText];
|
||||||
|
|
||||||
|
const referenceType = await vscode.window.showQuickPick(
|
||||||
|
referenceTypes,
|
||||||
|
{ title: constants.referenceType, ignoreFocusOut: true });
|
||||||
|
if (!referenceType) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (referenceType) {
|
||||||
|
case constants.projectLabel:
|
||||||
|
return addProjectReference(otherProjectsInWorkspace);
|
||||||
|
case constants.systemDatabase:
|
||||||
|
return addSystemDatabaseReference(project);
|
||||||
|
case constants.dacpacText:
|
||||||
|
return addDacpacReference();
|
||||||
|
default:
|
||||||
|
console.log(`Unknown reference type ${referenceType}`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addProjectReference(otherProjectsInWorkspace: vscode.Uri[]): Promise<IProjectReferenceSettings | undefined> {
|
||||||
|
// (steps continued from addDatabaseReferenceQuickpick)
|
||||||
|
// 2. Prompt database project
|
||||||
|
const otherProjectQuickpickItems: (vscode.QuickPickItem & { uri: vscode.Uri })[] = otherProjectsInWorkspace.map(p => {
|
||||||
|
return {
|
||||||
|
label: path.parse(p.fsPath).name,
|
||||||
|
uri: p
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const selectedProject = await vscode.window.showQuickPick(
|
||||||
|
otherProjectQuickpickItems,
|
||||||
|
{ title: constants.databaseProject, ignoreFocusOut: true, });
|
||||||
|
if (!selectedProject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prompt location
|
||||||
|
const location = await promptLocation();
|
||||||
|
if (!location) {
|
||||||
|
// User cancelled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const referenceSettings: IProjectReferenceSettings = {
|
||||||
|
projectName: selectedProject.label,
|
||||||
|
projectGuid: '',
|
||||||
|
projectRelativePath: undefined,
|
||||||
|
databaseName: undefined,
|
||||||
|
databaseVariable: undefined,
|
||||||
|
serverName: undefined,
|
||||||
|
serverVariable: undefined,
|
||||||
|
suppressMissingDependenciesErrors: false
|
||||||
|
};
|
||||||
|
|
||||||
|
const dbServerValues = await promptDbServerValues(location, selectedProject.label);
|
||||||
|
if (!dbServerValues) {
|
||||||
|
// User cancelled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
referenceSettings.databaseName = dbServerValues.dbName;
|
||||||
|
referenceSettings.databaseVariable = dbServerValues.dbVariable;
|
||||||
|
referenceSettings.serverName = dbServerValues.serverName;
|
||||||
|
referenceSettings.serverVariable = dbServerValues.serverVariable;
|
||||||
|
|
||||||
|
// 7. Prompt suppress unresolved ref errors
|
||||||
|
const suppressErrors = await promptSuppressUnresolvedRefErrors();
|
||||||
|
referenceSettings.suppressMissingDependenciesErrors = suppressErrors;
|
||||||
|
|
||||||
|
return referenceSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addSystemDatabaseReference(project: Project): Promise<ISystemDatabaseReferenceSettings | undefined> {
|
||||||
|
// (steps continued from addDatabaseReferenceQuickpick)
|
||||||
|
// 2. Prompt System DB
|
||||||
|
|
||||||
|
const selectedSystemDb = await vscode.window.showQuickPick(
|
||||||
|
getSystemDbOptions(project),
|
||||||
|
{ title: constants.systemDatabase, ignoreFocusOut: true, });
|
||||||
|
if (!selectedSystemDb) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prompt DB name
|
||||||
|
const dbName = await promptDbName(selectedSystemDb);
|
||||||
|
|
||||||
|
// 4. Prompt suppress unresolved ref errors
|
||||||
|
const suppressErrors = await promptSuppressUnresolvedRefErrors();
|
||||||
|
|
||||||
|
return {
|
||||||
|
databaseName: dbName,
|
||||||
|
systemDb: getSystemDatabase(selectedSystemDb),
|
||||||
|
suppressMissingDependenciesErrors: suppressErrors
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function addDacpacReference(): Promise<IDacpacReferenceSettings | undefined> {
|
||||||
|
// (steps continued from addDatabaseReferenceQuickpick)
|
||||||
|
// 2. Prompt for location
|
||||||
|
const location = await promptLocation();
|
||||||
|
if (!location) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prompt for dacpac location
|
||||||
|
// Show quick pick with just browse option to give user context about what the file dialog is for (since that doesn't always have a title)
|
||||||
|
const browseSelected = await vscode.window.showQuickPick(
|
||||||
|
[constants.browseEllipsis],
|
||||||
|
{ title: constants.selectDacpac, ignoreFocusOut: true });
|
||||||
|
if (!browseSelected) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dacPacLocation = (await promptDacpacLocation())?.[0];
|
||||||
|
if (!dacPacLocation) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Prompt for db/server values
|
||||||
|
const dbServerValues = await promptDbServerValues(location, path.parse(dacPacLocation.fsPath).name);
|
||||||
|
if (!dbServerValues) {
|
||||||
|
// User cancelled
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Prompt suppress unresolved ref errors
|
||||||
|
const suppressErrors = await promptSuppressUnresolvedRefErrors();
|
||||||
|
|
||||||
|
return {
|
||||||
|
databaseName: dbServerValues.dbName,
|
||||||
|
dacpacFileLocation: dacPacLocation,
|
||||||
|
databaseVariable: removeSqlCmdVariableFormatting(dbServerValues.dbVariable),
|
||||||
|
serverName: dbServerValues.serverName,
|
||||||
|
serverVariable: removeSqlCmdVariableFormatting(dbServerValues.serverVariable),
|
||||||
|
suppressMissingDependenciesErrors: suppressErrors
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptLocation(): Promise<string | undefined> {
|
||||||
|
return vscode.window.showQuickPick(
|
||||||
|
constants.locationDropdownValues,
|
||||||
|
{ title: constants.location, ignoreFocusOut: true, });
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptDbName(defaultValue: string): Promise<string | undefined> {
|
||||||
|
return vscode.window.showInputBox(
|
||||||
|
{
|
||||||
|
title: constants.databaseName,
|
||||||
|
value: defaultValue,
|
||||||
|
validateInput: (value) => {
|
||||||
|
return value ? undefined : constants.nameMustNotBeEmpty;
|
||||||
|
},
|
||||||
|
ignoreFocusOut: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptDbVar(defaultValue: string): Promise<string> {
|
||||||
|
return await vscode.window.showInputBox(
|
||||||
|
{
|
||||||
|
title: constants.databaseVariable,
|
||||||
|
value: defaultValue,
|
||||||
|
validateInput: (value: string) => {
|
||||||
|
return isValidSqlCmdVariableName(value) ? '' : constants.notValidVariableName(value);
|
||||||
|
},
|
||||||
|
ignoreFocusOut: true
|
||||||
|
}) ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptServerName(): Promise<string | undefined> {
|
||||||
|
return vscode.window.showInputBox(
|
||||||
|
{
|
||||||
|
title: constants.serverName,
|
||||||
|
value: constants.otherServer,
|
||||||
|
validateInput: (value) => {
|
||||||
|
return value ? undefined : constants.nameMustNotBeEmpty;
|
||||||
|
},
|
||||||
|
ignoreFocusOut: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptServerVar(): Promise<string> {
|
||||||
|
return await vscode.window.showInputBox(
|
||||||
|
{
|
||||||
|
title: constants.serverVariable,
|
||||||
|
value: constants.otherSeverVariable,
|
||||||
|
validateInput: (value: string) => {
|
||||||
|
return isValidSqlCmdVariableName(value) ? '' : constants.notValidVariableName(value);
|
||||||
|
},
|
||||||
|
ignoreFocusOut: true
|
||||||
|
}) ?? '';
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptSuppressUnresolvedRefErrors(): Promise<boolean> {
|
||||||
|
const selectedOption = await vscode.window.showQuickPick(
|
||||||
|
[constants.noStringDefault, constants.yesString],
|
||||||
|
{ title: constants.suppressMissingDependenciesErrors, ignoreFocusOut: true, });
|
||||||
|
return selectedOption === constants.yesString ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function promptDbServerValues(location: string, defaultDbName: string): Promise<DbServerValues | undefined> {
|
||||||
|
const ret: DbServerValues = {};
|
||||||
|
|
||||||
|
// Only prompt db values if the location is on a different db/server
|
||||||
|
if (location !== constants.sameDatabase) {
|
||||||
|
// 4. Prompt database name
|
||||||
|
const dbName = await promptDbName(defaultDbName);
|
||||||
|
if (!dbName) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
ret.dbName = dbName;
|
||||||
|
|
||||||
|
// 5. Prompt db var
|
||||||
|
const dbVar = await promptDbVar(dbName);
|
||||||
|
// DB Variable is optional so treat escape as skipping it (not cancel in this case)
|
||||||
|
ret.dbVariable = dbVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only prompt server values if location is different server
|
||||||
|
if (location === constants.differentDbDifferentServer) {
|
||||||
|
// 5. Prompt server name
|
||||||
|
const serverName = await promptServerName();
|
||||||
|
if (!serverName) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
ret.serverName = serverName;
|
||||||
|
|
||||||
|
// 6. Prompt server var
|
||||||
|
const serverVar = await promptServerVar();
|
||||||
|
if (!serverVar) {
|
||||||
|
// User cancelled
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
ret.serverVariable = serverVar;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -269,7 +269,7 @@ export class CreateProjectFromDatabaseDialog {
|
|||||||
|
|
||||||
this.projectLocationTextBox = view.modelBuilder.inputBox().withProps({
|
this.projectLocationTextBox = view.modelBuilder.inputBox().withProps({
|
||||||
value: '',
|
value: '',
|
||||||
ariaLabel: constants.projectLocationLabel,
|
ariaLabel: constants.location,
|
||||||
placeHolder: constants.projectLocationPlaceholderText,
|
placeHolder: constants.projectLocationPlaceholderText,
|
||||||
width: cssStyles.createProjectFromDatabaseTextboxWidth
|
width: cssStyles.createProjectFromDatabaseTextboxWidth
|
||||||
}).component();
|
}).component();
|
||||||
@@ -280,7 +280,7 @@ export class CreateProjectFromDatabaseDialog {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const projectLocationLabel = view.modelBuilder.text().withProps({
|
const projectLocationLabel = view.modelBuilder.text().withProps({
|
||||||
value: constants.projectLocationLabel,
|
value: constants.location,
|
||||||
requiredIndicator: true,
|
requiredIndicator: true,
|
||||||
width: cssStyles.createProjectFromDatabaseLabelWidth
|
width: cssStyles.createProjectFromDatabaseLabelWidth
|
||||||
}).component();
|
}).component();
|
||||||
|
|||||||
@@ -192,7 +192,6 @@ export async function launchPublishDatabaseQuickpick(project: Project, projectCo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO@chgagnon: Get deployment options
|
|
||||||
// 6. Generate script/publish
|
// 6. Generate script/publish
|
||||||
let settings: IDeploySettings = {
|
let settings: IDeploySettings = {
|
||||||
databaseName: databaseName,
|
databaseName: databaseName,
|
||||||
|
|||||||
@@ -583,7 +583,7 @@ describe('ProjectsController', function (): void {
|
|||||||
});
|
});
|
||||||
|
|
||||||
let dialog = await projController.object.addDatabaseReference(proj);
|
let dialog = await projController.object.addDatabaseReference(proj);
|
||||||
await dialog.addReferenceClick();
|
await dialog!.addReferenceClick();
|
||||||
|
|
||||||
should(holler).equal(addDbRefHoller, 'executionCallback() is supposed to have been setup and called for add database reference scenario');
|
should(holler).equal(addDbRefHoller, 'executionCallback() is supposed to have been setup and called for add database reference scenario');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user