Compare commits

..

17 Commits

Author SHA1 Message Date
brian-harris
6783aa6967 improve account and tenant selection error handling (#17476) (#17489)
* improve account/tenant selection error handling

* remove extra space from user string
2021-10-26 09:39:05 -07:00
brian-harris
ccbc2f74fe apply unique filter to getLocations api's (#17454) (#17473)
* apply unique filter to getLocations api's

* filter resource locations to distinct list

* simplify location filter
2021-10-26 09:38:38 -07:00
Daniel Grajeda
d7283a6e56 Notebook Views initialization fix (#17109) (#17471)
Separate the Views load from the initialization. This way we can load previously created views, and only add the new views data to the document when needed. For now, this happens only when a view is created.
2021-10-22 15:29:22 -07:00
Charles Gagnon
0684040d34 Fix backups not restoring in correct editor (#17466) (#17468) 2021-10-22 13:36:29 -07:00
Karl Burtram
625eb00be2 Remove duplicate Getting Started contributions (#17465) (#17470) 2021-10-22 12:55:09 -07:00
brian-harris
c5a27a89f3 Retry sql migration (#17376) (#17448) 2021-10-21 21:14:15 -07:00
Charles Gagnon
b9a7d5e4bd Fix URL protocol for non-insiders builds (#17446) 2021-10-21 17:12:39 -07:00
Alan Ren
f876c00ca1 fix scrolling issue (#17443) (#17449) 2021-10-21 16:25:09 -07:00
Z Chen
83ae789aa0 Warning when .NET 6 SDK is detected (#17422) (#17447)
* Check for max supported version

* Separate dialog for downgrade warning

* Address PR comments

* Use markdown link

* Update warning message
2021-10-21 16:24:14 -07:00
Maddy
6fe4d0a561 add path.posix while reading relative paths (#17326) (#17441)
* path.posix

* add test for nested folders scenario

* update message and remove the redundant check
2021-10-21 14:11:33 -07:00
Benjin Dubishar
2eaec9f41d Use correct string when checking "browse" option (#17432) (#17440)
* Correct browse string match

* Deduping const
2021-10-21 14:10:47 -07:00
rajeshka
2edafe50bb remove trailing line after the cursor (#17431) (#17436)
* remove trailing line after the cursor

* Addressed PR

(cherry picked from commit 914ac2b09d)
2021-10-21 11:38:23 -07:00
rajeshka
24c5686bd6 fixing the svg (#17427) (#17429)
(cherry picked from commit d196588661)
2021-10-20 20:11:04 -07:00
rajeshka
1731aeffbe Fix for Split Cell duplicates cell #17400 (#17417) (#17425)
(cherry picked from commit d251bbd1a1)
2021-10-20 16:28:47 -07:00
Lucy Zhang
b35ff6451a add listener for celltype change (#17414) (#17418) 2021-10-20 14:38:35 -07:00
Vasu Bhog
07aa256f4c Move split cell icon (#17383) (#17392)
* move split cell icon before delete icon
2021-10-19 13:01:57 -07:00
Lucy Zhang
473764de9a use setContent instead of addElement (#17386) (#17388) 2021-10-19 10:28:19 -07:00
521 changed files with 7321 additions and 37284 deletions

View File

@@ -751,7 +751,7 @@
"chart.js",
"plotly.js",
"angular2-grid",
"kburtram-query-plan",
"html-query-plan",
"html-to-image",
"turndown",
"gridstack",

25
.vscode/launch.json vendored
View File

@@ -269,31 +269,6 @@
"presentation": {
"group": "4_web"
}
},
{
"name": "Run Sample Resource Deployment Extension",
"type": "sqlopsExtensionHost",
"request": "launch",
"windows": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.bat"
},
"osx": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"linux": {
"runtimeExecutable": "${workspaceFolder}/scripts/sql.sh"
},
"args": [
"--extensionDevelopmentPath=${workspaceRoot}/samples/sample-resource-deployment"
],
"outFiles": [
"${workspaceRoot}/samples/sample-resource-deployment/out/**/*.js"
],
"preLaunchTask": "Watch sample-resource-deployment",
"presentation": {
"group": "5_samples"
},
"timeout": 30000
}
],
"compounds": [

12
.vscode/tasks.json vendored
View File

@@ -231,18 +231,6 @@
"group": "build",
"label": "npm: tsec-compile-check",
"detail": "node_modules/tsec/bin/tsec -p src/tsconfig.json --noEmit"
},
{
"type": "npm",
"script": "watch",
"label": "Watch sample-resource-deployment",
"path": "./samples/sample-resource-deployment/package.json",
"problemMatcher": "$tsc-watch",
"isBackground": true,
"presentation": {
"reveal": "never"
},
"group": "build"
}
]
}

View File

@@ -1,61 +1,5 @@
# Change Log
## Version 1.33.1
* Release date: Nov 4, 2021
* Release status: General Availability
## Hotfix release
- Fix for [#16535 Unable to See Saved Connections in Restricted Mode](https://github.com/microsoft/azuredatastudio/issues/17535)
- Fix for [#17579 Can't type in Notebook code cell after editing text cell](https://github.com/microsoft/azuredatastudio/issues/17579)
| Platform |
| --------------------------------------- |
| [Windows User Installer][win-user] |
| [Windows System Installer][win-system] |
| [Windows ZIP][win-zip] |
| [macOS ZIP][osx-zip] |
| [Linux TAR.GZ][linux-zip] |
| [Linux RPM][linux-rpm] |
| [Linux DEB][linux-deb] |
[win-user]: https://go.microsoft.com/fwlink/?linkid=2176805
[win-system]: https://go.microsoft.com/fwlink/?linkid=2175910
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2176806
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2176807
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2176505
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2176005
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2176006
## Version 1.33.0
* Release date: October 27, 2021
* Release status: General Availability
## What's new in this version
* New Notebook Features:
* Notebook Views
* Split cell support
* Keyboard shortcuts for Markdown Toolbar Cells
* Ctrl/Cmd + B = Bold Text
* Ctrl/Cmd + I = Italicize Text
* Ctrl/Cmd + U = Underline Text
* Ctrl/Cmd + Shift + K = Add Code Block
* Ctrl/Cmd + Shift + H = Highlight Text
* Book improvements
* Add a new section
* Drag and Drop
* Extension Updates:
* Import
* Langpacks
* Schema Compare
* Sql Database Projects
* Bug Fixes
* Notebook linking improvements
* Horizontal Scrollbar improvement (when word wrap is off in MD Splitview / MD mode) in Notebooks
* Vertical Scrollbar improvement for MD Splitview in Notebooks
## Version 1.32.0
* Release date: August 18, 2021
* Release status: General Availability

View File

@@ -131,10 +131,10 @@ Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the [Source EULA](LICENSE.txt).
[win-user]: https://go.microsoft.com/fwlink/?linkid=2176805
[win-system]: https://go.microsoft.com/fwlink/?linkid=2175910
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2176806
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2176807
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2176505
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2176005
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2176006
[win-user]: https://go.microsoft.com/fwlink/?linkid=2170400
[win-system]: https://go.microsoft.com/fwlink/?linkid=2170401
[win-zip]: https://go.microsoft.com/fwlink/?linkid=2170402
[osx-zip]: https://go.microsoft.com/fwlink/?linkid=2169955
[linux-zip]: https://go.microsoft.com/fwlink/?linkid=2170045
[linux-rpm]: https://go.microsoft.com/fwlink/?linkid=2170403
[linux-deb]: https://go.microsoft.com/fwlink/?linkid=2169956

View File

@@ -1 +1 @@
2021-11-19T02:27:18.022Z
2021-08-23T03:52:18.011Z

View File

@@ -61,7 +61,6 @@ steps:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
continueOnError: true
- script: |
set -e

View File

@@ -57,7 +57,6 @@ steps:
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
continueOnError: true
- script: |
set -e
@@ -188,7 +187,7 @@ steps:
displayName: 'Install .NET Core sdk for signing'
inputs:
packageType: sdk
version: 5.0.x
version: 2.1.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1

View File

@@ -52,7 +52,6 @@ steps:
# Sync up to latest from the DT repo
git remote add upstream https://github.com/DefinitelyTyped/DefinitelyTyped.git
git fetch upstream
git merge upstream/master
git push origin

View File

@@ -2,7 +2,7 @@ resources:
containers:
- container: linux-x64
image: sqltoolscontainers.azurecr.io/linux-build-agent:3
endpoint: SqlToolsContainers
endpoint: ContainerRegistry
jobs:
- job: Compile
@@ -20,7 +20,7 @@ jobs:
- job: macOS
condition: and(succeeded(), eq(variables['VSCODE_BUILD_MACOS'], 'true'), ne(variables['VSCODE_QUALITY'], 'saw'))
pool:
vmImage: 'macOS-10.15'
vmImage: macOS-latest
dependsOn:
- Compile
steps:
@@ -30,7 +30,7 @@ jobs:
- job: macOS_Signing
condition: and(succeeded(), eq(variables['VSCODE_BUILD_MACOS'], 'true'), eq(variables['signed'], true), ne(variables['VSCODE_QUALITY'], 'saw'))
pool:
vmImage: 'macOS-10.15'
vmImage: macOS-latest
dependsOn:
- macOS
steps:
@@ -53,7 +53,7 @@ jobs:
- job: Windows
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
pool:
vmImage: 'windows-2019'
vmImage: VS2017-Win2016
dependsOn:
- Compile
steps:

View File

@@ -2,7 +2,7 @@ resources:
containers:
- container: linux-x64
image: sqltoolscontainers.azurecr.io/web-build-image:2
endpoint: SqlToolsContainers
endpoint: ContainerRegistry
jobs:
- job: LinuxWeb

View File

@@ -43,7 +43,6 @@ steps:
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore Cache - Node Modules
continueOnError: true
- script: |
set -e
@@ -109,7 +108,7 @@ steps:
set -e
node ./node_modules/playwright/install.js
APP_ROOT=$(Agent.BuildDirectory)/vscode-reh-web-linux-x64
xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots" --log "$(Build.ArtifactStagingDirectory)/logs/web/smoke.log"
xvfb-run yarn smoketest --build "$(Agent.BuildDirectory)/vscode-reh-web-linux-x64" --web --headless --screenshots "$(Build.ArtifactStagingDirectory)/smokeshots"
displayName: Run smoke tests (Browser)
continueOnError: true
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
@@ -171,7 +170,7 @@ steps:
displayName: 'Install .NET Core sdk for signing'
inputs:
packageType: sdk
version: 5.0.x
version: 2.1.x
installationPath: $(Agent.ToolsDirectory)/dotnet
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1

View File

@@ -27,7 +27,7 @@ steps:
- powershell: |
. build/azure-pipelines/win32/exec.ps1
$ErrorActionPreference = "Stop"
exec { tar -xf $(Pipeline.Workspace)/compilation.tar.gz }
exec { tar --force-local -xzf $(Pipeline.Workspace)/compilation.tar.gz }
displayName: Extract compilation output
- powershell: |
@@ -57,7 +57,6 @@ steps:
path: .build/node_modules_cache
cacheHitVar: NODE_MODULES_RESTORED
displayName: Restore Cache - Node Modules
continueOnError: true
- powershell: |
. build/azure-pipelines/win32/exec.ps1

View File

@@ -65,8 +65,5 @@
"watch": "tsc -p tsconfig.build.json --watch",
"npmCheckJs": "tsc --noEmit"
},
"dependencies": {},
"resolutions": {
"json-schema": "0.4.0"
}
"dependencies": {}
}

View File

@@ -1382,10 +1382,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -9,12 +9,6 @@
"vscode": "*",
"azdata": "*"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionPack": [
"Microsoft.agent",
"Microsoft.profiler",

View File

@@ -15,12 +15,6 @@
"scripts": {
"postinstall": "node ./build/postinstall.js"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"activationEvents": [
"onCommand:adminToolExtWin.launchSsmsMinPropertiesDialog",
"onCommand:adminToolExtWin.launchSsmsMinGswDialog"

View File

@@ -19,12 +19,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -1,10 +1,27 @@
{
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python",
"version": "3.6.6",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "82e60c1a-7acf-47ee-877f-9e85e92e11da"
},
"source": [
"![Microsoft](https://raw.githubusercontent.com/microsoft/azuredatastudio/main/extensions/arc/images/microsoft-small-logo.png)\n",
" \n",
@@ -16,13 +33,13 @@
"* The **Required information** will check and prompt you for password if it is not set in the environment variable. The password can be used to access the data controller.\n",
"\n",
"<span style=\"color:red\"><font size=\"3\">Please press the \"Run All\" button to run the notebook</font></span>"
]
],
"metadata": {
"azdata_cell_guid": "82e60c1a-7acf-47ee-877f-9e85e92e11da"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "714582b9-10ee-409e-ab12-15a4825c9471"
},
"source": [
"### **Prerequisites** \n",
"Ensure the following tools are installed and added to PATH before proceeding.\n",
@@ -32,25 +49,23 @@
"|kubectl | Command-line tool for monitoring the underlying Kubernetes cluster | [Installation](https://kubernetes.io/docs/tasks/tools/install-kubectl/#install-kubectl-binary-using-native-package-management) |\n",
"|Azure CLI (az) | Command-line tool for installing and managing resources in an Azure Arc cluster |[Installation](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) |\n",
"|Azure CLI arcdata extension | Commands for using Azure Arc for Azure data services. | [Installation](https://docs.microsoft.com/azure/azure-arc/data/install-arcdata-extension)"
]
],
"metadata": {
"azdata_cell_guid": "714582b9-10ee-409e-ab12-15a4825c9471"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "e3dd8e75-e15f-44b4-81fc-1f54d6f0b1e2"
},
"source": [
"### **Setup**"
]
],
"metadata": {
"azdata_cell_guid": "e3dd8e75-e15f-44b4-81fc-1f54d6f0b1e2"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "d973d5b4-7f0a-4a9d-b204-a16480f3940d",
"tags": []
},
"outputs": [],
"source": [
"import sys,os,getpass\n",
"def run_command(command):\n",
@@ -59,56 +74,56 @@
" if _exit_code != 0:\n",
" sys.exit(f'Command execution failed with exit code: {str(_exit_code)}.\\n\\t{command}\\n')\n",
" print(f'Successfully executed: {command}')"
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "d973d5b4-7f0a-4a9d-b204-a16480f3940d",
"tags": []
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "4b266b2d-bd1b-4565-92c9-3fc146cdce6d"
},
"source": [
"### **Set variables**\n",
"Generated by Azure Data Studio using the values collected in the 'Create Azure Arc data controller' wizard."
]
],
"metadata": {
"azdata_cell_guid": "4b266b2d-bd1b-4565-92c9-3fc146cdce6d"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "2544648b-59c9-4ce5-a3b6-87086e214d4c"
},
"source": [
"### **Check dependencies**"
]
],
"metadata": {
"azdata_cell_guid": "2544648b-59c9-4ce5-a3b6-87086e214d4c"
}
},
{
"cell_type": "code",
"execution_count": null,
"source": [
"run_command('az --version')"
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "691671d7-3f05-406c-a183-4cff7d17f83d",
"tags": []
},
"outputs": [],
"source": [
"run_command('az --version')"
]
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "0bb02e76-fee8-4dbc-a75b-d5b9d1b187d0"
},
"source": [
"### **Required information**"
]
],
"metadata": {
"azdata_cell_guid": "0bb02e76-fee8-4dbc-a75b-d5b9d1b187d0"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "e7e10828-6cae-45af-8c2f-1484b6d4f9ac",
"tags": []
},
"outputs": [],
"source": [
"if \"AZDATA_NB_VAR_ARC_ADMIN_PASSWORD\" in os.environ:\n",
" arc_admin_password = os.environ[\"AZDATA_NB_VAR_ARC_ADMIN_PASSWORD\"]\n",
@@ -120,130 +135,85 @@
" confirm_password = getpass.getpass(prompt = 'Confirm password')\n",
" if arc_admin_password != confirm_password:\n",
" sys.exit(f'Passwords do not match.')"
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "e7e10828-6cae-45af-8c2f-1484b6d4f9ac",
"tags": []
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "127c8042-181f-4862-a390-96e59c181d09"
},
"source": [
"### **Set and show current context**"
]
],
"metadata": {
"azdata_cell_guid": "127c8042-181f-4862-a390-96e59c181d09"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "7d1a03d4-1df8-48eb-bff0-0042603b95b1",
"tags": []
},
"outputs": [],
"source": [
"os.environ[\"KUBECONFIG\"] = arc_config_file\n",
"run_command(f'kubectl config use-context {arc_cluster_context}')\n",
"run_command('kubectl config current-context')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### **Log in to Azure CLI**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
],
"outputs": [],
"source": [
"is_indirect = arc_data_controller_connectivity_mode == 'Indirect'\n",
"\n",
"if not is_indirect:\n",
"\trun_command('az login')"
]
"metadata": {
"azdata_cell_guid": "7d1a03d4-1df8-48eb-bff0-0042603b95b1",
"tags": []
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
},
"source": [
"### **Create Azure Arc Data Controller**"
]
],
"metadata": {
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "373947a1-90b9-49ee-86f4-17a4c7d4ca76",
"tags": []
},
"outputs": [],
"source": [
"print (f'Creating Azure Arc Data Controller: {arc_data_controller_name} using configuration {arc_cluster_context}')\n",
"os.environ[\"AZDATA_USERNAME\"] = arc_admin_username\n",
"os.environ[\"AZDATA_PASSWORD\"] = arc_admin_password\n",
"\n",
"namespace = f' --k8s-namespace {arc_data_controller_namespace}' if is_indirect else ''\n",
"use_k8s = ' --use-k8s' if is_indirect else ''\n",
"\n",
"custom_location = f' --custom-location {arc_data_controller_custom_location}' if not is_indirect else ''\n",
"\n",
"auto_upload_metrics_value = 'true' if arc_data_controller_auto_upload_metrics == 'true' else 'false'\n",
"auto_upload_logs_value = 'true' if arc_data_controller_auto_upload_logs == 'true' else 'false'\n",
"\n",
"auto_upload_metrics = f' --auto-upload-metrics {auto_upload_metrics_value}' if not is_indirect else ''\n",
"auto_upload_logs = f' --auto-upload-logs {auto_upload_logs_value}' if not is_indirect else ''\n",
"\n",
"if os.name == 'nt':\n",
" print(f'If you don\\'t see output produced by az, you can run the following command in a terminal window to check the deployment status:\\n\\t {os.environ[\"AZDATA_NB_VAR_KUBECTL\"]} get pods -n {arc_data_controller_namespace}')\n",
"run_command(f'az arcdata dc create --connectivity-mode {arc_data_controller_connectivity_mode} --name {arc_data_controller_name}{namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure}{custom_location}{auto_upload_metrics}{auto_upload_logs}{use_k8s}')\n",
"run_command(f'az arcdata dc create --connectivity-mode indirect --name {arc_data_controller_name} --k8s-namespace {arc_data_controller_namespace} --subscription {arc_subscription} --resource-group {arc_resource_group} --location {arc_data_controller_location} --storage-class {arc_data_controller_storage_class} --profile-name {arc_profile} --infrastructure {arc_infrastructure} --use-k8s')\n",
"print(f'Azure Arc Data Controller: {arc_data_controller_name} created.') "
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "373947a1-90b9-49ee-86f4-17a4c7d4ca76",
"tags": []
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "a3ddc701-811d-4058-b3fb-b7295fcf50ae"
},
"source": [
"### **Setting context to created Azure Arc Data Controller**"
]
],
"metadata": {
"azdata_cell_guid": "a3ddc701-811d-4058-b3fb-b7295fcf50ae"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "c974561f-13d0-4e7a-b74b-d781c2e06d68"
},
"outputs": [],
"source": [
"# Setting context to Data Controller.\n",
"#\n",
"run_command(f'kubectl config set-context --current --namespace {arc_data_controller_namespace}')"
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "c974561f-13d0-4e7a-b74b-d781c2e06d68"
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
]
}

View File

@@ -1,10 +1,28 @@
{
"metadata": {
"kernelspec": {
"name": "python3",
"display_name": "Python 3",
"language": "python"
},
"language_info": {
"name": "python",
"version": "3.6.6",
"mimetype": "text/x-python",
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"pygments_lexer": "ipython3",
"nbconvert_exporter": "python",
"file_extension": ".py"
}
},
"nbformat_minor": 2,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "e4ed0892-7b5a-4d95-bd0d-a6c3eb0b2c99"
},
"source": [
"![Microsoft](https://raw.githubusercontent.com/microsoft/azuredatastudio/main/extensions/arc/images/microsoft-small-logo.png)\n",
" \n",
@@ -16,13 +34,13 @@
"* Make sure you have the target Azure Arc Data Controller already created.\n",
"\n",
"<span style=\"color:red\"><font size=\"3\">Please press the \"Run All\" button to run the notebook</font></span>"
]
],
"metadata": {
"azdata_cell_guid": "e4ed0892-7b5a-4d95-bd0d-a6c3eb0b2c99"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "d1c8258e-9efd-4380-a48c-cd675423ed2f"
},
"source": [
"### **Prerequisites** \n",
"Ensure the following tools are installed and added to PATH before proceeding.\n",
@@ -31,25 +49,23 @@
"|---|---|---|\n",
"|Azure CLI (az) | Command-line tool for installing and managing resources in an Azure Arc cluster |[Installation](https://docs.microsoft.com/cli/azure/install-azure-cli-windows?tabs=azure-cli) |\n",
"|Azure CLI arcdata extension | Commands for using Azure Arc for Azure data services. | [Installation](https://docs.microsoft.com/azure/azure-arc/data/install-arcdata-extension)"
]
],
"metadata": {
"azdata_cell_guid": "d1c8258e-9efd-4380-a48c-cd675423ed2f"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "68531b91-ddce-47d7-a1d8-2ddc3d17f3e7"
},
"source": [
"### **Setup and Check Prerequisites**"
]
],
"metadata": {
"azdata_cell_guid": "68531b91-ddce-47d7-a1d8-2ddc3d17f3e7"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "749d8dba-3da8-46e9-ae48-2b38056ab7a2",
"tags": []
},
"outputs": [],
"source": [
"import sys,os,json,subprocess\n",
"def run_command():\n",
@@ -64,37 +80,38 @@
" return output.stdout.decode(\"utf-8\")\n",
"cmd = 'az --version'\n",
"out = run_command()\n"
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "749d8dba-3da8-46e9-ae48-2b38056ab7a2",
"tags": []
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "68ec0760-27d1-4ded-9a9f-89077c40b8bb"
},
"source": [
"### **Set variables**\n",
"\n",
"#### \n",
"\n",
"Generated by Azure Data Studio using the values collected in the 'Deploy Azure SQL managed instance - Azure Arc' wizard"
]
],
"metadata": {
"azdata_cell_guid": "68ec0760-27d1-4ded-9a9f-89077c40b8bb"
}
},
{
"cell_type": "markdown",
"metadata": {
"azdata_cell_guid": "90b0e162-2987-463f-9ce6-12dda1267189"
},
"source": [
"### **Creating the SQL managed instance - Azure Arc instance**"
]
],
"metadata": {
"azdata_cell_guid": "90b0e162-2987-463f-9ce6-12dda1267189"
}
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"azdata_cell_guid": "4fbaf071-55a1-40bc-be7e-7b9b5547b886"
},
"outputs": [],
"source": [
"print (f'Creating the SQL managed instance - Azure Arc instance')\n",
"\n",
@@ -107,44 +124,24 @@
"storage_class_datalogs_option = f' --storage-class-datalogs \"{sql_storage_class_datalogs}\"'if sql_storage_class_datalogs else \"\"\n",
"storage_class_logs_option = f' --storage-class-logs \"{sql_storage_class_logs}\"'if sql_storage_class_logs else \"\"\n",
"storage_class_backup_option = f' --storage-class-backups \"{sql_storage_class_backups}\"'if sql_storage_class_backups else \"\"\n",
"retention_days = f' --retention-days \"{sql_retention_days}\"' if sql_retention_days else \"\"\n",
"retention_days = f' --retention-days \"{sql_retention_days}\"' if sql_retention_days else \"\"\n",
"\n",
"volume_size_data = f' --volume-size-data {sql_volume_size_data}Gi'\n",
"volume_size_datalogs = f' --volume-size-datalogs {sql_volume_size_datalogs}Gi'\n",
"volume_size_logs = f' --volume-size-logs {sql_volume_size_logs}Gi'\n",
"volume_size_backups = f' --volume-size-backups {sql_volume_size_backups}Gi'\n",
"\n",
"service_tier = f' --tier {sql_service_tier}'\n",
"cores_limit = f' --cores-limit {sql_cores_limit}'\n",
"dev_use = ' --dev' if sql_dev_use else ''\n",
"license_type = ' --license-type BasePrice' if sql_license_type else ' --license-type LicenseIncluded'\n",
"\n",
"os.environ[\"AZDATA_USERNAME\"] = sql_username\n",
"os.environ[\"AZDATA_PASSWORD\"] = os.environ[\"AZDATA_NB_VAR_SQL_PASSWORD\"]\n",
"cmd = f'az sql mi-arc create --name {sql_instance_name} --k8s-namespace {arc_data_controller_namespace} --replicas {sql_replicas}{cores_request_option}{cores_limit_option}{memory_request_option}{memory_limit_option}{storage_class_data_option}{storage_class_datalogs_option}{storage_class_logs_option}{storage_class_backup_option}{volume_size_data}{volume_size_datalogs}{volume_size_logs}{volume_size_backups}{retention_days}{service_tier}{dev_use}{license_type}{cores_limit} --use-k8s'\n",
"cmd = f'az sql mi-arc create --name {sql_instance_name} --k8s-namespace {arc_data_controller_namespace} --replicas {sql_replicas}{cores_request_option}{cores_limit_option}{memory_request_option}{memory_limit_option}{storage_class_data_option}{storage_class_datalogs_option}{storage_class_logs_option}{storage_class_backup_option}{volume_size_data}{volume_size_datalogs}{volume_size_logs}{volume_size_backups}{retention_days} --use-k8s'\n",
"out=run_command()"
]
],
"outputs": [],
"metadata": {
"azdata_cell_guid": "4fbaf071-55a1-40bc-be7e-7b9b5547b886"
}
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
]
}

View File

@@ -2,7 +2,7 @@
"name": "arc",
"displayName": "%arc.displayName%",
"description": "%arc.description%",
"version": "0.9.7",
"version": "0.9.6",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
@@ -21,12 +21,6 @@
"Microsoft.azcli",
"Microsoft.resource-deployment"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
@@ -261,20 +255,6 @@
"label": "%arc.data.controller.details.description%",
"labelWidth": "600px"
},
{
"type": "options",
"label": "%arc.data.controller.connectivity.mode%",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"options": {
"values": [
"Indirect",
"Direct"
],
"defaultValue": "Indirect",
"optionsType": "radio"
}
},
{
"type": "text",
"label": "%arc.data.controller.namespace%",
@@ -287,11 +267,7 @@
],
"defaultValue": "arc",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE",
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Indirect"
}
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE"
},
{
"type": "text",
@@ -328,39 +304,6 @@
"onpremises",
"other"
]
},
{
"type": "text",
"label": "%arc.data.controller.custom.location%",
"description": "%arc.data.controller.custom.location.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CUSTOM_LOCATION",
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
},
{
"type": "checkbox",
"label": "%arc.data.controller.auto.upload.metrics%",
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_METRICS",
"description": "%arc.data.controller.auto.upload.metrics.description%",
"defaultValue": false,
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
},
{
"type": "checkbox",
"label": "%arc.data.controller.auto.upload.logs%",
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_AUTO_UPLOAD_LOGS",
"description": "%arc.data.controller.auto.upload.logs.description%",
"defaultValue": false,
"enabled": {
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
"value": "Direct"
}
}
]
},
@@ -1040,7 +983,7 @@
"fields": [
{
"type": "options",
"label": "%arc.sql.replicas%",
"label": "%arc.sql.high.availability.label%",
"description": "%arc.sql.high.availability.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_SQL_REPLICAS",
@@ -1136,7 +1079,6 @@
"variableName": "AZDATA_NB_VAR_SQL_CORES_REQUEST",
"type": "number",
"min": 1,
"defaultValue": 2,
"required": false,
"validations": [
{
@@ -1153,7 +1095,6 @@
"type": "number",
"min": 1,
"required": false,
"defaultValue": 4,
"validations": [
{
"type": ">=",
@@ -1168,7 +1109,6 @@
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_REQUEST",
"type": "number",
"min": 2,
"defaultValue": 4,
"required": false,
"validations": [
{
@@ -1184,7 +1124,6 @@
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_LIMIT",
"type": "number",
"min": 2,
"defaultValue": 8,
"required": false,
"validations": [
{
@@ -1197,9 +1136,9 @@
{
"type": "options",
"label": "%arc.sql.service.tier.label%",
"variableName": "AZDATA_NB_VAR_SQL_SERVICE_TIER",
"description": "%arc.sql.service.tier.description%",
"required": true,
"variableName": "AZDATA_NB_VAR_SQL_SERVICE_TIER",
"options": {
"values": [
"%arc.sql.service.tier.business.critical%",
@@ -1212,16 +1151,10 @@
{
"type": "checkbox",
"label": "%arc.sql.dev.use.label%",
"variableName": "AZDATA_NB_VAR_SQL_DEV_USE",
"description": "%arc.sql.dev.use.description%",
"defaultValue": false
},
{
"type": "checkbox",
"label": "%arc.sql.license.type.label%",
"variableName": "AZDATA_NB_VAR_SQL_LICENSE_TYPE",
"description": "%arc.sql.license.type.description%",
"defaultValue": false
"defaultValue": "false",
"variableName": "AZDATA_NB_VAR_SQL_DEV_USE",
"required": true
}
]
},
@@ -1246,85 +1179,13 @@
"description": "%arc.sql.retention.days.description%",
"variableName": "AZDATA_NB_VAR_SQL_RETENTION_DAYS",
"type": "number",
"min": 0,
"min": 1,
"max": 35,
"required": false
}
]
},
{
"title": "%arc.sql.cost.summary%",
"fields": [
{
"label": "%arc.sql.cost.summary.additional.charge%",
"type": "readonly_text",
"enabled": true,
"labelWidth": "750px",
"links": [
{
"text": "%arc.sql.cost.summary.pricing.details%",
"url": "https://aka.ms/ArcSQLBilling"
}
]
},
{
"label": "%arc.sql.cost.summary.cost.vcore%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "0.00 USD",
"valueProvider": {
"providerId": "params-to-cost-per-vcore",
"triggerFields": [
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER"
]
}
},
{
"label": "%arc.sql.cost.summary.vcore.limit%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "x 4",
"valueProvider": {
"providerId": "params-to-vcore-limit",
"triggerFields": [
"AZDATA_NB_VAR_SQL_CORES_LIMIT"
]
}
},
{
"label": "%arc.sql.cost.summary.azure.hybrid.benefit.discount%",
"type": "readonly_text",
"isEvaluated": true,
"defaultValue": "- 0",
"valueProvider": {
"providerId": "params-to-hybrid-benefit-discount",
"triggerFields": [
"AZDATA_NB_VAR_SQL_CORES_LIMIT",
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER",
"AZDATA_NB_VAR_SQL_LICENSE_TYPE"
]
}
},
{
"label": "%arc.sql.cost.summary.estimated.cost.per.month%",
"type": "readonly_text",
"defaultValue": "0.00 USD",
"valueProvider": {
"providerId": "params-to-estimated-cost",
"triggerFields": [
"AZDATA_NB_VAR_SQL_REPLICAS",
"AZDATA_NB_VAR_SQL_CORES_LIMIT",
"AZDATA_NB_VAR_SQL_DEV_USE",
"AZDATA_NB_VAR_SQL_SERVICE_TIER",
"AZDATA_NB_VAR_SQL_LICENSE_TYPE"
]
}
}
]
}
]
]
}
]
},
@@ -1374,6 +1235,7 @@
]
},
"dependencies": {
"request": "^2.88.0",
"uuid": "^8.3.0",
"vscode-nls": "^4.1.2",
"yamljs": "^0.3.0"
@@ -1381,6 +1243,7 @@
"devDependencies": {
"@types/mocha": "^5.2.5",
"@types/node": "^12.11.7",
"@types/request": "^2.48.3",
"@types/sinon": "^9.0.4",
"@types/uuid": "^8.3.0",
"@types/yamljs": "^0.2.31",

View File

@@ -10,7 +10,6 @@
"command.removeController.title": "Remove Controller",
"command.refresh.title": "Refresh",
"command.editConnection.title": "Edit Connection",
"command.estimateCostSqlMiaa.title": "Estimate Cost of SQL Managed Instance - Azure Arc",
"arc.openDashboard": "Manage",
"resource.type.azure.arc.display.name": "Azure Arc data controller (preview)",
@@ -28,22 +27,13 @@
"arc.data.controller.project.details.title": "Azure details",
"arc.data.controller.project.details.description": "Select the subscription to manage deployed resources and costs. Use resource groups like folders to organize and manage all your resources.",
"arc.data.controller.details.title": "Data controller details",
"arc.data.controller.details.description": "For indirect mode, provide a namespace, name and storage class for your Azure Arc data controller. This name will be used to identify your Arc instance for remote management and monitoring. For direct mode you do not need to provide a namespace, but please provide the custom location name.",
"arc.data.controller.connectivity.mode": "Connectivity mode",
"arc.data.controller.details.description": "Provide a namespace, name and storage class for your Azure Arc data controller. This name will be used to identify your Arc instance for remote management and monitoring.",
"arc.data.controller.namespace": "Data controller namespace",
"arc.data.controller.namespace.description": "Indirect mode only.",
"arc.data.controller.namespace.validation.description": "Namespace must consist of lower case alphanumeric characters or '-', start/end with an alphanumeric character, and be 63 characters or fewer in length.",
"arc.data.controller.name": "Data controller name",
"arc.data.controller.name.validation.description": "Name must consist of lower case alphanumeric characters, '-' or '.', start/end with an alphanumeric character and be 253 characters or less in length.",
"arc.data.controller.location": "Location",
"arc.data.controller.infrastructure": "Infrastructure",
"arc.data.controller.custom.location": "Custom Location",
"arc.data.controller.custom.location.description": "The name of the custom location. Direct mode only.",
"arc.data.controller.auto.upload.metrics": "Auto-upload Metrics",
"arc.data.controller.auto.upload.metrics.description": "Enable the automatic upload of metrics. Direct mode only.",
"arc.data.controller.auto.upload.logs": "Auto-upload Logs",
"arc.data.controller.auto.upload.logs.description": "Enable the automatic upload of logs. Direct mode only.",
"arc.data.controller.admin.account.title": "Administrator account",
"arc.data.controller.admin.account.name": "Data controller login",
"arc.data.controller.admin.account.password": "Password",
@@ -97,39 +87,15 @@
"arc.sql.invalid.instance.name": "Instance name must consist of lower case alphanumeric characters or '-', start with a letter, end with an alphanumeric character, and be 13 characters or fewer in length.",
"arc.storage-class.dc.label": "Storage Class",
"arc.sql.storage-class.dc.description": "The storage class to be used for all data and logs persistent volumes for all data controller pods that require them.",
"arc.sql.replicas": "Replicas",
"arc.sql.high.availability.description": "Enable additional replicas for high availabilty. The compute and storage configuration selected below will be applied to all replicas. Choose from: General Purpose (Up to 24 vCores and 128 Gi of RAM, standard high availability) or [PREVIEW] Business Critical (Unlimited vCores and RAM, advanced high availability).",
"arc.sql.service.tier.general.purpose": "GeneralPurpose",
"arc.sql.service.tier.business.critical": "BusinessCritical",
"arc.sql.one.replica": "1",
"arc.sql.two.replicas": "2",
"arc.sql.three.replicas": "3",
"arc.sql.high.availability.label": "High Availability",
"arc.sql.high.availability.description": "Enable additional replicas for high availabilty. The compute and storage configuration selected below will be applied to all replicas.",
"arc.sql.service.tier.general.purpose": "General Purpose (Up to 24 vCores and 128 Gi of RAM, standard high availability)",
"arc.sql.service.tier.business.critical": "[PREVIEW] Business Critical (Unlimited vCores and RAM, advanced high availability)",
"arc.sql.one.replica": "1 replica",
"arc.sql.two.replicas": "2 replicas",
"arc.sql.three.replicas": "3 replicas",
"arc.storage-class.data.label": "Storage Class (Data)",
"arc.sql.storage-class.data.description": "The storage class to be used for data (.mdf). If no value is specified, the default storage class will be used.",
"arc.sql.cost.summary.sql.miaa.cost.summary": "SQL Managed Instance - Azure Arc Cost Summary",
"arc.sql.cost.summary.sql.miaa": "SQL managed instance - Azure Arc",
"arc.sql.cost.summary.estimated.cost.per.month": "Estimated cost per month",
"arc.sql.summary.arc.by.microsoft" : "by Microsoft",
"arc.sql.cost.summary": "Cost Summary",
"arc.sql.cost.summary.service.tier": "Service Tier",
"arc.sql.cost.summary.general.purpose": "General Purpose",
"arc.sql.cost.summary.business.critical": "Business Critical",
"arc.sql.cost.summary.cost.vcore": "Cost per vCore (in USD)",
"arc.sql.cost.summary.vcore.limit": "CPU vCores Limit",
"arc.sql.cost.summary.azure.hybrid.benefit.discount": "Azure Hybrid Benefit discount (in USD)",
"arc.sql.cost.summary.sql.connection.info": "SQL Connection Information",
"arc.sql.cost.summary.sql.instance.settings": "SQL Instance Settings",
"arc.sql.cost.summary.service.tier.learn.more.description": "Select from the latest vCore service tiers available for SQL Managed Instance - Azure Arc including General Purpose and Business Critical. {0}",
"arc.sql.cost.summary.service.tier.learn.more.text": "Learn more",
"arc.sql.cost.summary.basics": "Basics",
"arc.sql.cost.summary.subscription": "Subscription",
"arc.sql.cost.summary.resource.group": "Resource group",
"arc.sql.cost.summary.instance.name": "Instance name",
"arc.sql.cost.summary.custom.location": "Custom location",
"arc.sql.cost.summary.admin.account": "Administrator account",
"arc.sql.cost.summary.managed.instance.admin.login": "Managed Instance admin login",
"arc.sql.cost.summary.additional.charge": "Additional charge per usage. See {0} for more detail.",
"arc.sql.cost.summary.pricing.details": "pricing details",
"arc.postgres.storage-class.data.description": "The storage class to be used for data persistent volumes",
"arc.storage-class.datalogs.label": "Storage Class (Database logs)",
"arc.sql.storage-class.datalogs.description": "The storage class to be used for database logs (.ldf). If no value is specified, the default storage class will be used.",
@@ -157,10 +123,8 @@
"arc.sql.service.tier.label": "Service Tier",
"arc.sql.service.tier.description": "Select from the latest vCore service tiers available for SQL Managed Instance - Azure Arc including General Purpose and Business Critical. {0}",
"arc.sql.dev.use.label": "For development use only",
"arc.sql.license.type.label": "I already have a SQL Server License",
"arc.sql.license.type.description": "Apply the Azure Hybrid Benefit if you already own a SQL Server License",
"arc.sql.pitr.description": "Point in time restore",
"arc.sql.retention.days.label": "Point in time retention (days)",
"arc.sql.retention.days.label": "PITR retention (days)",
"arc.sql.retention.days.description": "Specify how long you want to keep your point-in-time backups.",
"arc.sql.dev.use.description": "Check the box to indicate this instance will be used for development or testing purposes only. This instance will not be billed.",
"arc.postgres.storage-class.backups.description": "The storage class to be used for backup persistent volumes",

View File

@@ -1,117 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { InputValueType } from 'resource-deployment';
import * as loc from '../localizedConstants';
export const SqlManagedInstanceGeneralPurpose = {
tierName: loc.generalPurposeLabel,
basePricePerCore: 80,
licenseIncludedPricePerCore: 153,
maxMemorySize: 128,
maxVCores: 24,
replicaOptions: [
{
text: loc.replicaOne,
value: 1,
}
],
defaultReplicaValue: 1
};
const SqlManagedInstanceBusinessCritical = {
tierName: loc.businessCriticalLabel,
// Set to real values when BC is ready
basePricePerCore: 0,
licenseIncludedPricePerCore: 0,
replicaOptions: [
{
text: loc.replicaTwo,
value: 2,
},
{
text: loc.replicaThree,
value: 3,
}
],
defaultReplicaValue: 3
};
export const SqlManagedInstancePricingLink: string = 'https://aka.ms/ArcSQLBilling';
export const serviceTierVarName = 'AZDATA_NB_VAR_SQL_SERVICE_TIER';
export const devUseVarName = 'AZDATA_NB_VAR_SQL_DEV_USE';
export const vcoresLimitVarName = 'AZDATA_NB_VAR_SQL_CORES_LIMIT';
export const licenseTypeVarName = 'AZDATA_NB_VAR_SQL_LICENSE_TYPE';
// Estimated base price for one vCore.
export function estimatedBasePriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
let price = 0;
if (mapping[devUseVarName] === 'true') {
price = 0;
} else if (mapping[devUseVarName] === 'false') {
if (mapping[serviceTierVarName] === SqlManagedInstanceGeneralPurpose.tierName) {
price = SqlManagedInstanceGeneralPurpose.basePricePerCore;
} else if (mapping[serviceTierVarName] === SqlManagedInstanceBusinessCritical.tierName) {
price = SqlManagedInstanceBusinessCritical.basePricePerCore;
}
}
return price;
}
// Estimated SQL server license price for one vCore.
export function estimatedSqlServerLicensePriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
let price = 0;
if (mapping[devUseVarName] === 'true') {
price = 0;
} else if (mapping[devUseVarName] === 'false') {
if (mapping[serviceTierVarName] === SqlManagedInstanceGeneralPurpose.tierName) {
price = SqlManagedInstanceGeneralPurpose.licenseIncludedPricePerCore - SqlManagedInstanceGeneralPurpose.basePricePerCore;
} else if (mapping[serviceTierVarName] === SqlManagedInstanceBusinessCritical.tierName) {
price = SqlManagedInstanceBusinessCritical.licenseIncludedPricePerCore - SqlManagedInstanceBusinessCritical.basePricePerCore;
}
}
return price;
}
// Full price for one vCore. This is shown on the cost summary card.
export function fullPriceForOneVCore(mapping: { [key: string]: InputValueType }): number {
return estimatedBasePriceForOneVCore(mapping) + estimatedSqlServerLicensePriceForOneVCore(mapping);
}
// Gets number of vCores limit specified
export function numCores(mapping: { [key: string]: InputValueType }): number {
return mapping[vcoresLimitVarName] ? <number>mapping[vcoresLimitVarName] : 0;
}
// Full price for all selected vCores.
export function vCoreFullPriceForAllCores(mapping: { [key: string]: InputValueType }): number {
return fullPriceForOneVCore(mapping) * numCores(mapping);
}
// SQL Server License price for all vCores. This is shown on the cost summary card if customer has SQL server license.
export function vCoreSqlServerLicensePriceForAllCores(mapping: { [key: string]: InputValueType }): number {
return estimatedSqlServerLicensePriceForOneVCore(mapping) * numCores(mapping);
}
// If the customer doesn't already have SQL Server License, AHB discount is set to zero because the price will be included
// in the total cost. If they already have it (they checked the box), then a discount will be applied.
export function azureHybridBenefitDiscount(mapping: { [key: string]: InputValueType }): number {
if (mapping[licenseTypeVarName] === 'true') {
return vCoreSqlServerLicensePriceForAllCores(mapping);
} else {
return 0;
}
}
// Total price that will be charged to a customer. Is shown on the cost summary card.
export function total(mapping: { [key: string]: InputValueType }): number {
return vCoreFullPriceForAllCores(mapping) - azureHybridBenefitDiscount(mapping);
}

View File

@@ -363,11 +363,3 @@ export function debounce(delay: number): Function {
};
});
}
export function getTimeStamp(dateTime: string | undefined): number {
return dateTime ? (new Date(dateTime)).getTime() : 0;
}
export function checkISOTimeString(dateTime: string): boolean {
return /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d.*Z/.test(dateTime);
}

View File

@@ -14,7 +14,6 @@ import { ConnectToControllerDialog } from './ui/dialogs/connectControllerDialog'
import { AzureArcTreeDataProvider } from './ui/tree/azureArcTreeDataProvider';
import { ControllerTreeNode } from './ui/tree/controllerTreeNode';
import { TreeNode } from './ui/tree/treeNode';
import * as pricing from './common/pricingUtils';
export async function activate(context: vscode.ExtensionContext): Promise<arc.IExtension> {
IconPathHelper.setExtensionContext(context);
@@ -62,38 +61,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<arc.IE
const rdApi = <rd.IExtension>vscode.extensions.getExtension(rd.extension.name)?.exports;
context.subscriptions.push(rdApi.registerOptionsSourceProvider(new ArcControllersOptionsSourceProvider(treeDataProvider)));
// Register valueprovider for getting the calculated cost per VCore.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-cost-per-vcore',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return pricing.fullPriceForOneVCore(mapping);
}
}));
// Register valueprovider for getting the number of CPU VCores Limit input by the user.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-vcore-limit',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return 'x ' + pricing.numCores(mapping).toString();
}
}));
// Register valueprovider for getting the amount of hybrid benefit discount to be applied.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-hybrid-benefit-discount',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return '- ' + pricing.azureHybridBenefitDiscount(mapping).toString();
}
}));
// Register valueprovider for getting the total estimated cost.
context.subscriptions.push(rdApi.registerValueProvider({
id: 'params-to-estimated-cost',
getValue: async (mapping: { [key: string]: rd.InputValueType }) => {
return pricing.total(mapping).toString() + ' ' + loc.USD;
}
}));
return arcApi(treeDataProvider);
}

View File

@@ -60,19 +60,18 @@ export const type = localize('arc.type', "Type");
export const status = localize('arc.status', "Status");
export const database = localize('arc.database', "Database");
export const sourceDatabase = localize('arc.sourceDatabase', "Source database");
export const earliestPitrRestorePoint = localize('arc.earliestPitrRestorePoint', "Earliest point in time");
export const latestpitrRestorePoint = localize('arc.latestpitrRestorePoint', "Latest point in time");
export const pitr = localize('arc.pitr', "Point in time restore");
export const earliestPitrRestorePoint = localize('arc.earliestPitrRestorePoint', "Earliest PITR restore point");
export const latestpitrRestorePoint = localize('arc.latestpitrRestorePoint', "Latest PITR restore point");
export const pitr = localize('arc.pitr', "Point-in-time restore (PITR)");
export const projectDetails = localize('arc.projectDetails', "Project Details");
export const projectDetailsText = localize('arc.projectDetailsText', "Select the subscription to manage deployed resources. Use resource groups like folders to organize and manage all your resources.");
export const sourceDetails = localize('arc.sourceDetails', "Source Details");
export const sourceDetailsText = localize('arc.sourceDetailsText', "Select a backup source and provide details. Additional settings will be defaulted where possible based on the selected database.");
export const databaseDetails = localize('arc.databaseDetails', "Destination Details");
export const restorePointDetails = localize('arc.restorePointDetails', "Restore Point Details");
export const databaseDetailsText = localize('arc.databaseDetailsText', "Enter the required settings for target database name and SQL managed instance. By default, the source managed instance is selected.");
export const sourceDetailsText = localize('arc.sourceDetailsText', "Select a backup source and provide details. Additional settings will be defaulted where possible based on the selected backup.");
export const databaseDetails = localize('arc.databaseDetails', "Database Details");
export const databaseDetailsText = localize('arc.databaseDetailsText', "Enter the required settings for this database, including a name and a target managed instance. By default, the source instance is selected.");
export const restore = localize('arc.restore', "Restore");
export const instance = localize('arc.instance', "Instance");
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC), in a time format: 'YYYY-MM-DDTHH:MM:SSZ");
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC)");
export const restoreDatabase = localize('arc.restoreDatabase', "Restore Database");
export const miaaAdmin = localize('arc.miaaAdmin', "Managed instance admin");
export const extensionName = localize('arc.extensionName', "Extension name");
@@ -80,7 +79,6 @@ export const extensionsDescription = localize('arc.extensionsDescription', "Post
export const extensionsFunction = localize('arc.extensionsFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. These preloaded extensions can be viewed and edited below.");
export function extensionsAddFunction(extensions: string): string { return localize('arc.extensionsAddFunction', "Some extensions must be loaded into PostgreSQL at startup time before they can be used. To edit, type in comma separated list of valid extensions: ({0}).", extensions); }
export function extensionsAddErrorrMessage(extensions: string): string { return localize('arc.extensionsAddErrorrMessage', "Value should be either of the following: ({0}).", extensions); }
export function restorePointErrorMessage(earliestPoint: string, latestPoint: string) { return localize('arc.restorePointErrorrMessage', "Provide time in correct format and within range: {0} to {1}", earliestPoint, latestPoint); }
export const extensionsLearnMore = localize('arc.extensionsLearnMore', "Learn more about PostgreSQL extensions.");
export const extensionsTableLoading = localize('arc.extensionsTableLoading', "Table of preloaded extensions are loading.");
export const extensionsTableLabel = localize('arc.extensionsTableLabel', "Table of preloaded extensions.");
@@ -194,8 +192,7 @@ export const postgresComputeAndStorageDescriptionPartOne = localize('arc.postgre
export const miaaComputeAndStorageDescriptionPartOne = localize('arc.miaaComputeAndStorageDescriptionPartOne', "You can scale your Azure SQL managed instance - Azure Arc by");
export const miaaBackupsDatabasesDescription = localize('arc.miaaBackupsDatabasesDescription', "Databases with available backups are displayed below. Restore databases to this instance or any other instance within the same custom location.");
export const pitrInfo = localize('arc.pitrInfo', "Specify how long you want to keep your point-in-time backups. Customize this for backup availability.");
export const restoreInfo = localize('arc.restoreInfo', "Restore a database to an Azure Arc enabled SQL Managed Instance.");
export const restorePointText = localize('arc.restorePointText', "Enter a restore point in the specified time format within given range of earliest and latest restore time.");
export const restoreInfo = localize('arc.restoreInfo', "Restore a database to an Azure Arc enabled SQL Managed Instance of your choice.");
export const postgresComputeAndStorageDescriptionPartTwo = localize('arc.postgres.computeAndStorageDescriptionPartTwo', "PostgreSQL Hyperscale server group by");
export const computeAndStorageDescriptionPartThree = localize('arc.computeAndStorageDescriptionPartThree', "without downtime and by");
export const computeAndStorageDescriptionPartFour = localize('arc.computeAndStorageDescriptionPartFour', "Before doing so, you need to ensure");
@@ -277,14 +274,6 @@ export function connectionString(type: string): string { return localize({ key:
export function copyConnectionStringToClipboard(type: string): string { return localize({ key: 'arc.copyConnectionStringToClipboard', comment: ['{0} is the name of the type of connection string (e.g. Java)'] }, "Copy {0} Connection String to clipboard", type); }
export function copyValueToClipboard(valueName: string): string { return localize({ key: 'arc.copyValueToClipboard', comment: ['{0} is the name of the type of value being copied (e.g. Coordinator endpoint)'] }, "Copy {0} to clipboard", valueName); }
// Pricing Constants
export const replicaOne = localize('arc.replicaOne', "1");
export const replicaTwo = localize('arc.replicaTwo', "2");
export const replicaThree = localize('arc.replicaThree', "3");
export const generalPurposeLabel = localize('arc.generalPurposeLabel', "GeneralPurpose");
export const businessCriticalLabel = localize('arc.businessCriticalLabel', "BusinessCritical");
export const USD = localize('arc.USD', "USD");
// Errors
export const pgConnectionRequired = localize('arc.pgConnectionRequired', "A connection is required to show and set database engine settings.");
export const miaaConnectionRequired = localize('arc.miaaConnectionRequired', "A connection is required to list the databases on this instance.");
@@ -292,7 +281,6 @@ export const couldNotFindControllerRegistration = localize('arc.couldNotFindCont
export const dropMultipleExtensions = localize('arc.dropMultipleExtensions', "Currently dropping another extension, try again once that is completed.");
export function updateExtensionsFailed(error: any): string { return localize('arc.updateExtensionsFailed', "Editing extensions failed. {0}", getErrorMessage(error)); }
export function refreshFailed(error: any): string { return localize('arc.refreshFailed', "Refresh failed. {0}", getErrorMessage(error)); }
export function restoreTimeWindowUpdateFailed(error: any): string { return localize('arc.restoreTimeWindowUpdateFailed', "Point in time restore time window update failed. {0}", getErrorMessage(error)); }
export function resetFailed(error: any): string { return localize('arc.resetFailed', "Reset failed. {0}", getErrorMessage(error)); }
export function openDashboardFailed(error: any): string { return localize('arc.openDashboardFailed', "Error opening dashboard. {0}", getErrorMessage(error)); }
export function instanceDeletionFailed(name: string, error: any): string { return localize('arc.instanceDeletionFailed', "Failed to delete instance {0}. {1}", name, getErrorMessage(error)); }

View File

@@ -9,14 +9,14 @@ import * as azExt from 'az-ext';
import * as vscode from 'vscode';
import { UserCancelledError } from '../common/api';
import { Deferred } from '../common/promise';
import { getTimeStamp, parseIpAndPort } from '../common/utils';
import { parseIpAndPort } from '../common/utils';
import * as loc from '../localizedConstants';
import { ConnectToMiaaSqlDialog } from '../ui/dialogs/connectMiaaDialog';
import { AzureArcTreeDataProvider } from '../ui/tree/azureArcTreeDataProvider';
import { ControllerModel, Registration } from './controllerModel';
import { ResourceModel } from './resourceModel';
export type DatabaseModel = { name: string, status: string, earliestBackup: string, lastBackup: string };
export type DatabaseModel = { name: string, status: string, lastBackup: string };
export type RPModel = { recoveryPointObjective: string, retentionDays: string };
export type PITRModel = {
instanceName: string,
@@ -27,9 +27,7 @@ export type PITRModel = {
restorePoint: string,
earliestPitr: string,
latestPitr: string,
destDbName: string
};
export const systemDbs = ['master', 'msdb', 'tempdb', 'model'];
export class MiaaModel extends ResourceModel {
@@ -46,20 +44,12 @@ export class MiaaModel extends ResourceModel {
recoveryPointObjective: '',
retentionDays: ''
};
private _databaseTimeWindow: Map<string, string[]>;
private _refreshPromise: Deferred<void> | undefined = undefined;
private _pitrArgs = {
destName: '',
managedInstance: '',
time: '',
noWait: true,
dryRun: false
};
constructor(_controllerModel: ControllerModel, private _miaaInfo: MiaaResourceInfo, registration: Registration, private _treeDataProvider: AzureArcTreeDataProvider) {
super(_controllerModel, _miaaInfo, registration);
this._azApi = <azExt.IExtension>vscode.extensions.getExtension(azExt.extension.name)?.exports;
this._databaseTimeWindow = new Map<string, string[]>();
}
/**
@@ -102,7 +92,6 @@ export class MiaaModel extends ResourceModel {
this.configLastUpdated = new Date();
this.rpSettings.retentionDays = this._config?.spec?.backup?.retentionPeriodInDays?.toString() ?? '';
this._onConfigUpdated.fire(this._config);
this._onDatabasesUpdated.fire(this._databases);
} catch (err) {
// If an error occurs show a message so the user knows something failed but still
// fire the event so callers can know to update (e.g. so dashboards don't show the
@@ -149,12 +138,6 @@ export class MiaaModel extends ResourceModel {
throw error;
}
}
/**
* Gets the list of databases and adds backup earliest and latest point in time
* information, this could be used as an upper and lower time limit for restoring
* backup.
*/
public async getDatabases(promptForConnection: boolean = true): Promise<void> {
if (!this._connectionProfile) {
await this.getConnectionProfile(promptForConnection);
@@ -175,21 +158,10 @@ export class MiaaModel extends ResourceModel {
if (!databases) {
throw new Error('Could not fetch databases');
}
else {
if (databases.length > 0 && typeof (databases[0]) === 'object') {
for (let i in databases) {
const di: azdata.DatabaseInfo = <azdata.DatabaseInfo>databases[i];
const name = di.options['name'];
await this.executeDryRun(di.options['name']);
const dm: DatabaseModel = {
name: name, status: di.options['state'], earliestBackup: this._databaseTimeWindow.get(name)?.[0] ?? '',
lastBackup: this._databaseTimeWindow.get(name)?.[1] ?? ''
};
this._databases[i] = dm;
}
} else {
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', earliestBackup: '', lastBackup: '' }; });
}
if (databases.length > 0 && typeof (databases[0]) === 'object') {
this._databases = (<azdata.DatabaseInfo[]>databases).map(db => { return { name: db.options['name'], status: db.options['state'], lastBackup: db.options['lastBackup'] }; });
} else {
this._databases = (<string[]>databases).map(db => { return { name: db, status: '-', lastBackup: '' }; });
}
this.databasesLastUpdated = new Date();
this._onDatabasesUpdated.fire(this._databases);
@@ -234,33 +206,4 @@ export class MiaaModel extends ResourceModel {
await this._treeDataProvider.saveControllers();
}
protected async executeDryRun(dbName: string): Promise<void> {
// Allow next dry Run to be executed only after 5(300000 ms ) minutes from current time as the log backups are
// generated only at 5 minutes interval
if ((systemDbs.indexOf(dbName) === -1) && (Date.now() - getTimeStamp(this._databaseTimeWindow.get(dbName)?.[1]) >= 300000)) {
try {
//Execute dryRun for earliestTime and save latest time as well so there is one call to az cli
this._pitrArgs.destName = dbName + '-' + Date.now().toString();
this._pitrArgs.managedInstance = this.info.name;
this._pitrArgs.time = new Date().toISOString();
this._pitrArgs.noWait = false;
this._pitrArgs.dryRun = true;
const result = await this._azApi.az.sql.midbarc.restore(
dbName, this._pitrArgs, this.controllerModel.info.namespace, this.controllerModel.azAdditionalEnvVars);
const restoreResult = result.stdout;
if (restoreResult) {
const earliestTime = restoreResult['earliestRestoreTime'];
const latestTime = restoreResult['latestRestoreTime'];
console.log(loc.earliestPitrRestorePoint + '-' + dbName + ':' + earliestTime);
console.log(loc.latestpitrRestorePoint + '-' + dbName + ':' + latestTime);
this._databaseTimeWindow.set(dbName, [earliestTime, latestTime]);
}
}
catch (err) {
console.log(loc.pitr + ' ' + loc.failed + ':' + err);
this._databaseTimeWindow.set(dbName, ['', '']);
}
}
}
}

View File

@@ -20,6 +20,7 @@ export class MiaaBackupsPage extends DashboardPage {
this._azApi = vscode.extensions.getExtension(azExt.extension.name)?.exports;
this.disposables.push(
this._miaaModel.onDatabasesUpdated(() => this.eventuallyRunOnInitialized(() => this.handleDatabasesUpdated())),
this._miaaModel.onConfigUpdated(() => this.eventuallyRunOnInitialized(() => this.handleDatabasesUpdated()))
);
}
private _databasesContainer!: azdata.DivContainer;
@@ -31,17 +32,16 @@ export class MiaaBackupsPage extends DashboardPage {
private _databasesMessage!: azdata.TextComponent;
private readonly _azApi: azExt.IExtension;
private _saveArgs: RPModel = {
public saveArgs: RPModel = {
recoveryPointObjective: '',
retentionDays: ''
};
private _pitrArgs = {
public pitrArgs = {
destName: '',
managedInstance: '',
time: '',
noWait: true,
dryRun: false
noWait: true
};
public get title(): string {
@@ -66,7 +66,7 @@ export class MiaaBackupsPage extends DashboardPage {
.component();
const content = this.modelView.modelBuilder.divContainer().component();
this._databasesContainer = this.modelView.modelBuilder.divContainer().component();
root.addItem(content, { CSSStyles: { 'margin': '5px' } });
root.addItem(content, { CSSStyles: { 'margin': '20px' } });
const databaseTitle = this.modelView.modelBuilder.text().withProps({
value: loc.databases,
CSSStyles: { ...cssStyles.title },
@@ -130,19 +130,11 @@ export class MiaaBackupsPage extends DashboardPage {
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
{
displayName: loc.earliestPitrRestorePoint,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: '30%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
{
displayName: loc.latestpitrRestorePoint,
valueType: azdata.DeclarativeDataType.string,
isReadOnly: true,
width: '30%',
width: '50%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow
},
@@ -150,7 +142,7 @@ export class MiaaBackupsPage extends DashboardPage {
displayName: loc.restore,
valueType: azdata.DeclarativeDataType.component,
isReadOnly: true,
width: '10%',
width: '20%',
headerCssStyles: cssStyles.tableHeader,
rowCssStyles: cssStyles.tableRow,
}
@@ -206,13 +198,13 @@ export class MiaaBackupsPage extends DashboardPage {
this._configureRetentionPolicyButton.onDidClick(async () => {
const retentionPolicySqlDialog = new ConfigureRPOSqlDialog(this._miaaModel);
this.refreshRD();
retentionPolicySqlDialog.showDialog(loc.configureRP, this._saveArgs.retentionDays);
retentionPolicySqlDialog.showDialog(loc.configureRP, this.saveArgs.retentionDays);
let rpArg = await retentionPolicySqlDialog.waitForClose();
if (rpArg) {
try {
this._configureRetentionPolicyButton.enabled = false;
this._saveArgs.retentionDays = rpArg.retentionDays;
this.saveArgs.retentionDays = rpArg.retentionDays;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
@@ -221,7 +213,7 @@ export class MiaaBackupsPage extends DashboardPage {
},
async (_progress, _token): Promise<void> => {
await this._azApi.az.sql.miarc.edit(
this._miaaModel.info.name, this._saveArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
this._miaaModel.info.name, this.saveArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
try {
await this._miaaModel.refresh();
@@ -252,16 +244,13 @@ export class MiaaBackupsPage extends DashboardPage {
// If we were able to get the databases it means we have a good connection so update the username too
let databaseDisplay = this._miaaModel.databases.map(d => [
d.name,
d.earliestBackup,
d.lastBackup,
this.createRestoreButton(d)]);
let databasesValues = databaseDisplay.map(d => {
return d.map((value): azdata.DeclarativeTableCellValue => {
return { value: value };
});
});
this._databasesTable.setDataValues(databasesValues);
this._databasesTableLoading.loading = false;
@@ -282,7 +271,7 @@ export class MiaaBackupsPage extends DashboardPage {
}
private refreshRD(): void {
this._saveArgs.retentionDays = this._miaaModel.config?.spec?.backup?.retentionPeriodInDays.toString() ?? '';
this.saveArgs.retentionDays = this._miaaModel.config?.spec?.backup?.retentionPeriodInDays.toString() ?? '';
}
// Create restore button for every database entry in the database table
@@ -303,9 +292,9 @@ export class MiaaBackupsPage extends DashboardPage {
if (args) {
try {
restoreButton.enabled = false;
this._pitrArgs.destName = args.destDbName;
this._pitrArgs.managedInstance = args.instanceName;
this._pitrArgs.time = `"${args.restorePoint}"`;
this.pitrArgs.destName = args.dbName;
this.pitrArgs.managedInstance = args.instanceName;
this.pitrArgs.time = `"${args.restorePoint}"`;
await vscode.window.withProgress(
{
location: vscode.ProgressLocation.Notification,
@@ -314,7 +303,7 @@ export class MiaaBackupsPage extends DashboardPage {
},
async (_progress, _token): Promise<void> => {
await this._azApi.az.sql.midbarc.restore(
db.name, this._pitrArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
db.name, this.pitrArgs, this._miaaModel.controllerModel.info.namespace, this._miaaModel.controllerModel.azAdditionalEnvVars);
try {
await this._miaaModel.refresh();
} catch (error) {
@@ -331,6 +320,4 @@ export class MiaaBackupsPage extends DashboardPage {
}));
return restoreButton;
}
}

View File

@@ -32,7 +32,7 @@ export class ConfigureRPOSqlDialog extends InitializingComponent {
this.retentionDaysInputBox = this.modelBuilder.inputBox()
.withProps({
readOnly: false,
min: 0,
min: 1,
max: 35,
inputType: 'number',
ariaLabel: loc.retentionDays,

View File

@@ -5,7 +5,6 @@
import * as azdata from 'azdata';
import { Deferred } from '../../common/promise';
import { getTimeStamp, checkISOTimeString } from '../../common/utils';
import * as loc from '../../localizedConstants';
import * as vscode from 'vscode';
import { cssStyles } from '../../constants';
@@ -25,7 +24,6 @@ export class RestoreSqlDialog extends InitializingComponent {
restorePoint: '-',
earliestPitr: '-',
latestPitr: '-',
destDbName: '-',
};
private earliestRestorePointInputBox!: azdata.InputBoxComponent;
@@ -38,11 +36,10 @@ export class RestoreSqlDialog extends InitializingComponent {
private instanceInputBox!: azdata.InputBoxComponent;
protected _completionPromise = new Deferred<PITRModel | undefined>();
private _azurecoreApi: azurecore.IExtension;
protected disposables: vscode.Disposable[] = [];
constructor(protected _miaaModel: MiaaModel, protected _controllerModel: ControllerModel, protected _database: DatabaseModel) {
super();
this._azurecoreApi = vscode.extensions.getExtension(azurecore.extension.name)?.exports;
this.refreshPitrSettings();
}
public showDialog(dialogTitle: string): azdata.window.Dialog {
@@ -53,15 +50,14 @@ export class RestoreSqlDialog extends InitializingComponent {
this.refreshPitrSettings();
const pitrTitle = this.modelBuilder.text().withProps({
value: loc.pitr,
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' },
CSSStyles: { ...cssStyles.title }
}).component();
const projectDetailsTitle = this.modelBuilder.text().withProps({
value: loc.projectDetails,
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
CSSStyles: { ...cssStyles.title }
}).component();
const projectDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.projectDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.subscriptionInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -78,11 +74,10 @@ export class RestoreSqlDialog extends InitializingComponent {
const sourceDetailsTitle = this.modelBuilder.text().withProps({
value: loc.sourceDetails,
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
CSSStyles: { ...cssStyles.title }
}).component();
const sourceDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.sourceDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.sourceDbInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -90,15 +85,12 @@ export class RestoreSqlDialog extends InitializingComponent {
ariaLabel: loc.sourceDatabase,
value: this._database.name
}).component();
const restoreDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.restorePointText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.earliestRestorePointInputBox = this.modelBuilder.inputBox()
.withProps({
enabled: false,
ariaLabel: loc.earliestPitrRestorePoint,
value: this._database.earliestBackup
value: ''
}).component();
this.latestRestorePointInputBox = this.modelBuilder.inputBox()
@@ -112,39 +104,14 @@ export class RestoreSqlDialog extends InitializingComponent {
.withProps({
readOnly: false,
ariaLabel: loc.restorePoint,
value: '',
validationErrorMessage: loc.restorePointErrorMessage(this.earliestRestorePointInputBox.value ?? loc.earliestPitrRestorePoint, this.latestRestorePointInputBox.value ?? loc.latestpitrRestorePoint),
}).withValidation(async () => {
try {
if (!checkISOTimeString(this.restorePointInputBox.value ?? '')) { return false; }
if (this.earliestRestorePointInputBox.value) {
if ((getTimeStamp(this.restorePointInputBox.value) >= getTimeStamp(this.earliestRestorePointInputBox.value)
&& getTimeStamp(this.restorePointInputBox.value) <= getTimeStamp(this.latestRestorePointInputBox.value))) {
this.pitrSettings.restorePoint = this.restorePointInputBox.value ?? '';
return true;
}
else {
return false;
}
}
}
catch (err) {
throw err;
return false;
}
return true;
value: ''
}).component();
const pitrDetailsTitle = this.modelBuilder.text().withProps({
value: loc.restorePointDetails,
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
const destinationDetailsTitle = this.modelBuilder.text().withProps({
const databaseDetailsTitle = this.modelBuilder.text().withProps({
value: loc.databaseDetails,
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
CSSStyles: { ...cssStyles.title }
}).component();
const databaseDetailsTextLabel = this.modelBuilder.text().withProps({
value: loc.databaseDetailsText,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
}).component();
this.databaseNameInputBox = this.modelBuilder.inputBox()
.withProps({
@@ -152,10 +119,7 @@ export class RestoreSqlDialog extends InitializingComponent {
ariaLabel: loc.databaseName,
value: ''
}).component();
this.disposables.push(
this.databaseNameInputBox.onTextChanged(() => {
this.pitrSettings.destDbName = this.databaseNameInputBox.value ?? '';
}));
this.instanceInputBox = this.modelBuilder.inputBox()
.withProps({
enabled: false,
@@ -164,7 +128,7 @@ export class RestoreSqlDialog extends InitializingComponent {
}).component();
const info = this.modelBuilder.text().withProps({
value: loc.restoreInfo,
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
}).component();
const link = this.modelBuilder.hyperlink().withProps({
@@ -213,28 +177,6 @@ export class RestoreSqlDialog extends InitializingComponent {
title: loc.sourceDatabase,
},
{
component: destinationDetailsTitle,
},
{
component: databaseDetailsTextLabel,
},
{
component: this.databaseNameInputBox,
title: loc.databaseName,
required: true
},
{
component: this.instanceInputBox,
title: loc.instance,
},
{
component: pitrDetailsTitle
},
{
component: restoreDetailsTextLabel,
},
{
component: this.earliestRestorePointInputBox,
title: loc.earliestPitrRestorePoint,
@@ -250,6 +192,22 @@ export class RestoreSqlDialog extends InitializingComponent {
title: loc.restorePoint,
required: true
},
{
component: databaseDetailsTitle,
},
{
component: databaseDetailsTextLabel,
},
{
component: this.databaseNameInputBox,
title: loc.databaseName,
required: true
},
{
component: this.instanceInputBox,
title: loc.instance,
},
],
title: ''
}]).withLayout({ width: '100%' }).component();
@@ -311,9 +269,4 @@ export class RestoreSqlDialog extends InitializingComponent {
this.pitrSettings.restorePoint = this._database.lastBackup;
this.pitrSettings.earliestPitr = '';
}
public updatePitrTimeWindow(earliestPitr: string, latestPitr: string): void {
this.earliestRestorePointInputBox.value = earliestPitr;
this.latestRestorePointInputBox.value = latestPitr;
}
}

View File

@@ -228,16 +228,36 @@
resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
"@types/caseless@*":
version "0.12.2"
resolved "https://registry.yarnpkg.com/@types/caseless/-/caseless-0.12.2.tgz#f65d3d6389e01eeb458bd54dc8f52b95a9463bc8"
integrity sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==
"@types/mocha@^5.2.5":
version "5.2.7"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea"
integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==
"@types/node@*":
version "13.11.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7"
integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==
"@types/node@^12.11.7":
version "12.12.47"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.47.tgz#5007b8866a2f9150de82335ca7e24dd1d59bdfb5"
integrity sha512-yzBInQFhdY8kaZmqoL2+3U5dSTMrKaYcb561VU+lDzAYvqt+2lojvBEy+hmpSNuXnPTx7m9+04CzWYOUqWME2A==
"@types/request@^2.48.3":
version "2.48.4"
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.4.tgz#df3d43d7b9ed3550feaa1286c6eabf0738e6cf7e"
integrity sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==
dependencies:
"@types/caseless" "*"
"@types/node" "*"
"@types/tough-cookie" "*"
form-data "^2.5.0"
"@types/sinon@^9.0.4":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.4.tgz#e934f904606632287a6e7f7ab0ce3f08a0dad4b1"
@@ -250,6 +270,11 @@
resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e"
integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA==
"@types/tough-cookie@*":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
"@types/uuid@^8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.0.tgz#215c231dff736d5ba92410e6d602050cce7e273f"
@@ -267,6 +292,16 @@ agent-base@4, agent-base@^4.3.0:
dependencies:
es6-promisify "^5.0.0"
ajv@^6.5.5:
version "6.12.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7"
integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
@@ -293,11 +328,45 @@ argparse@^1.0.7:
dependencies:
sprintf-js "~1.0.2"
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.8.0:
version "1.9.1"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -316,6 +385,11 @@ callsite@^1.0.0:
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -347,6 +421,13 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
combined-stream@^1.0.6, combined-stream@~1.0.6:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@2.15.1:
version "2.15.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
@@ -364,11 +445,23 @@ convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -411,6 +504,11 @@ default-require-extensions@^3.0.0:
dependencies:
strip-bom "^4.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
diff@3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
@@ -421,6 +519,14 @@ diff@^4.0.2:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
es6-promise@^4.0.3:
version "4.2.8"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a"
@@ -438,6 +544,54 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-deep-equal@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@^2.5.0:
version "2.5.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4"
integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.6"
mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -448,6 +602,13 @@ gensync@^1.0.0-beta.1:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
glob@7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -482,6 +643,19 @@ growl@1.10.5:
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
dependencies:
ajv "^6.5.5"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -510,6 +684,15 @@ http-proxy-agent@^2.1.0:
agent-base "4"
debug "3.1.0"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
https-proxy-agent@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
@@ -536,11 +719,21 @@ is-buffer@~1.1.1:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
istanbul-lib-coverage@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
@@ -601,11 +794,31 @@ js-tokens@^4.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@@ -613,6 +826,16 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
just-extend@^4.0.2:
version "4.1.0"
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4"
@@ -652,6 +875,18 @@ md5@^2.1.0:
crypt "~0.0.1"
is-buffer "~1.1.1"
mime-db@1.43.0:
version "1.43.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.26"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==
dependencies:
mime-db "1.43.0"
minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -740,6 +975,11 @@ nise@^4.0.1:
just-extend "^4.0.2"
path-to-regexp "^1.7.0"
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -764,6 +1004,11 @@ path-to-regexp@^1.7.0:
dependencies:
isarray "0.0.1"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
@@ -774,6 +1019,47 @@ postinstall-build@^5.0.1:
resolved "https://registry.yarnpkg.com/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
psl@^1.1.28:
version "1.8.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
punycode@^2.1.0, punycode@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
request@^2.88.0:
version "2.88.2"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.3"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.5.0"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve@^1.3.2:
version "1.17.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
@@ -788,11 +1074,21 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
safe-buffer@^5.0.1, safe-buffer@^5.1.2:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
semver@^5.4.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@@ -875,6 +1171,21 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
sshpk@^1.7.0:
version "1.16.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
bcrypt-pbkdf "^1.0.0"
dashdash "^1.12.0"
ecc-jsbn "~0.1.1"
getpass "^0.1.1"
jsbn "~0.1.0"
safer-buffer "^2.0.2"
tweetnacl "~0.14.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
@@ -913,6 +1224,26 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
dependencies:
psl "^1.1.28"
punycode "^2.1.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
type-detect@4.0.8, type-detect@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
@@ -927,11 +1258,32 @@ typemoq@2.1.0, typemoq@^2.1.0:
lodash "^4.17.4"
postinstall-build "^5.0.1"
uri-js@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==
dependencies:
punycode "^2.1.0"
uuid@^3.3.2:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.3.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea"
integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"

View File

@@ -16,12 +16,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"forceReload": true,
"contributes": {
"resourceDeploymentTypes": [

View File

@@ -2,7 +2,7 @@
"name": "azcli",
"displayName": "%azcli.arc.displayName%",
"description": "%azcli.arc.description%",
"version": "0.1.1",
"version": "0.1.0",
"publisher": "Microsoft",
"preview": true,
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
@@ -18,12 +18,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"microsoft.resource-deployment"
],
@@ -111,9 +105,6 @@
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
},
"__metadata": {
"id": "84",
"publisherDisplayName": "Microsoft",

View File

@@ -140,7 +140,6 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
managedInstance?: string,
time?: string,
noWait?: boolean,
dryRun?: boolean
},
namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
await localAzDiscovered;

View File

@@ -185,18 +185,16 @@ export class AzTool implements azExt.IAzApi {
managedInstance?: string,
time?: string,
noWait?: boolean,
dryRun?: boolean
},
namespace: string,
additionalEnvVars?: azExt.AdditionalEnvVars
): Promise<azExt.AzOutput<azExt.SqlMiDbRestoreResult>> => {
): Promise<azExt.AzOutput<void>> => {
const argsArray = ['sql', 'midb-arc', 'restore', '--name', name, '--k8s-namespace', namespace, '--use-k8s'];
if (args.destName) { argsArray.push('--dest-name', args.destName); }
if (args.managedInstance) { argsArray.push('--managed-instance', args.managedInstance); }
if (args.time) { argsArray.push('--time', args.time); }
if (args.noWait) { argsArray.push('--no-wait'); }
if (args.dryRun) { argsArray.push('--dry-run'); }
return this.executeCommand<azExt.SqlMiDbRestoreResult>(argsArray, additionalEnvVars);
return this.executeCommand<void>(argsArray, additionalEnvVars);
}
}
};

View File

@@ -173,17 +173,6 @@ declare module 'az-ext' {
}
}
export interface SqlMiDbRestoreResult {
destDatabase: string, //testDbToRestore
earliestRestoreTime: string, // "2020-08-19T20:25:11Z"
latestRestoreTime: string, //"2020-08-19T20:25:11Z"
message: string, //Dry run for restore operation succeeded.
observedGeneration: number, //1
restorePoint: string, // "2020-08-19T20:25:11Z"
sourceDatabase: string, //testDb
state: string //Completed
}
export interface PostgresServerShowResult {
apiVersion: string, // "arcdata.microsoft.com/v1alpha1"
kind: string, // "postgresql"
@@ -347,11 +336,10 @@ declare module 'az-ext' {
managedInstance?: string, //sqlmi1
time?: string, //2021-10-12T11:16:30.000Z
noWait?: boolean, //true
dryRun?: boolean, //true
},
namespace?: string,
additionalEnvVars?: AdditionalEnvVars
): Promise<AzOutput<SqlMiDbRestoreResult>>
): Promise<AzOutput<void>>
}
},
getPath(): Promise<string>,

View File

@@ -768,10 +768,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -18,12 +18,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"resourceViewResources": [
{
@@ -328,6 +322,11 @@
}
]
},
"resourceDeploymentValueProviders": [
{
"id": "subscription-id-to-tenant-id"
}
],
"hasAzureResourceProviders": true
},
"dependencies": {

View File

@@ -8,6 +8,7 @@ import * as vscode from 'vscode';
import { promises as fs } from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as resourceDeployment from 'resource-deployment';
import { AppContext } from './appContext';
import { AzureAccountProviderService } from './account-provider/azureAccountProviderService';
@@ -114,6 +115,40 @@ export async function activate(context: vscode.ExtensionContext): Promise<azurec
}
});
// Don't block on this since there's a bit of a circular dependency here with the extension activation since resource deployment
// depends on this extension too. It's fine to wait a bit for that to finish before registering the provider
vscode.extensions.getExtension(resourceDeployment.extension.name).activate().then((api: resourceDeployment.IExtension) => {
context.subscriptions.push(api.registerValueProvider({
id: 'subscription-id-to-tenant-id',
getValue: async (triggerValue: string) => {
if (triggerValue === '') {
return '';
}
let accounts: azurecore.AzureAccount[] = [];
try {
accounts = await azdata.accounts.getAllAccounts();
} catch (err) {
console.warn(`Error fetching accounts for subscription-id-to-tenant-id provider : ${err}`);
return '';
}
for (const account of accounts) {
// Ignore any errors - they'll be logged in the called function and we still want to look
// at any subscriptions that are returned - worst case we'll just return an empty string if we didn't
// find the matching subscription
const subs = await azureResourceUtils.getSubscriptions(appContext, account, true);
const sub = subs.subscriptions.find(sub => sub.id === triggerValue);
if (sub) {
return sub.tenant;
}
}
console.error(`Unable to find subscription with ID ${triggerValue} when mapping subscription ID to tenant ID`);
return '';
}
}));
}).then(undefined, err => console.error('Error registering Azure ResourceDeployment value provider ', err));
return {
getSubscriptions(account?: azurecore.AzureAccount, ignoreErrors?: boolean, selectedOnly: boolean = false): Promise<azurecore.GetSubscriptionsResult> {
return selectedOnly

View File

@@ -7,4 +7,5 @@
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
/// <reference path='../../../../src/sql/azdata.d.ts'/>
/// <reference path='../../../../src/sql/azdata.proposed.d.ts'/>
/// <reference path='../../../resource-deployment/src/typings/resource-deployment.d.ts'/>
/// <reference types='@types/node'/>

View File

@@ -15,12 +15,6 @@
"activationEvents": [
"*"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"repository": {
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"

View File

@@ -16,12 +16,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"typings": "./src/azuremonitor",
"contributes": {
"connectionProvider": {
@@ -115,6 +109,20 @@
"categoryValues": null,
"isRequired": true,
"isArray": false
},
{
"specialValueType": "databaseName",
"isIdentity": true,
"name": "database",
"displayName": "%azuremonitor.connectionOptions.databaseName.displayName%",
"description": "%azuremonitor.connectionOptions.databaseName.description%",
"groupName": "%azuremonitor.connectionProperties.groupName.source%",
"valueType": "string",
"defaultValue": null,
"objectType": null,
"categoryValues": null,
"isRequired": false,
"isArray": false
}
]
},

View File

@@ -11,12 +11,6 @@
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"languages": [
{

View File

@@ -27,12 +27,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/extension",
"contributes": {
"dataExplorer": {
@@ -254,7 +248,7 @@
},
{
"name": "azdata",
"version": "20.3.9"
"version": "20.3.4"
}
],
"when": "target=new-aks&&version=bdc2019"
@@ -272,7 +266,7 @@
},
{
"name": "azdata",
"version": "20.3.9"
"version": "20.3.4"
}
],
"when": "target=existing-aks&&version=bdc2019"
@@ -290,7 +284,7 @@
},
{
"name": "azdata",
"version": "20.3.9"
"version": "20.3.4"
}
],
"when": "target=existing-kubeadm&&version=bdc2019"
@@ -308,7 +302,7 @@
},
{
"name": "azdata",
"version": "20.3.9"
"version": "20.3.4"
}
],
"when": "target=existing-aro&&version=bdc2019"
@@ -326,7 +320,7 @@
},
{
"name": "azdata",
"version": "20.3.9"
"version": "20.3.4"
}
],
"when": "target=existing-openshift&&version=bdc2019"
@@ -362,8 +356,5 @@
},
"devDependencies": {
"@types/request": "^2.48.3"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -212,10 +212,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -22,12 +22,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/extension",
"contributes": {
"configuration": {
@@ -624,8 +618,7 @@
"when": "viewItem == cms.resource.itemType.databaseServerContainer",
"group": "navigation@10"
}
],
"commandPalette": [
],"commandPalette": [
{
"command": "cms.resource.addRegisteredServer",
"when": "false"
@@ -654,6 +647,7 @@
}
},
"dependencies": {
"request": "2.88.0",
"vscode-nls": "^4.0.0"
},
"devDependencies": {

View File

@@ -192,6 +192,16 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.7.tgz#01e4ea724d9e3bd50d90c11fd5980ba317d8fa11"
integrity sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
integrity sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
@@ -211,11 +221,45 @@ append-transform@^2.0.0:
dependencies:
default-require-extensions "^3.0.0"
asn1@~0.2.3:
version "0.2.4"
resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
dependencies:
safer-buffer "~2.1.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
aws4@^1.8.0:
version "1.8.0"
resolved "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
dependencies:
tweetnacl "^0.14.3"
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -234,6 +278,11 @@ callsite@^1.0.0:
resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20"
integrity sha1-KAOY5dZkvXQDi28JBRU+borxvCA=
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
chalk@^2.0.0:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
@@ -253,6 +302,11 @@ circular-json@^0.3.1:
resolved "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66"
integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==
co@^4.6.0:
version "4.6.0"
resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -265,6 +319,20 @@ color-name@1.1.3:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
combined-stream@1.0.6:
version "1.0.6"
resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818"
integrity sha1-cj599ugBrFYTETp+RFqbactjKBg=
dependencies:
delayed-stream "~1.0.0"
combined-stream@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828"
integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==
dependencies:
delayed-stream "~1.0.0"
commander@2.15.1:
version "2.15.1"
resolved "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f"
@@ -282,11 +350,23 @@ convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
dependencies:
assert-plus "^1.0.0"
debug@3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
@@ -329,16 +409,68 @@ default-require-extensions@^3.0.0:
dependencies:
strip-bom "^4.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
diff@3.5.0:
version "3.5.0"
resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
ecc-jsbn@~0.1.1:
version "0.1.2"
resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
dependencies:
jsbn "~0.1.0"
safer-buffer "^2.1.0"
escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
fast-deep-equal@^1.0.0:
version "1.1.0"
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614"
integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
form-data@~2.3.2:
version "2.3.2"
resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099"
integrity sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=
dependencies:
asynckit "^0.4.0"
combined-stream "1.0.6"
mime-types "^2.1.12"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@@ -349,6 +481,13 @@ gensync@^1.0.0-beta.1:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269"
integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
dependencies:
assert-plus "^1.0.0"
glob@7.1.2:
version "7.1.2"
resolved "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -395,6 +534,19 @@ growl@1.10.5:
resolved "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
har-validator@~5.1.0:
version "5.1.0"
resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29"
integrity sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==
dependencies:
ajv "^5.3.0"
har-schema "^2.0.0"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -415,6 +567,15 @@ html-escaper@^2.0.0:
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@@ -433,6 +594,16 @@ is-buffer@~1.1.1:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
istanbul-lib-coverage@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49"
@@ -496,11 +667,31 @@ js-tokens@^4.0.0:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
jsesc@^2.5.1:
version "2.5.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
integrity sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
json5@^2.1.2:
version "2.1.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43"
@@ -508,6 +699,16 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
lodash@^4.16.4, lodash@^4.17.13, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -537,6 +738,18 @@ md5@^2.1.0:
crypt "~0.0.1"
is-buffer "~1.1.1"
mime-db@~1.36.0:
version "1.36.0"
resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397"
integrity sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==
mime-types@^2.1.12, mime-types@~2.1.19:
version "2.1.20"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19"
integrity sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==
dependencies:
mime-db "~1.36.0"
minimatch@3.0.4, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
@@ -607,6 +820,11 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
oauth-sign@~0.9.0:
version "0.9.0"
resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -624,6 +842,11 @@ path-parse@^1.0.6:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
@@ -634,6 +857,47 @@ postinstall-build@^5.0.1:
resolved "https://registry.npmjs.org/postinstall-build/-/postinstall-build-5.0.3.tgz#238692f712a481d8f5bc8960e94786036241efc7"
integrity sha512-vPvPe8TKgp4FLgY3+DfxCE5PIfoXBK2lyLfNCxsRbDsV6vS4oU5RG/IWxrblMn6heagbnMED3MemUQllQ2bQUg==
psl@^1.1.24:
version "1.1.29"
resolved "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67"
integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
qs@~6.5.2:
version "6.5.2"
resolved "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
request@2.88.0:
version "2.88.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.8.0"
caseless "~0.12.0"
combined-stream "~1.0.6"
extend "~3.0.2"
forever-agent "~0.6.1"
form-data "~2.3.2"
har-validator "~5.1.0"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.19"
oauth-sign "~0.9.0"
performance-now "^2.1.0"
qs "~6.5.2"
safe-buffer "^5.1.2"
tough-cookie "~2.4.3"
tunnel-agent "^0.6.0"
uuid "^3.3.2"
resolve@^1.3.2:
version "1.15.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
@@ -648,11 +912,16 @@ rimraf@^2.6.3:
dependencies:
glob "^7.1.3"
safe-buffer@~5.1.1:
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
version "2.1.2"
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
semver@^5.4.1, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
@@ -717,6 +986,22 @@ source-map@^0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sshpk@^1.7.0:
version "1.14.2"
resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98"
integrity sha1-xvxhZIo9nE52T9P8306hBeSSupg=
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
safer-buffer "^2.0.2"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
@@ -755,6 +1040,26 @@ to-fast-properties@^2.0.0:
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
tough-cookie@~2.4.3:
version "2.4.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
dependencies:
psl "^1.1.24"
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
typemoq@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/typemoq/-/typemoq-2.1.0.tgz#4452ce360d92cf2a1a180f0c29de2803f87af1e8"
@@ -764,6 +1069,20 @@ typemoq@^2.1.0:
lodash "^4.17.4"
postinstall-build "^5.0.1"
uuid@^3.3.2:
version "3.3.2"
resolved "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
verror@1.10.0:
version "1.10.0"
resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"

View File

@@ -2,7 +2,7 @@
"name": "dacpac",
"displayName": "SQL Server Dacpac",
"description": "SQL Server Dacpac for Azure Data Studio.",
"version": "1.10.0",
"version": "1.9.1",
"publisher": "Microsoft",
"preview": false,
"engines": {
@@ -20,12 +20,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -1,17 +1,3 @@
# Microsoft Data Workspace for Azure Data Studio and VS Code
## Overview
This extension provides additional common functionality for database projects in Azure Data Studio and VS Code. It requires other extensions to contribute support for specific project types.
### VS Code
This extension is bundled into the `SQL Server (MSSQL)` extension for VS Code and is required by the `SQL Database Projects` extension. It will be installed automatically when those extensions are updated or installed.
### Azure Data Studio
This extension is built into Azure Data Studio and will show up under the list of builtin extensions.
## 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.

View File

@@ -1,7 +1,7 @@
{
"name": "data-workspace",
"displayName": "Data Workspace",
"description": "Additional common functionality for database projects",
"displayName": "%extension-displayName%",
"description": "%extension-description%",
"version": "0.1.0",
"publisher": "Microsoft",
"preview": true,
@@ -20,12 +20,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [],
"contributes": {
"configuration": [

View File

@@ -1,6 +1,8 @@
{
"data-workspace-view-container-name": "Database Projects",
"main-view-name": "Database Projects",
"extension-displayName": "Data workspace",
"extension-description": "Data workspace",
"data-workspace-view-container-name": "Projects",
"main-view-name": "Projects",
"new-command": "New",
"refresh-workspace-command": "Refresh",
"close-workspace-command": "Close Workspace",

View File

@@ -1,6 +1,5 @@
{
"name": "data-workspace-vscode",
"publisher": "ms-mssql",
"extensionDependencies": [
"ms-mssql.mssql"
]

View File

@@ -8,7 +8,7 @@ declare module 'dataworkspace' {
import * as vscode from 'vscode';
export const enum extension {
name = 'Microsoft.data-workspace',
vscodeName = 'ms-mssql.data-workspace-vscode'
vscodeName = 'Microsoft.data-workspace-vscode'
}
/**

View File

@@ -20,12 +20,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql"
],

View File

@@ -9,7 +9,7 @@
"azdata": "*"
},
"activationEvents": [
"onFileSystem:memfs",
"onFileSystem:memfs",
"onDebug",
"onCommand:integration-tests.onboarding.showDevelopers"
],
@@ -26,7 +26,7 @@
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-colorize-tests ./tsconfig.json"
},
"contributes": {
"commands": [
"commands":[
{
"command": "integration-tests.onboarding.showDevelopers",
"title": "Show Developers"
@@ -44,8 +44,5 @@
"mocha-multi-reporters": "^1.1.7",
"ms-rest-azure": "^2.6.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -54,10 +54,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -67,10 +63,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -122,10 +114,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: sourceDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -135,10 +123,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -195,10 +179,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -208,10 +188,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -255,10 +231,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
let target: mssql.SchemaCompareEndpointInfo = {
@@ -268,10 +240,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -329,10 +297,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -342,10 +306,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -363,7 +323,7 @@ suite('Schema compare integration test suite @DacFx@', () => {
assertIncludeExcludeResult(includeResult, true, 0, 0);
//publish the updated changes. Function1 should not be added to the target database
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
const publishChangesResult = await schemaCompareService.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
assert(publishChangesResult.success === true, `Publish changes should complete successfully. But it failed with error : ${publishChangesResult.errorMessage}`);
//verify table Table3 is added
@@ -412,10 +372,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -425,10 +381,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
@@ -438,7 +390,7 @@ suite('Schema compare integration test suite @DacFx@', () => {
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
//publish all the changes
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
const publishChangesResult = await schemaCompareService.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
assert(publishChangesResult.success === true, `Publish changes should complete successfully. But it failed with error : ${publishChangesResult.errorMessage}`);
//verify table Table3 is added
@@ -483,10 +435,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: '',
databaseName: '',
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
const target: mssql.SchemaCompareEndpointInfo = {
@@ -496,10 +444,6 @@ suite('Schema compare integration test suite @DacFx@', () => {
serverName: server.serverName,
databaseName: targetDB,
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};

View File

@@ -202,11 +202,6 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.45.tgz#4c49ba34106bc7dced77ff6bae8eb6543cde8351"
integrity sha512-tGVTbA+i3qfXsLbq9rEq/hezaHY55QxQLeXQL2ejNgFAxxrgu8eMmYIOsRcl7hN1uTLVsKOOYacV/rcJM3sfgQ==
"@xmldom/xmldom@^0.7.0":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d"
integrity sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==
adal-node@^0.1.28:
version "0.1.28"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.28.tgz#468c4bb3ebbd96b1270669f4b9cba4e0065ea485"
@@ -222,20 +217,6 @@ adal-node@^0.1.28:
xmldom ">= 0.1.x"
xpath.js "~1.1.0"
adal-node@^0.2.2:
version "0.2.3"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.2.3.tgz#87ed3dbed344f6e114e36bf18fe1c4e7d3cc6069"
integrity sha512-gMKr8RuYEYvsj7jyfCv/4BfKToQThz20SP71N3AtFn3ia3yAR8Qt2T3aVQhuJzunWs2b38ZsQV0qsZPdwZr7VQ==
dependencies:
"@xmldom/xmldom" "^0.7.0"
async "^2.6.3"
axios "^0.21.1"
date-utils "*"
jws "3.x.x"
underscore ">= 1.3.1"
uuid "^3.1.0"
xpath.js "~1.1.0"
ajv@^6.5.5:
version "6.10.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1"
@@ -294,13 +275,6 @@ async@>=0.6.0:
dependencies:
lodash "^4.17.11"
async@^2.6.3:
version "2.6.3"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
dependencies:
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -316,13 +290,6 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axios@^0.21.1:
version "0.21.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575"
integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==
dependencies:
follow-redirects "^1.14.0"
azure-keyvault@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/azure-keyvault/-/azure-keyvault-3.0.4.tgz#b7733d8f58d99a66f9ae766451556eb3b058dae5"
@@ -548,11 +515,6 @@ fast-json-stable-stringify@^2.0.0:
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
follow-redirects@^1.14.0:
version "1.14.5"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
@@ -780,10 +742,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"
@@ -824,7 +786,7 @@ jws@3.x.x:
jwa "^1.4.1"
safe-buffer "^5.0.1"
lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14:
lodash@^4.14.0, lodash@^4.16.4, lodash@^4.17.11, lodash@^4.17.13:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -942,7 +904,7 @@ moment@^2.21.0, moment@^2.22.2:
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==
ms-rest-azure@^2.5.5:
ms-rest-azure@^2.5.5, ms-rest-azure@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/ms-rest-azure/-/ms-rest-azure-2.6.0.tgz#2098efec529eecfa0c6e215b69143abcaba12140"
integrity sha512-J6386a9krZ4VtU7CRt+Ypgo9RGf8+d3gjMBkH7zbkM4zzkhbbMOYiPRaZ+bHZcfihkKLlktTgA6rjshTjF329A==
@@ -954,17 +916,6 @@ ms-rest-azure@^2.5.5:
request "^2.88.0"
uuid "^3.2.1"
ms-rest-azure@^2.6.0:
version "2.6.1"
resolved "https://registry.yarnpkg.com/ms-rest-azure/-/ms-rest-azure-2.6.1.tgz#f59911da931902d0d22f3f44b2a76cc317d02038"
integrity sha512-LRpluf3wI/GQiuPe8PorhuwKt7YP2atG0wMOdyqSM2SQQH3+VMl9crjEBRe19CNa9zdoxOIPsAdyMwKtDs8Ung==
dependencies:
adal-node "^0.2.2"
async "2.6.0"
ms-rest "^2.3.2"
request "^2.88.0"
uuid "^3.2.1"
ms-rest@^2.3.2:
version "2.5.0"
resolved "https://registry.yarnpkg.com/ms-rest/-/ms-rest-2.5.0.tgz#d483c003f7de7703ade6bc19c3b4319affac2687"

View File

@@ -20,12 +20,6 @@
"compile": "gulp compile-extension:kusto-client",
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-kusto ./syntaxes/kusto.tmLanguage"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -23,12 +23,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"Microsoft.mssql",
"Microsoft.notebook"
@@ -156,9 +150,6 @@
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
},
"__metadata": {
"id": "65",
"publisherDisplayName": "Microsoft",

View File

@@ -303,7 +303,6 @@ export function createViewContext(): ViewTestContext {
registerCloseValidator: () => { },
registerOperation: () => { },
onValidityChanged: new vscode.EventEmitter<boolean>().event,
onClosed: new vscode.EventEmitter<azdata.window.CloseReason>().event,
registerContent: () => { },
modelView: undefined!,
valid: true

View File

@@ -769,10 +769,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -1,6 +1,6 @@
{
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
"version": "3.0.0-release.174",
"version": "3.0.0-release.139",
"downloadFileNames": {
"Windows_86": "win-x86-net5.0.zip",
"Windows_64": "win-x64-net5.0.zip",

View File

@@ -19,12 +19,6 @@
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-mssql syntaxes/SQL.plist ./syntaxes/sql.tmLanguage.json",
"postinstall": "node ./build/postinstall.js"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"problemMatchers": [
{
@@ -498,11 +492,6 @@
"command": "mssqlCluster.livy.cmd.submitFileToSparkJob",
"when": "nodeType == mssqlCluster:file && nodeSubType =~/:spark:/",
"group": "1mssqlCluster@6"
},
{
"command": "mssql.designTable",
"when": "connectionProvider == MSSQL && nodeType == Table && config.tableDesigner.enableFeature",
"group": "0_query@3"
}
],
"notebook/toolbar": [
@@ -1315,8 +1304,5 @@
"should": "^13.2.3",
"typemoq": "^2.1.0",
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"json-schema": "0.4.0"
}
}

View File

@@ -628,20 +628,13 @@ export interface SchemaCompareGenerateScriptParams {
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaComparePublishDatabaseChangesParams {
export interface SchemaComparePublishChangesParams {
operationId: string;
targetServerName: string;
targetDatabaseName: string;
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaComparePublishProjectChangesParams {
operationId: string;
targetProjectPath: string;
targetFolderStructure: mssql.ExtractTarget;
taskExecutionMode: TaskExecutionMode;
}
export interface SchemaCompareGetOptionsParams {
}
@@ -680,15 +673,7 @@ export namespace SchemaCompareGenerateScriptRequest {
}
export namespace SchemaComparePublishChangesRequest {
export const type = new RequestType<SchemaComparePublishDatabaseChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publish');
}
export namespace SchemaComparePublishDatabaseChangesRequest {
export const type = new RequestType<SchemaComparePublishDatabaseChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publishDatabase');
}
export namespace SchemaComparePublishProjectChangesRequest {
export const type = new RequestType<SchemaComparePublishProjectChangesParams, mssql.SchemaComparePublishProjectResult, void, void>('schemaCompare/publishProject');
export const type = new RequestType<SchemaComparePublishChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publish');
}
export namespace SchemaCompareGetDefaultOptionsRequest {
@@ -1045,12 +1030,12 @@ export namespace GetSqlMigrationAssessmentItemsRequest {
export interface TableDesignerEditRequestParams {
tableInfo: azdata.designers.TableInfo,
tableChangeInfo: azdata.designers.DesignerEdit,
viewModel: azdata.designers.DesignerViewModel
data: azdata.designers.DesignerData
}
export interface SaveTableDesignerChangesRequestParams {
tableInfo: azdata.designers.TableInfo,
viewModel: azdata.designers.DesignerViewModel
data: azdata.designers.DesignerData
}
export namespace GetTableDesignerInfoRequest {
@@ -1065,7 +1050,4 @@ export namespace SaveTableDesignerChangesRequest {
export const type = new RequestType<SaveTableDesignerChangesRequestParams, void, void, void>('tabledesigner/savechanges');
}
export namespace DisposeTableDesignerRequest {
export const type = new RequestType<azdata.designers.TableInfo, void, void, void>('tabledesigner/dispose');
}
// ------------------------------- < Table Designer > ------------------------------------

View File

@@ -1117,10 +1117,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
return Promise.reject(e);
}
};
const processTableEdit = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
const processTableEdit = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
let params: contracts.TableDesignerEditRequestParams = {
tableInfo: tableInfo,
viewModel: viewModel,
data: data,
tableChangeInfo: tableChangeInfo
};
try {
@@ -1132,10 +1132,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
}
};
const saveTable = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel): Thenable<void> => {
const saveTable = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData): Thenable<void> => {
let params: contracts.SaveTableDesignerChangesRequestParams = {
tableInfo: tableInfo,
viewModel: viewModel
data: data
};
try {
return client.sendRequest(contracts.SaveTableDesignerChangesRequest.type, params);
@@ -1146,22 +1146,11 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
}
};
const disposeTableDesigner = (tableInfo: azdata.designers.TableInfo): Thenable<void> => {
try {
return client.sendRequest(contracts.DisposeTableDesignerRequest.type, tableInfo);
}
catch (e) {
client.logFailedRequest(contracts.DisposeTableDesignerRequest.type, e);
return Promise.reject(e);
}
};
return azdata.dataprotocol.registerTableDesignerProvider({
providerId: client.providerId,
getTableDesignerInfo,
processTableEdit,
saveTable,
disposeTableDesigner
saveTable
});
}
}

View File

@@ -122,10 +122,7 @@ export const enum SchemaDifferenceType {
export const enum SchemaCompareEndpointType {
Database = 0,
Dacpac = 1,
Project = 2,
// must be kept in-sync with SchemaCompareEndpointType in SQL Tools Service
// located at \src\Microsoft.SqlTools.ServiceLayer\SchemaCompare\Contracts\SchemaCompareRequest.cs
Dacpac = 1
}
export interface SchemaCompareEndpointInfo {
@@ -137,10 +134,6 @@ export interface SchemaCompareEndpointInfo {
ownerUri: string;
connectionDetails: azdata.ConnectionInfo;
connectionName?: string;
projectFilePath: string;
targetScripts: string[];
folderStructure: string;
dataSchemaProvider: string;
}
export interface SchemaCompareObjectId {
@@ -314,11 +307,10 @@ export interface SchemaCompareObjectId {
}
export interface ISchemaCompareService {
schemaCompare(operationId: string, sourceEndpointInfo: SchemaCompareEndpointInfo, targetEndpointInfo: SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode, deploymentOptions: DeploymentOptions): Thenable<SchemaCompareResult>;
schemaCompareGenerateScript(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus>;
schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<SchemaComparePublishProjectResult>;
schemaCompareGetDefaultOptions(): Thenable<SchemaCompareOptionsResult>;
schemaCompareIncludeExcludeNode(operationId: string, diffEntry: DiffEntry, IncludeRequest: boolean, taskExecutionMode: azdata.TaskExecutionMode): Thenable<SchemaCompareIncludeExcludeResult>;
schemaCompareOpenScmp(filePath: string): Thenable<SchemaCompareOpenScmpResult>;
@@ -336,12 +328,6 @@ export interface SchemaCompareOpenScmpResult extends azdata.ResultStatus {
excludedTargetElements: SchemaCompareObjectId[];
}
export interface SchemaComparePublishProjectResult extends azdata.ResultStatus {
changedFiles: string[];
addedFiles: string[];
deletedFiles: string[];
}
//#endregion
//#region --- dacfx

View File

@@ -55,31 +55,11 @@ export class SchemaCompareService implements mssql.ISchemaCompareService {
}
public schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
const params: contracts.SchemaComparePublishDatabaseChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishChangesRequest.type, params).then(undefined,
e => {
this.client.logFailedRequest(contracts.SchemaComparePublishChangesRequest.type, e); return Promise.resolve(undefined);
}
);
}
public schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
const params: contracts.SchemaComparePublishDatabaseChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishDatabaseChangesRequest.type, params).then(
const params: contracts.SchemaComparePublishChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishChangesRequest.type, params).then(
undefined,
e => {
this.client.logFailedRequest(contracts.SchemaComparePublishDatabaseChangesRequest.type, e);
return Promise.resolve(undefined);
}
);
}
public schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: mssql.ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaComparePublishProjectResult> {
const params: contracts.SchemaComparePublishProjectChangesParams = { operationId: operationId, targetProjectPath: targetProjectPath, targetFolderStructure: targetFolderStructure, taskExecutionMode: taskExecutionMode };
return this.client.sendRequest(contracts.SchemaComparePublishProjectChangesRequest.type, params).then(
undefined,
(e: any) => {
this.client.logFailedRequest(contracts.SchemaComparePublishProjectChangesRequest.type, e);
this.client.logFailedRequest(contracts.SchemaComparePublishChangesRequest.type, e);
return Promise.resolve(undefined);
}
);

View File

@@ -7,17 +7,15 @@ import { AppContext } from '../appContext';
import * as azdata from 'azdata';
import * as vscode from 'vscode';
import { sqlProviderName } from '../constants';
import { generateUuid } from 'vscode-languageclient/lib/utils/uuid';
export function registerTableDesignerCommands(appContext: AppContext) {
appContext.extensionContext.subscriptions.push(vscode.commands.registerCommand('mssql.newTable', async (context: azdata.ObjectExplorerContext) => {
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
await azdata.designers.openTableDesigner(sqlProviderName, {
server: context.connectionProfile.serverName,
database: context.connectionProfile.databaseName,
isNewTable: true,
id: generateUuid(),
connectionString: connectionString
connectionUri: connectionUri
});
}));
@@ -26,7 +24,6 @@ export function registerTableDesignerCommands(appContext: AppContext) {
const database = context.connectionProfile.databaseName;
const schema = context.nodeInfo.metadata.schema;
const name = context.nodeInfo.metadata.name;
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
const connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
await azdata.designers.openTableDesigner(sqlProviderName, {
server: server,
@@ -34,8 +31,9 @@ export function registerTableDesignerCommands(appContext: AppContext) {
isNewTable: false,
name: name,
schema: schema,
id: `${connectionUri}|${database}|${schema}|${name}`,
connectionString: connectionString
id: `${server}|${database}|${schema}|${name}`,
connectionUri: connectionUri
});
}));
}

View File

@@ -1136,10 +1136,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stringify-safe@~5.0.1:
version "5.0.1"

View File

@@ -13,12 +13,6 @@
"activationEvents": [
"*"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"configuration": {
"type": "object",
@@ -424,10 +418,6 @@
"command": "notebook.command.addNotebook",
"when": "false"
},
{
"command": "notebook.command.addSection",
"when": "false"
},
{
"command": "notebook.command.addMarkdown",
"when": "false"
@@ -690,50 +680,48 @@
]
}
],
"notebook.providers": [
{
"provider": "jupyter",
"fileExtensions": [
".ipynb"
],
"standardKernels": [
{
"name": "pysparkkernel",
"displayName": "PySpark",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkkernel",
"displayName": "Spark | Scala",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkrkernel",
"displayName": "Spark | R",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "python3",
"displayName": "Python 3",
"connectionProviderIds": []
},
{
"name": "powershell",
"displayName": "PowerShell",
"connectionProviderIds": []
}
]
}
]
"notebook.providers": {
"provider": "jupyter",
"fileExtensions": [
"IPYNB"
],
"standardKernels": [
{
"name": "pysparkkernel",
"displayName": "PySpark",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkkernel",
"displayName": "Spark | Scala",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "sparkrkernel",
"displayName": "Spark | R",
"connectionProviderIds": [
"MSSQL"
],
"blockedOnSAW": true
},
{
"name": "python3",
"displayName": "Python 3",
"connectionProviderIds": []
},
{
"name": "powershell",
"displayName": "PowerShell",
"connectionProviderIds": []
}
]
}
},
"dependencies": {
"@jupyterlab/services": "^3.2.1",
@@ -774,8 +762,7 @@
"vscodetestcover": "^1.1.0"
},
"resolutions": {
"url-parse": "^1.5.1",
"json-schema": "0.4.0"
"url-parse": "^1.5.1"
},
"enableProposedApi": true
}

View File

@@ -92,7 +92,7 @@ export class InstalledPackagesTab {
}
],
data: [[]],
height: '500px',
height: '600px',
width: '400px'
}).component();
this.disposables.push(this.installedPackagesTable.onCellAction(async (rowState) => {

View File

@@ -1171,10 +1171,10 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema@0.2.3, json-schema@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5"
integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
json-stable-stringify@^1.0.1:
version "1.0.1"

View File

@@ -25,12 +25,6 @@
"extensionDependencies": [
"Microsoft.mssql"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -20,12 +20,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [],
"contributes": {
"commands": [

View File

@@ -1,236 +0,0 @@
# Resource Deployment Extension Developer Guide
This guide is meant to provide details on what this extension does and how other extension authors are meant to use it. If there is any missing or incorrect information please submit an [issue](https://github.com/microsoft/azuredatastudio/issues).
## Overview
This extension provides a way for other extension authors to contribute types to the Resource Deployment Wizard which allows users to create and deploy resources such as servers.
This wizard is launched by either running the `Deployment: New Deployment...` command from the command palette or by clicking the `...` on the `Connections` pane and selecting `New Deployment...`
## How to Contribute a new Type
Resource Deployment types are contributed through the `package.json` of a loaded extension. This is done by adding an `resourceDeploymentTypes` property under the `contributes` section of your `package.json`.
``` json
... // Other sections in your package.json
"contributes": {
..., // Other contributions
"resourceDeploymentTypes": [
// provided types go here
]
}
```
The rest of this guide will detail the various options and configuration available to provided types - most contributions will only need a subset of the available features.
The [sample-resource-deployment](https://github.com/microsoft/azuredatastudio/tree/main/samples/sample-resource-deployment) extension provides working examples of contributed sample resource deployment types.
## resourceDeploymentTypes Schema
The contribution must adhere to a specific schema, if there is an error in your `package.json` such as an unexpected type then this may result in errors in both your extension and the feature as a whole.
**!! THIS IS A WORK IN PROGRESS, IF YOU NEED INFORMATION ON A SPECIFIC TOPIC PLEASE OPEN AN ISSUE!**
### resourceDeploymentTypes
This is the top contribution and must be an array of [ResourceType](#resourcetype) objects.
``` json
"resourceDeploymentTypes": [
{
... // Contributed type
},
{
... // Another contributed type
}
]
```
### ResourceType
The type is defined [here](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/interfaces.ts#L13).
There are a number of properties on each `ResourceType`.
`name` - The name of the type, this is not displayed to the user so should be a non-localized value and typically `-` delimited (e.g. `my-resource-type`)
`displayName` - The name of the type displayed to the user, this should be a localized string
`description` - The description of the type displayed to the user
`platforms` - The OS platforms that the type supports running on, options are `linux` (Linux distros), `darwin` (MacOS), `win32` (Windows) or`*` for all.
`icon` - The icon to display for the type - supports either single icon or separate ones for light and dark mode. The icon should be in `svg` format.
`options` - An array of [ResourceTypeOption](#resourcetypeoption) objects, allowing users to provide different sub-options for a given resource type. (e.g. the specific version of SQL Server to deploy)
`providers` - An array of [DeploymentProvider](#deploymentprovider) objects which define the wizards, dialogs or other means for a user to deploy their resource.
`agreements` - **OPTIONAL** An array of [AgreementInfo](#agreementinfo) objects which define any agreements the user must accept before proceeding with the deployment.
`displayIndex` - **OPTIONAL** A number corresponding to where the type should be displayed relative to the other types. A lower number means it will show up earlier in the list. Any types which don't specify this value will be shown last.
`okButtonText` - **OPTIONAL** The text to use for the `OK` button at the bottom of the Type Picker dialog. Default is `Select`.
`helpTexts` - **OPTIONAL** An array of strings to display to the user providing more information for the resource type (such as links to docs)
`tags` - **OPTIONAL** An array of strings that are used to indicate the category that the resource type belongs to. The usable tags are defined [here](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/constants.ts#L10).
### ResourceTypeOption
**TODO**
### DeploymentProvider
#### Provider Types
There are a number of different types of providers that can be used which affect what happens when the user selects that provider. These are indicated by what fields the provider contains - the provider is checked in order of top to bottom for each property and uses the first type that it finds in the properties for that provider.
`Notebook Wizard` - A wizard is opened that can be used to prompt the user for values and display information, and then at the very end will open the specified Notebook with those values injected in. Indicated by the presence of the `notebookWizard` property.
`Dialog` - A single page dialog is opened that can be used to prompt the user for values. Indicated by the presence of the `dialog` property.
`Notebook` - The specified Notebook is opened for the user to run. Indicated by the presence of the `notebook` property.
`Download` - An installer is downloaded and ran. Indicated by the presence of the `downloadUrl` property.
`Web Page` - The specified URL is opened in the default browser for the user. Indicated by the presence of the `webPageUrl` property.
`Command` - The specified command is executed. Indicated by the presence of the `command` property.
### AgreementInfo
**TODO**
### NotebookWizard (extends [WizardInfoBase](#wizardinfobase))
See [NotebookWizardInfo](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/interfaces.ts#L170) for how it's defined in code.
`notebook` - The path to the Python-based Notebook that is used as a template for the wizard.
`pages` - An array of [NotebookWizardPageInfo](#notebookwizardpageinfo) containing information for each page in the Notebook Wizard.
`codeCellInsertionPosition` - **OPTIONAL** The index of the code cell to insert the injected parameters cell. Default is 0.
### WizardInfoBase
`type` - **OPTIONAL** This is an internal type only used for BDC deployment wizards. Any other deployment providers can leave it out.
`doneAction`
`scriptAction` - **OPTIONAL**
`title`
`name` - **OPTIONAL**
`pages` - An array of the pages for this wizard. Each wizard implementation will usually have its own page type that extends [PageInfoBase](#pageinfobase).
`isSummaryPageAutoGenerated` - **OPTIONAL**
### NotebookWizardPageInfo (extends [PageInfoBase](#pageinfobase))
`description` - **OPTIONAL** The page description to display at the top of the page.
### PageInfoBase
`title` - The title to display for the page
`isSummaryPage` - **OPTIONAL** Whether this page is set as a summary page that displays a summary of the Note
`sections` - An array of [SectionInfo] objects containing the details of each section to display on this page.
### SectionInfo (extends [FieldInfoBase](#fieldinfobase))
`title` - **OPTIONAL** The title to display at the top of the section
`fields` - **OPTIONAL** An array of [FieldInfo](#fieldinfo) objects containing details for each field in this section.
`rows` - **OPTIONAL** Used for wide dialogs or wizards, the label for each field will be placed to the left of the field component.
`collapsible` - **OPTIONAL** Whether the section is collapsible or not. Default is `true`.
`collapsed` - **OPTIONAL** Whether the section starts off collapsed. Default is `false`.
`spaceBetweenFields` - **OPTIONAL** A string defining how much space should be between each field. Default is `50px`.
### FieldInfo
`subFields`
`type`
`defaultValue`
`confirmationRequired`
`confirmationLabel`
`min`
`max`
`required`
`options` - **REQUIRED** if `type` is `options`. See [Options](#options) for more information.
`placeHolder`
`description`
`labelCSSStyles`
`fontWeight`
`editable`
`enabled`
`dynamicOptions`
`isEvaluated`
`validations`
`valueProvider` - **OPTIONAL** If defined then the value for this field is retrieved using the specified [Value Provider](#value-provider).
#### Options
This defines the set of options for this field to display. There are a number of different ways to configure the set of options :
* String array (`string[]`) - A static list of values that will be shown as a dropdown. Default value selected is defined as `FieldInfo.defaultValue`.
* CategoryValue array (`azdata.CategoryValue[]`) - A static list of CategoryValue objects that will be shown as a dropdown. Each value will define a display name separate from its value - use this for values you want to display differently to the user (such as names for an Azure region).
* [OptionsInfo](#optionsinfo) - An object allowing more control over the option values.
See [sample-options](https://github.com/microsoft/azuredatastudio/blob/main/samples/sample-resource-deployment/package.json) for example implementations.
##### OptionsInfo
This object defines a set of options for a field, similar to the arrays that can be used for the [options](#options) field but with greater control over of the options. Currently there are two reasons that you would use this object over the arrays - either you want to display the options as something other than a dropdown or you wish to use an [Options Source Provider](#options-source-provider) to populate the options dynamically.
`values` - An array of either `strings` or `azdata.CategoryValue` objects. See [options](#options) for more details on each of those.
`defaultValue` - The string value of the default option to have selected
`optionsType` - How to display the options, either `radio` or `dropdown`
`source` - OPTIONAL If set defines the [Options Source Provider](#options-source-provider) to use for populating the options dynamically.
### Options Source Provider
### Value Provider
When a field specifies a value provider then it is saying that the value for that field is dynamic and will be retrieved from a value provider that is registered by an extension separately. This can be used for more complex logic such as running calculations, reading files, making web requests, etc.
See [sample-value-provider](https://github.com/microsoft/azuredatastudio/blob/main/samples/sample-resource-deployment/package.json) for an example implementation.
**NOTE** There is currently some behavior that should be known before using this :
1. The value providers are hooked up after all the components are made, so order doesn't generally matter (you don't have to define the trigger fields before the target field) when the values are on the same page.
2. If the fields are on different pages then currently the hookup logic is non-deterministic and so you may end up with trigger components not existing yet if they are on a different page which hasn't completed its initialization. **So currently having a value provider that has trigger fields on another page is not something officially supported. Contact the dev team if you need this for your scenario**
`providerId` - The string ID of this provider, this must be registered by an extension using [registerValueProvider](https://github.com/microsoft/azuredatastudio/blob/main/extensions/resource-deployment/src/typings/resource-deployment.d.ts#L47).
`triggerFields` - The field IDs (`variableName` or `label`) of the fields that - when changed - will trigger `getValue` to be called and the result set as the value of the dependent field. **NOTE** While `variableName` OR `label` is supported it is generally strongly suggested to use a `variableName` (even if you don't need that variable in the final deployment target) due to potential localization mismatches that could happen between the localized strings in the package.json and the ones used by the `valueProvider`.

View File

@@ -21,12 +21,6 @@
"type": "git",
"url": "https://github.com/Microsoft/azuredatastudio.git"
},
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"extensionDependencies": [
"microsoft.mssql",
"microsoft.notebook"

View File

@@ -307,7 +307,7 @@ export interface DynamicOptionsAlternates {
export interface ValueProviderInfo {
providerId: string,
triggerFields: string[]
triggerField: string
}
export interface FieldInfoBase {

View File

@@ -5,10 +5,10 @@
import * as azdata from 'azdata';
import 'mocha';
import { InputValueType } from 'resource-deployment';
import * as should from 'should';
import * as sinon from 'sinon';
import * as vscode from 'vscode';
import { InputValueType } from '../../../ui/modelViewUtils';
import { createValidation, GreaterThanOrEqualsValidation, IntegerValidation, LessThanOrEqualsValidation, RegexValidation, validateInputBoxComponent, Validation, ValidationType } from '../../../ui/validation/validations';
const inputBox = <azdata.InputBoxComponent>{

View File

@@ -24,19 +24,9 @@ declare module 'resource-deployment' {
getIsPassword?: (variableName: string) => boolean | Promise<boolean>;
}
export type InputValueType = string | number | boolean | undefined;
export interface IValueProvider {
/**
* The ID associated with this value provider. Fields use this ID in the package.json to indicate which provider to use to get the value for that field.
* Each ID must be globally unique - an error will be thrown if the same ID is already registered.
*/
readonly id: string,
/**
* Gets a calculated value based on the given input values.
* @param triggerValues A map of the trigger field names and their current values specified in the valueProvider field info
*/
getValue(triggerValues: {[key: string]: InputValueType}): Promise<InputValueType>;
getValue(triggerValue: string): Promise<string>;
}
/**
@@ -48,12 +38,6 @@ declare module 'resource-deployment' {
export interface IExtension {
registerOptionsSourceProvider(provider: IOptionsSourceProvider): vscode.Disposable,
/**
* Registers a value provider that resource deployment definitions can use to dynamically fetch the value for specified fields.
* @param provider The provider to register
* @returns A disposable is returned that will unregister the provider when is disposed - this should be used to ensure
* that the provider is unregistered when the extension is uninstalled/deactivated.
*/
registerValueProvider(provider: IValueProvider): vscode.Disposable
}
}

View File

@@ -7,7 +7,7 @@ import { azureResource } from 'azureResource';
import * as fs from 'fs';
import { EOL } from 'os';
import * as path from 'path';
import { InputValueType, IOptionsSourceProvider } from 'resource-deployment';
import { IOptionsSourceProvider } from 'resource-deployment';
import * as vscode from 'vscode';
import * as nls from 'vscode-nls';
import { getDateTimeString, getErrorMessage, isUserCancelledError, throwUnless } from '../common/utils';
@@ -33,6 +33,7 @@ const localize = nls.loadMessageBundle();
*/
export type Validator = () => { valid: boolean, message: string };
export type InputValueType = string | number | undefined;
export type InputComponent = azdata.TextComponent | azdata.InputBoxComponent | azdata.DropDownComponent | azdata.CheckBoxComponent | RadioGroupLoadingComponentBuilder;
export type InputComponentInfo<T extends InputComponent> = {
component: T;
@@ -470,35 +471,20 @@ async function hookUpValueProviders(context: WizardPageContext): Promise<void> {
if (field.valueProvider) {
const fieldKey = field.variableName || field.label;
const fieldComponent = context.inputComponents[fieldKey];
const targetComponent = context.inputComponents[field.valueProvider.triggerField];
if (!targetComponent) {
console.error(`Could not find target component ${field.valueProvider.triggerField} when hooking up value providers for ${field.label}`);
return;
}
const provider = await valueProviderService.getValueProvider(field.valueProvider.providerId);
let targetComponentLabelToComponent: { [label: string]: InputComponentInfo<InputComponent>; } = {};
field.valueProvider.triggerFields.forEach((triggerField) => {
const targetComponent = context.inputComponents[triggerField];
if (!targetComponent) {
console.error(`Could not find target component '${triggerField}' when hooking up value providers for '${field.label}'`);
return;
}
targetComponentLabelToComponent[triggerField] = targetComponent;
});
// If one triggerfield changes value, update the new field value.
const updateFields = async () => {
let targetComponentLabelToValue: { [label: string]: InputValueType; } = {};
for (let label in targetComponentLabelToComponent) {
targetComponentLabelToValue[label] = await targetComponentLabelToComponent[label].getValue();
}
let newFieldValue = await provider.getValue(targetComponentLabelToValue);
const targetComponentValue = await targetComponent.getValue();
const newFieldValue = await provider.getValue(targetComponentValue?.toString() ?? '');
fieldComponent.setValue(newFieldValue);
};
// Set the onValueChanged behavior for each component
for (let label in targetComponentLabelToComponent) {
context.onNewDisposableCreated(targetComponentLabelToComponent[label].onValueChanged(() => {
updateFields();
}));
}
targetComponent.onValueChanged(() => {
updateFields();
});
await updateFields();
}
}));
@@ -776,10 +762,7 @@ function processDropdownOptionsTypeField(context: FieldContext): azdata.DropDown
// Note we don't currently check that the value actually exists in the list - if it doesn't then it'll
// just default to the first one anyways
const initialValue = context.fieldInfo.variableName && context.initialVariableValues?.[context.fieldInfo.variableName]?.toString();
const optionValues = options.values;
// If we have an array of CategoryValues then find the option that matches the defaultValue specified - otherwise just use the defaultValue provided
const defaultValueOption = (optionValues && optionValues.length > 0 && typeof optionValues[0] === 'object') ? (optionValues as azdata.CategoryValue[]).find(v => v.name === options.defaultValue) : options.defaultValue;
const defaultValue = initialValue || defaultValueOption;
const defaultValue = initialValue || options.defaultValue;
const dropdown = createDropdownInputInfo(context.view, {
values: options.values,
defaultValue: defaultValue,
@@ -880,18 +863,6 @@ function processReadonlyTextField(context: FieldContext, allowEvaluation: boolea
const text = context.fieldInfo.defaultValue !== undefined
? createLabel(context.view, { text: context.fieldInfo.defaultValue, description: '', required: false, width: context.fieldInfo.inputWidth })
: undefined;
if (text) {
// If we created the text component then add it to our list of inputs so other fields can utilize it
const onChangedEmitter = new vscode.EventEmitter<void>(); // Stub event since we don't currently support updating this when the dependent fields change
context.onNewDisposableCreated(onChangedEmitter);
context.onNewInputComponentCreated(context.fieldInfo.variableName || context.fieldInfo.label, {
component: text,
getValue: async (): Promise<InputValueType> => typeof text.value === 'string' ? text.value : text.value?.join(EOL),
setValue: (value: InputValueType) => text.value = value?.toString(),
onValueChanged: onChangedEmitter.event,
});
}
addLabelInputPairToContainer(context.view, context.components, label, text, context.fieldInfo);
return { label: label, text: text };
}

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import { InputValueType } from 'resource-deployment';
import * as vscode from 'vscode';
import { isUndefinedOrEmpty, throwUnless } from '../../common/utils';
import { InputValueType } from '../modelViewUtils';
export interface ValidationResult {
valid: boolean;

View File

@@ -2,7 +2,7 @@
"name": "schema-compare",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.13.0",
"version": "1.12.0",
"publisher": "Microsoft",
"preview": false,
"engines": {
@@ -23,12 +23,6 @@
"extensionDependencies": [
"Microsoft.mssql"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"commands": [
{

View File

@@ -9,7 +9,7 @@ import * as loc from '../localizedConstants';
import * as path from 'path';
import { SchemaCompareMainWindow } from '../schemaCompareMainWindow';
import { TelemetryReporter, TelemetryViews } from '../telemetry';
import { getEndpointName, getRootPath, exists, getAzdataApi, getSchemaCompareEndpointString } from '../utils';
import { getEndpointName, getRootPath, exists } from '../utils';
import * as mssql from '../../../mssql';
const titleFontSize: number = 13;
@@ -18,16 +18,13 @@ interface Deferred<T> {
resolve: (result: T | Promise<T>) => void;
reject: (reason: any) => void;
}
export class SchemaCompareDialog {
public dialog: azdata.window.Dialog;
public dialogName: string;
private schemaCompareTab: azdata.window.DialogTab;
private sourceDacpacRadioButton: azdata.RadioButtonComponent;
private sourceDatabaseRadioButton: azdata.RadioButtonComponent;
private sourceProjectRadioButton: azdata.RadioButtonComponent;
private schemaCompareTab: azdata.window.DialogTab;
private sourceDacpacComponent: azdata.FormComponent;
private sourceProjectFilePathComponent: azdata.FormComponent;
private sourceTextBox: azdata.InputBoxComponent;
private sourceFileButton: azdata.ButtonComponent;
private sourceServerComponent: azdata.FormComponent;
@@ -35,30 +32,22 @@ export class SchemaCompareDialog {
private sourceConnectionButton: azdata.ButtonComponent;
private sourceDatabaseComponent: azdata.FormComponent;
private sourceDatabaseDropdown: azdata.DropDownComponent;
private sourceEndpointType: mssql.SchemaCompareEndpointType;
private sourceDbEditable: string;
private sourceDacpacPath: string;
private sourceProjectFilePath: string;
private targetDacpacComponent: azdata.FormComponent;
private targetProjectFilePathComponent: azdata.FormComponent;
private targetProjectStructureComponent: azdata.FormComponent;
private targetTextBox: azdata.InputBoxComponent;
private targetFileButton: azdata.ButtonComponent;
private targetStructureDropdown: azdata.DropDownComponent;
private targetServerComponent: azdata.FormComponent;
protected targetServerDropdown: azdata.DropDownComponent;
private targetConnectionButton: azdata.ButtonComponent;
private targetDatabaseComponent: azdata.FormComponent;
private targetDatabaseDropdown: azdata.DropDownComponent;
private targetDacpacPath: string;
private targetProjectFilePath: string;
private targetEndpointType: mssql.SchemaCompareEndpointType;
private formBuilder: azdata.FormBuilder;
private sourceIsDacpac: boolean;
private targetIsDacpac: boolean;
private connectionId: string;
private sourceDbEditable: string;
private targetDbEditable: string;
private previousSource: mssql.SchemaCompareEndpointInfo;
private previousTarget: mssql.SchemaCompareEndpointInfo;
private formBuilder: azdata.FormBuilder;
private connectionId: string;
private toDispose: vscode.Disposable[] = [];
private initDialogComplete: Deferred<void>;
private initDialogPromise: Promise<void> = new Promise<void>((resolve, reject) => this.initDialogComplete = { resolve, reject });
@@ -70,11 +59,6 @@ export class SchemaCompareDialog {
constructor(private schemaCompareMainWindow: SchemaCompareMainWindow, private view?: azdata.ModelView, private extensionContext?: vscode.ExtensionContext) {
this.previousSource = schemaCompareMainWindow.sourceEndpointInfo;
this.previousTarget = schemaCompareMainWindow.targetEndpointInfo;
this.dialog = azdata.window.createModelViewDialog(loc.SchemaCompareLabel);
this.dialog.registerCloseValidator(async () => {
return this.validate();
});
}
protected async initializeDialog(): Promise<void> {
@@ -95,17 +79,27 @@ export class SchemaCompareDialog {
this.dialog.okButton.label = loc.OkButtonText;
this.dialog.okButton.enabled = false;
this.toDispose.push(this.dialog.okButton.onClick(async () => await this.handleOkButtonClick()));
this.dialog.okButton.onClick(async () => await this.execute());
this.dialog.cancelButton.label = loc.CancelButtonText;
this.toDispose.push(this.dialog.cancelButton.onClick(async () => await this.cancel()));
this.dialog.cancelButton.onClick(async () => await this.cancel());
azdata.window.openDialog(this.dialog);
await this.initDialogPromise;
}
public async execute(): Promise<void> {
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Database) {
if (this.sourceIsDacpac) {
this.schemaCompareMainWindow.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: this.sourceTextBox.value,
connectionDetails: undefined
};
} else {
const sourceServerDropdownValue = this.sourceServerDropdown.value as ConnectionDropdownValue;
const ownerUri = await azdata.connection.getUriForConnection(sourceServerDropdownValue.connection.connectionId);
@@ -115,45 +109,23 @@ export class SchemaCompareDialog {
serverName: sourceServerDropdownValue.name,
databaseName: this.sourceDatabaseDropdown.value.toString(),
ownerUri: ownerUri,
projectFilePath: '',
targetScripts: [],
folderStructure: '',
packageFilePath: '',
dataSchemaProvider: '',
connectionDetails: undefined,
connectionName: sourceServerDropdownValue.connection.options.connectionName
};
} else if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.schemaCompareMainWindow.sourceEndpointInfo = {
}
if (this.targetIsDacpac) {
this.schemaCompareMainWindow.targetEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
targetScripts: [],
folderStructure: '',
dataSchemaProvider: '',
packageFilePath: this.sourceTextBox.value,
packageFilePath: this.targetTextBox.value,
connectionDetails: undefined
};
} else {
this.schemaCompareMainWindow.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
projectFilePath: this.sourceTextBox.value,
targetScripts: await this.getTargetScripts(true),
dataSchemaProvider: await this.getDsp(this.sourceTextBox.value),
folderStructure: '',
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined
};
}
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Database) {
const targetServerDropdownValue = this.targetServerDropdown.value as ConnectionDropdownValue;
const ownerUri = await azdata.connection.getUriForConnection(targetServerDropdownValue.connection.connectionId);
@@ -163,48 +135,16 @@ export class SchemaCompareDialog {
serverName: targetServerDropdownValue.name,
databaseName: this.targetDatabaseDropdown.value.toString(),
ownerUri: ownerUri,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
packageFilePath: '',
dataSchemaProvider: '',
connectionDetails: undefined,
connectionName: targetServerDropdownValue.connection.options.connectionName
};
} else if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.schemaCompareMainWindow.targetEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
packageFilePath: this.targetTextBox.value,
connectionDetails: undefined
};
} else {
this.schemaCompareMainWindow.targetEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
projectFilePath: this.targetTextBox.value,
folderStructure: this.targetStructureDropdown!.value as string,
targetScripts: await this.getTargetScripts(false),
dataSchemaProvider: await this.getDsp(this.targetTextBox.value),
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined
};
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareDialog, 'SchemaCompareStart')
.withAdditionalProperties({
sourceEndpointType: getSchemaCompareEndpointString(this.sourceEndpointType),
targetEndpointType: getSchemaCompareEndpointString(this.targetEndpointType)
sourceIsDacpac: this.sourceIsDacpac.toString(),
targetIsDacpac: this.targetIsDacpac.toString()
}).send();
// update source and target values that are displayed
@@ -242,7 +182,6 @@ export class SchemaCompareDialog {
}
protected async cancel(): Promise<void> {
this.dispose();
}
private async initializeSchemaCompareTab(): Promise<void> {
@@ -251,67 +190,36 @@ export class SchemaCompareDialog {
this.view = view;
}
let sourceValue = '';
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
sourceValue = this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath;
} else if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
sourceValue = this.schemaCompareMainWindow.sourceEndpointInfo.projectFilePath;
}
this.sourceTextBox = this.view.modelBuilder.inputBox().withProps({
value: sourceValue,
value: this.schemaCompareMainWindow.sourceEndpointInfo ? this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath : '',
width: this.textBoxWidth,
ariaLabel: loc.sourceFile
}).component();
this.sourceTextBox.onTextChanged(async (e) => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.sourceDacpacPath = e;
} else if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project) {
this.sourceProjectFilePath = e;
}
});
let targetValue = '';
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
targetValue = this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath;
} else if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
targetValue = this.schemaCompareMainWindow.targetEndpointInfo.projectFilePath;
}
this.targetTextBox = this.view.modelBuilder.inputBox().withProps({
value: targetValue,
value: this.schemaCompareMainWindow.targetEndpointInfo ? this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath : '',
width: this.textBoxWidth,
ariaLabel: loc.targetFile
}).component();
this.targetTextBox.onTextChanged(async (e) => {
this.targetTextBox.onTextChanged(async () => {
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
this.targetDacpacPath = e;
} else if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project) {
this.targetProjectFilePath = e;
}
});
this.sourceServerComponent = this.createSourceServerDropdown();
this.sourceDatabaseComponent = this.createSourceDatabaseDropdown();
this.targetServerComponent = this.createTargetServerDropdown();
this.targetDatabaseComponent = this.createTargetDatabaseDropdown();
this.sourceDacpacComponent = this.createFileBrowser(false, true, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetDacpacComponent = this.createFileBrowser(true, true, this.schemaCompareMainWindow.targetEndpointInfo);
this.sourceProjectFilePathComponent = this.createFileBrowser(false, false, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetProjectFilePathComponent = this.createFileBrowser(true, false, this.schemaCompareMainWindow.targetEndpointInfo);
this.targetProjectStructureComponent = this.createStructureDropdown();
this.sourceDacpacComponent = this.createFileBrowser(false, this.schemaCompareMainWindow.sourceEndpointInfo);
this.targetDacpacComponent = this.createFileBrowser(true, this.schemaCompareMainWindow.targetEndpointInfo);
let sourceRadioButtons = this.createSourceRadioButtons();
let targetRadioButtons = this.createTargetRadioButtons();
@@ -319,37 +227,31 @@ export class SchemaCompareDialog {
let sourceComponents = [];
let targetComponents = [];
// start source and target with either dacpac, database, or project selection based on what the previous value was
sourceComponents = [sourceRadioButtons];
switch (this.sourceEndpointType) {
case mssql.SchemaCompareEndpointType.Database:
sourceComponents.push(
this.sourceServerComponent,
this.sourceDatabaseComponent);
break;
case mssql.SchemaCompareEndpointType.Dacpac:
sourceComponents.push(this.sourceDacpacComponent);
break;
case mssql.SchemaCompareEndpointType.Project:
sourceComponents.push(this.sourceProjectFilePathComponent);
break;
// start source and target with either dacpac or database selection based on what the previous value was
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
sourceComponents = [
sourceRadioButtons,
this.sourceServerComponent,
this.sourceDatabaseComponent
];
} else {
sourceComponents = [
sourceRadioButtons,
this.sourceDacpacComponent,
];
}
targetComponents = [targetRadioButtons];
switch (this.targetEndpointType) {
case mssql.SchemaCompareEndpointType.Database:
targetComponents.push(
this.targetServerComponent,
this.targetDatabaseComponent);
break;
case mssql.SchemaCompareEndpointType.Dacpac:
targetComponents.push(this.targetDacpacComponent);
break;
case mssql.SchemaCompareEndpointType.Project:
targetComponents.push(this.targetProjectFilePathComponent);
break;
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
targetComponents = [
targetRadioButtons,
this.targetServerComponent,
this.targetDatabaseComponent
];
} else {
targetComponents = [
targetRadioButtons,
this.targetDacpacComponent,
];
}
this.formBuilder = <azdata.FormBuilder>this.view.modelBuilder.formContainer()
@@ -372,26 +274,17 @@ export class SchemaCompareDialog {
let formModel = this.formBuilder.component();
await this.view.initializeModel(formModel);
switch (this.sourceEndpointType) {
case (mssql.SchemaCompareEndpointType.Database):
await this.sourceDatabaseRadioButton.focus();
break;
case (mssql.SchemaCompareEndpointType.Dacpac):
await this.sourceDacpacRadioButton.focus();
break;
case (mssql.SchemaCompareEndpointType.Project):
await this.sourceProjectRadioButton.focus();
break;
if (this.sourceIsDacpac) {
await this.sourceDacpacRadioButton.focus();
} else {
await this.sourceDatabaseRadioButton.focus();
}
this.initDialogComplete.resolve();
});
}
private createFileBrowser(isTarget: boolean, dacpac: boolean, endpoint: mssql.SchemaCompareEndpointInfo): azdata.FormComponent {
private createFileBrowser(isTarget: boolean, endpoint: mssql.SchemaCompareEndpointInfo): azdata.FormComponent {
let currentTextbox = isTarget ? this.targetTextBox : this.sourceTextBox;
if (isTarget) {
this.targetFileButton = this.view.modelBuilder.button().withProps({
title: loc.selectTargetFile,
@@ -409,9 +302,8 @@ export class SchemaCompareDialog {
}
let currentButton = isTarget ? this.targetFileButton : this.sourceFileButton;
const filter = dacpac ? 'dacpac' : 'sqlproj';
currentButton.onDidClick(async () => {
currentButton.onDidClick(async (click) => {
// file browser should open where the current dacpac is or the appropriate default folder
let rootPath = getRootPath();
let defaultUri = endpoint && endpoint.packageFilePath && await exists(endpoint.packageFilePath) ? endpoint.packageFilePath : rootPath;
@@ -424,7 +316,7 @@ export class SchemaCompareDialog {
defaultUri: vscode.Uri.file(defaultUri),
openLabel: loc.open,
filters: {
'Files': [filter],
'dacpac Files': ['dacpac'],
}
}
);
@@ -444,22 +336,6 @@ export class SchemaCompareDialog {
};
}
private createStructureDropdown(): azdata.FormComponent {
this.targetStructureDropdown = this.view.modelBuilder.dropDown().withProps({
editable: true,
fireOnTextChange: true,
ariaLabel: loc.targetStructure,
width: this.textBoxWidth,
values: [loc.file, loc.flat, loc.objectType, loc.schema, loc.schemaObjectType],
value: loc.schemaObjectType,
}).component();
return {
component: this.targetStructureDropdown,
title: loc.StructureDropdownLabel,
};
}
private createSourceRadioButtons(): azdata.FormComponent {
this.sourceDacpacRadioButton = this.view.modelBuilder.radioButton()
.withProps({
@@ -473,69 +349,36 @@ export class SchemaCompareDialog {
label: loc.DatabaseRadioButtonLabel
}).component();
this.sourceProjectRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'source',
label: loc.ProjectRadioButtonLabel
}).component();
// show dacpac file browser
this.sourceDacpacRadioButton.onDidClick(async () => {
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
this.sourceTextBox.value = this.sourceDacpacPath;
this.sourceIsDacpac = true;
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.removeFormItem(this.sourceProjectFilePathComponent);
this.formBuilder.insertFormItem(this.sourceDacpacComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns
this.sourceDatabaseRadioButton.onDidClick(async () => {
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Database;
this.sourceIsDacpac = false;
this.formBuilder.insertFormItem(this.sourceServerComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.insertFormItem(this.sourceDatabaseComponent, 3, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
this.formBuilder.removeFormItem(this.sourceProjectFilePathComponent);
await this.populateServerDropdown(false);
});
// show project directory browser
this.sourceProjectRadioButton.onDidClick(async () => {
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Project;
this.sourceTextBox.value = this.sourceProjectFilePath;
this.formBuilder.removeFormItem(this.sourceServerComponent);
this.formBuilder.removeFormItem(this.sourceDatabaseComponent);
this.formBuilder.removeFormItem(this.sourceDacpacComponent);
this.formBuilder.insertFormItem(this.sourceProjectFilePathComponent, 2, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.sourceEndpointType = this.schemaCompareMainWindow.sourceEndpointInfo?.endpointType ?? mssql.SchemaCompareEndpointType.Database; // default to database if no specific source is passed
switch (this.sourceEndpointType) {
case mssql.SchemaCompareEndpointType.Dacpac:
this.sourceDacpacRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Project:
this.sourceProjectRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Database:
this.sourceDatabaseRadioButton.checked = true;
break;
// if source is currently a db, show it in the server and db dropdowns
if (this.schemaCompareMainWindow.sourceEndpointInfo && this.schemaCompareMainWindow.sourceEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.sourceDatabaseRadioButton.checked = true;
this.sourceIsDacpac = false;
} else {
this.sourceDacpacRadioButton.checked = true;
this.sourceIsDacpac = true;
}
let radioButtons = [this.sourceDatabaseRadioButton, this.sourceDacpacRadioButton];
// TODO: re-add once database projects changes are checked in; chicken-and-egg problem (https://github.com/microsoft/azuredatastudio/pull/17738)
// if (vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId)) {
// radioButtons.push(this.sourceProjectRadioButton);
// }
let flexRadioButtonsModel = this.view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'column' })
.withItems(radioButtons)
.withItems([this.sourceDacpacRadioButton, this.sourceDatabaseRadioButton])
.withProps({ ariaRole: 'radiogroup' })
.component();
@@ -546,85 +389,50 @@ export class SchemaCompareDialog {
}
private createTargetRadioButtons(): azdata.FormComponent {
let targetDacpacRadioButton = this.view.modelBuilder.radioButton()
let dacpacRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.DacpacRadioButtonLabel
}).component();
let targetDatabaseRadioButton = this.view.modelBuilder.radioButton()
let databaseRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.DatabaseRadioButtonLabel
}).component();
let targetProjectRadioButton = this.view.modelBuilder.radioButton()
.withProps({
name: 'target',
label: loc.ProjectRadioButtonLabel
}).component();
// show dacpac file browser
targetDacpacRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
this.targetTextBox.value = this.targetDacpacPath;
dacpacRadioButton.onDidClick(async () => {
this.targetIsDacpac = true;
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.removeFormItem(this.targetProjectFilePathComponent);
this.formBuilder.removeFormItem(this.targetProjectStructureComponent);
this.formBuilder.addFormItem(this.targetDacpacComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
// show server and db dropdowns
targetDatabaseRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Database;
databaseRadioButton.onDidClick(async () => {
this.targetIsDacpac = false;
this.formBuilder.removeFormItem(this.targetDacpacComponent);
this.formBuilder.removeFormItem(this.targetProjectFilePathComponent);
this.formBuilder.removeFormItem(this.targetProjectStructureComponent);
this.formBuilder.addFormItem(this.targetServerComponent, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.addFormItem(this.targetDatabaseComponent, { horizontal: true, titleFontSize: titleFontSize });
await this.populateServerDropdown(true);
});
// show project directory browser
targetProjectRadioButton.onDidClick(async () => {
this.targetEndpointType = mssql.SchemaCompareEndpointType.Project;
this.targetTextBox.value = this.targetProjectFilePath;
this.formBuilder.removeFormItem(this.targetServerComponent);
this.formBuilder.removeFormItem(this.targetDatabaseComponent);
this.formBuilder.removeFormItem(this.targetDacpacComponent);
this.formBuilder.addFormItem(this.targetProjectFilePathComponent, { horizontal: true, titleFontSize: titleFontSize });
this.formBuilder.addFormItem(this.targetProjectStructureComponent, { horizontal: true, titleFontSize: titleFontSize });
this.dialog.okButton.enabled = await this.shouldEnableOkayButton();
});
this.targetEndpointType = this.schemaCompareMainWindow.targetEndpointInfo?.endpointType ?? mssql.SchemaCompareEndpointType.Database; // default to database if no specific target is passed
switch (this.targetEndpointType) {
case mssql.SchemaCompareEndpointType.Dacpac:
targetDacpacRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Project:
targetProjectRadioButton.checked = true;
break;
case mssql.SchemaCompareEndpointType.Database:
targetDatabaseRadioButton.checked = true;
break;
// if target is currently a db, show it in the server and db dropdowns
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
databaseRadioButton.checked = true;
this.targetIsDacpac = false;
} else {
dacpacRadioButton.checked = true;
this.targetIsDacpac = true;
}
let radioButtons = [targetDatabaseRadioButton, targetDacpacRadioButton];
// TODO: re-add once database projects changes are checked in; chicken-and-egg problem (https://github.com/microsoft/azuredatastudio/pull/17738)
// if (vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId)) {
// radioButtons.push(targetProjectRadioButton);
// }
let flexRadioButtonsModel = this.view.modelBuilder.flexContainer()
.withLayout({ flexFlow: 'column' })
.withItems(radioButtons)
.withItems([dacpacRadioButton, databaseRadioButton]
)
.withProps({ ariaRole: 'radiogroup' })
.component();
@@ -635,83 +443,18 @@ export class SchemaCompareDialog {
}
private async shouldEnableOkayButton(): Promise<boolean> {
let sourcefilled = (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac && await this.existsDacpac(this.sourceTextBox.value))
|| (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project && this.existsProjectFile(this.sourceTextBox.value))
|| (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Database && !isNullOrUndefined(this.sourceDatabaseDropdown.value) && this.sourceDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.sourceDbEditable)) !== -1);
let targetfilled = (this.targetEndpointType === mssql.SchemaCompareEndpointType.Dacpac && await this.existsDacpac(this.targetTextBox.value))
|| (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project && this.existsProjectFile(this.targetTextBox.value))
|| (this.targetEndpointType === mssql.SchemaCompareEndpointType.Database && !isNullOrUndefined(this.targetDatabaseDropdown.value) && this.targetDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.targetDbEditable)) !== -1);
let sourcefilled = (this.sourceIsDacpac && await this.existsDacpac(this.sourceTextBox.value))
|| (!this.sourceIsDacpac && !isNullOrUndefined(this.sourceDatabaseDropdown.value) && this.sourceDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.sourceDbEditable)) !== -1);
let targetfilled = (this.targetIsDacpac && await this.existsDacpac(this.targetTextBox.value))
|| (!this.targetIsDacpac && !isNullOrUndefined(this.targetDatabaseDropdown.value) && this.targetDatabaseDropdown.values.findIndex(x => this.matchesValue(x, this.targetDbEditable)) !== -1);
return sourcefilled && targetfilled;
}
public async handleOkButtonClick(): Promise<void> {
await this.execute();
this.dispose();
}
protected showErrorMessage(message: string): void {
this.dialog.message = {
text: message,
level: getAzdataApi()!.window.MessageLevel.Error
};
}
async validate(): Promise<boolean> {
try {
// check project extension is installed
if (!vscode.extensions.getExtension(loc.sqlDatabaseProjectExtensionId) &&
(this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project ||
this.targetEndpointType === mssql.SchemaCompareEndpointType.Project)) {
this.showErrorMessage(loc.noProjectExtension);
return false;
}
// check Database Schema Providers are set and valid
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Project) {
try {
await this.getDsp(this.sourceTextBox.value);
} catch (err) {
this.showErrorMessage(loc.dspErrorSource);
}
}
if (this.targetEndpointType === mssql.SchemaCompareEndpointType.Project) {
try {
await this.getDsp(this.targetTextBox.value);
} catch (err) {
this.showErrorMessage(loc.dspErrorTarget);
}
}
return true;
} catch (e) {
this.showErrorMessage(e?.message ? e.message : e);
return false;
}
}
private dispose(): void {
this.toDispose.forEach(disposable => disposable.dispose());
}
private async existsDacpac(filename: string): Promise<boolean> {
return !isNullOrUndefined(filename) && await exists(filename) && (filename.toLocaleLowerCase().endsWith('.dacpac'));
}
private async existsProjectFile(filename: string): Promise<boolean> {
return !isNullOrUndefined(filename) && await exists(filename) && (filename.toLocaleLowerCase().endsWith('.sqlproj'));
}
private async getTargetScripts(source: boolean): Promise<string[]> {
const projectFilePath = source ? this.sourceTextBox.value : this.targetTextBox.value;
return await vscode.commands.executeCommand(loc.sqlDatabaseProjectsGetTargetScripts, projectFilePath);
}
private async getDsp(projectFilePath: string): Promise<string> {
return await vscode.commands.executeCommand(loc.sqlDatabaseProjectsGetDsp, projectFilePath);
}
protected createSourceServerDropdown(): azdata.FormComponent {
this.sourceServerDropdown = this.view.modelBuilder.dropDown().withProps(
{
@@ -781,7 +524,9 @@ export class SchemaCompareDialog {
width: this.textBoxWidth
}
).component();
this.targetConnectionButton = this.createConnectionButton(true);
this.targetServerDropdown.onValueChanged(async (value) => {
if (value.selected && this.targetServerDropdown.values.findIndex(x => this.matchesValue(x, value.selected)) === -1) {
await this.targetDatabaseDropdown.updateProperties({
@@ -794,8 +539,10 @@ export class SchemaCompareDialog {
await this.populateDatabaseDropdown((this.targetServerDropdown.value as ConnectionDropdownValue).connection, true);
}
});
// don't await so that dialog loading won't be blocked. Dropdown will show loading indicator until it is populated
this.populateServerDropdown(true);
return {
component: this.targetServerDropdown,
title: loc.ServerDropdownLabel,

View File

@@ -7,7 +7,7 @@ import * as vscode from 'vscode';
import { SchemaCompareMainWindow } from './schemaCompareMainWindow';
export async function activate(extensionContext: vscode.ExtensionContext): Promise<void> {
vscode.commands.registerCommand('schemaCompare.start', async (sourceContext: any, targetContext: any = undefined, comparisonResult: any = undefined) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(sourceContext, targetContext, comparisonResult); });
vscode.commands.registerCommand('schemaCompare.start', async (context: any) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(context); });
}
export function deactivate(): void {

View File

@@ -14,11 +14,9 @@ export const TargetTitle: string = localize('schemaCompareDialog.TargetTitle', "
export const FileTextBoxLabel: string = localize('schemaCompareDialog.fileTextBoxLabel', "File");
export const DacpacRadioButtonLabel: string = localize('schemaCompare.dacpacRadioButtonLabel', "Data-tier Application File (.dacpac)");
export const DatabaseRadioButtonLabel: string = localize('schemaCompare.databaseButtonLabel', "Database");
export const ProjectRadioButtonLabel: string = localize('schemaCompare.projectButtonLabel', "Database Project");
export const RadioButtonsLabel: string = localize('schemaCompare.radioButtonsLabel', "Type");
export const ServerDropdownLabel: string = localize('schemaCompareDialog.serverDropdownTitle', "Server");
export const DatabaseDropdownLabel: string = localize('schemaCompareDialog.databaseDropdownTitle', "Database");
export const StructureDropdownLabel: string = localize('schemaCompareDialog.structureDropdownLabel', "Folder Structure");
export const SchemaCompareLabel: string = localize('schemaCompare.dialogTitle', "Schema Compare");
export const differentSourceMessage: string = localize('schemaCompareDialog.differentSourceMessage', "A different source schema has been selected. Compare to see the comparison?");
export const differentTargetMessage: string = localize('schemaCompareDialog.differentTargetMessage', "A different target schema has been selected. Compare to see the comparison?");
@@ -33,12 +31,6 @@ export const sourceServer: string = localize('schemaCompareDialog.sourceServerDr
export const targetServer: string = localize('schemaCompareDialog.targetServerDropdown', "Target Server");
export const defaultText: string = localize('schemaCompareDialog.defaultUser', "default");
export const open: string = localize('schemaCompare.openFile', "Open");
export const targetStructure = localize('targetStructure', "Target Folder Structure");
export const file = localize('file', "File");
export const flat = localize('flat', "Flat");
export const objectType = localize('objectType', "Object Type");
export const schema = localize('schema', "Schema");
export const schemaObjectType = localize('schemaObjectType', "Schema/Object Type");
export const selectSourceFile: string = localize('schemaCompare.selectSourceFile', "Select source file");
export const selectTargetFile: string = localize('schemaCompare.selectTargetFile', "Select target file");
export const ResetButtonText: string = localize('SchemaCompareOptionsDialog.Reset', "Reset");
@@ -69,7 +61,7 @@ export const include: string = localize('schemaCompare.includeColumnName', "Incl
export const action: string = localize('schemaCompare.actionColumn', "Action");
export const targetName: string = localize('schemaCompare.targetNameColumn', "Target Name");
export const generateScriptDisabled: string = localize('schemaCompare.generateScriptButtonDisabledTitle', "Generate script is enabled when the target is a database");
export const applyDisabled: string = localize('schemaCompare.applyButtonDisabledTitle', "Apply is enabled when the target is a database or database project");
export const applyDisabled: string = localize('schemaCompare.applyButtonDisabledTitle', "Apply is enabled when the target is a database");
export function cannotExcludeMessageDependent(diffEntryName: string, firstDependentName: string): string { return localize('schemaCompare.cannotExcludeMessageWithDependent', "Cannot exclude {0}. Included dependents exist, such as {1}", diffEntryName, firstDependentName); }
export function cannotIncludeMessageDependent(diffEntryName: string, firstDependentName: string): string { return localize('schemaCompare.cannotIncludeMessageWithDependent', "Cannot include {0}. Excluded dependents exist, such as {1}", diffEntryName, firstDependentName); }
export function cannotExcludeMessage(diffEntryName: string): string { return localize('schemaCompare.cannotExcludeMessage', "Cannot exclude {0}. Included dependents exist", diffEntryName); }
@@ -326,20 +318,3 @@ export function cancelErrorMessage(errorMessage: string): string { return locali
export function generateScriptErrorMessage(errorMessage: string): string { return localize('schemaCompare.generateScriptErrorMessage', "Generate script failed: '{0}'", (errorMessage) ? errorMessage : 'Unknown'); }
export function applyErrorMessage(errorMessage: string): string { return localize('schemaCompare.updateErrorMessage', "Schema Compare Apply failed '{0}'", errorMessage ? errorMessage : 'Unknown'); }
export function openScmpErrorMessage(errorMessage: string): string { return localize('schemaCompare.openScmpErrorMessage', "Open scmp failed: '{0}'", (errorMessage) ? errorMessage : 'Unknown'); }
export const applyError: string = localize('schemaCompare.applyError', "There was an error updating the project");
export const dspErrorSource: string = localize('schemaCompareDialog.dspErrorSource', "The source .sqlproj file does not specify a database schema component");
export const dspErrorTarget: string = localize('schemaCompareDialog.dspErrorTarget', "The target .sqlproj file does not specify a database schema component");
export const noProjectExtension: string = localize('schemaCompareDialog.noProjectExtension', "The sql-database-projects extension is required to perform schema comparison with database projects");
export const noProjectExtensionApply: string = localize('schemaCompareDialog.noProjectExtensionApply', "The sql-database-projects extension is required to apply changes to a project");
// Information messages
export const applySuccess: string = localize('schemaCompare.applySuccess', "Project was successfully updated");
// Extensions
export const sqlDatabaseProjectExtensionId: string = 'microsoft.sql-database-projects';
// Commands
export const sqlDatabaseProjectsGetTargetScripts: string = 'sqlDatabaseProjects.schemaCompareGetTargetScripts';
export const sqlDatabaseProjectsGetDsp: string = 'sqlDatabaseProjects.schemaCompareGetDsp';
export const sqlDatabaseProjectsPublishChanges: string = 'sqlDatabaseProjects.schemaComparePublishProjectChanges';
export const sqlDatabaseProjectsShowProjectsView: string = 'sqlDatabaseProjects.schemaCompareShowProjectsView';

View File

@@ -11,7 +11,7 @@ import * as mssql from '../../mssql';
import * as loc from './localizedConstants';
import { SchemaCompareOptionsDialog } from './dialogs/schemaCompareOptionsDialog';
import { TelemetryReporter, TelemetryViews } from './telemetry';
import { getTelemetryErrorType, getEndpointName, verifyConnectionAndGetOwnerUri, getRootPath, getSchemaCompareEndpointString } from './utils';
import { getTelemetryErrorType, getEndpointName, verifyConnectionAndGetOwnerUri, getRootPath } from './utils';
import { SchemaCompareDialog } from './dialogs/schemaCompareDialog';
import { isNullOrUndefined } from 'util';
@@ -81,33 +81,14 @@ export class SchemaCompareMainWindow {
this.editor = azdata.workspace.createModelViewEditor(loc.SchemaCompareLabel, { retainContextWhenHidden: true, supportsSave: true, resourceName: schemaCompareResourceName }, 'SchemaCompareEditor');
}
// schema compare can get started with four contexts for the source:
// schema compare can get started with three contexts for the source:
// 1. undefined
// 2. connection profile
// 3. dacpac
// 4. project
public async start(sourceContext: any, targetContext: mssql.SchemaCompareEndpointInfo = undefined, comparisonResult: mssql.SchemaCompareResult = undefined): Promise<void> {
const targetIsSetAsProject: boolean = targetContext && targetContext.endpointType === mssql.SchemaCompareEndpointType.Project;
// if schema compare was launched from a db or a connection profile, set that as the source
let profile: azdata.IConnectionProfile;
if (targetIsSetAsProject) {
profile = sourceContext;
this.targetEndpointInfo = targetContext;
} else {
profile = sourceContext ? <azdata.IConnectionProfile>sourceContext.connectionProfile : undefined;
}
let sourceDacpac = undefined;
let sourceProject = undefined;
if (!profile && sourceContext as string && (sourceContext as string).endsWith('.dacpac')) {
sourceDacpac = sourceContext as string;
} else if (!profile) {
sourceProject = sourceContext as string;
}
public async start(context: any): Promise<void> {
// if schema compare was launched from a db, set that as the source
let profile = context ? <azdata.IConnectionProfile>context.connectionProfile : undefined;
let sourceDacpac = context as string;
if (profile) {
let ownerUri = await azdata.connection.getUriForConnection((profile.id));
let usr = profile.userName;
@@ -123,11 +104,7 @@ export class SchemaCompareMainWindow {
ownerUri: ownerUri,
packageFilePath: '',
connectionDetails: undefined,
connectionName: profile.connectionName,
projectFilePath: '',
targetScripts: [],
dataSchemaProvider: '',
folderStructure: ''
connectionName: profile.connectionName
};
} else if (sourceDacpac) {
this.sourceEndpointInfo = {
@@ -137,25 +114,7 @@ export class SchemaCompareMainWindow {
databaseName: '',
ownerUri: '',
packageFilePath: sourceDacpac,
connectionDetails: undefined,
projectFilePath: '',
targetScripts: [],
dataSchemaProvider: '',
folderStructure: ''
};
} else if (sourceProject) {
this.sourceEndpointInfo = {
endpointType: mssql.SchemaCompareEndpointType.Project,
packageFilePath: '',
serverDisplayName: '',
serverName: '',
databaseName: '',
ownerUri: '',
connectionDetails: undefined,
projectFilePath: sourceProject,
targetScripts: [],
dataSchemaProvider: undefined,
folderStructure: ''
connectionDetails: undefined
};
}
@@ -164,10 +123,6 @@ export class SchemaCompareMainWindow {
this.registerContent(),
this.editor.openEditor()
]);
if (targetIsSetAsProject) {
await this.execute(comparisonResult);
}
}
private async registerContent(): Promise<void> {
@@ -207,8 +162,7 @@ export class SchemaCompareMainWindow {
this.createSourceAndTargetButtons();
this.sourceName = getEndpointName(this.sourceEndpointInfo);
this.targetName = getEndpointName(this.targetEndpointInfo);
this.targetName = ' ';
this.sourceNameComponent = this.view.modelBuilder.inputBox().withProps({
value: this.sourceName,
title: this.sourceName,
@@ -321,44 +275,34 @@ export class SchemaCompareMainWindow {
this.deploymentOptions = deploymentOptions;
}
public async execute(comparisonResult: mssql.SchemaCompareCompletionResult = undefined) {
public async execute() {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
const service = await this.getService();
if (comparisonResult) {
this.operationId = comparisonResult.operationId;
this.comparisonResult = comparisonResult;
this.flexModel.removeItem(this.startText);
} else {
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
if (!this.operationId) {
// create once per page
this.operationId = generateGuid();
}
this.comparisonResult = await service.schemaCompare(this.operationId, this.sourceEndpointInfo, this.targetEndpointInfo, azdata.TaskExecutionMode.execute, this.deploymentOptions);
if (!this.comparisonResult || !this.comparisonResult.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFailed', undefined, getTelemetryErrorType(this.comparisonResult?.errorMessage))
.withAdditionalProperties({
operationId: this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.compareErrorMessage(this.comparisonResult?.errorMessage));
// reset state so a new comparison can be made
this.resetWindow();
return;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
.withAdditionalProperties({
'endTime': Date.now().toString(),
'operationId': this.comparisonResult.operationId
}).send();
if (!this.operationId) {
// create once per page
this.operationId = generateGuid();
}
this.comparisonResult = await service.schemaCompare(this.operationId, this.sourceEndpointInfo, this.targetEndpointInfo, azdata.TaskExecutionMode.execute, this.deploymentOptions);
if (!this.comparisonResult || !this.comparisonResult.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFailed', undefined, getTelemetryErrorType(this.comparisonResult?.errorMessage))
.withAdditionalProperties({
operationId: this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.compareErrorMessage(this.comparisonResult?.errorMessage));
// reset state so a new comparison can be made
this.resetWindow();
return;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonFinished')
.withAdditionalProperties({
'endTime': Date.now().toString(),
'operationId': this.comparisonResult.operationId
}).send();
let data = this.getAllDifferences(this.comparisonResult.differences);
this.differencesTable.updateProperties({
@@ -419,15 +363,9 @@ export class SchemaCompareMainWindow {
// only enable generate script button if the target is a db
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.generateScriptButton.enabled = true;
} else {
this.generateScriptButton.title = loc.generateScriptDisabled;
}
// only enable apply button if the target is a db or a project
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database ||
this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
this.applyButton.enabled = true;
} else {
this.generateScriptButton.title = loc.generateScriptDisabled;
this.applyButton.title = loc.applyDisabled;
}
} else {
@@ -824,6 +762,7 @@ export class SchemaCompareMainWindow {
}
public async publishChanges(): Promise<void> {
// need only yes button - since the modal dialog has a default cancel
const yesString = loc.YesButtonText;
await vscode.window.showWarningMessage(loc.applyConfirmation, { modal: true }, yesString).then(async (result) => {
@@ -837,26 +776,14 @@ export class SchemaCompareMainWindow {
// disable apply and generate script buttons because the results are no longer valid after applying the changes
this.setButtonsForRecompare();
const service: mssql.ISchemaCompareService = await this.getService();
let result: azdata.ResultStatus | undefined = undefined;
switch (this.targetEndpointInfo.endpointType) {
case mssql.SchemaCompareEndpointType.Database:
result = await service.schemaComparePublishDatabaseChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
break;
case mssql.SchemaCompareEndpointType.Project: // Project apply needs sql-database-projects updates in (circular dependency; coming next) // TODO: re-add this and show project logic below
case mssql.SchemaCompareEndpointType.Dacpac: // Dacpac is an invalid publish target
default:
throw new Error(`Unsupported SchemaCompareEndpointType: ${getSchemaCompareEndpointString(this.targetEndpointInfo.endpointType)}`);
}
const service = await this.getService();
const result = await service.schemaComparePublishChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
if (!result || !result.success) {
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyFailed', undefined, getTelemetryErrorType(result?.errorMessage))
TelemetryReporter.createErrorEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyFailed', undefined, getTelemetryErrorType(result.errorMessage))
.withAdditionalProperties({
'operationId': this.comparisonResult.operationId
}).send();
vscode.window.showErrorMessage(loc.applyErrorMessage(result?.errorMessage));
vscode.window.showErrorMessage(loc.applyErrorMessage(result.errorMessage));
// reenable generate script and apply buttons if apply failed
this.generateScriptButton.enabled = true;
@@ -864,7 +791,6 @@ export class SchemaCompareMainWindow {
this.applyButton.enabled = true;
this.applyButton.title = loc.applyEnabledMessage;
}
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyEnded')
.withAdditionalProperties({
'endTime': Date.now().toString(),
@@ -1156,15 +1082,11 @@ export class SchemaCompareMainWindow {
}
private setButtonStatesForNoChanges(enableButtons: boolean): void {
// generate script and apply can only be enabled if the target is a database or project
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database ||
this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Project) {
this.applyButton.enabled = enableButtons;
this.applyButton.title = enableButtons ? loc.applyEnabledMessage : loc.applyNoChangesMessage;
}
// generate script and apply can only be enabled if the target is a database
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
this.applyButton.enabled = enableButtons;
this.generateScriptButton.enabled = enableButtons;
this.applyButton.title = enableButtons ? loc.applyEnabledMessage : loc.applyNoChangesMessage;
this.generateScriptButton.title = enableButtons ? loc.generateScriptEnabledMessage : loc.generateScriptNoChangesMessage;
}
}

View File

@@ -110,7 +110,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should show error if publish changes fails', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: false,
errorMessage: 'error1'
}));
@@ -121,7 +121,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
@@ -131,7 +131,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should show not error if publish changes succeed', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));
@@ -140,7 +140,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
await schemaCompareResult.start(undefined);
schemaCompareResult.sourceEndpointInfo = setDacpacEndpointInfo(mocksource);
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
schemaCompareResult.targetEndpointInfo = setDacpacEndpointInfo(mocktarget);
await schemaCompareResult.execute();
await schemaCompareResult.publishChanges();
should(showErrorMessageSpy.notCalled).be.true();
@@ -343,7 +343,7 @@ describe('SchemaCompareMainWindow.results @DacFx@', function (): void {
it('Should not show error if user does not want to publish', async function (): Promise<void> {
let service = createServiceMock();
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
service.setup(x => x.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
success: true,
errorMessage: ''
}));

View File

@@ -24,14 +24,6 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
throw new Error('Method not implemented.');
}
schemaComparePublishDatabaseChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
throw new Error('Method not implemented.');
}
schemaComparePublishProjectChanges(operationId: string, targetProjectPath: string, targetFolderStructure: mssql.ExtractTarget, taskExecutionMode: azdata.TaskExecutionMode): Thenable<mssql.SchemaComparePublishProjectResult> {
throw new Error('Method not implemented.');
}
schemaCompareGetDefaultOptions(): Thenable<mssql.SchemaCompareOptionsResult> {
let result: mssql.SchemaCompareOptionsResult = {
defaultDeploymentOptions: undefined,
@@ -50,6 +42,7 @@ export class SchemaCompareTestService implements mssql.ISchemaCompareService {
throw new Error('Method not implemented.');
}
schemaCompareSaveScmp(sourceEndpointInfo: mssql.SchemaCompareEndpointInfo, targetEndpointInfo: mssql.SchemaCompareEndpointInfo, taskExecutionMode: azdata.TaskExecutionMode, deploymentOptions: mssql.DeploymentOptions, scmpFilePath: string, excludedSourceObjects: mssql.SchemaCompareObjectId[], excludedTargetObjects: mssql.SchemaCompareObjectId[]): Thenable<azdata.ResultStatus> {
throw new Error('Method not implemented.');
}

View File

@@ -94,11 +94,7 @@ export const mockDacpacEndpoint: mssql.SchemaCompareEndpointInfo = {
databaseName: '',
ownerUri: '',
packageFilePath: mockFilePath,
connectionDetails: undefined,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
@@ -108,11 +104,7 @@ export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
databaseName: '',
ownerUri: '',
packageFilePath: '',
connectionDetails: undefined,
projectFilePath: '',
folderStructure: '',
targetScripts: [],
dataSchemaProvider: '',
connectionDetails: undefined
};
export async function shouldThrowSpecificError(block: Function, expectedMessage: string, details?: string) {

View File

@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import * as azdata from 'azdata';
import type * as azdataType from 'azdata'; // eslint-disable-line no-duplicate-imports
import * as vscode from 'vscode';
import * as mssql from '../../mssql';
import * as os from 'os';
@@ -40,19 +39,6 @@ export function getTelemetryErrorType(msg: string): string {
}
}
export function getSchemaCompareEndpointString(endpointType: mssql.SchemaCompareEndpointType): string {
switch (endpointType) {
case mssql.SchemaCompareEndpointType.Database:
return 'Database';
case mssql.SchemaCompareEndpointType.Dacpac:
return 'Dacpac';
case mssql.SchemaCompareEndpointType.Project:
return 'Project';
default:
return `Unknown: ${endpointType}`;
}
}
/**
* Return the appropriate endpoint name depending on if the endpoint is a dacpac or a database
* @param endpoint endpoint to get the name of
@@ -78,11 +64,8 @@ export function getEndpointName(endpoint: mssql.SchemaCompareEndpointInfo): stri
return ' ';
}
} else if (endpoint.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
return endpoint.packageFilePath;
} else {
return endpoint.projectFilePath;
return endpoint.packageFilePath;
}
}
@@ -161,24 +144,3 @@ export async function exists(path: string): Promise<boolean> {
return false;
}
}
// Try to load the azdata API - but gracefully handle the failure in case we're running
// in a context where the API doesn't exist (such as VS Code)
let azdataApi: typeof azdataType | undefined = undefined;
try {
azdataApi = require('azdata');
if (!azdataApi?.version) {
// webpacking makes the require return an empty object instead of throwing an error so make sure we clear the var
azdataApi = undefined;
}
} catch {
// no-op
}
/**
* Gets the azdata API if it's available in the context this extension is running in.
* @returns The azdata API if it's available
*/
export function getAzdataApi(): typeof azdataType | undefined {
return azdataApi;
}

View File

@@ -19,12 +19,6 @@
"*"
],
"main": "./out/extension",
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"forceReload": true,
"contributes": {
"commands": [

View File

@@ -15,12 +15,6 @@
"activationEvents": [
"onDashboardOpen"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"main": "./out/main",
"repository": {
"type": "git",

View File

@@ -4,11 +4,14 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
// This task is meant for running the VS Code version of the extension. See VSCODE_DEVELOPMENT.md for more information
// Note for debugging the VS Code version of the extension, currently you will need to modify
// the package.json and manually copy over the values from package.vscode.json into package.json
// (otherwise you'll get errors since other extensions depend on an extension with the name
// data-workspace-vscode, not data-workspace)
{
"type": "extensionHost",
"request": "launch",
"name": "Launch Extension in VS Code",
"name": "Launch Extension",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}"
@@ -18,4 +21,4 @@
]
}
]
}
}

View File

@@ -1,17 +1,9 @@
# Microsoft SQL Server Database Projects for Azure Data Studio and VS Code
## Overview
Microsoft SQL Server Database Projects for Azure Data Studio and VS Code provides a way to design, edit, and publish schemas for SQL databases from a source controlled project.
### VS Code
This extension is bundled into the `SQL Server (MSSQL)` extension for VS Code and will be installed automatically when that extension is updated or installed.
### Azure Data Studio
This extension is provided as a separate extension in the marketplace.
Microsoft SQL Server Database Projects for Azure Data Studio and VS Code includes:
## Database Projects
The Database Projects extension provides a way to design, edit, and publish schemas for SQL databases from a source controlled project.
Please report issues and feature requests [here.](https://github.com/microsoft/azuredatastudio/issues)
@@ -19,8 +11,7 @@ Please report issues and feature requests [here.](https://github.com/microsoft/a
* Create a new database project by going to the **Projects** viewlet or by searching **Projects: New** in the command palette.
* Existing database projects can be opened by going to the **Projects** viewlet or by searching **Projects: Open Existing** in the command palette.
* Start from an existing database by using the **Create Project from Database** from the command palette or database context menu.
* Start from an OpenAPI/Swagger spec by using the **Generate SQL Project from OpenAPI/Swagger spec** command.
* Start from an existing database by using **Create Project From Database** from the command palette or database context menu.
## Code of Conduct

View File

@@ -1,15 +0,0 @@
# VS Code Extension Development
For working on the VS Code version of the package follow these steps for local development/testing.
1. Copy the values from [package.vscode.json](./package.vscode.json) into [package.json](./package.json) (overwriting the properties with the same name there)
2. Delete the following properties (this includes their arrays of values as well) from the `contributes/menus` property in the [package.json](./package.json)
* `objectExplorer/item/context`
* `dataExplorer/context`
* `dashboard/toolbar`
3. Compile Azure Data Studio as normal and wait for it to finish
4. Run `code <PathToAzureDataStudioSource>/extensions/sql-database-projects` from the command line to open a new VS Code instance at the `sql-database-projects` folder
5. Run the `Launch Extension in VS Code` launch target from the `Run and Debug` view
6. This should launch an `Extension Development Host` version of VS Code that is running the extension from sources.
If you have the compilation running as watch then once you make changes you can just reload the window to pick up the latest changes being made.

View File

@@ -1,8 +1,8 @@
{
"name": "sql-database-projects",
"displayName": "SQL Database Projects",
"description": "Enables users to develop and publish database schemas for MSSQL Databases",
"version": "0.14.0",
"description": "The SQL Database Projects extension for Azure Data Studio and VS Code allows users to develop and publish database schemas.",
"version": "0.13.0",
"publisher": "Microsoft",
"preview": true,
"engines": {
@@ -17,7 +17,6 @@
"onCommand:sqlDatabaseProjects.open",
"onCommand:sqlDatabaseProjects.createProjectFromDatabase",
"onCommand:sqlDatabaseProjects.generateProjectFromOpenApiSpec",
"onCommand:sqlDatabaseProjects.addSqlBinding",
"workspaceContains:**/*.sqlproj",
"onView:dataworkspace.views.main"
],
@@ -30,12 +29,6 @@
"Microsoft.mssql",
"Microsoft.schema-compare"
],
"capabilities": {
"virtualWorkspaces": false,
"untrustedWorkspaces": {
"supported": true
}
},
"contributes": {
"projects": [
"sqlproj"
@@ -44,14 +37,18 @@
{
"title": "%sqlDatabaseProjects.Settings%",
"properties": {
"sqlDatabaseProjects.dotnetSDK Location": {
"sqlDatabaseProjects.netCoreSDKLocation": {
"type": "string",
"description": "%sqlDatabaseProjects.dotnetInstallLocation%"
"description": "%sqlDatabaseProjects.netCoreInstallLocation%"
},
"sqlDatabaseProjects.netCoreDoNotAsk": {
"type": "boolean",
"description": "%sqlDatabaseProjects.netCoreDoNotAsk%"
},
"sqlDatabaseProjects.netCoreDowngradeDoNotShow": {
"type": "boolean",
"description": "%sqlDatabaseProjects.netCoreDowngradeDoNotShow%"
},
"sqlDatabaseProjects.nodejsDoNotAsk": {
"type": "boolean",
"description": "%sqlDatabaseProjects.nodejsDoNotAsk%"
@@ -165,11 +162,6 @@
"title": "%sqlDatabaseProjects.editProjectFile%",
"category": "%sqlDatabaseProjects.displayName%"
},
{
"command": "sqlDatabaseProjects.addSqlBinding",
"title": "%sqlDatabaseProjects.addSqlBinding%",
"category": "MS SQL"
},
{
"command": "sqlDatabaseProjects.changeTargetPlatform",
"title": "%sqlDatabaseProjects.changeTargetPlatform%",
@@ -270,10 +262,6 @@
"command": "sqlDatabaseProjects.editProjectFile",
"when": "false"
},
{
"command": "sqlDatabaseProjects.addSqlBinding",
"when": "editorLangId == csharp && !azdataAvailable && resourceScheme != untitled"
},
{
"command": "sqlDatabaseProjects.exclude",
"when": "false"

View File

@@ -33,11 +33,12 @@
"sqlDatabaseProjects.generateProjectFromOpenApiSpec": "Generate SQL Project from OpenAPI/Swagger spec",
"sqlDatabaseProjects.Settings": "Database Projects",
"sqlDatabaseProjects.dotnetInstallLocation": "Full path to .NET SDK on the machine.",
"sqlDatabaseProjects.netCoreInstallLocation": "Full path to .NET Core SDK on the machine.",
"sqlDatabaseProjects.netCoreDoNotAsk": "Whether to prompt the user to install .NET Core when not detected.",
"sqlDatabaseProjects.netCoreDowngradeDoNotShow": "Whether to prompt the user to set .NET SDK version when a newer unsupported version is detected.",
"sqlDatabaseProjects.nodejsDoNotAsk": "Whether to prompt the user to install Node.js when not detected.",
"sqlDatabaseProjects.autorestSqlVersion": "Which version of Autorest.Sql to use from NPM. Latest will be used if not set.",
"sqlDatabaseProjects.welcome": "No database projects currently open.\n[New Project](command:sqlDatabaseProjects.new)\n[Open Project](command:sqlDatabaseProjects.open)\n[Create Project From Database](command:sqlDatabaseProjects.importDatabase)",
"sqlDatabaseProjects.addSqlBinding":"Add SQL Binding (preview)"
"sqlDatabaseProjects.addSqlBinding":"Add SQL Binding"
}

View File

@@ -1,8 +1,7 @@
{
"name": "sql-database-projects-vscode",
"publisher": "ms-mssql",
"extensionDependencies": [
"ms-mssql.mssql",
"ms-mssql.data-workspace-vscode"
"Microsoft.data-workspace-vscode"
]
}

View File

@@ -21,7 +21,6 @@ export const msdb = 'msdb';
export const msdbDacpac = 'msdb.dacpac';
export const MicrosoftDatatoolsSchemaSqlSql = 'Microsoft.Data.Tools.Schema.Sql.Sql';
export const databaseSchemaProvider = 'DatabaseSchemaProvider';
export const sqlProjectSdk = 'Microsoft.Build.Sql';
// Project Provider
export const emptySqlDatabaseProjectTypeId = 'EmptySqlDbProj';
@@ -70,7 +69,6 @@ export const dataSourcesNodeName = localize('dataSourcesNodeName', "Data Sources
export const databaseReferencesNodeName = localize('databaseReferencesNodeName', "Database References");
export const sqlConnectionStringFriendly = localize('sqlConnectionStringFriendly', "SQL connection string");
export const yesString = localize('yesString', "Yes");
export const openEulaString = localize('openEulaString', "Open License Agreement");
export const noString = localize('noString', "No");
export const noStringDefault = localize('noStringDefault', "No (default)");
export const okString = localize('okString', "Ok");
@@ -106,7 +104,7 @@ export const dataSourceDropdownTitle = localize('dataSourceDropdownTitle', "Data
export const noDataSourcesText = localize('noDataSourcesText', "No data sources in this project");
export const loadProfilePlaceholderText = localize('loadProfilePlaceholderText', "Load profile...");
export const profileReadError = (err: any) => localize('profileReadError', "Error loading the publish profile. {0}", utils.getErrorMessage(err));
export const sqlCmdVariables = localize('sqlCmdTableLabel', "SQLCMD Variables");
export const sqlCmdTableLabel = localize('sqlCmdTableLabel', "SQLCMD Variables");
export const sqlCmdVariableColumn = localize('sqlCmdVariableColumn', "Name");
export const sqlCmdValueColumn = localize('sqlCmdValueColumn', "Value");
export const loadSqlCmdVarsButtonTitle = localize('reloadValuesFromProjectButtonTitle', "Reload values from project");
@@ -134,11 +132,6 @@ export const selectPublishOption = localize('selectPublishOption', "Select where
export const publishToExistingServer = localize('publishToExistingServer', "Publish to existing server");
export const publishToDockerContainer = localize('publishToDockerContainer', "Publish to new server in a container");
export const enterPortNumber = localize('enterPortNumber', "Enter SQL server port number or press enter to use the default value");
export const serverPortNumber = localize('serverPortNumber', "SQL server port number");
export const serverPassword = localize('serverPassword', "SQL Server admin password");
export const confirmServerPassword = localize('confirmServerPassword', "Confirm SQL Server admin password");
export const baseDockerImage = localize('baseDockerImage', "Base SQL Server Docker image");
export const publishTo = localize('publishTo', "Publish Target");
export const enterConnectionStringEnvName = localize('enterConnectionStringEnvName', "Enter connection string environment variable name");
export const enterConnectionStringTemplate = localize('enterConnectionStringTemplate', "Enter connection string template");
export const enterPassword = localize('enterPassword', "Enter SQL Server admin password");
@@ -150,14 +143,6 @@ export const portMustBeNumber = localize('portMustNotBeNumber', "Port must a be
export const valueCannotBeEmpty = localize('valueCannotBeEmpty', "Value cannot be empty");
export const dockerImageLabelPrefix = 'source=sqldbproject';
export const dockerImageNamePrefix = 'sqldbproject';
//
export const eulaAgreementTemplate = localize({ key: 'eulaAgreementTemplate', comment: ['The placeholders are contents of the line and should not be translated.'] }, "I accept the {0}.");
export function eulaAgreementText(name: string) { return localize({ key: 'eulaAgreementText', comment: ['The placeholders are contents of the line and should not be translated.'] }, "I accept the {0}.", name); }
export const eulaAgreementTitle = localize('eulaAgreementTitle', "Microsoft SQL Server License Agreement");
export const edgeEulaAgreementTitle = localize('edgeEulaAgreementTitle', "Microsoft Azure SQL Edge License Agreement");
export const sqlServerEulaLink = 'https://go.microsoft.com/fwlink/?linkid=857698';
export const sqlServerEdgeEulaLink = 'https://go.microsoft.com/fwlink/?linkid=2139274';
export const connectionNamePrefix = 'SQLDbProject';
export const sqlServerDockerRegistry = 'mcr.microsoft.com';
export const sqlServerDockerRepository = 'mssql/server';
@@ -167,8 +152,6 @@ export const mssqlFolderName = '.mssql';
export const dockerFileName = 'Dockerfile';
export const startCommandName = 'start.sh';
export const defaultPortNumber = '1433';
export const defaultLocalServerName = 'localhost';
export const defaultLocalServerAdminName = 'sa';
export const defaultConnectionStringEnvVarName = 'SQLConnectionString';
export const defaultConnectionStringTemplate = 'Data Source=@@SERVER@@,@@PORT@@;Initial Catalog=@@DATABASE@@;User id=@@USER@@;Password=@@SA_PASSWORD@@;';
export const azureFunctionLocalSettingsFileName = 'local.settings.json';
@@ -179,8 +162,6 @@ export const deployDbTaskName = localize('deployDbTaskName', "Deploying SQL Db P
export const publishProjectSucceed = localize('publishProjectSucceed', "Database project published successfully");
export const publishingProjectMessage = localize('publishingProjectMessage', "Publishing project in a container...");
export const cleaningDockerImagesMessage = localize('cleaningDockerImagesMessage', "Cleaning existing deployments...");
export const dockerImageMessage = localize('dockerImageMessage', "Docker Image:");
export const dockerImageEulaMessage = localize('dockerImageEulaMessage', "License Agreement:");
export const creatingDeploymentSettingsMessage = localize('creatingDeploymentSettingsMessage', "Creating deployment settings ...");
export const runningDockerMessage = localize('runningDockerMessage', "Building and running the docker container ...");
export function dockerNotRunningError(error: string) { return localize('dockerNotRunningError', "Failed to verify docker. Please make sure docker is installed and running. Error: '{0}'", error || ''); }
@@ -246,7 +227,8 @@ export const browseButtonText = localize('browseButtonText', "Browse folder");
export const selectFolderStructure = localize('selectFolderStructure', "Select folder structure");
export const folderStructureLabel = localize('folderStructureLabel', "Folder structure");
export const WorkspaceFileExtension = '.code-workspace';
export const browseEllipsisWithIcon = `$(folder) ${localize('browseEllipsis', "Browse...")}`;
export const browseEllipsis = localize('browseEllipsis', "Browse...");
export const browseEllipsisWithIcon = `$(folder) ${browseEllipsis}`;
export const selectProjectLocation = localize('selectProjectLocation', "Select project location");
export const ProjectParentDirectoryNotExistError = (location: string): string => { return localize('dataworkspace.projectParentDirectoryNotExistError', "The selected project location '{0}' does not exist or is not a directory.", location); };
export const ProjectDirectoryAlreadyExistError = (projectName: string, location: string): string => { return localize('dataworkspace.projectDirectoryAlreadyExistError', "There is already a directory named '{0}' in the selected location: '{1}'.", projectName, location); };
@@ -264,8 +246,8 @@ export const invalidSqlConnectionString = localize('invalidSqlConnectionString',
export const extractTargetRequired = localize('extractTargetRequired', "Target information for extract is required to create database project.");
export const schemaCompareNotInstalled = localize('schemaCompareNotInstalled', "Schema compare extension installation is required to run schema compare");
export const buildFailedCannotStartSchemaCompare = localize('buildFailedCannotStartSchemaCompare', "Schema compare could not start because build failed");
export function updateProjectForRoundTrip(projectName: string) { return localize('updateProjectForRoundTrip', "The targets, references, and system database references need to be updated to build the project '{0}'. If the project was created in SSDT, it will continue to work in both tools. Do you want to update the project?", projectName); }
export function updateProjectDatabaseReferencesForRoundTrip(projectName: string) { return localize('updateProjectDatabaseReferencesForRoundTrip', "The system database references need to be updated to build the project '{0}'. If the project was created in SSDT, it will continue to work in both tools. Do you want to update the project?", projectName); }
export const updateProjectForRoundTrip = localize('updateProjectForRoundTrip', "The targets, references, and system database references need to be updated to build this project. If the project is created in SSDT, it will continue to work in both tools. Do you want to update the project?");
export const updateProjectDatabaseReferencesForRoundTrip = localize('updateProjectDatabaseReferencesForRoundTrip', "The system database references need to be updated to build this project. If the project is created in SSDT, it will continue to work in both tools. Do you want to update the project?");
export const databaseReferenceTypeRequired = localize('databaseReferenceTypeRequired', "Database reference type is required for adding a reference to a database");
export const systemDatabaseReferenceRequired = localize('systemDatabaseReferenceRequired', "System database selection is required for adding a reference to a system database");
export const dacpacFileLocationRequired = localize('dacpacFileLocationRequired', "Dacpac file location is required for adding a reference to a database");
@@ -304,7 +286,7 @@ export function unableToFindSqlCmdVariable(variableName: string) { return locali
export function unableToFindDatabaseReference(reference: string) { return localize('unableToFindReference', "Unable to find database reference {0}", reference); }
export function invalidGuid(guid: string) { return localize('invalidGuid', "Specified GUID is invalid: {0}", guid); }
export function invalidTargetPlatform(targetPlatform: string, supportedTargetPlatforms: string[]) { return localize('invalidTargetPlatform', "Invalid target platform: {0}. Supported target platforms: {1}", targetPlatform, supportedTargetPlatforms.toString()); }
export function errorReadingProject(section: string, path: string) { return localize('errorReadingProjectGuid', "Error trying to read {0} of project '{1}'", section, path); }
// Action types
export const deleteAction = localize('deleteAction', 'Delete');
@@ -330,21 +312,22 @@ export const postDeployScriptFriendlyName = localize('postDeployScriptFriendlyNa
// Build
export const DotnetInstallationConfirmation: string = localize('sqlDatabaseProjects.DotnetInstallationConfirmation', "The .NET SDK cannot be located. Project build will not work. Please install .NET Core SDK version 3.1 or higher or update the .NET SDK location in settings if already installed.");
export function NetCoreSupportedVersionInstallationConfirmation(installedVersion: string) { return localize('sqlDatabaseProjects.NetCoreSupportedVersionInstallationConfirmation', "Currently installed .NET Core SDK version is {0}, which is not supported. Project build will not work. Please install .NET Core SDK version 3.1 or higher or update the .NET SDK supported version location in settings if already installed.", installedVersion); }
export const UpdateDotnetLocation: string = localize('sqlDatabaseProjects.UpdateDotnetLocation', "Update Location");
export const NetCoreInstallationConfirmation: string = localize('sqlDatabaseProjects.NetCoreInstallationConfirmation', "The .NET Core SDK cannot be located. Project build will not work. Please install .NET Core SDK version 3.1 or update the .NET Core SDK location in settings if already installed.");
export function NetCoreSupportedVersionInstallationConfirmation(installedVersion: string) { return localize('sqlDatabaseProjects.NetCoreSupportedVersionInstallationConfirmation', "Currently installed .NET Core SDK version is {0}, which is not supported. Project build will not work. Please install .NET Core SDK version 3.1 or update the .NET Core SDK supported version location in settings if already installed.", installedVersion); }
export function NetCoreVersionDowngradeConfirmation(installedVersion: string) { return localize('sqlDatabaseProjects.NetCoreVersionDowngradeConfirmation', "Installed .NET SDK version {0} is newer than the currently supported versions. Project build will not work. Please install .NET Core SDK version 3.1 and include a global.json in the project folder specifying the SDK version to use. [More Information](https://docs.microsoft.com/dotnet/core/versions/selection)", installedVersion); }
export const UpdateNetCoreLocation: string = localize('sqlDatabaseProjects.UpdateNetCoreLocation', "Update Location");
export const projectsOutputChannel = localize('sqlDatabaseProjects.outputChannel', "Database Projects");
// Prompt buttons
export const Install: string = localize('sqlDatabaseProjects.Install', "Install");
export const DoNotAskAgain: string = localize('sqlDatabaseProjects.doNotAskAgain', "Don't Ask Again");
export const DoNotShowAgain: string = localize('sqlDatabaseProjects.doNotShowAgain', "Don't Show Again");
// SqlProj file XML names
export const ItemGroup = 'ItemGroup';
export const Build = 'Build';
export const Folder = 'Folder';
export const Include = 'Include';
export const Remove = 'Remove';
export const Import = 'Import';
export const Project = 'Project';
export const Condition = 'Condition';
@@ -378,17 +361,6 @@ export const Private = 'Private';
export const ProjectGuid = 'ProjectGuid';
export const Type = 'Type';
export const ExternalStreamingJob: string = 'ExternalStreamingJob';
export const Sdk: string = 'Sdk';
export const BuildElements = localize('buildElements', "Build Elements");
export const FolderElements = localize('folderElements', "Folder Elements");
export const PreDeployElements = localize('preDeployElements', "PreDeploy Elements");
export const PostDeployElements = localize('postDeployElements', "PostDeploy Elements");
export const NoneElements = localize('noneElements', "None Elements");
export const ImportElements = localize('importElements', "Import Elements");
export const ProjectReferenceNameElement = localize('projectReferenceNameElement', "Project reference name element");
export const ProjectReferenceElement = localize('projectReferenceElement', "Project reference");
export const DacpacReferenceElement = localize('dacpacReferenceElement', "Dacpac reference");
/** Name of the property item in the project file that defines default database collation. */
export const DefaultCollationProperty = 'DefaultCollation';
@@ -451,12 +423,9 @@ export enum DatabaseProjectItemType {
// AutoRest
export const autorestPostDeploymentScriptName = 'PostDeploymentScript.sql';
export const nodeButNotAutorestFound = localize('nodeButNotAutorestFound', "Autorest tool not found in system path, but found Node.js. Prompting user for how to proceed. Execute 'npm install autorest -g' to install permanently and avoid this message.");
export const nodeButNotAutorestFound = localize('nodeButNotAutorestFound', "Autorest tool not found in system path, but found Node.js. Running via npx. Please execute 'npm install autorest -g' to install permanently.");
export const nodeNotFound = localize('nodeNotFound', "Neither Autorest nor Node.js (npx) found in system path. Please install Node.js for Autorest generation to work.");
export const nodeButNotAutorestFoundPrompt = localize('nodeButNotAutorestFoundPrompt', "Autorest is not installed. To proceed, choose whether to run Autorest from a temporary location via 'npx' or install Autorest globally then run.");
export const userSelectionInstallGlobally = localize('userSelectionInstallGlobally', "User selected to install autorest gloablly. Installing now...");
export const userSelectionRunNpx = localize('userSelectionRunNpx', "User selected to run via npx.");
export const userSelectionCancelled = localize('userSelectionCancelled', "User has cancelled selection for how to run autorest.");
export const installGlobally = localize('installGlobally', "Install globally");
export const runViaNpx = localize('runViaNpx', "Run via npx");
@@ -524,7 +493,6 @@ export const noAzureFunctionsProjectsInWorkspace = localize('noAzureFunctionsPro
export const addPackage = localize('addPackage', "Add Package");
export const createNewLocalAppSetting = localize('createNewLocalAppSetting', 'Create new local app setting');
export const createNewLocalAppSettingWithIcon = `$(add) ${createNewLocalAppSetting}`;
export const sqlConnectionStringSetting = 'SqlConnectionString';
export const valueMustNotBeEmpty = localize('valueMustNotBeEmpty', "Value must not be empty");
export const enterConnectionStringSettingName = localize('enterConnectionStringSettingName', "Enter connection string setting name");
export const enterConnectionString = localize('enterConnectionString', "Enter connection string");
@@ -535,4 +503,3 @@ export function failedToParse(errorMessage: string) { return localize('failedToP
export function jsonParseError(error: string, line: number, column: number) { return localize('jsonParseError', '{0} near line "{1}", column "{2}"', error, line, column); }
export const moreInformation = localize('moreInformation', "More Information");
export const addPackageReferenceMessage = localize('addPackageReferenceMessage', 'To use SQL bindings, ensure your Azure Functions project has a reference to {0}', sqlExtensionPackageName);
export const addSqlBindingPackageError = localize('addSqlBindingPackageError', 'Error adding Sql Binding extension package to project');

View File

@@ -6,20 +6,7 @@
/**
* Deferred promise
*/
export class Deferred<T = void> {
promise: Promise<T>;
resolve!: (value: T | PromiseLike<T>) => void;
reject!: (reason?: any) => void;
constructor() {
this.promise = new Promise<T>((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => void): Thenable<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | Thenable<TResult>, onrejected?: (reason: any) => TResult | Thenable<TResult>): Thenable<TResult> {
return this.promise.then(onfulfilled, onrejected);
}
export interface Deferred<T> {
resolve: (result: T | Promise<T>) => void;
reject: (reason: any) => void;
}

Some files were not shown because too many files have changed in this diff Show More