DacFx import/export wizard (#3162)

Basic wizard to import/export bacpacs and deploy/extract dacpacs
This commit is contained in:
kisantia
2018-11-27 16:10:17 -08:00
committed by GitHub
parent 9ea8baca05
commit 4c075df327
26 changed files with 1745 additions and 121 deletions

View File

@@ -0,0 +1,78 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as sqlops from 'sqlops';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IConnectionManagementService } from 'sql/parts/connection/common/connectionManagement';
import { TPromise } from 'vs/base/common/winjs.base';
import { localize } from 'vs/nls';
import { data } from 'vs/base/test/common/filters.perf.data';
export const SERVICE_ID = 'dacFxService';
export const IDacFxService = createDecorator<IDacFxService>(SERVICE_ID);
export interface IDacFxService {
_serviceBrand: any;
registerProvider(providerId: string, provider: sqlops.DacFxServicesProvider): void;
exportBacpac(sourceDatabaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): void;
importBacpac(packageFilePath: string, targetDatabaseName: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): void;
extractDacpac(sourceDatabaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): void;
deployDacpac(packageFilePath: string, targetDatabaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): void;
}
export class DacFxService implements IDacFxService {
_serviceBrand: any;
private _providers: { [handle: string]: sqlops.DacFxServicesProvider; } = Object.create(null);
constructor(
@IConnectionManagementService private _connectionService: IConnectionManagementService
) {
}
registerProvider(providerId: string, provider: sqlops.DacFxServicesProvider): void {
this._providers[providerId] = provider;
}
exportBacpac(databasesName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return this._runAction(ownerUri, (runner) => {
return runner.exportBacpac(databasesName, packageFilePath, ownerUri, taskExecutionMode);
});
}
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return this._runAction(ownerUri, (runner) => {
return runner.importBacpac(packageFilePath, databaseName, ownerUri, taskExecutionMode);
});
}
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return this._runAction(ownerUri, (runner) => {
return runner.extractDacpac(databaseName, packageFilePath, applicationName, applicationVersion, ownerUri, taskExecutionMode);
});
}
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return this._runAction(ownerUri, (runner) => {
return runner.deployDacpac(packageFilePath, databaseName, upgradeExisting, ownerUri, taskExecutionMode);
});
}
private _runAction<T>(uri: string, action: (handler: sqlops.DacFxServicesProvider) => Thenable<T>): Thenable<T> {
let providerId: string = this._connectionService.getProviderIdFromUri(uri);
if (!providerId) {
return TPromise.wrapError(new Error(localize('providerIdNotValidError', "Connection is required in order to interact with DacFxService")));
}
let handler = this._providers[providerId];
if (handler) {
return action(handler);
} else {
return TPromise.wrapError(new Error(localize('noHandlerRegistered', "No Handler Registered")));
}
}
}

45
src/sql/sqlops.d.ts vendored
View File

@@ -37,6 +37,8 @@ declare module 'sqlops' {
export function registerCapabilitiesServiceProvider(provider: CapabilitiesProvider): vscode.Disposable;
export function registerDacFxServicesProvider(provider: DacFxServicesProvider): vscode.Disposable;
/**
* An [event](#Event) which fires when the specific flavor of a language used in DMP
* connections has changed. And example is for a SQL connection, the flavor changes
@@ -1583,6 +1585,49 @@ declare module 'sqlops' {
registerOnUpdated(handler: () => any): void;
}
// DacFx interfaces -----------------------------------------------------------------------
export interface DacFxResult extends ResultStatus {
operationId: string;
}
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;
taskExecutionMode: TaskExecutionMode;
}
export interface DeployParams {
packageFilePath: string;
databaseName: string;
upgradeExisting: boolean;
ownerUri: string;
taskExecutionMode: TaskExecutionMode;
}
export interface DacFxServicesProvider extends DataProvider {
exportBacpac(databaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: TaskExecutionMode): Thenable<DacFxResult>;
}
// Security service interfaces ------------------------------------------------------------------------
export interface CredentialInfo {
id: number;

View File

@@ -1232,7 +1232,8 @@ declare module 'sqlops' {
QueryProvider = 'QueryProvider',
AdminServicesProvider = 'AdminServicesProvider',
AgentServicesProvider = 'AgentServicesProvider',
CapabilitiesProvider = 'CapabilitiesProvider'
CapabilitiesProvider = 'CapabilitiesProvider',
DacFxServicesProvider = 'DacFxServicesProvider',
}
export namespace dataprotocol {

View File

@@ -285,7 +285,8 @@ export enum DataProviderType {
QueryProvider = 'QueryProvider',
AdminServicesProvider = 'AdminServicesProvider',
AgentServicesProvider = 'AgentServicesProvider',
CapabilitiesProvider = 'CapabilitiesProvider'
CapabilitiesProvider = 'CapabilitiesProvider',
DacFxServicesProvider = 'DacFxServicesProvider',
}
export enum DeclarativeDataType {

View File

@@ -156,6 +156,12 @@ export class ExtHostDataProtocol extends ExtHostDataProtocolShape {
return rt;
}
$registerDacFxServiceProvider(provider: sqlops.DacFxServicesProvider): vscode.Disposable {
let rt = this.registerProvider(provider, DataProviderType.DacFxServicesProvider);
this._proxy.$registerDacFxServicesProvider(provider.providerId, provider.handle);
return rt;
}
// Capabilities Discovery handlers
$getServerCapabilities(handle: number, client: sqlops.DataProtocolClientCapabilities): Thenable<sqlops.DataProtocolServerCapabilities> {
return this._resolveProvider<sqlops.CapabilitiesProvider>(handle).getServerCapabilities(client);

View File

@@ -26,6 +26,7 @@ import { IProfilerService } from 'sql/parts/profiler/service/interfaces';
import { ISerializationService } from 'sql/services/serialization/serializationService';
import { IFileBrowserService } from 'sql/parts/fileBrowser/common/interfaces';
import { IExtHostContext } from 'vs/workbench/api/node/extHost.protocol';
import { IDacFxService } from 'sql/services/dacfx/dacFxService';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
/**
@@ -55,7 +56,8 @@ export class MainThreadDataProtocol implements MainThreadDataProtocolShape {
@ITaskService private _taskService: ITaskService,
@IProfilerService private _profilerService: IProfilerService,
@ISerializationService private _serializationService: ISerializationService,
@IFileBrowserService private _fileBrowserService: IFileBrowserService
@IFileBrowserService private _fileBrowserService: IFileBrowserService,
@IDacFxService private _dacFxService: IDacFxService,
) {
if (extHostContext) {
this._proxy = extHostContext.getProxy(SqlExtHostContext.ExtHostDataProtocol);
@@ -399,6 +401,26 @@ export class MainThreadDataProtocol implements MainThreadDataProtocolShape {
return undefined;
}
public $registerDacFxServicesProvider(providerId: string, handle: number): TPromise<any> {
const self = this;
this._dacFxService.registerProvider(providerId, <sqlops.DacFxServicesProvider>{
exportBacpac(databaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return self._proxy.$exportBacpac(handle, databaseName, packageFilePath, ownerUri, taskExecutionMode);
},
importBacpac(packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return self._proxy.$importBacpac(handle, packageFilePath, databaseName, ownerUri, taskExecutionMode);
},
extractDacpac(databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return self._proxy.$extractDacpac(handle, databaseName, packageFilePath, applicationName, applicationVersion, ownerUri, taskExecutionMode);
},
deployDacpac(packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> {
return self._proxy.$deployDacpac(handle, packageFilePath, databaseName, upgradeExisting, ownerUri, taskExecutionMode);
}
});
return undefined;
}
// Connection Management handlers
public $onConnectionComplete(handle: number, connectionInfoSummary: sqlops.ConnectionInfoSummary): void {
this._connectionManagementService.onConnectionComplete(handle, connectionInfoSummary);

View File

@@ -310,6 +310,10 @@ export function createApiFactory(
return extHostDataProvider.$registerAgentServiceProvider(provider);
};
let registerDacFxServicesProvider = (provider: sqlops.DacFxServicesProvider): vscode.Disposable => {
return extHostDataProvider.$registerDacFxServiceProvider(provider);
};
// namespace: dataprotocol
const dataprotocol: typeof sqlops.dataprotocol = {
registerBackupProvider,
@@ -325,6 +329,7 @@ export function createApiFactory(
registerAdminServicesProvider,
registerAgentServicesProvider,
registerCapabilitiesServiceProvider,
registerDacFxServicesProvider,
onDidChangeLanguageFlavor(listener: (e: sqlops.DidChangeLanguageFlavorParams) => any, thisArgs?: any, disposables?: extHostTypes.Disposable[]) {
return extHostDataProvider.onDidChangeLanguageFlavor(listener, thisArgs, disposables);
},

View File

@@ -409,6 +409,26 @@ export abstract class ExtHostDataProtocolShape {
* Get Agent Credentials list
*/
$getCredentials(handle: number, connectionUri: string): Thenable<sqlops.GetCredentialsResult> { throw ni(); }
/**
* DacFx export bacpac
*/
$exportBacpac(handle: number, databaseName: string, packageFilePath: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> { throw ni(); }
/**
* DacFx import bacpac
*/
$importBacpac(handle: number, packageFilePath: string, databaseName: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> { throw ni(); }
/**
* DacFx extract dacpac
*/
$extractDacpac(handle: number, databaseName: string, packageFilePath: string, applicationName: string, applicationVersion: string, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> { throw ni(); }
/**
* DacFx deploy dacpac
*/
$deployDacpac(handle: number, packageFilePath: string, databaseName: string, upgradeExisting: boolean, ownerUri: string, taskExecutionMode: sqlops.TaskExecutionMode): Thenable<sqlops.DacFxResult> { throw ni(); }
}
/**
@@ -476,6 +496,7 @@ export interface MainThreadDataProtocolShape extends IDisposable {
$registerCapabilitiesServiceProvider(providerId: string, handle: number): TPromise<any>;
$registerAdminServicesProvider(providerId: string, handle: number): TPromise<any>;
$registerAgentServicesProvider(providerId: string, handle: number): TPromise<any>;
$registerDacFxServicesProvider(providerId: string, handle: number): TPromise<any>;
$unregisterProvider(handle: number): TPromise<any>;
$onConnectionComplete(handle: number, connectionInfoSummary: sqlops.ConnectionInfoSummary): void;
$onIntelliSenseCacheComplete(handle: number, connectionUri: string): void;