From 5f003b0dd7017607de0a13409e798e050b6ea504 Mon Sep 17 00:00:00 2001 From: kisantia <31145923+kisantia@users.noreply.github.com> Date: Wed, 6 Mar 2019 17:45:30 -0800 Subject: [PATCH] Move DacFx wizard into separate extension (#4115) * Moved dacfx wizard into separate extension * updating to use azdata * one more azdata change * bump import extension version * renaming extension to dacpac --- build/lib/extensions.js | 3 +- build/lib/extensions.ts | 3 +- extensions/dacpac/README.md | 37 +++++ extensions/dacpac/images/sqlserver.png | Bin 0 -> 37585 bytes extensions/dacpac/package.json | 49 ++++++ .../dacpac/src/controllers/controllerBase.ts | 30 ++++ .../dacpac/src/controllers/mainController.ts | 34 +++++ extensions/dacpac/src/main.ts | 37 +++++ extensions/dacpac/src/typings/ref.d.ts | 11 ++ extensions/dacpac/src/wizard/api/basePage.ts | 139 ++++++++++++++++++ .../src/wizard/api/dacFxConfigPage.ts | 0 extensions/dacpac/src/wizard/api/models.ts | 22 +++ .../src/wizard/dataTierApplicationWizard.ts | 0 .../src/wizard/pages/dacFxSummaryPage.ts | 0 .../src/wizard/pages/deployActionPage.ts | 0 .../src/wizard/pages/deployConfigPage.ts | 0 .../src/wizard/pages/deployPlanPage.ts | 0 .../src/wizard/pages/exportConfigPage.ts | 0 .../src/wizard/pages/extractConfigPage.ts | 0 .../src/wizard/pages/importConfigPage.ts | 0 .../src/wizard/pages/selectOperationpage.ts | 0 extensions/dacpac/tsconfig.json | 19 +++ extensions/dacpac/yarn.lock | 84 +++++++++++ extensions/import/README.md | 22 +-- extensions/import/package.json | 16 +- .../import/src/controllers/mainController.ts | 6 - extensions/import/src/wizard/api/basePage.ts | 4 +- extensions/import/src/wizard/api/models.ts | 23 +-- 28 files changed, 473 insertions(+), 66 deletions(-) create mode 100644 extensions/dacpac/README.md create mode 100644 extensions/dacpac/images/sqlserver.png create mode 100644 extensions/dacpac/package.json create mode 100644 extensions/dacpac/src/controllers/controllerBase.ts create mode 100644 extensions/dacpac/src/controllers/mainController.ts create mode 100644 extensions/dacpac/src/main.ts create mode 100644 extensions/dacpac/src/typings/ref.d.ts create mode 100644 extensions/dacpac/src/wizard/api/basePage.ts rename extensions/{import => dacpac}/src/wizard/api/dacFxConfigPage.ts (100%) create mode 100644 extensions/dacpac/src/wizard/api/models.ts rename extensions/{import => dacpac}/src/wizard/dataTierApplicationWizard.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/dacFxSummaryPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/deployActionPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/deployConfigPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/deployPlanPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/exportConfigPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/extractConfigPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/importConfigPage.ts (100%) rename extensions/{import => dacpac}/src/wizard/pages/selectOperationpage.ts (100%) create mode 100644 extensions/dacpac/tsconfig.json create mode 100644 extensions/dacpac/yarn.lock diff --git a/build/lib/extensions.js b/build/lib/extensions.js index 167dc4629b..7506286ab6 100644 --- a/build/lib/extensions.js +++ b/build/lib/extensions.js @@ -249,7 +249,8 @@ const sqlBuiltInExtensions = [ 'import', 'profiler', 'admin-pack', - 'big-data-cluster' + 'big-data-cluster', + 'dacpac' ]; var azureExtensions = ['azurecore', 'mssql']; const builtInExtensions = require('../builtInExtensions.json'); diff --git a/build/lib/extensions.ts b/build/lib/extensions.ts index 7cbece5db9..f8312f1a2b 100644 --- a/build/lib/extensions.ts +++ b/build/lib/extensions.ts @@ -296,7 +296,8 @@ const sqlBuiltInExtensions = [ 'import', 'profiler', 'admin-pack', - 'big-data-cluster' + 'big-data-cluster', + 'dacpac' ]; var azureExtensions = ['azurecore', 'mssql']; // {{SQL CARBON EDIT}} - End diff --git a/extensions/dacpac/README.md b/extensions/dacpac/README.md new file mode 100644 index 0000000000..8341633f08 --- /dev/null +++ b/extensions/dacpac/README.md @@ -0,0 +1,37 @@ +# Microsoft SQL Server Dacpac for Azure Data Studio + +Microsoft SQL Server Dacpac for Azure Data Studio includes the wizard: +- [Data-tier Application Wizard.](#data-tier-application-wizard-preview) + +## Data-tier Application Wizard *(preview)* +**The Data-tier Application Wizard** provides an easy to use experience to deploy and extract .dacpac files and import and export .bacpac files. + +This experience is currently in its initial preview. Please report issues and feature requests [here.](https://github.com/microsoft/azuredatastudio/issues) + + + + ### Requirements + * This wizard requires an active connection to a SQL Server instance to start. + + ### How do I start the Data-tier Application wizard? + * The main entry point for the wizard is to right click a database in the Object Explorer, and click **Data-tier Application wizard**. + * If a user is connected to a SQL Server instance, the user can also start the wizard from the command palette (Ctrl+Shift+P) by searching for **Data-tier Application wizard.** + + ### Why would I use the Data-tier Application wizard? + This wizard was created to add the ability to extract and deploy .dacpac files and import and export .bacpac files in Azure Data Studio. + +To learn more about Data-Tier Applications and working with dacpac and bacpac files, [you can read more here.](https://docs.microsoft.com/en-us/sql/relational-databases/data-tier-applications/data-tier-applications?view=sql-server-2017) + +## Code of Conduct + +This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. + +## Privacy Statement + +The [Microsoft Enterprise and Developer Privacy Statement](https://privacy.microsoft.com/en-us/privacystatement) describes the privacy statement of this software. + +## License + +Copyright (c) Microsoft Corporation. All rights reserved. + +Licensed under the [Source EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt). diff --git a/extensions/dacpac/images/sqlserver.png b/extensions/dacpac/images/sqlserver.png new file mode 100644 index 0000000000000000000000000000000000000000..d884faa14a804f63aa2a9d365fc75c09c12eeeb5 GIT binary patch literal 37585 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 RTp9-alNMJHs}M2r`#&r#oSOgu literal 0 HcmV?d00001 diff --git a/extensions/dacpac/package.json b/extensions/dacpac/package.json new file mode 100644 index 0000000000..1a1274d897 --- /dev/null +++ b/extensions/dacpac/package.json @@ -0,0 +1,49 @@ +{ + "name": "dacpac", + "displayName": "SQL Server Dacpac", + "description": "SQL Server Dacpac for Azure Data Studio.", + "version": "0.1.0", + "publisher": "Microsoft", + "preview": true, + "engines": { + "vscode": "^1.25.0", + "sqlops": "*" + }, + "license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/LICENSE.txt", + "icon": "images/sqlserver.png", + "aiKey": "AIF-5574968e-856d-40d2-af67-c89a14e76412", + "activationEvents": [ + "*" + ], + "main": "./out/main", + "repository": { + "type": "git", + "url": "https://github.com/Microsoft/azuredatastudio.git" + }, + "extensionDependencies": [ + "Microsoft.mssql" + ], + "contributes": { + "commands": [ + { + "command": "dacFx.start", + "title": "Data-tier Application wizard", + "category": "Data-tier Application" + } + ], + "menus": { + "objectExplorer/item/context": [ + { + "command": "dacFx.start", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", + "group": "export" + } + ] + } + }, + "dependencies": { + "htmlparser2": "^3.10.1", + "vscode-nls": "^3.2.1" + }, + "devDependencies": {} +} diff --git a/extensions/dacpac/src/controllers/controllerBase.ts b/extensions/dacpac/src/controllers/controllerBase.ts new file mode 100644 index 0000000000..fb4a2e8920 --- /dev/null +++ b/extensions/dacpac/src/controllers/controllerBase.ts @@ -0,0 +1,30 @@ + +/*--------------------------------------------------------------------------------------------- + * 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 vscode from 'vscode'; + +export default abstract class ControllerBase implements vscode.Disposable { + protected _context: vscode.ExtensionContext; + + protected constructor(context: vscode.ExtensionContext) { + this._context = context; + } + + public get extensionContext(): vscode.ExtensionContext { + return this._context; + } + + abstract activate(): Promise; + + abstract deactivate(): void; + + public dispose(): void { + this.deactivate(); + } +} + diff --git a/extensions/dacpac/src/controllers/mainController.ts b/extensions/dacpac/src/controllers/mainController.ts new file mode 100644 index 0000000000..32dcab6751 --- /dev/null +++ b/extensions/dacpac/src/controllers/mainController.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * 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 azdata from 'azdata'; +import ControllerBase from './controllerBase'; +import * as vscode from 'vscode'; +import { DataTierApplicationWizard } from '../wizard/dataTierApplicationWizard'; + +/** + * The main controller class that initializes the extension + */ +export default class MainController extends ControllerBase { + + public constructor(context: vscode.ExtensionContext) { + super(context); + } + /** + */ + public deactivate(): void { + } + + public activate(): Promise { + this.initializeDacFxWizard(); + return Promise.resolve(true); + } + + private initializeDacFxWizard() { + azdata.tasks.registerTask('dacFx.start', (profile: azdata.IConnectionProfile, ...args: any[]) => new DataTierApplicationWizard().start(profile, args)); + } +} diff --git a/extensions/dacpac/src/main.ts b/extensions/dacpac/src/main.ts new file mode 100644 index 0000000000..cac1908f61 --- /dev/null +++ b/extensions/dacpac/src/main.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * 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 vscode from 'vscode'; + +import ControllerBase from './controllers/controllerBase'; +import MainController from './controllers/mainController'; + +let controllers: ControllerBase[] = []; + +export function activate(context: vscode.ExtensionContext) { + let activations: Promise[] = []; + + // Start the main controller + let mainController = new MainController(context); + controllers.push(mainController); + context.subscriptions.push(mainController); + activations.push(mainController.activate()); + + return Promise.all(activations) + .then((results: boolean[]) => { + for (let result of results) { + if (!result) { + return false; + } + } + return true; + }); +} + +export function deactivate() { + for (let controller of controllers) { + controller.deactivate(); + } +} diff --git a/extensions/dacpac/src/typings/ref.d.ts b/extensions/dacpac/src/typings/ref.d.ts new file mode 100644 index 0000000000..1c00f76a98 --- /dev/null +++ b/extensions/dacpac/src/typings/ref.d.ts @@ -0,0 +1,11 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the Source EULA. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +/// +/// +/// +/// +/// +/// \ No newline at end of file diff --git a/extensions/dacpac/src/wizard/api/basePage.ts b/extensions/dacpac/src/wizard/api/basePage.ts new file mode 100644 index 0000000000..c462745733 --- /dev/null +++ b/extensions/dacpac/src/wizard/api/basePage.ts @@ -0,0 +1,139 @@ +/*--------------------------------------------------------------------------------------------- + * 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 azdata from 'azdata'; +import { DacFxDataModel } from './models'; + +export abstract class BasePage { + + protected readonly wizardPage: azdata.window.modelviewdialog.WizardPage; + protected readonly model: DacFxDataModel; + protected readonly view: azdata.ModelView; + + /** + * This method constructs all the elements of the page. + * @returns {Promise} + */ + public async abstract start(): Promise; + + /** + * This method is called when the user is entering the page. + * @returns {Promise} + */ + public async abstract onPageEnter(): Promise; + + /** + * This method is called when the user is leaving the page. + * @returns {Promise} + */ + async onPageLeave(): Promise { + return true; + } + + /** + * Override this method to cleanup what you don't need cached in the page. + * @returns {Promise} + */ + public async cleanup(): Promise { + return true; + } + + /** + * Sets up a navigation validator. + * This will be called right before onPageEnter(). + */ + public abstract setupNavigationValidator(); + + protected async getServerValues(): Promise<{ connection, displayName, name }[]> { + let cons = await azdata.connection.getActiveConnections(); + // This user has no active connections ABORT MISSION + if (!cons || cons.length === 0) { + return undefined; + } + + let count = -1; + let idx = -1; + + + let values = cons.map(c => { + // Handle the code to remember what the user's choice was from before + count++; + if (idx === -1) { + if (this.model.server && c.connectionId === this.model.server.connectionId) { + idx = count; + } else if (this.model.serverId && c.connectionId === this.model.serverId) { + idx = count; + } + } + + let db = c.options.databaseDisplayName; + let usr = c.options.user; + let srv = c.options.server; + + if (!db) { + db = ''; + } + + if (!usr) { + usr = 'default'; + } + + let finalName = `${srv}, ${db} (${usr})`; + return { + connection: c, + displayName: finalName, + name: c.connectionId + }; + }); + + if (idx >= 0) { + let tmp = values[0]; + values[0] = values[idx]; + values[idx] = tmp; + } else { + this.deleteServerValues(); + } + + return values; + } + + protected async getDatabaseValues(): Promise<{ displayName, name }[]> { + let idx = -1; + let count = -1; + let values = (await azdata.connection.listDatabases(this.model.server.connectionId)).map(db => { + count++; + if (this.model.database && db === this.model.database) { + idx = count; + } + + return { + displayName: db, + name: db + }; + }); + + if (idx >= 0) { + let tmp = values[0]; + values[0] = values[idx]; + values[idx] = tmp; + } else { + this.deleteDatabaseValues(); + } + + return values; + } + + protected deleteServerValues() { + delete this.model.server; + delete this.model.serverId; + delete this.model.database; + } + + protected deleteDatabaseValues() { + return; + } +} + diff --git a/extensions/import/src/wizard/api/dacFxConfigPage.ts b/extensions/dacpac/src/wizard/api/dacFxConfigPage.ts similarity index 100% rename from extensions/import/src/wizard/api/dacFxConfigPage.ts rename to extensions/dacpac/src/wizard/api/dacFxConfigPage.ts diff --git a/extensions/dacpac/src/wizard/api/models.ts b/extensions/dacpac/src/wizard/api/models.ts new file mode 100644 index 0000000000..ddad104b02 --- /dev/null +++ b/extensions/dacpac/src/wizard/api/models.ts @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * 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 azdata from 'azdata'; + +/** + * Data model to communicate between DacFx pages + */ +export interface DacFxDataModel { + server: azdata.connection.Connection; + database: string; + serverName: string; + serverId: string; + filePath: string; + version: string; + upgradeExisting: boolean; + scriptFilePath: string; + generateScriptAndDeploy: boolean; +} diff --git a/extensions/import/src/wizard/dataTierApplicationWizard.ts b/extensions/dacpac/src/wizard/dataTierApplicationWizard.ts similarity index 100% rename from extensions/import/src/wizard/dataTierApplicationWizard.ts rename to extensions/dacpac/src/wizard/dataTierApplicationWizard.ts diff --git a/extensions/import/src/wizard/pages/dacFxSummaryPage.ts b/extensions/dacpac/src/wizard/pages/dacFxSummaryPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/dacFxSummaryPage.ts rename to extensions/dacpac/src/wizard/pages/dacFxSummaryPage.ts diff --git a/extensions/import/src/wizard/pages/deployActionPage.ts b/extensions/dacpac/src/wizard/pages/deployActionPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/deployActionPage.ts rename to extensions/dacpac/src/wizard/pages/deployActionPage.ts diff --git a/extensions/import/src/wizard/pages/deployConfigPage.ts b/extensions/dacpac/src/wizard/pages/deployConfigPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/deployConfigPage.ts rename to extensions/dacpac/src/wizard/pages/deployConfigPage.ts diff --git a/extensions/import/src/wizard/pages/deployPlanPage.ts b/extensions/dacpac/src/wizard/pages/deployPlanPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/deployPlanPage.ts rename to extensions/dacpac/src/wizard/pages/deployPlanPage.ts diff --git a/extensions/import/src/wizard/pages/exportConfigPage.ts b/extensions/dacpac/src/wizard/pages/exportConfigPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/exportConfigPage.ts rename to extensions/dacpac/src/wizard/pages/exportConfigPage.ts diff --git a/extensions/import/src/wizard/pages/extractConfigPage.ts b/extensions/dacpac/src/wizard/pages/extractConfigPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/extractConfigPage.ts rename to extensions/dacpac/src/wizard/pages/extractConfigPage.ts diff --git a/extensions/import/src/wizard/pages/importConfigPage.ts b/extensions/dacpac/src/wizard/pages/importConfigPage.ts similarity index 100% rename from extensions/import/src/wizard/pages/importConfigPage.ts rename to extensions/dacpac/src/wizard/pages/importConfigPage.ts diff --git a/extensions/import/src/wizard/pages/selectOperationpage.ts b/extensions/dacpac/src/wizard/pages/selectOperationpage.ts similarity index 100% rename from extensions/import/src/wizard/pages/selectOperationpage.ts rename to extensions/dacpac/src/wizard/pages/selectOperationpage.ts diff --git a/extensions/dacpac/tsconfig.json b/extensions/dacpac/tsconfig.json new file mode 100644 index 0000000000..e6baa6d40d --- /dev/null +++ b/extensions/dacpac/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compileOnSave": true, + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "outDir": "./out", + "lib": [ + "es6", "es2015.promise" + ], + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "moduleResolution": "node", + "declaration": true + }, + "exclude": [ + "node_modules" + ] +} diff --git a/extensions/dacpac/yarn.lock b/extensions/dacpac/yarn.lock new file mode 100644 index 0000000000..568b64df58 --- /dev/null +++ b/extensions/dacpac/yarn.lock @@ -0,0 +1,84 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +dom-serializer@0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" + integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== + dependencies: + domelementtype "^1.3.0" + entities "^1.1.1" + +domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" + integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== + +domhandler@^2.3.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" + integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== + dependencies: + domelementtype "1" + +domutils@^1.5.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" + integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== + dependencies: + dom-serializer "0" + domelementtype "1" + +entities@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" + integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== + +htmlparser2@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" + integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== + dependencies: + domelementtype "^1.3.1" + domhandler "^2.3.0" + domutils "^1.5.1" + entities "^1.1.1" + inherits "^2.0.1" + readable-stream "^3.1.1" + +inherits@^2.0.1, inherits@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +readable-stream@^3.1.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.2.0.tgz#de17f229864c120a9f56945756e4f32c4045245d" + integrity sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +string_decoder@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.2.0.tgz#fe86e738b19544afe70469243b2a1ee9240eae8d" + integrity sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w== + dependencies: + safe-buffer "~5.1.0" + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +vscode-nls@^3.2.1: + version "3.2.5" + resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-3.2.5.tgz#25520c1955108036dec607c85e00a522f247f1a4" + integrity sha512-ITtoh3V4AkWXMmp3TB97vsMaHRgHhsSFPsUdzlueSL+dRZbSNTZeOmdQv60kjCV306ghPxhDeoNUEm3+EZMuyw== diff --git a/extensions/import/README.md b/extensions/import/README.md index 7a5d7d988b..ed3b58bb6c 100644 --- a/extensions/import/README.md +++ b/extensions/import/README.md @@ -1,8 +1,7 @@ # Microsoft SQL Server Import for Azure Data Studio -Microsoft SQL Server Import for Azure Data Studio includes two wizards: +Microsoft SQL Server Import for Azure Data Studio includes the wizard: - [Import Flat File Wizard](#import-flat-file-wizard-preview) -- [Data-tier Application Wizard.](#data-tier-application-wizard-preview) ## Import Flat File Wizard *(preview)* **The Import Flat File Wizard** is a simple way to copy data from a flat file (.csv, .txt, .json) to a SQL Server table. Checkout below the reasons for using the Import Flat File wizard, how to find this wizard, and a simple example. @@ -24,25 +23,6 @@ This wizard was created to improve the current import experience leveraging an i PROSE analyzes data patterns in your input file to infer column names, types, delimiters, and more. This framework learns the structure of the file and does all of the hard work so users don't have to. Please note that the PROSE binary components used by this extension are licensed under the [MICROSOFT SQL TOOLS IMPORT FLAT FILE EULA](https://raw.githubusercontent.com/Microsoft/azuredatastudio/master/extensions/import/Microsoft_SQL_Server_Import_Extension_and_Tools_Import_Flat_File_Preview.docx). - -## Data-tier Application Wizard *(preview)* -**The Data-tier Application Wizard** provides an easy to use experience to deploy and extract .dacpac files and import and export .bacpac files. - -This experience is currently in its initial preview. Please report issues and feature requests [here.](https://github.com/microsoft/azuredatastudio/issues) - - - - ### Requirements - * This wizard requires an active connection to a SQL Server instance to start. - - ### How do I start the Data-tier Application wizard? - * The main entry point for the wizard is to right click a database in the Object Explorer, and click **Data-tier Application wizard**. - * If a user is connected to a SQL Server instance, the user can also start the wizard from the command palette (Ctrl+Shift+P) by searching for **Data-tier Application wizard.** - - ### Why would I use the Data-tier Application wizard? - This wizard was created to add the ability to extract and deploy .dacpac files and import and export .bacpac files in Azure Data Studio. - -To learn more about Data-Tier Applications and working with dacpac and bacpac files, [you can read more here.](https://docs.microsoft.com/en-us/sql/relational-databases/data-tier-applications/data-tier-applications?view=sql-server-2017) ## License diff --git a/extensions/import/package.json b/extensions/import/package.json index f551087bb7..bc8127d26b 100644 --- a/extensions/import/package.json +++ b/extensions/import/package.json @@ -2,7 +2,7 @@ "name": "import", "displayName": "SQL Server Import", "description": "SQL Server Import for Azure Data Studio supports importing CSV or JSON files into SQL Server.", - "version": "0.6.1", + "version": "0.7.0", "publisher": "Microsoft", "preview": true, "engines": { @@ -33,15 +33,6 @@ "light": "./images/light_icon.svg", "dark": "./images/dark_icon.svg" } - }, - { - "command": "dacFx.start", - "title": "Data-tier Application Wizard", - "category": "Data-tier Application", - "icon": { - "light": "./images/light_icon.svg", - "dark": "./images/dark_icon.svg" - } } ], "keybindings": [ @@ -57,11 +48,6 @@ "command": "flatFileImport.start", "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", "group": "import" - }, - { - "command": "dacFx.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", - "group": "export" } ] } diff --git a/extensions/import/src/controllers/mainController.ts b/extensions/import/src/controllers/mainController.ts index 5769fb6f3e..0afa738898 100644 --- a/extensions/import/src/controllers/mainController.ts +++ b/extensions/import/src/controllers/mainController.ts @@ -13,7 +13,6 @@ import { FlatFileWizard } from '../wizard/flatFileWizard'; import { ServiceClient } from '../services/serviceClient'; import { ApiType, managerInstance } from '../services/serviceApiManager'; import { FlatFileProvider } from '../services/contracts'; -import { DataTierApplicationWizard } from '../wizard/dataTierApplicationWizard'; /** * The main controller class that initializes the extension @@ -36,15 +35,10 @@ export default class MainController extends ControllerBase { this.initializeFlatFileProvider(provider); }); - this.initializeDacFxWizard(); return Promise.resolve(true); } private initializeFlatFileProvider(provider: FlatFileProvider) { azdata.tasks.registerTask('flatFileImport.start', (profile: azdata.IConnectionProfile, ...args: any[]) => new FlatFileWizard(provider).start(profile, args)); } - - private initializeDacFxWizard() { - azdata.tasks.registerTask('dacFx.start', (profile: azdata.IConnectionProfile, ...args: any[]) => new DataTierApplicationWizard().start(profile, args)); - } } diff --git a/extensions/import/src/wizard/api/basePage.ts b/extensions/import/src/wizard/api/basePage.ts index 5c1f857366..86c6bc0803 100644 --- a/extensions/import/src/wizard/api/basePage.ts +++ b/extensions/import/src/wizard/api/basePage.ts @@ -5,12 +5,12 @@ 'use strict'; import * as azdata from 'azdata'; -import { BaseDataModel } from './models'; +import { ImportDataModel } from './models'; export abstract class BasePage { protected readonly wizardPage: azdata.window.WizardPage; - protected readonly model: BaseDataModel; + protected readonly model: ImportDataModel; protected readonly view: azdata.ModelView; /** diff --git a/extensions/import/src/wizard/api/models.ts b/extensions/import/src/wizard/api/models.ts index 5051df192e..c008f8f1ee 100644 --- a/extensions/import/src/wizard/api/models.ts +++ b/extensions/import/src/wizard/api/models.ts @@ -6,16 +6,12 @@ import * as azdata from 'azdata'; -export interface BaseDataModel { - server: azdata.connection.Connection; - serverId: string; - database: string; -} - /** * The main data model that communicates between the pages. */ -export interface ImportDataModel extends BaseDataModel { +export interface ImportDataModel { + server: azdata.connection.Connection; + serverId: string; ownerUri: string; proseColumns: ColumnMetadata[]; proseDataPreview: string[][]; @@ -35,16 +31,3 @@ export interface ColumnMetadata { primaryKey: boolean; nullable: boolean; } - -/** - * Data model to communicate between DacFx pages - */ -export interface DacFxDataModel extends BaseDataModel { - serverName: string; - serverId: string; - filePath: string; - version: string; - upgradeExisting: boolean; - scriptFilePath: string; - generateScriptAndDeploy: boolean; -}