diff --git a/extensions/sql-database-projects/src/common/constants.ts b/extensions/sql-database-projects/src/common/constants.ts index 41fefac963..0fefb2a341 100644 --- a/extensions/sql-database-projects/src/common/constants.ts +++ b/extensions/sql-database-projects/src/common/constants.ts @@ -90,7 +90,7 @@ export function currentTargetPlatform(projectName: string, currentTargetPlatform // Publish dialog strings export const publishDialogName = localize('publishDialogName', "Publish project"); -export const publishDialogOkButtonText = localize('publishDialogOkButtonText', "Publish"); +export const publish = localize('publish', "Publish"); export const cancelButtonText = localize('cancelButtonText', "Cancel"); export const generateScriptButtonText = localize('generateScriptButtonText', "Generate Script"); export const databaseNameLabel = localize('databaseNameLabel', "Database"); @@ -109,6 +109,19 @@ export const profile = localize('profile', "Profile"); export const selectConnection = localize('selectConnection', "Select connection"); export const server = localize('server', "Server"); export const defaultUser = localize('default', "default"); +export const selectProfile = localize('selectProfile', "Select publish profile to load"); +export const dontUseProfile = localize('dontUseProfile', "Don't use profile"); +export const browseForProfile = localize('browseForProfile', "Browse for profile"); +export const chooseAction = localize('chooseAction', "Choose action"); +export const chooseSqlcmdVarsToModify = localize('chooseSqlcmdVarsToModify', "Choose SQLCMD variables to modify"); +export const enterNewValueForVar = (varName: string) => localize('enterNewValueForVar', "Enter new value for variable '{0}'", varName); +export const resetAllVars = localize('resetAllVars', "Reset all variables"); +export const createNew = localize('createNew', ""); +export const enterNewDatabaseName = localize('enterNewDatabaseName', "Enter new database name"); +export const newDatabaseTitle = (name: string) => localize({ key: 'newDatabaseTitle', comment: ['Name is the name of a new database being created'] }, "{0} (new)", name); +export const selectDatabase = localize('selectDatabase', "Select database"); +export const done = localize('done', "Done"); +export const nameMustNotBeEmpty = localize('nameMustNotBeEmpty', "Name must not be empty"); // Add Database Reference dialog strings diff --git a/extensions/sql-database-projects/src/controllers/mainController.ts b/extensions/sql-database-projects/src/controllers/mainController.ts index 53038175f1..103defec50 100644 --- a/extensions/sql-database-projects/src/controllers/mainController.ts +++ b/extensions/sql-database-projects/src/controllers/mainController.ts @@ -47,7 +47,7 @@ export default class MainController implements vscode.Disposable { vscode.commands.registerCommand('sqlDatabaseProjects.properties', async (node: WorkspaceTreeItem) => { await vscode.window.showErrorMessage(`Properties not yet implemented: ${node.element.uri.path}`); }); // TODO vscode.commands.registerCommand('sqlDatabaseProjects.build', async (node: WorkspaceTreeItem) => { await this.projectsController.buildProject(node); }); - vscode.commands.registerCommand('sqlDatabaseProjects.publish', async (node: WorkspaceTreeItem) => { await this.projectsController.publishProject(node); }); + vscode.commands.registerCommand('sqlDatabaseProjects.publish', async (node: WorkspaceTreeItem) => { this.projectsController.publishProject(node); }); vscode.commands.registerCommand('sqlDatabaseProjects.schemaCompare', async (node: WorkspaceTreeItem) => { await this.projectsController.schemaCompare(node); }); vscode.commands.registerCommand('sqlDatabaseProjects.createProjectFromDatabase', async (profile: azdataType.IConnectionProfile) => { await this.projectsController.createProjectFromDatabase(profile); }); diff --git a/extensions/sql-database-projects/src/controllers/projectController.ts b/extensions/sql-database-projects/src/controllers/projectController.ts index acc6e3e215..dede788cbe 100644 --- a/extensions/sql-database-projects/src/controllers/projectController.ts +++ b/extensions/sql-database-projects/src/controllers/projectController.ts @@ -13,6 +13,7 @@ import * as templates from '../templates/templates'; import * as vscode from 'vscode'; import type * as azdataType from 'azdata'; import * as dataworkspace from 'dataworkspace'; +import type * as mssqlVscode from 'vscode-mssql'; import { promises as fs } from 'fs'; import { PublishDatabaseDialog } from '../dialogs/publishDatabaseDialog'; @@ -33,9 +34,12 @@ import { CreateProjectFromDatabaseDialog } from '../dialogs/createProjectFromDat import { TelemetryActions, TelemetryReporter, TelemetryViews } from '../common/telemetry'; import { IconPathHelper } from '../common/iconHelper'; import { DashboardData, PublishData, Status } from '../models/dashboardData/dashboardData'; +import { launchPublishDatabaseQuickpick } from '../dialogs/publishDatabaseQuickpick'; const maxTableLength = 10; +export type IDacFxService = mssql.IDacFxService | mssqlVscode.IDacFxService; + /** * Controller for managing lifecycle of projects */ @@ -231,17 +235,22 @@ export class ProjectsController { * @param project Project to be built and published */ public publishProject(project: Project): PublishDatabaseDialog; - public publishProject(context: Project | dataworkspace.WorkspaceTreeItem): PublishDatabaseDialog { + public publishProject(context: Project | dataworkspace.WorkspaceTreeItem): PublishDatabaseDialog | undefined { const project: Project = this.getProjectFromContext(context); - let publishDatabaseDialog = this.getPublishDialog(project); + if (utils.getAzdataApi()) { + let publishDatabaseDialog = this.getPublishDialog(project); - publishDatabaseDialog.publish = async (proj, prof) => await this.publishProjectCallback(proj, prof); - publishDatabaseDialog.generateScript = async (proj, prof) => await this.publishProjectCallback(proj, prof); - publishDatabaseDialog.readPublishProfile = async (profileUri) => await this.readPublishProfileCallback(profileUri); + publishDatabaseDialog.publish = async (proj, prof) => await this.publishProjectCallback(proj, prof); + publishDatabaseDialog.generateScript = async (proj, prof) => await this.publishProjectCallback(proj, prof); + publishDatabaseDialog.readPublishProfile = async (profileUri) => await this.readPublishProfileCallback(profileUri); - publishDatabaseDialog.openDialog(); + publishDatabaseDialog.openDialog(); - return publishDatabaseDialog; + return publishDatabaseDialog; + } else { + launchPublishDatabaseQuickpick(project); + return undefined; + } } public async publishProjectCallback(project: Project, settings: IPublishSettings | IGenerateScriptSettings): Promise { @@ -284,13 +293,26 @@ export class ProjectsController { } try { + const azdataApi = utils.getAzdataApi(); if ((settings).upgradeExisting) { telemetryProps.publishAction = 'deploy'; - result = await dacFxService.deployDacpac(tempPath, settings.databaseName, (settings).upgradeExisting, settings.connectionUri, utils.getAzdataApi()!.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); + if (azdataApi) { + result = await (dacFxService as mssql.IDacFxService).deployDacpac(tempPath, settings.databaseName, (settings).upgradeExisting, settings.connectionUri, azdataApi.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); + } else { + // TODO@chgagnon Fix typing + result = await (dacFxService as mssqlVscode.IDacFxService).deployDacpac(tempPath, settings.databaseName, (settings).upgradeExisting, settings.connectionUri, azdataApi!.TaskExecutionMode.execute, settings.sqlCmdVariables, settings.deploymentOptions); + } + } else { telemetryProps.publishAction = 'generateScript'; - result = await dacFxService.generateDeployScript(tempPath, settings.databaseName, settings.connectionUri, utils.getAzdataApi()!.TaskExecutionMode.script, settings.sqlCmdVariables, settings.deploymentOptions); + if (azdataApi) { + result = await (dacFxService as mssql.IDacFxService).generateDeployScript(tempPath, settings.databaseName, settings.connectionUri, azdataApi.TaskExecutionMode.script, settings.sqlCmdVariables, settings.deploymentOptions); + } else { + // TODO@chgagnon Fix typing + result = await (dacFxService as mssqlVscode.IDacFxService).generateDeployScript(tempPath, settings.databaseName, settings.connectionUri, undefined/*mssqlVscode.TaskExecutionMode.script*/, settings.sqlCmdVariables, settings.deploymentOptions); + } + } } catch (err) { const actionEndTime = new Date().getTime(); @@ -807,11 +829,17 @@ export class ProjectsController { } } - public async getDaxFxService(): Promise { - const ext: vscode.Extension = vscode.extensions.getExtension(mssql.extension.name)!; + public async getDaxFxService(): Promise { + if (utils.getAzdataApi()) { + const ext: vscode.Extension = vscode.extensions.getExtension(mssql.extension.name)!; + const extensionApi = await ext.activate(); + return extensionApi.dacFx; + } else { + const ext: vscode.Extension = vscode.extensions.getExtension(mssql.extension.name)!; + const extensionApi = await ext.activate(); + return extensionApi.dacFx; + } - await ext.activate(); - return (ext.exports as mssql.IExtension).dacFx; } diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts index f64c122be4..8d371a77b3 100644 --- a/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseDialog.ts @@ -57,7 +57,7 @@ export class PublishDatabaseDialog { public openDialog(): void { this.initializeDialog(); - this.dialog.okButton.label = constants.publishDialogOkButtonText; + this.dialog.okButton.label = constants.publish; this.dialog.okButton.enabled = false; this.toDispose.push(this.dialog.okButton.onClick(async () => await this.publishClick())); @@ -536,17 +536,7 @@ export class PublishDatabaseDialog { }).component(); loadProfileButton.onDidClick(async () => { - const fileUris = await vscode.window.showOpenDialog( - { - canSelectFiles: true, - canSelectFolders: false, - canSelectMany: false, - defaultUri: vscode.Uri.file(this.project.projectFolderPath), - filters: { - [constants.publishSettingsFiles]: ['publish.xml'] - } - } - ); + const fileUris = await promptForPublishProfile(this.project.projectFolderPath); if (!fileUris || fileUris.length === 0) { return; @@ -628,3 +618,17 @@ export class PublishDatabaseDialog { return true; } } + +export function promptForPublishProfile(defaultPath: string): Thenable { + return vscode.window.showOpenDialog( + { + canSelectFiles: true, + canSelectFolders: false, + canSelectMany: false, + defaultUri: vscode.Uri.file(defaultPath), + filters: { + [constants.publishSettingsFiles]: ['publish.xml'] + } + } + ); +} diff --git a/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts b/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts new file mode 100644 index 0000000000..3f71668a11 --- /dev/null +++ b/extensions/sql-database-projects/src/dialogs/publishDatabaseQuickpick.ts @@ -0,0 +1,157 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as constants from '../common/constants'; +import { IGenerateScriptSettings, IPublishSettings } from '../models/IPublishSettings'; +import { Project } from '../models/project'; +import { promptForPublishProfile } from './publishDatabaseDialog'; + +/** + * Create flow for Publishing a database using only VS Code-native APIs such as QuickPick + */ +export async function launchPublishDatabaseQuickpick(project: Project): Promise { + + // 1. Select publish settings file (optional) + // TODO@chgagnon: Hook up to dacfx service + const browseProfileOption = await vscode.window.showQuickPick( + [constants.dontUseProfile, constants.browseForProfile], + { title: constants.selectProfile, ignoreFocusOut: true }); + if (!browseProfileOption) { + return; + } + + // let publishSettingsFile: vscode.Uri | undefined; + if (browseProfileOption === constants.browseForProfile) { + const locations = await promptForPublishProfile(project.projectFolderPath); + if (!locations) { + return; + } + // publishSettingsFile = locations[0]; + } + + // 2. Select connection + // TODO@chgagnon: Hook up to MSSQL + const connectionProfile = await vscode.window.showQuickPick( + ['Connection 1', 'Connection 2', 'Create New Connection'], + { title: constants.selectConnection, ignoreFocusOut: true }); + if (!connectionProfile) { + return; + } + const dbs = ['db1', 'db2']; + const dbQuickpicks = dbs.map(db => { + return { + label: db, + dbName: db + } as vscode.QuickPickItem & { dbName: string, isCreateNew?: boolean }; + }); + // Ensure the project name is an option, either adding it if it doesn't already exist or moving it to the top if it does + const projectNameIndex = dbs.findIndex(db => db === project.projectFileName); + if (projectNameIndex === -1) { + dbQuickpicks.unshift({ label: constants.newDatabaseTitle(project.projectFileName), dbName: project.projectFileName }); + } else { + dbQuickpicks.splice(projectNameIndex, 1); + dbQuickpicks.unshift({ label: project.projectFileName, dbName: project.projectFileName }); + } + + dbQuickpicks.push({ label: constants.createNew, dbName: '', isCreateNew: true }); + // 3. Select database + // TODO@chgagnon: Hook up to MSSQL + let databaseName = ''; + while (databaseName === '') { + const selectedDatabase = await vscode.window.showQuickPick( + dbQuickpicks, + { title: constants.selectDatabase, ignoreFocusOut: true }); + if (!selectedDatabase) { + // User cancelled + return; + } + databaseName = selectedDatabase.dbName; + if (selectedDatabase.isCreateNew) { + databaseName = await vscode.window.showInputBox( + { + title: constants.enterNewDatabaseName, + ignoreFocusOut: true, + validateInput: input => input ? undefined : constants.nameMustNotBeEmpty + } + ) ?? ''; + // If user cancels out of this just return them to the db select quickpick in case they changed their mind + } + } + + + // 4. Modify sqlcmd vars + // TODO@chgagnon: Concat ones from publish profile + let sqlCmdVariables = Object.assign({}, project.sqlCmdVariables); + + if (Object.keys(sqlCmdVariables).length > 0) { + // Continually loop here, allowing the user to modify SQLCMD variables one + // at a time until they're done (either by selecting the "Done" option or + // escaping out of the quick pick dialog). Users can modify each variable + // as many times as they wish - with an option to reset all the variables + // to their starting values being provided as well. + while (true) { + const quickPickItems = Object.keys(sqlCmdVariables).map(key => { + return { + label: key, + description: sqlCmdVariables[key], + key: key + } as vscode.QuickPickItem & { key?: string, isResetAllVars?: boolean, isDone?: boolean }; + }); + quickPickItems.push({ label: constants.resetAllVars, isResetAllVars: true }); + quickPickItems.unshift({ label: constants.done, isDone: true }); + const sqlCmd = await vscode.window.showQuickPick( + quickPickItems, + { title: constants.chooseSqlcmdVarsToModify, ignoreFocusOut: true } + ); + if (!sqlCmd) { + // When user hits escape then we continue on here, we don't exit the publish + // flow since this is an optional step + break; + } + if (sqlCmd.key) { + const newValue = await vscode.window.showInputBox( + { + title: constants.enterNewValueForVar(sqlCmd.key), + value: sqlCmdVariables[sqlCmd.key], + ignoreFocusOut: true + } + ); + if (newValue) { + sqlCmdVariables[sqlCmd.key] = newValue; + } + } else if (sqlCmd.isResetAllVars) { + sqlCmdVariables = Object.assign({}, project.sqlCmdVariables); + } else if (sqlCmd.isDone) { + break; + } + + } + } + + // 5. Select action to take + const action = await vscode.window.showQuickPick( + [constants.generateScriptButtonText, constants.publish], + { title: constants.chooseAction, ignoreFocusOut: true }); + if (!action) { + return; + } + + // TODO@chgagnon: Get deployment options + // 6. Generate script/publish + let settings: IPublishSettings | IGenerateScriptSettings = { + databaseName: databaseName, + serverName: '', // TODO@chgagnon: Get from connection profile + connectionUri: '', // TODO@chgagnon: Get from connection profile + sqlCmdVariables: undefined, // this.getSqlCmdVariablesForPublish(), + deploymentOptions: undefined, // await this.getDeploymentOptions(), + profileUsed: true, // this.profileUsed, + }; + + // TODO@chgagnon Consolidate creation of the settings into one place + if (action === constants.publish) { + (settings as IPublishSettings).upgradeExisting = true; + } +} diff --git a/extensions/sql-database-projects/src/models/publishProfile/publishProfile.ts b/extensions/sql-database-projects/src/models/publishProfile/publishProfile.ts index c46c6ce1cc..4e6a86381b 100644 --- a/extensions/sql-database-projects/src/models/publishProfile/publishProfile.ts +++ b/extensions/sql-database-projects/src/models/publishProfile/publishProfile.ts @@ -7,10 +7,12 @@ import * as xmldom from 'xmldom'; import * as constants from '../../common/constants'; import * as utils from '../../common/utils'; import * as mssql from '../../../../mssql'; +import * as vscodeMssql from 'vscode-mssql'; import { promises as fs } from 'fs'; import { Uri } from 'vscode'; import { SqlConnectionDataSource } from '../dataSources/sqlConnectionStringSource'; +import { IDacFxService } from '../../controllers/projectController'; // only reading db name, connection string, and SQLCMD vars from profile for now export interface PublishProfile { @@ -19,13 +21,13 @@ export interface PublishProfile { connectionId: string; connection: string; sqlCmdVariables: Record; - options?: mssql.DeploymentOptions; + options?: mssql.DeploymentOptions | vscodeMssql.DeploymentOptions; } /** * parses the specified file to load publish settings */ -export async function load(profileUri: Uri, dacfxService: mssql.IDacFxService): Promise { +export async function load(profileUri: Uri, dacfxService: IDacFxService): Promise { const profileText = await fs.readFile(profileUri.fsPath); const profileXmlDoc = new xmldom.DOMParser().parseFromString(profileText.toString()); diff --git a/extensions/sql-database-projects/src/test/projectController.test.ts b/extensions/sql-database-projects/src/test/projectController.test.ts index e62e2ca78b..2ea4f93d33 100644 --- a/extensions/sql-database-projects/src/test/projectController.test.ts +++ b/extensions/sql-database-projects/src/test/projectController.test.ts @@ -345,7 +345,7 @@ describe('ProjectsController', function (): void { projController.callBase = true; projController.setup(x => x.getPublishDialog(TypeMoq.It.isAny())).returns(() => publishDialog.object); - await projController.object.publishProject(new Project('FakePath')); + projController.object.publishProject(new Project('FakePath')); should(opened).equal(true); }); @@ -376,12 +376,12 @@ describe('ProjectsController', function (): void { return Promise.resolve(undefined); }); - let dialog = await projController.object.publishProject(proj); + let dialog = projController.object.publishProject(proj); await dialog.publishClick(); should(holler).equal(publishHoller, 'executionCallback() is supposed to have been setup and called for Publish scenario'); - dialog = await projController.object.publishProject(proj); + dialog = projController.object.publishProject(proj); await dialog.generateScriptClick(); should(holler).equal(generateHoller, 'executionCallback() is supposed to have been setup and called for GenerateScript scenario'); diff --git a/extensions/sql-database-projects/src/typings/vscode-mssql.d.ts b/extensions/sql-database-projects/src/typings/vscode-mssql.d.ts new file mode 100644 index 0000000000..8ed816c6ea --- /dev/null +++ b/extensions/sql-database-projects/src/typings/vscode-mssql.d.ts @@ -0,0 +1,291 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +declare module 'vscode-mssql' { + /** + * Covers defining what the vscode-mssql extension exports to other extensions + * + * IMPORTANT: THIS IS NOT A HARD DEFINITION unlike vscode; therefore no enums or classes should be defined here + * (const enums get evaluated when typescript -> javascript so those are fine) + */ + + + export const enum extension { + name = 'Microsoft.mssql' + } + + /** + * The APIs provided by Mssql extension + */ + export interface IExtension { + + readonly dacFx: IDacFxService; + } + + export const enum ExtractTarget { + dacpac = 0, + file = 1, + flat = 2, + objectType = 3, + schema = 4, + schemaObjectType = 5 + } + + export interface IDacFxService { + exportBacpac(databaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable; + importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable; + extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable; + createProjectFromDatabase(databaseName: string, targetFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, extractTarget: ExtractTarget, taskExecutionMode: TaskExecutionMode): Thenable; + deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Record, deploymentOptions?: DeploymentOptions): Thenable; + generateDeployScript(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode, sqlCommandVariableValues?: Record, deploymentOptions?: DeploymentOptions): Thenable; + generateDeployPlan(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable; + getOptionsFromProfile(profilePath: string): Thenable; + validateStreamingJob(packageFilePath: string, createStreamingJobTsql: string): Thenable; + } + + export enum TaskExecutionMode { + execute = 0, + script = 1, + executeAndScript = 2 + } + + export interface DeploymentOptions { + ignoreTableOptions: boolean; + ignoreSemicolonBetweenStatements: boolean; + ignoreRouteLifetime: boolean; + ignoreRoleMembership: boolean; + ignoreQuotedIdentifiers: boolean; + ignorePermissions: boolean; + ignorePartitionSchemes: boolean; + ignoreObjectPlacementOnPartitionScheme: boolean; + ignoreNotForReplication: boolean; + ignoreLoginSids: boolean; + ignoreLockHintsOnIndexes: boolean; + ignoreKeywordCasing: boolean; + ignoreIndexPadding: boolean; + ignoreIndexOptions: boolean; + ignoreIncrement: boolean; + ignoreIdentitySeed: boolean; + ignoreUserSettingsObjects: boolean; + ignoreFullTextCatalogFilePath: boolean; + ignoreWhitespace: boolean; + ignoreWithNocheckOnForeignKeys: boolean; + verifyCollationCompatibility: boolean; + unmodifiableObjectWarnings: boolean; + treatVerificationErrorsAsWarnings: boolean; + scriptRefreshModule: boolean; + scriptNewConstraintValidation: boolean; + scriptFileSize: boolean; + scriptDeployStateChecks: boolean; + scriptDatabaseOptions: boolean; + scriptDatabaseCompatibility: boolean; + scriptDatabaseCollation: boolean; + runDeploymentPlanExecutors: boolean; + registerDataTierApplication: boolean; + populateFilesOnFileGroups: boolean; + noAlterStatementsToChangeClrTypes: boolean; + includeTransactionalScripts: boolean; + includeCompositeObjects: boolean; + allowUnsafeRowLevelSecurityDataMovement: boolean; + ignoreWithNocheckOnCheckConstraints: boolean; + ignoreFillFactor: boolean; + ignoreFileSize: boolean; + ignoreFilegroupPlacement: boolean; + doNotAlterReplicatedObjects: boolean; + doNotAlterChangeDataCaptureObjects: boolean; + disableAndReenableDdlTriggers: boolean; + deployDatabaseInSingleUserMode: boolean; + createNewDatabase: boolean; + compareUsingTargetCollation: boolean; + commentOutSetVarDeclarations: boolean; + blockWhenDriftDetected: boolean; + blockOnPossibleDataLoss: boolean; + backupDatabaseBeforeChanges: boolean; + allowIncompatiblePlatform: boolean; + allowDropBlockingAssemblies: boolean; + dropConstraintsNotInSource: boolean; + dropDmlTriggersNotInSource: boolean; + dropExtendedPropertiesNotInSource: boolean; + dropIndexesNotInSource: boolean; + ignoreFileAndLogFilePath: boolean; + ignoreExtendedProperties: boolean; + ignoreDmlTriggerState: boolean; + ignoreDmlTriggerOrder: boolean; + ignoreDefaultSchema: boolean; + ignoreDdlTriggerState: boolean; + ignoreDdlTriggerOrder: boolean; + ignoreCryptographicProviderFilePath: boolean; + verifyDeployment: boolean; + ignoreComments: boolean; + ignoreColumnCollation: boolean; + ignoreAuthorizer: boolean; + ignoreAnsiNulls: boolean; + generateSmartDefaults: boolean; + dropStatisticsNotInSource: boolean; + dropRoleMembersNotInSource: boolean; + dropPermissionsNotInSource: boolean; + dropObjectsNotInSource: boolean; + ignoreColumnOrder: boolean; + doNotDropObjectTypes: SchemaObjectType[]; + excludeObjectTypes: SchemaObjectType[]; + } + + /** + * Values from \Product\Source\DeploymentApi\ObjectTypes.cs + */ + export const enum SchemaObjectType { + Aggregates = 0, + ApplicationRoles = 1, + Assemblies = 2, + AssemblyFiles = 3, + AsymmetricKeys = 4, + BrokerPriorities = 5, + Certificates = 6, + ColumnEncryptionKeys = 7, + ColumnMasterKeys = 8, + Contracts = 9, + DatabaseOptions = 10, + DatabaseRoles = 11, + DatabaseTriggers = 12, + Defaults = 13, + ExtendedProperties = 14, + ExternalDataSources = 15, + ExternalFileFormats = 16, + ExternalTables = 17, + Filegroups = 18, + Files = 19, + FileTables = 20, + FullTextCatalogs = 21, + FullTextStoplists = 22, + MessageTypes = 23, + PartitionFunctions = 24, + PartitionSchemes = 25, + Permissions = 26, + Queues = 27, + RemoteServiceBindings = 28, + RoleMembership = 29, + Rules = 30, + ScalarValuedFunctions = 31, + SearchPropertyLists = 32, + SecurityPolicies = 33, + Sequences = 34, + Services = 35, + Signatures = 36, + StoredProcedures = 37, + SymmetricKeys = 38, + Synonyms = 39, + Tables = 40, + TableValuedFunctions = 41, + UserDefinedDataTypes = 42, + UserDefinedTableTypes = 43, + ClrUserDefinedTypes = 44, + Users = 45, + Views = 46, + XmlSchemaCollections = 47, + Audits = 48, + Credentials = 49, + CryptographicProviders = 50, + DatabaseAuditSpecifications = 51, + DatabaseEncryptionKeys = 52, + DatabaseScopedCredentials = 53, + Endpoints = 54, + ErrorMessages = 55, + EventNotifications = 56, + EventSessions = 57, + LinkedServerLogins = 58, + LinkedServers = 59, + Logins = 60, + MasterKeys = 61, + Routes = 62, + ServerAuditSpecifications = 63, + ServerRoleMembership = 64, + ServerRoles = 65, + ServerTriggers = 66, + ExternalStreams = 67, + ExternalStreamingJobs = 68 + } + + /** + * ResultStatus from d.ts + */ + export interface ResultStatus { + success: boolean; + errorMessage: string; + } + + export interface DacFxResult extends ResultStatus { + operationId: string; + } + + export interface GenerateDeployPlanResult extends DacFxResult { + report: string; + } + + export interface DacFxOptionsResult extends ResultStatus { + deploymentOptions: DeploymentOptions; + } + + export interface ValidateStreamingJobResult extends ResultStatus { } + + export interface ExportParams { + databaseName: string; + packageFilePath: string; + ownerUri: string; + taskExecutionMode: TaskExecutionMode; + } + + export interface ImportParams { + packageFilePath: string; + databaseName: string; + ownerUri: string; + taskExecutionMode: TaskExecutionMode; + } + + export interface ExtractParams { + databaseName: string; + packageFilePath: string; + applicationName: string; + applicationVersion: string; + ownerUri: string; + extractTarget?: ExtractTarget; + taskExecutionMode: TaskExecutionMode; + } + + export interface DeployParams { + packageFilePath: string; + databaseName: string; + upgradeExisting: boolean; + sqlCommandVariableValues?: Record; + deploymentOptions?: DeploymentOptions; + ownerUri: string; + taskExecutionMode: TaskExecutionMode; + } + + export interface GenerateDeployScriptParams { + packageFilePath: string; + databaseName: string; + sqlCommandVariableValues?: Record; + deploymentOptions?: DeploymentOptions; + ownerUri: string; + taskExecutionMode: TaskExecutionMode; + } + + export interface GenerateDeployPlanParams { + packageFilePath: string; + databaseName: string; + ownerUri: string; + taskExecutionMode: TaskExecutionMode; + } + + export interface GetOptionsFromProfileParams { + profilePath: string; + } + + export interface ValidateStreamingJobParams { + packageFilePath: string; + createStreamingJobTsql: string; + } + +}