mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-18 11:01:36 -05:00
Compare commits
224 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83a4316cf8 | ||
|
|
b4c22c698d | ||
|
|
b44891657c | ||
|
|
f99b27807f | ||
|
|
93ea635bac | ||
|
|
651f6fdcfc | ||
|
|
cfc8e41798 | ||
|
|
bcd2e7313a | ||
|
|
61f094f797 | ||
|
|
d5a3370b65 | ||
|
|
a2d5b2acd1 | ||
|
|
80541ce6f0 | ||
|
|
8d8b3983a9 | ||
|
|
6aab9d41a3 | ||
|
|
969eb16df7 | ||
|
|
8a205965d2 | ||
|
|
cde4e05320 | ||
|
|
bb83110606 | ||
|
|
f9e1f38393 | ||
|
|
a3faff2738 | ||
|
|
f404edbb60 | ||
|
|
36364e10c4 | ||
|
|
43d235ea42 | ||
|
|
8b09ba8844 | ||
|
|
9b87973205 | ||
|
|
5ad91135dd | ||
|
|
ba3e6343e8 | ||
|
|
d02eddda29 | ||
|
|
8b0371e036 | ||
|
|
09c2e73f14 | ||
|
|
39f8181af4 | ||
|
|
5f6b2bdbb8 | ||
|
|
de93938ef4 | ||
|
|
56d5061942 | ||
|
|
1006652a31 | ||
|
|
7e17bfb6ec | ||
|
|
ce7935e7d2 | ||
|
|
1f9a6a611b | ||
|
|
c073897056 | ||
|
|
917a30e66f | ||
|
|
0149d9f051 | ||
|
|
0bac949d3b | ||
|
|
0847f7cd38 | ||
|
|
5d2f17408e | ||
|
|
da56e59f6e | ||
|
|
33f01054c0 | ||
|
|
4c191d4acc | ||
|
|
a79c61ff4e | ||
|
|
ef4dab072a | ||
|
|
80f3f4eb88 | ||
|
|
1f98f29eae | ||
|
|
0caa6390b9 | ||
|
|
172e349947 | ||
|
|
5f3453c929 | ||
|
|
37e1da4ba2 | ||
|
|
bb28646670 | ||
|
|
9dcdfaea7a | ||
|
|
cc21588db8 | ||
|
|
6ba7bad90c | ||
|
|
ae5026b432 | ||
|
|
24b22f63d7 | ||
|
|
77e4fdd407 | ||
|
|
8a6ea2669b | ||
|
|
3136ce1b4d | ||
|
|
8e04d3992a | ||
|
|
09666bc4e8 | ||
|
|
377479617f | ||
|
|
7862515eb5 | ||
|
|
112810dbfb | ||
|
|
c74a89674a | ||
|
|
a801388e1d | ||
|
|
7cb7157821 | ||
|
|
9bdd6aca42 | ||
|
|
88b754b739 | ||
|
|
480bf56cef | ||
|
|
a273c54ebb | ||
|
|
7c26e14605 | ||
|
|
6f03cbac97 | ||
|
|
9e5a012dcd | ||
|
|
812ab1cc91 | ||
|
|
3d9f54b0c0 | ||
|
|
3cbd2fe5df | ||
|
|
2a127beb28 | ||
|
|
6725e07ece | ||
|
|
24a6de404c | ||
|
|
66c438db4d | ||
|
|
1b83c4623d | ||
|
|
42b9f3b552 | ||
|
|
343e314103 | ||
|
|
fc0d175f39 | ||
|
|
5fccd8ebcd | ||
|
|
b5f8e81250 | ||
|
|
d6159a2370 | ||
|
|
77e9d1c3a0 | ||
|
|
bf1cc057be | ||
|
|
4538103e60 | ||
|
|
7a1c0a67b9 | ||
|
|
56a697c887 | ||
|
|
ba92694fa3 | ||
|
|
1a9f2a5903 | ||
|
|
e0ad23a559 | ||
|
|
0a60ed4c75 | ||
|
|
f96a82f700 | ||
|
|
6b226de450 | ||
|
|
615df975ec | ||
|
|
bcc66218d1 | ||
|
|
6fb6f51295 | ||
|
|
1d3debb897 | ||
|
|
b6047ad87d | ||
|
|
329ea4103c | ||
|
|
8057bf855b | ||
|
|
209a93c578 | ||
|
|
8a6268cce8 | ||
|
|
e9ce8d902a | ||
|
|
4727333974 | ||
|
|
c00c5e044b | ||
|
|
f91a228066 | ||
|
|
a31388f37a | ||
|
|
9b06f3551d | ||
|
|
a0cce62926 | ||
|
|
5f8e1f384f | ||
|
|
b4d72af3d4 | ||
|
|
b8ea493f8c | ||
|
|
c9be45b9c7 | ||
|
|
1fe3f38c14 | ||
|
|
f5b1e7feb8 | ||
|
|
dd0261ca05 | ||
|
|
b8629acc4b | ||
|
|
5160814623 | ||
|
|
f07427f2c1 | ||
|
|
a34b5a0db7 | ||
|
|
00ff7a0000 | ||
|
|
99f5c406e3 | ||
|
|
893563c9c3 | ||
|
|
84ae306d57 | ||
|
|
f3e1c2cc8b | ||
|
|
6ae8db35df | ||
|
|
07b2b8128a | ||
|
|
43fe0ce482 | ||
|
|
c02c564a46 | ||
|
|
a3a91fbdfc | ||
|
|
312b410fff | ||
|
|
8c3c18e8dc | ||
|
|
0d485ffe2b | ||
|
|
d7b0b6c251 | ||
|
|
2be1ec0656 | ||
|
|
66ebbc2181 | ||
|
|
de3ae26873 | ||
|
|
25711acde0 | ||
|
|
6dda9392e0 | ||
|
|
9bbe39e9e2 | ||
|
|
cfdc7005a2 | ||
|
|
470f063124 | ||
|
|
a9d96e166a | ||
|
|
08d3803453 | ||
|
|
b48f392ab2 | ||
|
|
ce8f1156b1 | ||
|
|
82805638ad | ||
|
|
62b6e781ce | ||
|
|
00e5380331 | ||
|
|
114a768634 | ||
|
|
12261aa7a2 | ||
|
|
447b969b5c | ||
|
|
8906d44f24 | ||
|
|
5ab66056c8 | ||
|
|
e372fd9bdc | ||
|
|
d70ea2fbcb | ||
|
|
fee9c6e071 | ||
|
|
ab6b290b04 | ||
|
|
ca20ae4d64 | ||
|
|
7a5ad9f3aa | ||
|
|
d40d6fbe12 | ||
|
|
ec8e607f74 | ||
|
|
49473be3f7 | ||
|
|
d41c6f4052 | ||
|
|
67a9f7a547 | ||
|
|
9b45911141 | ||
|
|
3ec148248f | ||
|
|
cb6768463c | ||
|
|
aa0e52c245 | ||
|
|
8230d39120 | ||
|
|
7b9caffcc2 | ||
|
|
7049890f24 | ||
|
|
94cb358eae | ||
|
|
313e436c95 | ||
|
|
4268a8749b | ||
|
|
89c15c9496 | ||
|
|
7843993180 | ||
|
|
b1bc6d911b | ||
|
|
4ba192a5c3 | ||
|
|
70f6eebc5a | ||
|
|
6200a61382 | ||
|
|
6e65063317 | ||
|
|
f57c41fead | ||
|
|
7a62f44441 | ||
|
|
e1d34c24a4 | ||
|
|
65e67e9a37 | ||
|
|
86320155ed | ||
|
|
dc0651aef7 | ||
|
|
5fe569e864 | ||
|
|
57130f2f2b | ||
|
|
0b994651d1 | ||
|
|
2ed8aeb565 | ||
|
|
6f65119166 | ||
|
|
a05be3912e | ||
|
|
914ac2b09d | ||
|
|
4b26be5742 | ||
|
|
decad711c5 | ||
|
|
4715993726 | ||
|
|
d196588661 | ||
|
|
0bc8e54568 | ||
|
|
6fb66e5de6 | ||
|
|
d251bbd1a1 | ||
|
|
8212eecec7 | ||
|
|
c89aa26c0a | ||
|
|
328ed83cb9 | ||
|
|
ec8292adb7 | ||
|
|
5238244380 | ||
|
|
569d5cf694 | ||
|
|
e1a8885e43 | ||
|
|
1fabd233e9 | ||
|
|
9a05d81215 | ||
|
|
a8ee26ed89 | ||
|
|
dacfddc523 |
@@ -751,7 +751,7 @@
|
||||
"chart.js",
|
||||
"plotly.js",
|
||||
"angular2-grid",
|
||||
"html-query-plan",
|
||||
"kburtram-query-plan",
|
||||
"html-to-image",
|
||||
"turndown",
|
||||
"gridstack",
|
||||
|
||||
25
.vscode/launch.json
vendored
25
.vscode/launch.json
vendored
@@ -269,6 +269,31 @@
|
||||
"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
12
.vscode/tasks.json
vendored
@@ -231,6 +231,18 @@
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
56
CHANGELOG.md
56
CHANGELOG.md
@@ -1,5 +1,61 @@
|
||||
# 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
|
||||
|
||||
14
README.md
14
README.md
@@ -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=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
|
||||
[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
|
||||
|
||||
@@ -1 +1 @@
|
||||
2021-08-23T03:52:18.011Z
|
||||
2021-11-19T02:27:18.022Z
|
||||
|
||||
@@ -61,6 +61,7 @@ steps:
|
||||
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
|
||||
path: .build/node_modules_cache
|
||||
cacheHitVar: NODE_MODULES_RESTORED
|
||||
continueOnError: true
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
|
||||
@@ -57,6 +57,7 @@ steps:
|
||||
key: 'nodeModules | $(Agent.OS) | .build/yarnlockhash'
|
||||
path: .build/node_modules_cache
|
||||
cacheHitVar: NODE_MODULES_RESTORED
|
||||
continueOnError: true
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
@@ -187,7 +188,7 @@ steps:
|
||||
displayName: 'Install .NET Core sdk for signing'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 2.1.x
|
||||
version: 5.0.x
|
||||
installationPath: $(Agent.ToolsDirectory)/dotnet
|
||||
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
|
||||
@@ -52,6 +52,7 @@ 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
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ resources:
|
||||
containers:
|
||||
- container: linux-x64
|
||||
image: sqltoolscontainers.azurecr.io/linux-build-agent:3
|
||||
endpoint: ContainerRegistry
|
||||
endpoint: SqlToolsContainers
|
||||
|
||||
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-latest
|
||||
vmImage: 'macOS-10.15'
|
||||
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-latest
|
||||
vmImage: 'macOS-10.15'
|
||||
dependsOn:
|
||||
- macOS
|
||||
steps:
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
- job: Windows
|
||||
condition: and(succeeded(), eq(variables['VSCODE_BUILD_WIN32'], 'true'))
|
||||
pool:
|
||||
vmImage: VS2017-Win2016
|
||||
vmImage: 'windows-2019'
|
||||
dependsOn:
|
||||
- Compile
|
||||
steps:
|
||||
|
||||
@@ -2,7 +2,7 @@ resources:
|
||||
containers:
|
||||
- container: linux-x64
|
||||
image: sqltoolscontainers.azurecr.io/web-build-image:2
|
||||
endpoint: ContainerRegistry
|
||||
endpoint: SqlToolsContainers
|
||||
|
||||
jobs:
|
||||
- job: LinuxWeb
|
||||
|
||||
@@ -43,6 +43,7 @@ steps:
|
||||
path: .build/node_modules_cache
|
||||
cacheHitVar: NODE_MODULES_RESTORED
|
||||
displayName: Restore Cache - Node Modules
|
||||
continueOnError: true
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
@@ -108,7 +109,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"
|
||||
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"
|
||||
displayName: Run smoke tests (Browser)
|
||||
continueOnError: true
|
||||
condition: and(succeeded(), eq(variables['RUN_TESTS'], 'true'))
|
||||
@@ -170,7 +171,7 @@ steps:
|
||||
displayName: 'Install .NET Core sdk for signing'
|
||||
inputs:
|
||||
packageType: sdk
|
||||
version: 2.1.x
|
||||
version: 5.0.x
|
||||
installationPath: $(Agent.ToolsDirectory)/dotnet
|
||||
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
|
||||
@@ -27,7 +27,7 @@ steps:
|
||||
- powershell: |
|
||||
. build/azure-pipelines/win32/exec.ps1
|
||||
$ErrorActionPreference = "Stop"
|
||||
exec { tar --force-local -xzf $(Pipeline.Workspace)/compilation.tar.gz }
|
||||
exec { tar -xf $(Pipeline.Workspace)/compilation.tar.gz }
|
||||
displayName: Extract compilation output
|
||||
|
||||
- powershell: |
|
||||
@@ -57,6 +57,7 @@ steps:
|
||||
path: .build/node_modules_cache
|
||||
cacheHitVar: NODE_MODULES_RESTORED
|
||||
displayName: Restore Cache - Node Modules
|
||||
continueOnError: true
|
||||
|
||||
- powershell: |
|
||||
. build/azure-pipelines/win32/exec.ps1
|
||||
|
||||
@@ -65,5 +65,8 @@
|
||||
"watch": "tsc -p tsconfig.build.json --watch",
|
||||
"npmCheckJs": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {}
|
||||
"dependencies": {},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"vscode": "*",
|
||||
"azdata": "*"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionPack": [
|
||||
"Microsoft.agent",
|
||||
"Microsoft.profiler",
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
"scripts": {
|
||||
"postinstall": "node ./build/postinstall.js"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"activationEvents": [
|
||||
"onCommand:adminToolExtWin.launchSsmsMinPropertiesDialog",
|
||||
"onCommand:adminToolExtWin.launchSsmsMinGswDialog"
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
|
||||
@@ -1,27 +1,10 @@
|
||||
{
|
||||
"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": [
|
||||
"\n",
|
||||
" \n",
|
||||
@@ -33,13 +16,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",
|
||||
@@ -49,23 +32,25 @@
|
||||
"|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",
|
||||
"source": [
|
||||
"### **Setup**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "e3dd8e75-e15f-44b4-81fc-1f54d6f0b1e2"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Setup**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -74,56 +59,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",
|
||||
"source": [
|
||||
"### **Check dependencies**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "2544648b-59c9-4ce5-a3b6-87086e214d4c"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Check dependencies**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"source": [
|
||||
"### **Required information**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "0bb02e76-fee8-4dbc-a75b-d5b9d1b187d0"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Required information**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -135,85 +120,130 @@
|
||||
" 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",
|
||||
"source": [
|
||||
"### **Set and show current context**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "127c8042-181f-4862-a390-96e59c181d09"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Set and show current context**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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')"
|
||||
],
|
||||
"outputs": [],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "7d1a03d4-1df8-48eb-bff0-0042603b95b1",
|
||||
"tags": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### **Create Azure Arc Data Controller**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
|
||||
}
|
||||
"### **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')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "efe78cd3-ed73-4c9b-b586-fdd6c07dd37f"
|
||||
},
|
||||
"source": [
|
||||
"### **Create Azure Arc Data Controller**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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 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",
|
||||
"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",
|
||||
"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",
|
||||
"source": [
|
||||
"### **Setting context to created Azure Arc Data Controller**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "a3ddc701-811d-4058-b3fb-b7295fcf50ae"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Setting context to created Azure Arc Data Controller**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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
|
||||
}
|
||||
|
||||
@@ -1,28 +1,10 @@
|
||||
{
|
||||
"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": [
|
||||
"\n",
|
||||
" \n",
|
||||
@@ -34,13 +16,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",
|
||||
@@ -49,23 +31,25 @@
|
||||
"|---|---|---|\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",
|
||||
"source": [
|
||||
"### **Setup and Check Prerequisites**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "68531b91-ddce-47d7-a1d8-2ddc3d17f3e7"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Setup and Check Prerequisites**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -80,38 +64,37 @@
|
||||
" 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",
|
||||
"source": [
|
||||
"### **Creating the SQL managed instance - Azure Arc instance**"
|
||||
],
|
||||
"metadata": {
|
||||
"azdata_cell_guid": "90b0e162-2987-463f-9ce6-12dda1267189"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"### **Creating the SQL managed instance - Azure Arc instance**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -124,24 +107,44 @@
|
||||
"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} --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}{service_tier}{dev_use}{license_type}{cores_limit} --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
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "arc",
|
||||
"displayName": "%arc.displayName%",
|
||||
"description": "%arc.description%",
|
||||
"version": "0.9.6",
|
||||
"version": "0.9.7",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
@@ -21,6 +21,12 @@
|
||||
"Microsoft.azcli",
|
||||
"Microsoft.resource-deployment"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
@@ -255,6 +261,20 @@
|
||||
"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%",
|
||||
@@ -267,7 +287,11 @@
|
||||
],
|
||||
"defaultValue": "arc",
|
||||
"required": true,
|
||||
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE"
|
||||
"variableName": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_NAMESPACE",
|
||||
"enabled": {
|
||||
"target": "AZDATA_NB_VAR_ARC_DATA_CONTROLLER_CONNECTIVITY_MODE",
|
||||
"value": "Indirect"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "text",
|
||||
@@ -304,6 +328,39 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -983,7 +1040,7 @@
|
||||
"fields": [
|
||||
{
|
||||
"type": "options",
|
||||
"label": "%arc.sql.high.availability.label%",
|
||||
"label": "%arc.sql.replicas%",
|
||||
"description": "%arc.sql.high.availability.description%",
|
||||
"required": true,
|
||||
"variableName": "AZDATA_NB_VAR_SQL_REPLICAS",
|
||||
@@ -1079,6 +1136,7 @@
|
||||
"variableName": "AZDATA_NB_VAR_SQL_CORES_REQUEST",
|
||||
"type": "number",
|
||||
"min": 1,
|
||||
"defaultValue": 2,
|
||||
"required": false,
|
||||
"validations": [
|
||||
{
|
||||
@@ -1095,6 +1153,7 @@
|
||||
"type": "number",
|
||||
"min": 1,
|
||||
"required": false,
|
||||
"defaultValue": 4,
|
||||
"validations": [
|
||||
{
|
||||
"type": ">=",
|
||||
@@ -1109,6 +1168,7 @@
|
||||
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_REQUEST",
|
||||
"type": "number",
|
||||
"min": 2,
|
||||
"defaultValue": 4,
|
||||
"required": false,
|
||||
"validations": [
|
||||
{
|
||||
@@ -1124,6 +1184,7 @@
|
||||
"variableName": "AZDATA_NB_VAR_SQL_MEMORY_LIMIT",
|
||||
"type": "number",
|
||||
"min": 2,
|
||||
"defaultValue": 8,
|
||||
"required": false,
|
||||
"validations": [
|
||||
{
|
||||
@@ -1136,9 +1197,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%",
|
||||
@@ -1151,10 +1212,16 @@
|
||||
{
|
||||
"type": "checkbox",
|
||||
"label": "%arc.sql.dev.use.label%",
|
||||
"description": "%arc.sql.dev.use.description%",
|
||||
"defaultValue": "false",
|
||||
"variableName": "AZDATA_NB_VAR_SQL_DEV_USE",
|
||||
"required": true
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1179,13 +1246,85 @@
|
||||
"description": "%arc.sql.retention.days.description%",
|
||||
"variableName": "AZDATA_NB_VAR_SQL_RETENTION_DAYS",
|
||||
"type": "number",
|
||||
"min": 1,
|
||||
"min": 0,
|
||||
"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"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1235,7 +1374,6 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "^2.88.0",
|
||||
"uuid": "^8.3.0",
|
||||
"vscode-nls": "^4.1.2",
|
||||
"yamljs": "^0.3.0"
|
||||
@@ -1243,7 +1381,6 @@
|
||||
"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",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"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)",
|
||||
@@ -27,13 +28,22 @@
|
||||
"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": "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.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.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",
|
||||
@@ -87,15 +97,39 @@
|
||||
"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.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.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.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.",
|
||||
@@ -123,8 +157,10 @@
|
||||
"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": "PITR retention (days)",
|
||||
"arc.sql.retention.days.label": "Point in time 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",
|
||||
|
||||
117
extensions/arc/src/common/pricingUtils.ts
Normal file
117
extensions/arc/src/common/pricingUtils.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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);
|
||||
}
|
||||
@@ -363,3 +363,11 @@ 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);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ 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);
|
||||
@@ -61,6 +62,38 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,18 +60,19 @@ 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 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 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 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 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 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 restore = localize('arc.restore', "Restore");
|
||||
export const instance = localize('arc.instance', "Instance");
|
||||
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC)");
|
||||
export const restorePoint = localize('arc.restorePoint', "Restore point (UTC), in a time format: 'YYYY-MM-DDTHH:MM:SSZ");
|
||||
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");
|
||||
@@ -79,6 +80,7 @@ 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.");
|
||||
@@ -192,7 +194,8 @@ 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 of your choice.");
|
||||
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 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");
|
||||
@@ -274,6 +277,14 @@ 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.");
|
||||
@@ -281,6 +292,7 @@ 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)); }
|
||||
|
||||
@@ -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 { parseIpAndPort } from '../common/utils';
|
||||
import { getTimeStamp, 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, lastBackup: string };
|
||||
export type DatabaseModel = { name: string, status: string, earliestBackup: string, lastBackup: string };
|
||||
export type RPModel = { recoveryPointObjective: string, retentionDays: string };
|
||||
export type PITRModel = {
|
||||
instanceName: string,
|
||||
@@ -27,7 +27,9 @@ export type PITRModel = {
|
||||
restorePoint: string,
|
||||
earliestPitr: string,
|
||||
latestPitr: string,
|
||||
destDbName: string
|
||||
};
|
||||
|
||||
export const systemDbs = ['master', 'msdb', 'tempdb', 'model'];
|
||||
export class MiaaModel extends ResourceModel {
|
||||
|
||||
@@ -44,12 +46,20 @@ 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[]>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,6 +102,7 @@ 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
|
||||
@@ -138,6 +149,12 @@ 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);
|
||||
@@ -158,10 +175,21 @@ export class MiaaModel extends ResourceModel {
|
||||
if (!databases) {
|
||||
throw new Error('Could not fetch databases');
|
||||
}
|
||||
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: '' }; });
|
||||
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: '' }; });
|
||||
}
|
||||
}
|
||||
this.databasesLastUpdated = new Date();
|
||||
this._onDatabasesUpdated.fire(this._databases);
|
||||
@@ -206,4 +234,33 @@ 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, ['', '']);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ 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;
|
||||
@@ -32,16 +31,17 @@ export class MiaaBackupsPage extends DashboardPage {
|
||||
private _databasesMessage!: azdata.TextComponent;
|
||||
private readonly _azApi: azExt.IExtension;
|
||||
|
||||
public saveArgs: RPModel = {
|
||||
private _saveArgs: RPModel = {
|
||||
recoveryPointObjective: '',
|
||||
retentionDays: ''
|
||||
};
|
||||
|
||||
public pitrArgs = {
|
||||
private _pitrArgs = {
|
||||
destName: '',
|
||||
managedInstance: '',
|
||||
time: '',
|
||||
noWait: true
|
||||
noWait: true,
|
||||
dryRun: false
|
||||
};
|
||||
|
||||
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': '20px' } });
|
||||
root.addItem(content, { CSSStyles: { 'margin': '5px' } });
|
||||
const databaseTitle = this.modelView.modelBuilder.text().withProps({
|
||||
value: loc.databases,
|
||||
CSSStyles: { ...cssStyles.title },
|
||||
@@ -130,11 +130,19 @@ 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: '50%',
|
||||
width: '30%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow
|
||||
},
|
||||
@@ -142,7 +150,7 @@ export class MiaaBackupsPage extends DashboardPage {
|
||||
displayName: loc.restore,
|
||||
valueType: azdata.DeclarativeDataType.component,
|
||||
isReadOnly: true,
|
||||
width: '20%',
|
||||
width: '10%',
|
||||
headerCssStyles: cssStyles.tableHeader,
|
||||
rowCssStyles: cssStyles.tableRow,
|
||||
}
|
||||
@@ -198,13 +206,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,
|
||||
@@ -213,7 +221,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();
|
||||
@@ -244,13 +252,16 @@ 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;
|
||||
@@ -271,7 +282,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
|
||||
@@ -292,9 +303,9 @@ export class MiaaBackupsPage extends DashboardPage {
|
||||
if (args) {
|
||||
try {
|
||||
restoreButton.enabled = false;
|
||||
this.pitrArgs.destName = args.dbName;
|
||||
this.pitrArgs.managedInstance = args.instanceName;
|
||||
this.pitrArgs.time = `"${args.restorePoint}"`;
|
||||
this._pitrArgs.destName = args.destDbName;
|
||||
this._pitrArgs.managedInstance = args.instanceName;
|
||||
this._pitrArgs.time = `"${args.restorePoint}"`;
|
||||
await vscode.window.withProgress(
|
||||
{
|
||||
location: vscode.ProgressLocation.Notification,
|
||||
@@ -303,7 +314,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) {
|
||||
@@ -320,4 +331,6 @@ export class MiaaBackupsPage extends DashboardPage {
|
||||
}));
|
||||
return restoreButton;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export class ConfigureRPOSqlDialog extends InitializingComponent {
|
||||
this.retentionDaysInputBox = this.modelBuilder.inputBox()
|
||||
.withProps({
|
||||
readOnly: false,
|
||||
min: 1,
|
||||
min: 0,
|
||||
max: 35,
|
||||
inputType: 'number',
|
||||
ariaLabel: loc.retentionDays,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
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';
|
||||
@@ -24,6 +25,7 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
restorePoint: '-',
|
||||
earliestPitr: '-',
|
||||
latestPitr: '-',
|
||||
destDbName: '-',
|
||||
};
|
||||
|
||||
private earliestRestorePointInputBox!: azdata.InputBoxComponent;
|
||||
@@ -36,10 +38,11 @@ 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 {
|
||||
@@ -50,14 +53,15 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
this.refreshPitrSettings();
|
||||
const pitrTitle = this.modelBuilder.text().withProps({
|
||||
value: loc.pitr,
|
||||
CSSStyles: { ...cssStyles.title }
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' },
|
||||
}).component();
|
||||
const projectDetailsTitle = this.modelBuilder.text().withProps({
|
||||
value: loc.projectDetails,
|
||||
CSSStyles: { ...cssStyles.title }
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-start': '0px', 'margin-block-end': '0px', 'max-width': 'auto' }
|
||||
}).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({
|
||||
@@ -74,10 +78,11 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
|
||||
const sourceDetailsTitle = this.modelBuilder.text().withProps({
|
||||
value: loc.sourceDetails,
|
||||
CSSStyles: { ...cssStyles.title }
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
|
||||
}).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({
|
||||
@@ -85,12 +90,15 @@ 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: ''
|
||||
value: this._database.earliestBackup
|
||||
}).component();
|
||||
|
||||
this.latestRestorePointInputBox = this.modelBuilder.inputBox()
|
||||
@@ -104,14 +112,39 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
.withProps({
|
||||
readOnly: false,
|
||||
ariaLabel: loc.restorePoint,
|
||||
value: ''
|
||||
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;
|
||||
}).component();
|
||||
const databaseDetailsTitle = this.modelBuilder.text().withProps({
|
||||
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({
|
||||
value: loc.databaseDetails,
|
||||
CSSStyles: { ...cssStyles.title }
|
||||
CSSStyles: { ...cssStyles.title, 'margin-block-end': '0px', 'max-width': 'auto' }
|
||||
}).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({
|
||||
@@ -119,7 +152,10 @@ 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,
|
||||
@@ -128,7 +164,7 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
}).component();
|
||||
const info = this.modelBuilder.text().withProps({
|
||||
value: loc.restoreInfo,
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'margin-block-end': '0px' }
|
||||
CSSStyles: { ...cssStyles.text, 'margin-block-start': '0px', 'max-width': 'auto' }
|
||||
}).component();
|
||||
|
||||
const link = this.modelBuilder.hyperlink().withProps({
|
||||
@@ -178,22 +214,7 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
|
||||
},
|
||||
{
|
||||
component: this.earliestRestorePointInputBox,
|
||||
title: loc.earliestPitrRestorePoint,
|
||||
|
||||
},
|
||||
{
|
||||
component: this.latestRestorePointInputBox,
|
||||
title: loc.latestpitrRestorePoint,
|
||||
|
||||
},
|
||||
{
|
||||
component: this.restorePointInputBox,
|
||||
title: loc.restorePoint,
|
||||
required: true
|
||||
},
|
||||
{
|
||||
component: databaseDetailsTitle,
|
||||
component: destinationDetailsTitle,
|
||||
},
|
||||
{
|
||||
component: databaseDetailsTextLabel,
|
||||
@@ -208,6 +229,27 @@ export class RestoreSqlDialog extends InitializingComponent {
|
||||
title: loc.instance,
|
||||
|
||||
},
|
||||
{
|
||||
component: pitrDetailsTitle
|
||||
},
|
||||
{
|
||||
component: restoreDetailsTextLabel,
|
||||
},
|
||||
{
|
||||
component: this.earliestRestorePointInputBox,
|
||||
title: loc.earliestPitrRestorePoint,
|
||||
|
||||
},
|
||||
{
|
||||
component: this.latestRestorePointInputBox,
|
||||
title: loc.latestpitrRestorePoint,
|
||||
|
||||
},
|
||||
{
|
||||
component: this.restorePointInputBox,
|
||||
title: loc.restorePoint,
|
||||
required: true
|
||||
},
|
||||
],
|
||||
title: ''
|
||||
}]).withLayout({ width: '100%' }).component();
|
||||
@@ -269,4 +311,9 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -228,36 +228,16 @@
|
||||
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"
|
||||
@@ -270,11 +250,6 @@
|
||||
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"
|
||||
@@ -292,16 +267,6 @@ 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"
|
||||
@@ -328,45 +293,11 @@ 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"
|
||||
@@ -385,11 +316,6 @@ 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"
|
||||
@@ -421,13 +347,6 @@ 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"
|
||||
@@ -445,23 +364,11 @@ 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"
|
||||
@@ -504,11 +411,6 @@ 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"
|
||||
@@ -519,14 +421,6 @@ 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"
|
||||
@@ -544,54 +438,6 @@ 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"
|
||||
@@ -602,13 +448,6 @@ 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"
|
||||
@@ -643,19 +482,6 @@ 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"
|
||||
@@ -684,15 +510,6 @@ 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"
|
||||
@@ -719,21 +536,11 @@ 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"
|
||||
@@ -794,31 +601,11 @@ 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"
|
||||
@@ -826,16 +613,6 @@ 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"
|
||||
@@ -875,18 +652,6 @@ 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"
|
||||
@@ -975,11 +740,6 @@ 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"
|
||||
@@ -1004,11 +764,6 @@ 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"
|
||||
@@ -1019,47 +774,6 @@ 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"
|
||||
@@ -1074,21 +788,11 @@ 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"
|
||||
@@ -1171,21 +875,6 @@ 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"
|
||||
@@ -1224,26 +913,6 @@ 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"
|
||||
@@ -1258,32 +927,11 @@ 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"
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"forceReload": true,
|
||||
"contributes": {
|
||||
"resourceDeploymentTypes": [
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "azcli",
|
||||
"displayName": "%azcli.arc.displayName%",
|
||||
"description": "%azcli.arc.description%",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"license": "https://raw.githubusercontent.com/Microsoft/azuredatastudio/main/LICENSE.txt",
|
||||
@@ -18,6 +18,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"microsoft.resource-deployment"
|
||||
],
|
||||
@@ -105,6 +111,9 @@
|
||||
"typemoq": "^2.1.0",
|
||||
"vscodetestcover": "^1.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "84",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
|
||||
@@ -140,6 +140,7 @@ export function getAzApi(localAzDiscovered: Promise<IAzTool | undefined>, azTool
|
||||
managedInstance?: string,
|
||||
time?: string,
|
||||
noWait?: boolean,
|
||||
dryRun?: boolean
|
||||
},
|
||||
namespace: string, additionalEnvVars?: azExt.AdditionalEnvVars) => {
|
||||
await localAzDiscovered;
|
||||
|
||||
@@ -185,16 +185,18 @@ export class AzTool implements azExt.IAzApi {
|
||||
managedInstance?: string,
|
||||
time?: string,
|
||||
noWait?: boolean,
|
||||
dryRun?: boolean
|
||||
},
|
||||
namespace: string,
|
||||
additionalEnvVars?: azExt.AdditionalEnvVars
|
||||
): Promise<azExt.AzOutput<void>> => {
|
||||
): Promise<azExt.AzOutput<azExt.SqlMiDbRestoreResult>> => {
|
||||
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'); }
|
||||
return this.executeCommand<void>(argsArray, additionalEnvVars);
|
||||
if (args.dryRun) { argsArray.push('--dry-run'); }
|
||||
return this.executeCommand<azExt.SqlMiDbRestoreResult>(argsArray, additionalEnvVars);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
14
extensions/azcli/src/typings/az-ext.d.ts
vendored
14
extensions/azcli/src/typings/az-ext.d.ts
vendored
@@ -173,6 +173,17 @@ 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"
|
||||
@@ -336,10 +347,11 @@ 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<void>>
|
||||
): Promise<AzOutput<SqlMiDbRestoreResult>>
|
||||
}
|
||||
},
|
||||
getPath(): Promise<string>,
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"resourceViewResources": [
|
||||
{
|
||||
@@ -322,11 +328,6 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"resourceDeploymentValueProviders": [
|
||||
{
|
||||
"id": "subscription-id-to-tenant-id"
|
||||
}
|
||||
],
|
||||
"hasAzureResourceProviders": true
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -153,27 +153,27 @@ export async function getLocations(appContext: AppContext, account?: AzureAccoun
|
||||
result.errors.push(error);
|
||||
return result;
|
||||
}
|
||||
await Promise.all(account.properties.tenants.map(async (tenant: { id: string; }) => {
|
||||
try {
|
||||
const path = `/subscriptions/${subscription.id}/locations?api-version=2020-01-01`;
|
||||
const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors);
|
||||
result.locations.push(...response.response.data.value);
|
||||
result.errors.push(...response.errors);
|
||||
} catch (err) {
|
||||
const error = new Error(localize('azure.accounts.getLocations.queryError', "Error fetching locations for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}",
|
||||
account.displayInfo.displayName,
|
||||
account.displayInfo.userId,
|
||||
subscription.id,
|
||||
subscription.name,
|
||||
tenant.id,
|
||||
err instanceof Error ? err.message : err));
|
||||
console.warn(error);
|
||||
if (!ignoreErrors) {
|
||||
throw error;
|
||||
}
|
||||
result.errors.push(error);
|
||||
|
||||
try {
|
||||
const path = `/subscriptions/${subscription.id}/locations?api-version=2020-01-01`;
|
||||
const response = await makeHttpRequest(account, subscription, path, HttpRequestMethod.GET, undefined, ignoreErrors);
|
||||
result.locations.push(...response.response.data.value);
|
||||
result.errors.push(...response.errors);
|
||||
} catch (err) {
|
||||
const error = new Error(localize('azure.accounts.getLocations.queryError', "Error fetching locations for account {0} ({1}) subscription {2} ({3}) tenant {4} : {5}",
|
||||
account.displayInfo.displayName,
|
||||
account.displayInfo.userId,
|
||||
subscription.id,
|
||||
subscription.name,
|
||||
account.properties.tenants[0].id,
|
||||
err instanceof Error ? err.message : err));
|
||||
console.warn(error);
|
||||
if (!ignoreErrors) {
|
||||
throw error;
|
||||
}
|
||||
}));
|
||||
result.errors.push(error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ 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';
|
||||
@@ -115,40 +114,6 @@ 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
|
||||
|
||||
1
extensions/azurecore/src/typings/ref.d.ts
vendored
1
extensions/azurecore/src/typings/ref.d.ts
vendored
@@ -7,5 +7,4 @@
|
||||
/// <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'/>
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
|
||||
@@ -16,6 +16,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"typings": "./src/azuremonitor",
|
||||
"contributes": {
|
||||
"connectionProvider": {
|
||||
@@ -109,20 +115,6 @@
|
||||
"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
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"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": [
|
||||
{
|
||||
|
||||
@@ -27,6 +27,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"dataExplorer": {
|
||||
@@ -248,7 +254,7 @@
|
||||
},
|
||||
{
|
||||
"name": "azdata",
|
||||
"version": "20.3.4"
|
||||
"version": "20.3.9"
|
||||
}
|
||||
],
|
||||
"when": "target=new-aks&&version=bdc2019"
|
||||
@@ -266,7 +272,7 @@
|
||||
},
|
||||
{
|
||||
"name": "azdata",
|
||||
"version": "20.3.4"
|
||||
"version": "20.3.9"
|
||||
}
|
||||
],
|
||||
"when": "target=existing-aks&&version=bdc2019"
|
||||
@@ -284,7 +290,7 @@
|
||||
},
|
||||
{
|
||||
"name": "azdata",
|
||||
"version": "20.3.4"
|
||||
"version": "20.3.9"
|
||||
}
|
||||
],
|
||||
"when": "target=existing-kubeadm&&version=bdc2019"
|
||||
@@ -302,7 +308,7 @@
|
||||
},
|
||||
{
|
||||
"name": "azdata",
|
||||
"version": "20.3.4"
|
||||
"version": "20.3.9"
|
||||
}
|
||||
],
|
||||
"when": "target=existing-aro&&version=bdc2019"
|
||||
@@ -320,7 +326,7 @@
|
||||
},
|
||||
{
|
||||
"name": "azdata",
|
||||
"version": "20.3.4"
|
||||
"version": "20.3.9"
|
||||
}
|
||||
],
|
||||
"when": "target=existing-openshift&&version=bdc2019"
|
||||
@@ -356,5 +362,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/request": "^2.48.3"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
|
||||
@@ -22,6 +22,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"main": "./out/extension",
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
@@ -618,7 +624,8 @@
|
||||
"when": "viewItem == cms.resource.itemType.databaseServerContainer",
|
||||
"group": "navigation@10"
|
||||
}
|
||||
],"commandPalette": [
|
||||
],
|
||||
"commandPalette": [
|
||||
{
|
||||
"command": "cms.resource.addRegisteredServer",
|
||||
"when": "false"
|
||||
@@ -647,7 +654,6 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"request": "2.88.0",
|
||||
"vscode-nls": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -192,16 +192,6 @@
|
||||
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"
|
||||
@@ -221,45 +211,11 @@ 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"
|
||||
@@ -278,11 +234,6 @@ 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"
|
||||
@@ -302,11 +253,6 @@ 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"
|
||||
@@ -319,20 +265,6 @@ 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"
|
||||
@@ -350,23 +282,11 @@ 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"
|
||||
@@ -409,68 +329,16 @@ 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"
|
||||
@@ -481,13 +349,6 @@ 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"
|
||||
@@ -534,19 +395,6 @@ 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"
|
||||
@@ -567,15 +415,6 @@ 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"
|
||||
@@ -594,16 +433,6 @@ 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"
|
||||
@@ -667,31 +496,11 @@ 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"
|
||||
@@ -699,16 +508,6 @@ 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"
|
||||
@@ -738,18 +537,6 @@ 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"
|
||||
@@ -820,11 +607,6 @@ 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"
|
||||
@@ -842,11 +624,6 @@ 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"
|
||||
@@ -857,47 +634,6 @@ 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"
|
||||
@@ -912,16 +648,11 @@ rimraf@^2.6.3:
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.1:
|
||||
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"
|
||||
@@ -986,22 +717,6 @@ 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"
|
||||
@@ -1040,26 +755,6 @@ 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"
|
||||
@@ -1069,20 +764,6 @@ 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"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "dacpac",
|
||||
"displayName": "SQL Server Dacpac",
|
||||
"description": "SQL Server Dacpac for Azure Data Studio.",
|
||||
"version": "1.9.1",
|
||||
"version": "1.10.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": false,
|
||||
"engines": {
|
||||
@@ -20,6 +20,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
# 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.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "data-workspace",
|
||||
"displayName": "%extension-displayName%",
|
||||
"description": "%extension-description%",
|
||||
"displayName": "Data Workspace",
|
||||
"description": "Additional common functionality for database projects",
|
||||
"version": "0.1.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
@@ -20,6 +20,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [],
|
||||
"contributes": {
|
||||
"configuration": [
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
{
|
||||
"extension-displayName": "Data workspace",
|
||||
"extension-description": "Data workspace",
|
||||
"data-workspace-view-container-name": "Projects",
|
||||
"main-view-name": "Projects",
|
||||
"data-workspace-view-container-name": "Database Projects",
|
||||
"main-view-name": "Database Projects",
|
||||
"new-command": "New",
|
||||
"refresh-workspace-command": "Refresh",
|
||||
"close-workspace-command": "Close Workspace",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"name": "data-workspace-vscode",
|
||||
"publisher": "ms-mssql",
|
||||
"extensionDependencies": [
|
||||
"ms-mssql.mssql"
|
||||
]
|
||||
|
||||
@@ -8,7 +8,7 @@ declare module 'dataworkspace' {
|
||||
import * as vscode from 'vscode';
|
||||
export const enum extension {
|
||||
name = 'Microsoft.data-workspace',
|
||||
vscodeName = 'Microsoft.data-workspace-vscode'
|
||||
vscodeName = 'ms-mssql.data-workspace-vscode'
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
|
||||
@@ -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,5 +44,8 @@
|
||||
"mocha-multi-reporters": "^1.1.7",
|
||||
"ms-rest-azure": "^2.6.0",
|
||||
"vscodetestcover": "^1.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
let target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -63,6 +67,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -114,6 +122,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: sourceDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
let target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -123,6 +135,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: targetDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -179,6 +195,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
let target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -188,6 +208,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: targetDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -231,6 +255,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
let target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -240,6 +268,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -297,6 +329,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
const target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -306,6 +342,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: targetDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -323,7 +363,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.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
|
||||
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(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
|
||||
@@ -372,6 +412,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
const target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -381,6 +425,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: targetDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
@@ -390,7 +438,7 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
assertSchemaCompareResult(schemaCompareResult, operationId, 4);
|
||||
|
||||
//publish all the changes
|
||||
const publishChangesResult = await schemaCompareService.schemaComparePublishChanges(schemaCompareResult.operationId, server.serverName, targetDB, azdata.TaskExecutionMode.execute);
|
||||
const publishChangesResult = await schemaCompareService.schemaComparePublishDatabaseChanges(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
|
||||
@@ -435,6 +483,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
const target: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -444,6 +496,10 @@ suite('Schema compare integration test suite @DacFx@', () => {
|
||||
serverName: server.serverName,
|
||||
databaseName: targetDB,
|
||||
ownerUri: ownerUri,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
connectionDetails: undefined
|
||||
};
|
||||
|
||||
|
||||
@@ -202,6 +202,11 @@
|
||||
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"
|
||||
@@ -217,6 +222,20 @@ 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"
|
||||
@@ -275,6 +294,13 @@ 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"
|
||||
@@ -290,6 +316,13 @@ 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"
|
||||
@@ -515,6 +548,11 @@ 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"
|
||||
@@ -742,10 +780,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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
@@ -786,7 +824,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.14.0, lodash@^4.16.4, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@@ -904,7 +942,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.6.0:
|
||||
ms-rest-azure@^2.5.5:
|
||||
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==
|
||||
@@ -916,6 +954,17 @@ ms-rest-azure@^2.5.5, ms-rest-azure@^2.6.0:
|
||||
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"
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
"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": [
|
||||
{
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql",
|
||||
"Microsoft.notebook"
|
||||
@@ -150,6 +156,9 @@
|
||||
"typemoq": "^2.1.0",
|
||||
"vscodetestcover": "^1.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
},
|
||||
"__metadata": {
|
||||
"id": "65",
|
||||
"publisherDisplayName": "Microsoft",
|
||||
|
||||
@@ -303,6 +303,7 @@ 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
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"downloadUrl": "https://github.com/Microsoft/sqltoolsservice/releases/download/v{#version#}/microsoft.sqltools.servicelayer-{#fileName#}",
|
||||
"version": "3.0.0-release.139",
|
||||
"version": "3.0.0-release.174",
|
||||
"downloadFileNames": {
|
||||
"Windows_86": "win-x86-net5.0.zip",
|
||||
"Windows_64": "win-x64-net5.0.zip",
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
"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": [
|
||||
{
|
||||
@@ -492,6 +498,11 @@
|
||||
"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": [
|
||||
@@ -1304,5 +1315,8 @@
|
||||
"should": "^13.2.3",
|
||||
"typemoq": "^2.1.0",
|
||||
"vscodetestcover": "^1.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"json-schema": "0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,13 +628,20 @@ export interface SchemaCompareGenerateScriptParams {
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
}
|
||||
|
||||
export interface SchemaComparePublishChangesParams {
|
||||
export interface SchemaComparePublishDatabaseChangesParams {
|
||||
operationId: string;
|
||||
targetServerName: string;
|
||||
targetDatabaseName: string;
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
}
|
||||
|
||||
export interface SchemaComparePublishProjectChangesParams {
|
||||
operationId: string;
|
||||
targetProjectPath: string;
|
||||
targetFolderStructure: mssql.ExtractTarget;
|
||||
taskExecutionMode: TaskExecutionMode;
|
||||
}
|
||||
|
||||
export interface SchemaCompareGetOptionsParams {
|
||||
|
||||
}
|
||||
@@ -673,7 +680,15 @@ export namespace SchemaCompareGenerateScriptRequest {
|
||||
}
|
||||
|
||||
export namespace SchemaComparePublishChangesRequest {
|
||||
export const type = new RequestType<SchemaComparePublishChangesParams, azdata.ResultStatus, void, void>('schemaCompare/publish');
|
||||
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 namespace SchemaCompareGetDefaultOptionsRequest {
|
||||
@@ -1030,12 +1045,12 @@ export namespace GetSqlMigrationAssessmentItemsRequest {
|
||||
export interface TableDesignerEditRequestParams {
|
||||
tableInfo: azdata.designers.TableInfo,
|
||||
tableChangeInfo: azdata.designers.DesignerEdit,
|
||||
data: azdata.designers.DesignerData
|
||||
viewModel: azdata.designers.DesignerViewModel
|
||||
}
|
||||
|
||||
export interface SaveTableDesignerChangesRequestParams {
|
||||
tableInfo: azdata.designers.TableInfo,
|
||||
data: azdata.designers.DesignerData
|
||||
viewModel: azdata.designers.DesignerViewModel
|
||||
}
|
||||
|
||||
export namespace GetTableDesignerInfoRequest {
|
||||
@@ -1050,4 +1065,7 @@ 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 > ------------------------------------
|
||||
|
||||
@@ -1117,10 +1117,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
|
||||
return Promise.reject(e);
|
||||
}
|
||||
};
|
||||
const processTableEdit = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
|
||||
const processTableEdit = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel, tableChangeInfo: azdata.designers.DesignerEdit): Thenable<azdata.designers.DesignerEditResult> => {
|
||||
let params: contracts.TableDesignerEditRequestParams = {
|
||||
tableInfo: tableInfo,
|
||||
data: data,
|
||||
viewModel: viewModel,
|
||||
tableChangeInfo: tableChangeInfo
|
||||
};
|
||||
try {
|
||||
@@ -1132,10 +1132,10 @@ export class TableDesignerFeature extends SqlOpsFeature<undefined> {
|
||||
}
|
||||
};
|
||||
|
||||
const saveTable = (tableInfo: azdata.designers.TableInfo, data: azdata.designers.DesignerData): Thenable<void> => {
|
||||
const saveTable = (tableInfo: azdata.designers.TableInfo, viewModel: azdata.designers.DesignerViewModel): Thenable<void> => {
|
||||
let params: contracts.SaveTableDesignerChangesRequestParams = {
|
||||
tableInfo: tableInfo,
|
||||
data: data
|
||||
viewModel: viewModel
|
||||
};
|
||||
try {
|
||||
return client.sendRequest(contracts.SaveTableDesignerChangesRequest.type, params);
|
||||
@@ -1146,11 +1146,22 @@ 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
|
||||
saveTable,
|
||||
disposeTableDesigner
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
18
extensions/mssql/src/mssql.d.ts
vendored
18
extensions/mssql/src/mssql.d.ts
vendored
@@ -122,7 +122,10 @@ export const enum SchemaDifferenceType {
|
||||
|
||||
export const enum SchemaCompareEndpointType {
|
||||
Database = 0,
|
||||
Dacpac = 1
|
||||
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
|
||||
}
|
||||
|
||||
export interface SchemaCompareEndpointInfo {
|
||||
@@ -134,6 +137,10 @@ export interface SchemaCompareEndpointInfo {
|
||||
ownerUri: string;
|
||||
connectionDetails: azdata.ConnectionInfo;
|
||||
connectionName?: string;
|
||||
projectFilePath: string;
|
||||
targetScripts: string[];
|
||||
folderStructure: string;
|
||||
dataSchemaProvider: string;
|
||||
}
|
||||
|
||||
export interface SchemaCompareObjectId {
|
||||
@@ -307,10 +314,11 @@ 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>;
|
||||
@@ -328,6 +336,12 @@ export interface SchemaCompareOpenScmpResult extends azdata.ResultStatus {
|
||||
excludedTargetElements: SchemaCompareObjectId[];
|
||||
}
|
||||
|
||||
export interface SchemaComparePublishProjectResult extends azdata.ResultStatus {
|
||||
changedFiles: string[];
|
||||
addedFiles: string[];
|
||||
deletedFiles: string[];
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region --- dacfx
|
||||
|
||||
@@ -55,11 +55,31 @@ export class SchemaCompareService implements mssql.ISchemaCompareService {
|
||||
}
|
||||
|
||||
public schemaComparePublishChanges(operationId: string, targetServerName: string, targetDatabaseName: string, taskExecutionMode: azdata.TaskExecutionMode): Thenable<azdata.ResultStatus> {
|
||||
const params: contracts.SchemaComparePublishChangesParams = { operationId: operationId, targetServerName: targetServerName, targetDatabaseName: targetDatabaseName, taskExecutionMode: taskExecutionMode };
|
||||
return this.client.sendRequest(contracts.SchemaComparePublishChangesRequest.type, params).then(
|
||||
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(
|
||||
undefined,
|
||||
e => {
|
||||
this.client.logFailedRequest(contracts.SchemaComparePublishChangesRequest.type, 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);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -7,15 +7,17 @@ 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 connectionUri = await azdata.connection.getUriForConnection(context.connectionProfile.id);
|
||||
const connectionString = await azdata.connection.getConnectionString(context.connectionProfile.id, true);
|
||||
await azdata.designers.openTableDesigner(sqlProviderName, {
|
||||
server: context.connectionProfile.serverName,
|
||||
database: context.connectionProfile.databaseName,
|
||||
isNewTable: true,
|
||||
connectionUri: connectionUri
|
||||
id: generateUuid(),
|
||||
connectionString: connectionString
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -24,6 +26,7 @@ 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,
|
||||
@@ -31,9 +34,8 @@ export function registerTableDesignerCommands(appContext: AppContext) {
|
||||
isNewTable: false,
|
||||
name: name,
|
||||
schema: schema,
|
||||
id: `${server}|${database}|${schema}|${name}`,
|
||||
connectionUri: connectionUri
|
||||
id: `${connectionUri}|${database}|${schema}|${name}`,
|
||||
connectionString: connectionString
|
||||
});
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
"activationEvents": [
|
||||
"*"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"type": "object",
|
||||
@@ -418,6 +424,10 @@
|
||||
"command": "notebook.command.addNotebook",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "notebook.command.addSection",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "notebook.command.addMarkdown",
|
||||
"when": "false"
|
||||
@@ -680,48 +690,50 @@
|
||||
]
|
||||
}
|
||||
],
|
||||
"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",
|
||||
@@ -762,7 +774,8 @@
|
||||
"vscodetestcover": "^1.1.0"
|
||||
},
|
||||
"resolutions": {
|
||||
"url-parse": "^1.5.1"
|
||||
"url-parse": "^1.5.1",
|
||||
"json-schema": "0.4.0"
|
||||
},
|
||||
"enableProposedApi": true
|
||||
}
|
||||
|
||||
@@ -89,26 +89,26 @@ export class BookTocManager implements IBookTocManager {
|
||||
let toc: JupyterBookSection[] = [];
|
||||
for (const content of contents) {
|
||||
try {
|
||||
const contentStat = (await fs.promises.stat(path.join(directory, content)));
|
||||
const contentStat = (await fs.promises.stat(path.posix.join(directory, content)));
|
||||
const parsedFile = path.parse(content);
|
||||
if (contentStat.isFile() && allowedFileExtensions.includes(parsedFile.ext)) {
|
||||
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name) : path.posix.join(path.posix.sep, path.relative(rootDirectory, directory), parsedFile.name);
|
||||
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name) : path.posix.join(path.posix.sep, path.posix.relative(rootDirectory, directory), parsedFile.name);
|
||||
const section: JupyterBookSection = {
|
||||
title: parsedFile.name,
|
||||
file: filePath
|
||||
};
|
||||
toc.push(section);
|
||||
} else if (contentStat.isDirectory()) {
|
||||
let files = await fs.promises.readdir(path.join(directory, content));
|
||||
let files = await fs.promises.readdir(path.posix.join(directory, content));
|
||||
let initFile = this.getInitFile(files);
|
||||
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name, initFile.name) : path.posix.join(path.posix.sep, path.relative(rootDirectory, directory), parsedFile.name, initFile.name);
|
||||
let filePath = directory === rootDirectory ? path.posix.join(path.posix.sep, parsedFile.name, initFile.name) : path.posix.join(path.posix.sep, path.posix.relative(rootDirectory, directory), parsedFile.name, initFile.name);
|
||||
let section: JupyterBookSection = {};
|
||||
section = {
|
||||
title: parsedFile.name,
|
||||
file: filePath,
|
||||
expand_sections: true,
|
||||
numbered: false,
|
||||
sections: await this.createTocFromDir(files, path.join(directory, content), rootDirectory)
|
||||
sections: await this.createTocFromDir(files, path.posix.join(directory, content), rootDirectory)
|
||||
};
|
||||
toc.push(section);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ export class InstalledPackagesTab {
|
||||
}
|
||||
],
|
||||
data: [[]],
|
||||
height: '600px',
|
||||
height: '500px',
|
||||
width: '400px'
|
||||
}).component();
|
||||
this.disposables.push(this.installedPackagesTable.onCellAction(async (rowState) => {
|
||||
|
||||
@@ -85,6 +85,7 @@ describe('BookTocManagerTests', function () {
|
||||
let rootFolderPath: string;
|
||||
let root2FolderPath: string;
|
||||
const subfolder = 'Subfolder';
|
||||
const subfolder2 = 'Subfolder2';
|
||||
|
||||
afterEach(function (): void {
|
||||
sinon.restore();
|
||||
@@ -94,7 +95,7 @@ describe('BookTocManagerTests', function () {
|
||||
rootFolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
|
||||
bookFolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
|
||||
root2FolderPath = path.join(os.tmpdir(), `BookTestData_${uuid.v4()}`);
|
||||
notebooks = ['notebook1.ipynb', 'notebook2.ipynb', 'notebook3.ipynb', 'index.md'];
|
||||
notebooks = ['notebook1.ipynb', 'notebook2.ipynb', 'notebook3.ipynb', 'index.md', 'notebook4.ipynb', 'notebook5.ipynb'];
|
||||
|
||||
await fs.mkdir(rootFolderPath);
|
||||
await fs.writeFile(path.join(rootFolderPath, notebooks[0]), '');
|
||||
@@ -104,6 +105,8 @@ describe('BookTocManagerTests', function () {
|
||||
|
||||
await fs.mkdir(root2FolderPath);
|
||||
await fs.mkdir(path.join(root2FolderPath, subfolder));
|
||||
await fs.mkdir(path.join(root2FolderPath, subfolder, subfolder2));
|
||||
|
||||
await fs.writeFile(path.join(root2FolderPath, notebooks[0]), '');
|
||||
await fs.writeFile(path.join(root2FolderPath, subfolder, notebooks[1]), '');
|
||||
await fs.writeFile(path.join(root2FolderPath, subfolder, notebooks[2]), '');
|
||||
@@ -145,6 +148,51 @@ describe('BookTocManagerTests', function () {
|
||||
should(bookTocManager.tableofContents.length).be.equal(4);
|
||||
should(listFiles.length).be.equal(7);
|
||||
});
|
||||
|
||||
it ('should create a table of contents with sections if folder contains subfolders', async () => {
|
||||
await fs.writeFile(path.join(root2FolderPath, subfolder, subfolder2, notebooks[4]), '');
|
||||
await fs.writeFile(path.join(root2FolderPath, subfolder, subfolder2, notebooks[5]), '');
|
||||
|
||||
let bookTocManager: BookTocManager = new BookTocManager();
|
||||
await bookTocManager.createBook(bookFolderPath, root2FolderPath);
|
||||
let listFiles = await fs.promises.readdir(bookFolderPath);
|
||||
should(bookTocManager.tableofContents.length).be.equal(3);
|
||||
should(listFiles.length).be.equal(5);
|
||||
|
||||
let expectedSubSections: IJupyterBookSectionV2[] = [{
|
||||
title: 'notebook4',
|
||||
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4')
|
||||
},
|
||||
{
|
||||
title: 'notebook5',
|
||||
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook5')
|
||||
}];
|
||||
|
||||
let expectedSection: IJupyterBookSectionV2[] = [{
|
||||
title: 'index',
|
||||
file: path.posix.join(path.posix.sep, subfolder, 'index')
|
||||
},
|
||||
{
|
||||
title: 'notebook2',
|
||||
file: path.posix.join(path.posix.sep, subfolder, 'notebook2')
|
||||
},
|
||||
{
|
||||
title: 'notebook3',
|
||||
file: path.posix.join(path.posix.sep, subfolder, 'notebook3')
|
||||
},
|
||||
{
|
||||
title: 'Subfolder2',
|
||||
file: path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4'),
|
||||
sections : expectedSubSections
|
||||
}];
|
||||
|
||||
const index = bookTocManager.tableofContents.findIndex(entry => entry.file === path.posix.join(path.posix.sep, subfolder, 'index'));
|
||||
should(index).not.be.equal(-1, 'Should find a section with the Subfolder entry');
|
||||
if (index !== -1) {
|
||||
let subsection = bookTocManager.tableofContents[index].sections.find(entry => entry.file === path.posix.join(path.posix.sep, subfolder, subfolder2, 'notebook4'));
|
||||
should(equalSections(subsection, expectedSection[3])).be.true('Should find a subsection with the subfolder2 inside the subfolder');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('EditingBooks', () => {
|
||||
|
||||
@@ -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:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
|
||||
integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
|
||||
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-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
|
||||
@@ -25,6 +25,12 @@
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
|
||||
@@ -20,6 +20,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [],
|
||||
"contributes": {
|
||||
"commands": [
|
||||
|
||||
236
extensions/resource-deployment/DEVELOPER_GUIDE.md
Normal file
236
extensions/resource-deployment/DEVELOPER_GUIDE.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# 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`.
|
||||
|
||||
@@ -21,6 +21,12 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/azuredatastudio.git"
|
||||
},
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"extensionDependencies": [
|
||||
"microsoft.mssql",
|
||||
"microsoft.notebook"
|
||||
|
||||
@@ -307,7 +307,7 @@ export interface DynamicOptionsAlternates {
|
||||
|
||||
export interface ValueProviderInfo {
|
||||
providerId: string,
|
||||
triggerField: string
|
||||
triggerFields: string[]
|
||||
}
|
||||
|
||||
export interface FieldInfoBase {
|
||||
|
||||
@@ -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>{
|
||||
|
||||
@@ -24,9 +24,19 @@ 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,
|
||||
getValue(triggerValue: string): Promise<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>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,6 +48,12 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import { azureResource } from 'azureResource';
|
||||
import * as fs from 'fs';
|
||||
import { EOL } from 'os';
|
||||
import * as path from 'path';
|
||||
import { IOptionsSourceProvider } from 'resource-deployment';
|
||||
import { InputValueType, IOptionsSourceProvider } from 'resource-deployment';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { getDateTimeString, getErrorMessage, isUserCancelledError, throwUnless } from '../common/utils';
|
||||
@@ -33,7 +33,6 @@ 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;
|
||||
@@ -471,20 +470,35 @@ 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 () => {
|
||||
const targetComponentValue = await targetComponent.getValue();
|
||||
const newFieldValue = await provider.getValue(targetComponentValue?.toString() ?? '');
|
||||
let targetComponentLabelToValue: { [label: string]: InputValueType; } = {};
|
||||
for (let label in targetComponentLabelToComponent) {
|
||||
targetComponentLabelToValue[label] = await targetComponentLabelToComponent[label].getValue();
|
||||
}
|
||||
let newFieldValue = await provider.getValue(targetComponentLabelToValue);
|
||||
fieldComponent.setValue(newFieldValue);
|
||||
};
|
||||
targetComponent.onValueChanged(() => {
|
||||
updateFields();
|
||||
});
|
||||
|
||||
// Set the onValueChanged behavior for each component
|
||||
for (let label in targetComponentLabelToComponent) {
|
||||
context.onNewDisposableCreated(targetComponentLabelToComponent[label].onValueChanged(() => {
|
||||
updateFields();
|
||||
}));
|
||||
}
|
||||
await updateFields();
|
||||
}
|
||||
}));
|
||||
@@ -762,7 +776,10 @@ 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 defaultValue = initialValue || options.defaultValue;
|
||||
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 dropdown = createDropdownInputInfo(context.view, {
|
||||
values: options.values,
|
||||
defaultValue: defaultValue,
|
||||
@@ -863,6 +880,18 @@ 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 };
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "schema-compare",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.12.0",
|
||||
"version": "1.13.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": false,
|
||||
"engines": {
|
||||
@@ -23,6 +23,12 @@
|
||||
"extensionDependencies": [
|
||||
"Microsoft.mssql"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"commands": [
|
||||
{
|
||||
|
||||
@@ -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 } from '../utils';
|
||||
import { getEndpointName, getRootPath, exists, getAzdataApi, getSchemaCompareEndpointString } from '../utils';
|
||||
import * as mssql from '../../../mssql';
|
||||
|
||||
const titleFontSize: number = 13;
|
||||
@@ -18,13 +18,16 @@ 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 schemaCompareTab: azdata.window.DialogTab;
|
||||
private sourceProjectRadioButton: azdata.RadioButtonComponent;
|
||||
private sourceDacpacComponent: azdata.FormComponent;
|
||||
private sourceProjectFilePathComponent: azdata.FormComponent;
|
||||
private sourceTextBox: azdata.InputBoxComponent;
|
||||
private sourceFileButton: azdata.ButtonComponent;
|
||||
private sourceServerComponent: azdata.FormComponent;
|
||||
@@ -32,22 +35,30 @@ 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 formBuilder: azdata.FormBuilder;
|
||||
private sourceIsDacpac: boolean;
|
||||
private targetIsDacpac: boolean;
|
||||
private connectionId: string;
|
||||
private sourceDbEditable: string;
|
||||
private targetDacpacPath: string;
|
||||
private targetProjectFilePath: string;
|
||||
private targetEndpointType: mssql.SchemaCompareEndpointType;
|
||||
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 });
|
||||
|
||||
@@ -59,6 +70,11 @@ 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> {
|
||||
@@ -79,27 +95,17 @@ export class SchemaCompareDialog {
|
||||
|
||||
this.dialog.okButton.label = loc.OkButtonText;
|
||||
this.dialog.okButton.enabled = false;
|
||||
this.dialog.okButton.onClick(async () => await this.execute());
|
||||
this.toDispose.push(this.dialog.okButton.onClick(async () => await this.handleOkButtonClick()));
|
||||
|
||||
this.dialog.cancelButton.label = loc.CancelButtonText;
|
||||
this.dialog.cancelButton.onClick(async () => await this.cancel());
|
||||
this.toDispose.push(this.dialog.cancelButton.onClick(async () => await this.cancel()));
|
||||
|
||||
azdata.window.openDialog(this.dialog);
|
||||
await this.initDialogPromise;
|
||||
}
|
||||
|
||||
public async execute(): Promise<void> {
|
||||
if (this.sourceIsDacpac) {
|
||||
this.schemaCompareMainWindow.sourceEndpointInfo = {
|
||||
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
|
||||
serverDisplayName: '',
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
packageFilePath: this.sourceTextBox.value,
|
||||
connectionDetails: undefined
|
||||
};
|
||||
} else {
|
||||
if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Database) {
|
||||
const sourceServerDropdownValue = this.sourceServerDropdown.value as ConnectionDropdownValue;
|
||||
const ownerUri = await azdata.connection.getUriForConnection(sourceServerDropdownValue.connection.connectionId);
|
||||
|
||||
@@ -109,23 +115,45 @@ 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
|
||||
};
|
||||
}
|
||||
|
||||
if (this.targetIsDacpac) {
|
||||
this.schemaCompareMainWindow.targetEndpointInfo = {
|
||||
} else if (this.sourceEndpointType === mssql.SchemaCompareEndpointType.Dacpac) {
|
||||
this.schemaCompareMainWindow.sourceEndpointInfo = {
|
||||
endpointType: mssql.SchemaCompareEndpointType.Dacpac,
|
||||
serverDisplayName: '',
|
||||
serverName: '',
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
packageFilePath: this.targetTextBox.value,
|
||||
projectFilePath: '',
|
||||
targetScripts: [],
|
||||
folderStructure: '',
|
||||
dataSchemaProvider: '',
|
||||
packageFilePath: this.sourceTextBox.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);
|
||||
|
||||
@@ -135,16 +163,48 @@ 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({
|
||||
sourceIsDacpac: this.sourceIsDacpac.toString(),
|
||||
targetIsDacpac: this.targetIsDacpac.toString()
|
||||
sourceEndpointType: getSchemaCompareEndpointString(this.sourceEndpointType),
|
||||
targetEndpointType: getSchemaCompareEndpointString(this.targetEndpointType)
|
||||
}).send();
|
||||
|
||||
// update source and target values that are displayed
|
||||
@@ -182,6 +242,7 @@ export class SchemaCompareDialog {
|
||||
}
|
||||
|
||||
protected async cancel(): Promise<void> {
|
||||
this.dispose();
|
||||
}
|
||||
|
||||
private async initializeSchemaCompareTab(): Promise<void> {
|
||||
@@ -190,36 +251,67 @@ 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: this.schemaCompareMainWindow.sourceEndpointInfo ? this.schemaCompareMainWindow.sourceEndpointInfo.packageFilePath : '',
|
||||
value: sourceValue,
|
||||
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: this.schemaCompareMainWindow.targetEndpointInfo ? this.schemaCompareMainWindow.targetEndpointInfo.packageFilePath : '',
|
||||
value: targetValue,
|
||||
width: this.textBoxWidth,
|
||||
ariaLabel: loc.targetFile
|
||||
}).component();
|
||||
|
||||
this.targetTextBox.onTextChanged(async () => {
|
||||
this.targetTextBox.onTextChanged(async (e) => {
|
||||
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, this.schemaCompareMainWindow.sourceEndpointInfo);
|
||||
this.targetDacpacComponent = this.createFileBrowser(true, this.schemaCompareMainWindow.targetEndpointInfo);
|
||||
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();
|
||||
|
||||
let sourceRadioButtons = this.createSourceRadioButtons();
|
||||
let targetRadioButtons = this.createTargetRadioButtons();
|
||||
@@ -227,31 +319,37 @@ export class SchemaCompareDialog {
|
||||
let sourceComponents = [];
|
||||
let targetComponents = [];
|
||||
|
||||
// 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,
|
||||
];
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (this.schemaCompareMainWindow.targetEndpointInfo && this.schemaCompareMainWindow.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
|
||||
targetComponents = [
|
||||
targetRadioButtons,
|
||||
this.targetServerComponent,
|
||||
this.targetDatabaseComponent
|
||||
];
|
||||
} else {
|
||||
targetComponents = [
|
||||
targetRadioButtons,
|
||||
this.targetDacpacComponent,
|
||||
];
|
||||
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;
|
||||
}
|
||||
|
||||
this.formBuilder = <azdata.FormBuilder>this.view.modelBuilder.formContainer()
|
||||
@@ -274,17 +372,26 @@ export class SchemaCompareDialog {
|
||||
|
||||
let formModel = this.formBuilder.component();
|
||||
await this.view.initializeModel(formModel);
|
||||
if (this.sourceIsDacpac) {
|
||||
await this.sourceDacpacRadioButton.focus();
|
||||
} else {
|
||||
await this.sourceDatabaseRadioButton.focus();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
this.initDialogComplete.resolve();
|
||||
});
|
||||
}
|
||||
|
||||
private createFileBrowser(isTarget: boolean, endpoint: mssql.SchemaCompareEndpointInfo): azdata.FormComponent {
|
||||
private createFileBrowser(isTarget: boolean, dacpac: 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,
|
||||
@@ -302,8 +409,9 @@ export class SchemaCompareDialog {
|
||||
}
|
||||
|
||||
let currentButton = isTarget ? this.targetFileButton : this.sourceFileButton;
|
||||
const filter = dacpac ? 'dacpac' : 'sqlproj';
|
||||
|
||||
currentButton.onDidClick(async (click) => {
|
||||
currentButton.onDidClick(async () => {
|
||||
// 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;
|
||||
@@ -316,7 +424,7 @@ export class SchemaCompareDialog {
|
||||
defaultUri: vscode.Uri.file(defaultUri),
|
||||
openLabel: loc.open,
|
||||
filters: {
|
||||
'dacpac Files': ['dacpac'],
|
||||
'Files': [filter],
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -336,6 +444,22 @@ 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({
|
||||
@@ -349,36 +473,69 @@ 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.sourceIsDacpac = true;
|
||||
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
|
||||
this.sourceTextBox.value = this.sourceDacpacPath;
|
||||
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.sourceIsDacpac = false;
|
||||
this.sourceEndpointType = mssql.SchemaCompareEndpointType.Database;
|
||||
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);
|
||||
});
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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([this.sourceDacpacRadioButton, this.sourceDatabaseRadioButton])
|
||||
.withItems(radioButtons)
|
||||
.withProps({ ariaRole: 'radiogroup' })
|
||||
.component();
|
||||
|
||||
@@ -389,50 +546,85 @@ export class SchemaCompareDialog {
|
||||
}
|
||||
|
||||
private createTargetRadioButtons(): azdata.FormComponent {
|
||||
let dacpacRadioButton = this.view.modelBuilder.radioButton()
|
||||
let targetDacpacRadioButton = this.view.modelBuilder.radioButton()
|
||||
.withProps({
|
||||
name: 'target',
|
||||
label: loc.DacpacRadioButtonLabel
|
||||
}).component();
|
||||
|
||||
let databaseRadioButton = this.view.modelBuilder.radioButton()
|
||||
let targetDatabaseRadioButton = 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
|
||||
dacpacRadioButton.onDidClick(async () => {
|
||||
this.targetIsDacpac = true;
|
||||
targetDacpacRadioButton.onDidClick(async () => {
|
||||
this.targetEndpointType = mssql.SchemaCompareEndpointType.Dacpac;
|
||||
this.targetTextBox.value = this.targetDacpacPath;
|
||||
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
|
||||
databaseRadioButton.onDidClick(async () => {
|
||||
this.targetIsDacpac = false;
|
||||
targetDatabaseRadioButton.onDidClick(async () => {
|
||||
this.targetEndpointType = mssql.SchemaCompareEndpointType.Database;
|
||||
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);
|
||||
});
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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([dacpacRadioButton, databaseRadioButton]
|
||||
)
|
||||
.withItems(radioButtons)
|
||||
.withProps({ ariaRole: 'radiogroup' })
|
||||
.component();
|
||||
|
||||
@@ -443,18 +635,83 @@ export class SchemaCompareDialog {
|
||||
}
|
||||
|
||||
private async shouldEnableOkayButton(): Promise<boolean> {
|
||||
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);
|
||||
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);
|
||||
|
||||
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(
|
||||
{
|
||||
@@ -524,9 +781,7 @@ 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({
|
||||
@@ -539,10 +794,8 @@ 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,
|
||||
|
||||
@@ -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 (context: any) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(context); });
|
||||
vscode.commands.registerCommand('schemaCompare.start', async (sourceContext: any, targetContext: any = undefined, comparisonResult: any = undefined) => { await new SchemaCompareMainWindow(undefined, extensionContext, undefined).start(sourceContext, targetContext, comparisonResult); });
|
||||
}
|
||||
|
||||
export function deactivate(): void {
|
||||
|
||||
@@ -14,9 +14,11 @@ 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?");
|
||||
@@ -31,6 +33,12 @@ 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");
|
||||
@@ -61,7 +69,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");
|
||||
export const applyDisabled: string = localize('schemaCompare.applyButtonDisabledTitle', "Apply is enabled when the target is a database or database project");
|
||||
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); }
|
||||
@@ -318,3 +326,20 @@ 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';
|
||||
|
||||
@@ -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 } from './utils';
|
||||
import { getTelemetryErrorType, getEndpointName, verifyConnectionAndGetOwnerUri, getRootPath, getSchemaCompareEndpointString } from './utils';
|
||||
import { SchemaCompareDialog } from './dialogs/schemaCompareDialog';
|
||||
import { isNullOrUndefined } from 'util';
|
||||
|
||||
@@ -81,14 +81,33 @@ export class SchemaCompareMainWindow {
|
||||
this.editor = azdata.workspace.createModelViewEditor(loc.SchemaCompareLabel, { retainContextWhenHidden: true, supportsSave: true, resourceName: schemaCompareResourceName }, 'SchemaCompareEditor');
|
||||
}
|
||||
|
||||
// schema compare can get started with three contexts for the source:
|
||||
// schema compare can get started with four contexts for the source:
|
||||
// 1. undefined
|
||||
// 2. connection profile
|
||||
// 3. dacpac
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (profile) {
|
||||
let ownerUri = await azdata.connection.getUriForConnection((profile.id));
|
||||
let usr = profile.userName;
|
||||
@@ -104,7 +123,11 @@ export class SchemaCompareMainWindow {
|
||||
ownerUri: ownerUri,
|
||||
packageFilePath: '',
|
||||
connectionDetails: undefined,
|
||||
connectionName: profile.connectionName
|
||||
connectionName: profile.connectionName,
|
||||
projectFilePath: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
folderStructure: ''
|
||||
};
|
||||
} else if (sourceDacpac) {
|
||||
this.sourceEndpointInfo = {
|
||||
@@ -114,7 +137,25 @@ export class SchemaCompareMainWindow {
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
packageFilePath: sourceDacpac,
|
||||
connectionDetails: undefined
|
||||
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: ''
|
||||
};
|
||||
}
|
||||
|
||||
@@ -123,6 +164,10 @@ export class SchemaCompareMainWindow {
|
||||
this.registerContent(),
|
||||
this.editor.openEditor()
|
||||
]);
|
||||
|
||||
if (targetIsSetAsProject) {
|
||||
await this.execute(comparisonResult);
|
||||
}
|
||||
}
|
||||
|
||||
private async registerContent(): Promise<void> {
|
||||
@@ -162,7 +207,8 @@ export class SchemaCompareMainWindow {
|
||||
this.createSourceAndTargetButtons();
|
||||
|
||||
this.sourceName = getEndpointName(this.sourceEndpointInfo);
|
||||
this.targetName = ' ';
|
||||
this.targetName = getEndpointName(this.targetEndpointInfo);
|
||||
|
||||
this.sourceNameComponent = this.view.modelBuilder.inputBox().withProps({
|
||||
value: this.sourceName,
|
||||
title: this.sourceName,
|
||||
@@ -275,33 +321,43 @@ export class SchemaCompareMainWindow {
|
||||
this.deploymentOptions = deploymentOptions;
|
||||
}
|
||||
|
||||
public async execute() {
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
|
||||
public async execute(comparisonResult: mssql.SchemaCompareCompletionResult = undefined) {
|
||||
const service = await this.getService();
|
||||
|
||||
if (!this.operationId) {
|
||||
// create once per page
|
||||
this.operationId = generateGuid();
|
||||
}
|
||||
if (comparisonResult) {
|
||||
this.operationId = comparisonResult.operationId;
|
||||
this.comparisonResult = comparisonResult;
|
||||
this.flexModel.removeItem(this.startText);
|
||||
} else {
|
||||
TelemetryReporter.sendActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaComparisonStarted');
|
||||
|
||||
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))
|
||||
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({
|
||||
operationId: this.comparisonResult.operationId
|
||||
'endTime': Date.now().toString(),
|
||||
'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);
|
||||
|
||||
@@ -363,9 +419,15 @@ 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;
|
||||
this.applyButton.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.applyButton.title = loc.applyDisabled;
|
||||
}
|
||||
} else {
|
||||
@@ -762,7 +824,6 @@ 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) => {
|
||||
@@ -776,14 +837,26 @@ export class SchemaCompareMainWindow {
|
||||
// disable apply and generate script buttons because the results are no longer valid after applying the changes
|
||||
this.setButtonsForRecompare();
|
||||
|
||||
const service = await this.getService();
|
||||
const result = await service.schemaComparePublishChanges(this.comparisonResult.operationId, this.targetEndpointInfo.serverName, this.targetEndpointInfo.databaseName, azdata.TaskExecutionMode.execute);
|
||||
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)}`);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -791,6 +864,7 @@ export class SchemaCompareMainWindow {
|
||||
this.applyButton.enabled = true;
|
||||
this.applyButton.title = loc.applyEnabledMessage;
|
||||
}
|
||||
|
||||
TelemetryReporter.createActionEvent(TelemetryViews.SchemaCompareMainWindow, 'SchemaCompareApplyEnded')
|
||||
.withAdditionalProperties({
|
||||
'endTime': Date.now().toString(),
|
||||
@@ -1082,11 +1156,15 @@ export class SchemaCompareMainWindow {
|
||||
}
|
||||
|
||||
private setButtonStatesForNoChanges(enableButtons: boolean): void {
|
||||
// generate script and apply can only be enabled if the target is a database
|
||||
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
|
||||
// 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.generateScriptButton.enabled = enableButtons;
|
||||
this.applyButton.title = enableButtons ? loc.applyEnabledMessage : loc.applyNoChangesMessage;
|
||||
}
|
||||
|
||||
if (this.targetEndpointInfo.endpointType === mssql.SchemaCompareEndpointType.Database) {
|
||||
this.generateScriptButton.enabled = enableButtons;
|
||||
this.generateScriptButton.title = enableButtons ? loc.generateScriptEnabledMessage : loc.generateScriptNoChangesMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
|
||||
service.setup(x => x.schemaComparePublishDatabaseChanges(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 = setDacpacEndpointInfo(mocktarget);
|
||||
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
|
||||
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.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
|
||||
service.setup(x => x.schemaComparePublishDatabaseChanges(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 = setDacpacEndpointInfo(mocktarget);
|
||||
schemaCompareResult.targetEndpointInfo = setDatabaseEndpointInfo();
|
||||
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.schemaComparePublishChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
|
||||
service.setup(x => x.schemaComparePublishDatabaseChanges(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve({
|
||||
success: true,
|
||||
errorMessage: ''
|
||||
}));
|
||||
|
||||
@@ -24,6 +24,14 @@ 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,
|
||||
@@ -42,7 +50,6 @@ 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.');
|
||||
}
|
||||
|
||||
@@ -94,7 +94,11 @@ export const mockDacpacEndpoint: mssql.SchemaCompareEndpointInfo = {
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
packageFilePath: mockFilePath,
|
||||
connectionDetails: undefined
|
||||
connectionDetails: undefined,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
};
|
||||
|
||||
export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
|
||||
@@ -104,7 +108,11 @@ export const mockDatabaseEndpoint: mssql.SchemaCompareEndpointInfo = {
|
||||
databaseName: '',
|
||||
ownerUri: '',
|
||||
packageFilePath: '',
|
||||
connectionDetails: undefined
|
||||
connectionDetails: undefined,
|
||||
projectFilePath: '',
|
||||
folderStructure: '',
|
||||
targetScripts: [],
|
||||
dataSchemaProvider: '',
|
||||
};
|
||||
|
||||
export async function shouldThrowSpecificError(block: Function, expectedMessage: string, details?: string) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
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';
|
||||
@@ -39,6 +40,19 @@ 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
|
||||
@@ -64,8 +78,11 @@ export function getEndpointName(endpoint: mssql.SchemaCompareEndpointInfo): stri
|
||||
return ' ';
|
||||
}
|
||||
|
||||
} else {
|
||||
} else if (endpoint.endpointType === mssql.SchemaCompareEndpointType.Dacpac) {
|
||||
return endpoint.packageFilePath;
|
||||
|
||||
} else {
|
||||
return endpoint.projectFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,3 +161,24 @@ 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;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,12 @@
|
||||
"*"
|
||||
],
|
||||
"main": "./out/extension",
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"forceReload": true,
|
||||
"contributes": {
|
||||
"commands": [
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
"activationEvents": [
|
||||
"onDashboardOpen"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"main": "./out/main",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -4,14 +4,11 @@
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
// 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)
|
||||
// This task is meant for running the VS Code version of the extension. See VSCODE_DEVELOPMENT.md for more information
|
||||
{
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"name": "Launch Extension",
|
||||
"name": "Launch Extension in VS Code",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}"
|
||||
@@ -21,4 +18,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
# Microsoft SQL Server Database Projects for Azure Data Studio and VS Code
|
||||
|
||||
Microsoft SQL Server Database Projects for Azure Data Studio and VS Code includes:
|
||||
## 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.
|
||||
|
||||
## 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)
|
||||
|
||||
@@ -11,7 +19,8 @@ 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 **Create Project From Database** from the command palette or database context menu.
|
||||
* 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.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
|
||||
15
extensions/sql-database-projects/VSCODE_DEVELOPMENT.md
Normal file
15
extensions/sql-database-projects/VSCODE_DEVELOPMENT.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# 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.
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "sql-database-projects",
|
||||
"displayName": "SQL Database Projects",
|
||||
"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",
|
||||
"description": "Enables users to develop and publish database schemas for MSSQL Databases",
|
||||
"version": "0.14.0",
|
||||
"publisher": "Microsoft",
|
||||
"preview": true,
|
||||
"engines": {
|
||||
@@ -17,6 +17,7 @@
|
||||
"onCommand:sqlDatabaseProjects.open",
|
||||
"onCommand:sqlDatabaseProjects.createProjectFromDatabase",
|
||||
"onCommand:sqlDatabaseProjects.generateProjectFromOpenApiSpec",
|
||||
"onCommand:sqlDatabaseProjects.addSqlBinding",
|
||||
"workspaceContains:**/*.sqlproj",
|
||||
"onView:dataworkspace.views.main"
|
||||
],
|
||||
@@ -29,6 +30,12 @@
|
||||
"Microsoft.mssql",
|
||||
"Microsoft.schema-compare"
|
||||
],
|
||||
"capabilities": {
|
||||
"virtualWorkspaces": false,
|
||||
"untrustedWorkspaces": {
|
||||
"supported": true
|
||||
}
|
||||
},
|
||||
"contributes": {
|
||||
"projects": [
|
||||
"sqlproj"
|
||||
@@ -37,9 +44,9 @@
|
||||
{
|
||||
"title": "%sqlDatabaseProjects.Settings%",
|
||||
"properties": {
|
||||
"sqlDatabaseProjects.netCoreSDKLocation": {
|
||||
"sqlDatabaseProjects.dotnetSDK Location": {
|
||||
"type": "string",
|
||||
"description": "%sqlDatabaseProjects.netCoreInstallLocation%"
|
||||
"description": "%sqlDatabaseProjects.dotnetInstallLocation%"
|
||||
},
|
||||
"sqlDatabaseProjects.netCoreDoNotAsk": {
|
||||
"type": "boolean",
|
||||
@@ -158,6 +165,11 @@
|
||||
"title": "%sqlDatabaseProjects.editProjectFile%",
|
||||
"category": "%sqlDatabaseProjects.displayName%"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.addSqlBinding",
|
||||
"title": "%sqlDatabaseProjects.addSqlBinding%",
|
||||
"category": "MS SQL"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.changeTargetPlatform",
|
||||
"title": "%sqlDatabaseProjects.changeTargetPlatform%",
|
||||
@@ -258,6 +270,10 @@
|
||||
"command": "sqlDatabaseProjects.editProjectFile",
|
||||
"when": "false"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.addSqlBinding",
|
||||
"when": "editorLangId == csharp && !azdataAvailable && resourceScheme != untitled"
|
||||
},
|
||||
{
|
||||
"command": "sqlDatabaseProjects.exclude",
|
||||
"when": "false"
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
"sqlDatabaseProjects.generateProjectFromOpenApiSpec": "Generate SQL Project from OpenAPI/Swagger spec",
|
||||
|
||||
"sqlDatabaseProjects.Settings": "Database Projects",
|
||||
"sqlDatabaseProjects.netCoreInstallLocation": "Full path to .NET Core SDK on the machine.",
|
||||
"sqlDatabaseProjects.dotnetInstallLocation": "Full path to .NET SDK on the machine.",
|
||||
"sqlDatabaseProjects.netCoreDoNotAsk": "Whether to prompt the user to install .NET Core when not 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"
|
||||
"sqlDatabaseProjects.addSqlBinding":"Add SQL Binding (preview)"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user