From 397f6afaf184ba19a38940527ac0eb193b30d981 Mon Sep 17 00:00:00 2001 From: BranislavGrbicMDCS <55592643+BranislavGrbicMDCS@users.noreply.github.com> Date: Tue, 22 Oct 2019 12:50:15 +0200 Subject: [PATCH] ADS changes for new engine edition (#7695) * Sql on demand changes * Formating files * Removing features for new Engine Edition * Fixing Restore & Backup issue. Adding support for multiple conditions per flavor * tabifying * Formating documents * Work in progress * Resolving comments * Resolving comments. * Fixing typo --- extensions/admin-tool-ext-win/package.json | 6 +- extensions/agent/package.json | 2 +- extensions/dacpac/package.json | 6 +- extensions/import/package.json | 2 +- extensions/insights-default/package.json | 6 +- extensions/mssql/package.json | 59 +++++++++++++--- extensions/mssql/src/contextProvider.ts | 3 +- extensions/profiler/package.json | 2 +- extensions/schema-compare/package.json | 2 +- samples/extensionSamples/package.json | 4 +- src/sql/azdata.d.ts | 16 +++++ .../api/common/sqlExtHost.api.impl.ts | 3 +- .../workbench/api/common/sqlExtHostTypes.ts | 16 +++++ src/sql/workbench/browser/scriptingUtils.ts | 3 +- .../backup/browser/backup.contribution.ts | 9 ++- .../connection/common/serverInfoContextKey.ts | 7 ++ .../databaseDashboardPage.contribution.ts | 4 +- .../pages/serverDashboardPage.contribution.ts | 2 +- .../browser/widgets/explorer/explorerTree.ts | 3 +- .../widgets/explorer/explorerTreeContext.ts | 6 ++ .../widgets/properties/propertiesJson.ts | 61 +++++++++++++--- .../properties/propertiesWidget.component.ts | 69 ++++++++++++++----- .../browser/extensions.contribution.ts | 16 +++-- .../dataExplorer/browser/mssqlNodeContext.ts | 34 +++++++-- .../restore/browser/restore.contribution.ts | 10 ++- 25 files changed, 271 insertions(+), 80 deletions(-) diff --git a/extensions/admin-tool-ext-win/package.json b/extensions/admin-tool-ext-win/package.json index 2faa7772be..20c9aeaad4 100644 --- a/extensions/admin-tool-ext-win/package.json +++ b/extensions/admin-tool-ext-win/package.json @@ -50,17 +50,17 @@ "objectExplorer/item/context": [ { "command": "adminToolExtWin.launchSsmsMinGswDialog", - "when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Database", + "when": "isWindows && connectionProvider == MSSQL && nodeType && nodeType == Database && mssql:engineedition != 11", "group": "z-AdminToolExt@1" }, { "command": "adminToolExtWin.launchSsmsMinPropertiesDialog", - "when": "isWindows && connectionProvider == MSSQL && serverInfo && !isCloud && nodeType && nodeType == Server", + "when": "isWindows && connectionProvider == MSSQL && serverInfo && !isCloud && nodeType && nodeType == Server && mssql:engineedition != 11", "group": "z-AdminToolExt@2" }, { "command": "adminToolExtWin.launchSsmsMinPropertiesDialog", - "when": "isWindows && connectionProvider == MSSQL && serverInfo && nodeType && nodeType =~ /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/", + "when": "isWindows && connectionProvider == MSSQL && serverInfo && nodeType && mssql:engineedition != 11 && nodeType =~ /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/", "group": "z-AdminToolExt@2" } ] diff --git a/extensions/agent/package.json b/extensions/agent/package.json index d562585632..34b0384de3 100644 --- a/extensions/agent/package.json +++ b/extensions/agent/package.json @@ -32,7 +32,7 @@ "description": "Manage and troubleshoot SQL Agent jobs", "provider": "MSSQL", "title": "SQL Agent", - "when": "connectionProvider == 'MSSQL' && !mssql:iscloud", + "when": "connectionProvider == 'MSSQL' && !mssql:iscloud && mssql:engineedition != 11", "container": { "controlhost-container": { "type": "agent" diff --git a/extensions/dacpac/package.json b/extensions/dacpac/package.json index e3362968aa..8026b8540c 100644 --- a/extensions/dacpac/package.json +++ b/extensions/dacpac/package.json @@ -35,17 +35,17 @@ "objectExplorer/item/context": [ { "command": "dacFx.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Database && mssql:engineedition != 11", "group": "export" }, { "command": "dacFx.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Server", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Server && mssql:engineedition != 11", "group": "export" }, { "command": "dacFx.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Folder && nodeLabel == 'Databases'", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Folder && nodeLabel == 'Databases' && mssql:engineedition != 11", "group": "export" } ] diff --git a/extensions/import/package.json b/extensions/import/package.json index 524afae82e..7bf5279c92 100644 --- a/extensions/import/package.json +++ b/extensions/import/package.json @@ -46,7 +46,7 @@ "objectExplorer/item/context": [ { "command": "flatFileImport.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Database && mssql:engineedition != 11", "group": "import" } ] diff --git a/extensions/insights-default/package.json b/extensions/insights-default/package.json index 3acfa15a75..deda1a14b5 100644 --- a/extensions/insights-default/package.json +++ b/extensions/insights-default/package.json @@ -62,7 +62,7 @@ "id": "all-database-size-server-insight", "contrib": { "name": "Database Size (MB)", - "when": "connectionProvider == 'MSSQL' && !mssql:iscloud", + "when": "connectionProvider == 'MSSQL' && !mssql:iscloud && mssql:engineedition != 11", "gridItemConfig": { "x": 2, "y": 2 @@ -83,7 +83,7 @@ "contrib": { "cacheId": "backup-history-server-insight", "name": "Backup Status", - "when": "connectionProvider == 'MSSQL' && !mssql:iscloud", + "when": "connectionProvider == 'MSSQL' && !mssql:iscloud && mssql:engineedition != 11", "gridItemConfig": { "x": 1, "y": 1 @@ -133,4 +133,4 @@ } ] } -} \ No newline at end of file +} diff --git a/extensions/mssql/package.json b/extensions/mssql/package.json index 66055ab74d..cf87be8bab 100644 --- a/extensions/mssql/package.json +++ b/extensions/mssql/package.json @@ -308,11 +308,18 @@ "flavors": [ { "flavor": "on_prem", - "condition": { - "field": "isCloud", - "operator": "!=", - "value": true - }, + "conditions": [ + { + "field": "isCloud", + "operator": "!=", + "value": true + }, + { + "field": "engineEditionId", + "operator": "!=", + "value": "11" + } + ], "databaseProperties": [ { "displayName": "%onprem.databaseProperties.recoveryModel%", @@ -362,11 +369,13 @@ }, { "flavor": "cloud", - "condition": { - "field": "isCloud", - "operator": "==", - "value": true - }, + "conditions": [ + { + "field": "isCloud", + "operator": "==", + "value": true + } + ], "databaseProperties": [ { "displayName": "%cloud.databaseProperties.azureEdition%", @@ -395,6 +404,36 @@ "value": "serverEdition" } ] + }, + { + "flavor": "on_demand", + "conditions": [ + { + "field": "engineEditionId", + "operator": "==", + "value": "11" + } + ], + "databaseProperties": [ + { + "displayName": "%cloud.databaseProperties.compatibilityLevel%", + "value": "compatibilityLevel" + }, + { + "displayName": "%cloud.databaseProperties.owner%", + "value": "owner" + } + ], + "serverProperties": [ + { + "displayName": "%cloud.serverProperties.serverVersion%", + "value": "serverVersion" + }, + { + "displayName": "%cloud.serverProperties.serverEdition%", + "value": "serverEdition" + } + ] } ] }, diff --git a/extensions/mssql/src/contextProvider.ts b/extensions/mssql/src/contextProvider.ts index 4055509038..8c5ed23d2e 100644 --- a/extensions/mssql/src/contextProvider.ts +++ b/extensions/mssql/src/contextProvider.ts @@ -22,7 +22,8 @@ export enum ContextKeys { const isCloudEditions = [ 5, - 6 + 6, + 11 ]; export function setCommandContext(key: ContextKeys | string, value: any) { diff --git a/extensions/profiler/package.json b/extensions/profiler/package.json index 55754aa8db..71368b81e3 100644 --- a/extensions/profiler/package.json +++ b/extensions/profiler/package.json @@ -66,7 +66,7 @@ "objectExplorer/item/context": [ { "command": "profiler.newProfiler", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Server", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Server && mssql:engineedition != 11", "group": "profiler" } ] diff --git a/extensions/schema-compare/package.json b/extensions/schema-compare/package.json index 4274a6dfa1..4ec969cea5 100644 --- a/extensions/schema-compare/package.json +++ b/extensions/schema-compare/package.json @@ -52,7 +52,7 @@ "objectExplorer/item/context": [ { "command": "schemaCompare.start", - "when": "connectionProvider == MSSQL && nodeType && nodeType == Database", + "when": "connectionProvider == MSSQL && nodeType && nodeType == Database && mssql:engineedition != 11", "group": "export" } ] diff --git a/samples/extensionSamples/package.json b/samples/extensionSamples/package.json index 8107e2cffd..21ca9fbf43 100644 --- a/samples/extensionSamples/package.json +++ b/samples/extensionSamples/package.json @@ -109,11 +109,11 @@ "tasks-widget": [ { "name": "backup", - "when": "!mssql:iscloud" + "when": "!mssql:iscloud && mssql:engineedition != 11" }, { "name": "restore", - "when": "!mssql:iscloud" + "when": "!mssql:iscloud && mssql:engineedition != 11" }, "configureDashboard", "newQuery" diff --git a/src/sql/azdata.d.ts b/src/sql/azdata.d.ts index b82b08d9aa..d97a9e95f2 100644 --- a/src/sql/azdata.d.ts +++ b/src/sql/azdata.d.ts @@ -429,6 +429,22 @@ declare module 'azdata' { options: { [key: string]: any }; } + /** + * The possible values of the server engine edition + */ + export enum DatabaseEngineEdition { + Unknown = 0, + Personal = 1, + Standard = 2, + Enterprise = 3, + Express = 4, + SqlDatabase = 5, + SqlDataWarehouse = 6, + SqlStretchDatabase = 7, + SqlManagedInstance = 8, + SqlOnDemand = 11 + } + export interface DataProvider { handle?: number; readonly providerId: string; diff --git a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts index 8d1caafc74..ead95ea925 100644 --- a/src/sql/workbench/api/common/sqlExtHost.api.impl.ts +++ b/src/sql/workbench/api/common/sqlExtHost.api.impl.ts @@ -558,7 +558,8 @@ export function createAdsApiFactory(accessor: ServicesAccessor): IAdsExtensionAp StepCompletionAction: sqlExtHostTypes.StepCompletionAction, AgentSubSystem: sqlExtHostTypes.AgentSubSystem, ExtensionNodeType: sqlExtHostTypes.ExtensionNodeType, - ColumnSizingMode: sqlExtHostTypes.ColumnSizingMode + ColumnSizingMode: sqlExtHostTypes.ColumnSizingMode, + DatabaseEngineEdition: sqlExtHostTypes.DatabaseEngineEdition }; }, diff --git a/src/sql/workbench/api/common/sqlExtHostTypes.ts b/src/sql/workbench/api/common/sqlExtHostTypes.ts index cdebe8940d..7f0e7ce32b 100644 --- a/src/sql/workbench/api/common/sqlExtHostTypes.ts +++ b/src/sql/workbench/api/common/sqlExtHostTypes.ts @@ -357,6 +357,22 @@ export enum Orientation { Vertical = 'vertial' } +/** + * The possible values of the server engine edition + */ +export enum DatabaseEngineEdition { + Unknown = 0, + Personal = 1, + Standard = 2, + Enterprise = 3, + Express = 4, + SqlDatabase = 5, + SqlDataWarehouse = 6, + SqlStretchDatabase = 7, + SqlManagedInstance = 8, + SqlOnDemand = 11 +} + export interface ToolbarLayout { orientation: Orientation; } diff --git a/src/sql/workbench/browser/scriptingUtils.ts b/src/sql/workbench/browser/scriptingUtils.ts index a7ffcaf798..338b254b3a 100644 --- a/src/sql/workbench/browser/scriptingUtils.ts +++ b/src/sql/workbench/browser/scriptingUtils.ts @@ -34,7 +34,8 @@ const targetDatabaseEngineEditionMap = { 4: 'SqlServerExpressEdition', 5: 'SqlAzureDatabaseEdition', 6: 'SqlDatawarehouseEdition', - 7: 'SqlServerStretchEdition' + 7: 'SqlServerStretchEdition', + 11: 'SqlServerSqlOnDemandEdition', }; /** diff --git a/src/sql/workbench/parts/backup/browser/backup.contribution.ts b/src/sql/workbench/parts/backup/browser/backup.contribution.ts index 45ae425625..490295d2d0 100644 --- a/src/sql/workbench/parts/backup/browser/backup.contribution.ts +++ b/src/sql/workbench/parts/backup/browser/backup.contribution.ts @@ -20,6 +20,7 @@ import { TreeNodeContextKey } from 'sql/workbench/parts/objectExplorer/common/tr import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/connectionContextKey'; import { ServerInfoContextKey } from 'sql/workbench/parts/connection/common/serverInfoContextKey'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes'; new BackupAction().registerTask(); @@ -41,7 +42,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('backup', "Backup") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated()) + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated(), MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // oe @@ -61,7 +62,8 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { id: OE_BACKUP_COMMAND_ID, title: localize('backup', "Backup") }, - when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), ServerInfoContextKey.IsCloud.toNegated()) + when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), + ServerInfoContextKey.IsCloud.toNegated(), ServerInfoContextKey.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // dashboard explorer @@ -76,6 +78,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { id: ExplorerBackUpActionID, title: BackupAction.LABEL }, - when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), + ItemContextKey.IsCloud.toNegated(), ItemContextKey.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())), order: 2 }); diff --git a/src/sql/workbench/parts/connection/common/serverInfoContextKey.ts b/src/sql/workbench/parts/connection/common/serverInfoContextKey.ts index 8ca5a88e3b..6c0b28eacc 100644 --- a/src/sql/workbench/parts/connection/common/serverInfoContextKey.ts +++ b/src/sql/workbench/parts/connection/common/serverInfoContextKey.ts @@ -5,6 +5,7 @@ import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { ServerInfo } from 'azdata'; +import { DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes'; export class ServerInfoContextKey implements IContextKey { @@ -12,11 +13,13 @@ export class ServerInfoContextKey implements IContextKey { static ServerMajorVersion = new RawContextKey('serverMajorVersion', undefined); static IsCloud = new RawContextKey('isCloud', undefined); static IsBigDataCluster = new RawContextKey('isBigDataCluster', undefined); + static EngineEdition = new RawContextKey('engineEdition', undefined); private _serverInfo: IContextKey; private _serverMajorVersion: IContextKey; private _isCloud: IContextKey; private _isBigDataCluster: IContextKey; + private _engineEdition: IContextKey; constructor( @IContextKeyService contextKeyService: IContextKeyService @@ -25,6 +28,7 @@ export class ServerInfoContextKey implements IContextKey { this._serverMajorVersion = ServerInfoContextKey.ServerMajorVersion.bindTo(contextKeyService); this._isCloud = ServerInfoContextKey.IsCloud.bindTo(contextKeyService); this._isBigDataCluster = ServerInfoContextKey.IsBigDataCluster.bindTo(contextKeyService); + this._engineEdition = ServerInfoContextKey.EngineEdition.bindTo(contextKeyService); } set(value: ServerInfo) { @@ -33,12 +37,15 @@ export class ServerInfoContextKey implements IContextKey { this._serverMajorVersion.set(majorVersion && `${majorVersion}`); this._isCloud.set(value && value.isCloud); this._isBigDataCluster.set(value && value.options && value.options['isBigDataCluster']); + let engineEditionId = value && value.engineEditionId; + engineEditionId ? this._engineEdition.set(engineEditionId) : this._engineEdition.set(DatabaseEngineEdition.Unknown); } reset(): void { this._serverMajorVersion.reset(); this._isCloud.reset(); this._isBigDataCluster.reset(); + this._engineEdition.reset(); } public get(): ServerInfo { diff --git a/src/sql/workbench/parts/dashboard/browser/pages/databaseDashboardPage.contribution.ts b/src/sql/workbench/parts/dashboard/browser/pages/databaseDashboardPage.contribution.ts index 739437ae09..a0e34ea2ad 100644 --- a/src/sql/workbench/parts/dashboard/browser/pages/databaseDashboardPage.contribution.ts +++ b/src/sql/workbench/parts/dashboard/browser/pages/databaseDashboardPage.contribution.ts @@ -98,8 +98,8 @@ export const databaseDashboardSettingSchema: IJSONSchema = { 'tasks-widget': [ 'newQuery', 'mssqlCluster.task.newNotebook', - { name: 'backup', when: '!mssql:iscloud' }, - { name: 'restore', when: '!mssql:iscloud' }, + { name: 'backup', when: '!mssql:iscloud && mssql:engineedition != 11' }, + { name: 'restore', when: '!mssql:iscloud && mssql:engineedition != 11' }, 'configureDashboard' ] } diff --git a/src/sql/workbench/parts/dashboard/browser/pages/serverDashboardPage.contribution.ts b/src/sql/workbench/parts/dashboard/browser/pages/serverDashboardPage.contribution.ts index 560e741641..860be65711 100644 --- a/src/sql/workbench/parts/dashboard/browser/pages/serverDashboardPage.contribution.ts +++ b/src/sql/workbench/parts/dashboard/browser/pages/serverDashboardPage.contribution.ts @@ -78,7 +78,7 @@ const defaultVal = [ { name: 'Tasks', widget: { - 'tasks-widget': [{ name: 'restore', when: '!mssql:iscloud' }, 'configureDashboard', 'newQuery', 'mssqlCluster.task.newNotebook'] + 'tasks-widget': [{ name: 'restore', when: '!mssql:iscloud && mssql:engineedition != 11' }, 'configureDashboard', 'newQuery', 'mssqlCluster.task.newNotebook'] }, gridItemConfig: { sizex: 1, diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts index 7700f19c4e..0b6e152e2a 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTree.ts @@ -78,7 +78,8 @@ export class ExplorerController extends TreeDefaults.DefaultController { this.contextKey.set({ resource: element, providerName: this.bootStrapService.connectionManagementService.connectionInfo.providerId, - isCloud: this.bootStrapService.connectionManagementService.connectionInfo.serverInfo.isCloud + isCloud: this.bootStrapService.connectionManagementService.connectionInfo.serverInfo.isCloud, + engineEdition: this.bootStrapService.connectionManagementService.connectionInfo.serverInfo.engineEditionId }); let context: ManageActionContext | BaseActionContext; diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts index dad7f2ccde..af0394290a 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext.ts @@ -15,6 +15,7 @@ export interface IContextValue { resource: ContextResource; providerName: string; isCloud: boolean; + engineEdition: number; } export class ItemContextKey extends Disposable implements IContextKey { @@ -23,11 +24,13 @@ export class ItemContextKey extends Disposable implements IContextKey('item', undefined); static readonly ConnectionProvider = new RawContextKey('provider', undefined); static readonly IsCloud = new RawContextKey('isCloud', undefined); + static readonly EngineEdition = new RawContextKey('engineEdition', undefined); private _itemTypeKey: IContextKey; private _itemKey: IContextKey; private _connectionProviderKey: IContextKey; private _isCloudKey: IContextKey; + private _engineEditionKey: IContextKey; constructor( @IContextKeyService contextKeyService: IContextKeyService @@ -38,12 +41,14 @@ export class ItemContextKey extends Disposable implements IContextKey = [ flavors: [ { flavor: 'on_prem', - condition: { - field: 'isCloud', - operator: '!=', - value: true - }, + conditions: [ + { + field: 'isCloud', + operator: '!=', + value: true + }, + { + field: 'engineEditionId', + operator: '!=', + value: '11' + } + ], databaseProperties: [ { displayName: nls.localize('recoveryModel', "Recovery Model"), @@ -70,11 +77,13 @@ export const properties: Array = [ }, { flavor: 'cloud', - condition: { - field: 'isCloud', - operator: '==', - value: true - }, + conditions: [ + { + field: 'isCloud', + operator: '==', + value: true + } + ], databaseProperties: [ { displayName: azureEditionDisplayName, @@ -103,7 +112,37 @@ export const properties: Array = [ value: 'serverEdition' } ] + }, + { + flavor: 'on_demand', + conditions: [ + { + field: 'engineEditionId', + operator: '==', + value: '11' + } + ], + databaseProperties: [ + { + displayName: nls.localize('compatibilityLevel', "Compatibility Level"), + value: 'compatibilityLevel' + }, + { + displayName: nls.localize('owner', "Owner"), + value: 'owner' + } + ], + serverProperties: [ + { + displayName: nls.localize('version', "Version"), + value: 'serverVersion' + }, + { + displayName: azureType, + value: 'serverEdition' + } + ] } ] } -]; \ No newline at end of file +]; diff --git a/src/sql/workbench/parts/dashboard/browser/widgets/properties/propertiesWidget.component.ts b/src/sql/workbench/parts/dashboard/browser/widgets/properties/propertiesWidget.component.ts index 0dd3b6dbb3..6c5bd08c67 100644 --- a/src/sql/workbench/parts/dashboard/browser/widgets/properties/propertiesWidget.component.ts +++ b/src/sql/workbench/parts/dashboard/browser/widgets/properties/propertiesWidget.component.ts @@ -25,15 +25,18 @@ export interface PropertiesConfig { export interface FlavorProperties { flavor: string; - condition?: { - field: string; - operator: '==' | '<=' | '>=' | '!='; - value: string | boolean; - }; + condition?: ConditionProperties; + conditions?: Array; databaseProperties: Array; serverProperties: Array; } +export interface ConditionProperties { + field: string; + operator: '==' | '<=' | '>=' | '!='; + value: string | boolean; +} + export interface ProviderProperties { provider: string; flavors: Array; @@ -139,20 +142,23 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb return; } else { const flavorArray = providerProperties.flavors.filter((item) => { - const condition = this._connection.serverInfo[item.condition.field]; - switch (item.condition.operator) { - case '==': - return condition === item.condition.value; - case '!=': - return condition !== item.condition.value; - case '>=': - return condition >= item.condition.value; - case '<=': - return condition <= item.condition.value; - default: - this.logService.error('Could not parse operator: "', item.condition.operator, - '" on item "', item, '"'); - return false; + + // For backward compatibility we are supporting array of conditions and single condition. + // If nothing is specified, we return false. + if (item.conditions) { + let conditionResult = true; + for (let i = 0; i < item.conditions.length; i++) { + conditionResult = conditionResult && this.getConditionResult(item, item.conditions[i]); + } + + return conditionResult; + } + else if (item.condition) { + return this.getConditionResult(item, item.condition); + } + else { + this.logService.error('No condition was specified.'); + return false; } }); @@ -224,6 +230,31 @@ export class PropertiesWidgetComponent extends DashboardWidget implements IDashb } } + private getConditionResult(item: FlavorProperties, conditionItem: ConditionProperties): boolean { + let condition = this._connection.serverInfo[conditionItem.field]; + + // If we need to compare strings, then we should ensure that condition is string + // Otherwise tripple equals/unequals would return false values + if (typeof conditionItem.value === 'string') { + condition = condition.toString(); + } + + switch (conditionItem.operator) { + case '==': + return condition === conditionItem.value; + case '!=': + return condition !== conditionItem.value; + case '>=': + return condition >= conditionItem.value; + case '<=': + return condition <= conditionItem.value; + default: + this.logService.error('Could not parse operator: "', conditionItem.operator, + '" on item "', item, '"'); + return false; + } + } + private getValueOrDefault(infoObject: ServerInfo | {}, propertyValue: string, defaultVal?: any): T { let val: T = undefined; if (infoObject) { diff --git a/src/sql/workbench/parts/dataExplorer/browser/extensions.contribution.ts b/src/sql/workbench/parts/dataExplorer/browser/extensions.contribution.ts index c26d68dc2e..1295a97721 100644 --- a/src/sql/workbench/parts/dataExplorer/browser/extensions.contribution.ts +++ b/src/sql/workbench/parts/dataExplorer/browser/extensions.contribution.ts @@ -10,6 +10,7 @@ import { MssqlNodeContext } from 'sql/workbench/parts/dataExplorer/browser/mssql import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; import { localize } from 'vs/nls'; +import { DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes'; // Data-Tier Application Wizard MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { @@ -20,7 +21,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('dacFx', "Data-tier Application Wizard") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.IsDatabaseOrServer) + MssqlNodeContext.IsDatabaseOrServer, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); @@ -33,7 +34,8 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), MssqlNodeContext.NodeType.isEqualTo(NodeType.Folder), - MssqlNodeContext.NodeLabel.isEqualTo('Databases')) + MssqlNodeContext.NodeLabel.isEqualTo('Databases'), + MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // Profiler @@ -45,7 +47,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('profiler', "Launch Profiler") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Server)) + MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // Flat File Import @@ -69,7 +71,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('schemaCompare', "Schema Compare") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database)) + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // Generate Scripts Action @@ -82,7 +84,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), - MssqlNodeContext.IsWindows) + MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // Properties Action @@ -95,7 +97,7 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), MssqlNodeContext.NodeType.isEqualTo(NodeType.Server), ContextKeyExpr.not('isCloud'), - MssqlNodeContext.IsWindows) + MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { @@ -106,6 +108,6 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('properties', "Properties") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.IsWindows, + MssqlNodeContext.IsWindows, MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString()), ContextKeyRegexExpr.create('nodeType', /^(Database|Table|Column|Index|Statistic|View|ServerLevelLogin|ServerLevelServerRole|ServerLevelCredential|ServerLevelServerAudit|ServerLevelServerAuditSpecification|StoredProcedure|ScalarValuedFunction|TableValuedFunction|AggregateFunction|Synonym|Assembly|UserDefinedDataType|UserDefinedType|UserDefinedTableType|Sequence|User|DatabaseRole|ApplicationRole|Schema|SecurityPolicy|ServerLevelLinkedServer)$/)) }); diff --git a/src/sql/workbench/parts/dataExplorer/browser/mssqlNodeContext.ts b/src/sql/workbench/parts/dataExplorer/browser/mssqlNodeContext.ts index a69f8fb7cc..49548028ad 100644 --- a/src/sql/workbench/parts/dataExplorer/browser/mssqlNodeContext.ts +++ b/src/sql/workbench/parts/dataExplorer/browser/mssqlNodeContext.ts @@ -3,6 +3,7 @@ * Licensed under the Source EULA. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as azdata from 'azdata'; import { INodeContextValue } from 'sql/workbench/parts/dataExplorer/browser/nodeContext'; import { RawContextKey, IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { Disposable } from 'vs/base/common/lifecycle'; @@ -11,7 +12,7 @@ import { ConnectionProfile } from 'sql/platform/connection/common/connectionProf import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilitiesService'; import { mssqlProviderName } from 'sql/platform/connection/common/constants'; import { NodeType } from 'sql/workbench/parts/objectExplorer/common/nodeType'; -import { ExtensionNodeType } from 'sql/workbench/api/common/sqlExtHostTypes'; +import { ExtensionNodeType, DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes'; import { isWindows } from 'vs/base/common/platform'; export class MssqlNodeContext extends Disposable { @@ -32,6 +33,7 @@ export class MssqlNodeContext extends Disposable { static IsCloud = new RawContextKey('isCloud', false); static NodeType = new RawContextKey('nodeType', undefined); static NodeLabel = new RawContextKey('nodeLabel', undefined); + static EngineEdition = new RawContextKey('engineEdition', DatabaseEngineEdition.Unknown); // Scripting context keys static CanScriptAsSelect = new RawContextKey('canScriptAsSelect', false); @@ -45,6 +47,7 @@ export class MssqlNodeContext extends Disposable { private nodeTypeKey: IContextKey; private nodeLabelKey: IContextKey; private isDatabaseOrServerKey: IContextKey; + private engineEditionKey: IContextKey; private canScriptAsSelectKey: IContextKey; private canEditDataKey: IContextKey; @@ -67,6 +70,7 @@ export class MssqlNodeContext extends Disposable { if (node.payload) { this.setNodeProvider(); this.setIsCloud(); + this.setEngineEdition(); if (node.type) { this.setIsDatabaseOrServer(); this.nodeTypeKey.set(node.type); @@ -84,6 +88,7 @@ export class MssqlNodeContext extends Disposable { private bindContextKeys(): void { this.isCloudKey = MssqlNodeContext.IsCloud.bindTo(this.contextKeyService); + this.engineEditionKey = MssqlNodeContext.EngineEdition.bindTo(this.contextKeyService); this.nodeTypeKey = MssqlNodeContext.NodeType.bindTo(this.contextKeyService); this.nodeLabelKey = MssqlNodeContext.NodeLabel.bindTo(this.contextKeyService); this.isDatabaseOrServerKey = MssqlNodeContext.IsDatabaseOrServer.bindTo(this.contextKeyService); @@ -110,15 +115,34 @@ export class MssqlNodeContext extends Disposable { * Helper function to tell whether a connected node is cloud or not */ private setIsCloud(): void { + let serverInfo: azdata.ServerInfo = this.getServerInfo(); + if (serverInfo && serverInfo.isCloud) { + this.isCloudKey.set(true); + } + } + + /** + * Helper function to set engine edition + */ + private setEngineEdition(): void { + + let serverInfo: azdata.ServerInfo = this.getServerInfo(); + if (serverInfo && serverInfo.engineEditionId) { + this.engineEditionKey.set(serverInfo.engineEditionId); + } + } + + /** + * Helper function fetching the server info + */ + private getServerInfo(): azdata.ServerInfo | undefined { const profile = new ConnectionProfile(this.capabilitiesService, this.nodeContextValue.node.payload); const connection = this.connectionManagementService.findExistingConnection(profile); if (connection) { - const serverInfo = this.connectionManagementService.getServerInfo(connection.id); - if (serverInfo.isCloud) { - this.isCloudKey.set(true); - } + return this.connectionManagementService.getServerInfo(connection.id); } + return undefined; } /** diff --git a/src/sql/workbench/parts/restore/browser/restore.contribution.ts b/src/sql/workbench/parts/restore/browser/restore.contribution.ts index 31afd66431..307fbb48fa 100644 --- a/src/sql/workbench/parts/restore/browser/restore.contribution.ts +++ b/src/sql/workbench/parts/restore/browser/restore.contribution.ts @@ -18,6 +18,7 @@ import { ConnectionContextKey } from 'sql/workbench/parts/connection/common/conn import { ManageActionContext } from 'sql/workbench/browser/actions'; import { ItemContextKey } from 'sql/workbench/parts/dashboard/browser/widgets/explorer/explorerTreeContext'; import { ServerInfoContextKey } from 'sql/workbench/parts/connection/common/serverInfoContextKey'; +import { DatabaseEngineEdition } from 'sql/workbench/api/common/sqlExtHostTypes'; new RestoreAction().registerTask(); @@ -40,7 +41,8 @@ MenuRegistry.appendMenuItem(MenuId.DataExplorerContext, { title: localize('restore', "Restore") }, when: ContextKeyExpr.and(MssqlNodeContext.NodeProvider.isEqualTo(mssqlProviderName), - MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated()) + MssqlNodeContext.NodeType.isEqualTo(NodeType.Database), MssqlNodeContext.IsCloud.toNegated(), + MssqlNodeContext.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); // oe @@ -60,7 +62,8 @@ MenuRegistry.appendMenuItem(MenuId.ObjectExplorerItemContext, { id: OE_RESTORE_COMMAND_ID, title: localize('backup', "Restore") }, - when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), ServerInfoContextKey.IsCloud.toNegated()) + when: ContextKeyExpr.and(TreeNodeContextKey.NodeType.isEqualTo(NodeType.Database), ConnectionContextKey.Provider.isEqualTo(mssqlProviderName), + ServerInfoContextKey.IsCloud.toNegated(), ServerInfoContextKey.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())) }); const ExplorerRestoreActionID = 'explorer.restore'; @@ -74,6 +77,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerWidgetContext, { id: ExplorerRestoreActionID, title: RestoreAction.LABEL }, - when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), ItemContextKey.IsCloud.toNegated()), + when: ContextKeyExpr.and(ItemContextKey.ItemType.isEqualTo('database'), ItemContextKey.ConnectionProvider.isEqualTo('mssql'), + ItemContextKey.IsCloud.toNegated(), ItemContextKey.EngineEdition.notEqualsTo(DatabaseEngineEdition.SqlOnDemand.toString())), order: 2 });