Add object management handler for creating a database (#2071)

This commit is contained in:
Cory Rivera
2023-05-31 12:55:12 -07:00
committed by GitHub
parent eff103efba
commit d5cfc52ca7
9 changed files with 3712 additions and 8 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -6212,4 +6212,552 @@ The Query Processor estimates that implementing the following index could improv
<comment>. <comment>.
Parameters: 0 - serviceName (string) </comment> Parameters: 0 - serviceName (string) </comment>
</data> </data>
<data name="autogrowth_dialog_title" xml:space="preserve">
<value>Change Autogrowth for {0}</value>
<comment></comment>
</data>
<data name="autogrowth_dialog_filestreamtitle" xml:space="preserve">
<value>Change Maxsize for {0}</value>
<comment></comment>
</data>
<data name="autogrowth_dialog_defaulttitle" xml:space="preserve">
<value>Change Autogrowth</value>
<comment></comment>
</data>
<data name="autogrowth_dialog_defaultfilestreamtitle" xml:space="preserve">
<value>Change Maxsize</value>
<comment></comment>
</data>
<data name="createDatabase_title" xml:space="preserve">
<value>New Database</value>
<comment></comment>
</data>
<data name="error_60compatibility" xml:space="preserve">
<value>Database properties cannot be set or viewed for databases in 6.0 or 6.5 compatibility mode.</value>
<comment></comment>
</data>
<data name="error_cantModifyExistingFilePath" xml:space="preserve">
<value>You cannot modify the path for existing database files.</value>
<comment></comment>
</data>
<data name="error_databaseAlreadyExists" xml:space="preserve">
<value>There is already a database named &quot;{0}&quot; on the server.</value>
<comment></comment>
</data>
<data name="error_databaseProperties_title" xml:space="preserve">
<value>Database Properties</value>
<comment></comment>
</data>
<data name="error_emptyFileName" xml:space="preserve">
<value>File name was empty. Provide a file name for the file.</value>
<comment></comment>
</data>
<data name="error_fileNameContainsIllegalCharacter" xml:space="preserve">
<value>Cannot create a file with name &apos;{0}&apos; because it contains the invalid character &apos;{1}&apos;.</value>
<comment></comment>
</data>
<data name="error_fileNameStartsWithSpace" xml:space="preserve">
<value>Cannot create a file with name &apos;{0}&apos; because it begins with a space character.</value>
<comment></comment>
</data>
<data name="error_whitespaceDatabaseName" xml:space="preserve">
<value>A database name cannot consist of all whitespace characters.</value>
<comment></comment>
</data>
<data name="filegroup_dialog_defaultFilegroup" xml:space="preserve">
<value>Current default filegroup: {0}</value>
<comment></comment>
</data>
<data name="filegroup_dialog_title" xml:space="preserve">
<value>New Filegroup for {0}</value>
<comment></comment>
</data>
<data name="filegroups_default" xml:space="preserve">
<value>Default</value>
<comment></comment>
</data>
<data name="filegroups_files" xml:space="preserve">
<value>Files</value>
<comment></comment>
</data>
<data name="filegroups_name" xml:space="preserve">
<value>Name</value>
<comment></comment>
</data>
<data name="filegroups_readonly" xml:space="preserve">
<value>Read-Only</value>
<comment></comment>
</data>
<data name="filegroups_autogrowAllFiles" xml:space="preserve">
<value>Autogrow All Files</value>
<comment></comment>
</data>
<data name="general_autogrowth" xml:space="preserve">
<value>Autogrowth / Maxsize</value>
<comment></comment>
</data>
<data name="general_builderText" xml:space="preserve">
<value>...</value>
<comment></comment>
</data>
<data name="general_default" xml:space="preserve">
<value>&lt;default&gt;</value>
<comment></comment>
</data>
<data name="general_fileGroup" xml:space="preserve">
<value>Filegroup</value>
<comment></comment>
</data>
<data name="general_fileName" xml:space="preserve">
<value>Logical Name</value>
<comment></comment>
</data>
<data name="general_fileType" xml:space="preserve">
<value>File Type</value>
<comment></comment>
</data>
<data name="general_initialSize" xml:space="preserve">
<value>Initial Size (MB)</value>
<comment></comment>
</data>
<data name="general_currentSize" xml:space="preserve">
<value>Size (MB)</value>
<comment></comment>
</data>
<data name="general_newFilegroup" xml:space="preserve">
<value>&lt;new filegroup&gt;</value>
<comment></comment>
</data>
<data name="general_path" xml:space="preserve">
<value>Path</value>
<comment></comment>
</data>
<data name="general_physicalFileName" xml:space="preserve">
<value>File Name</value>
<comment></comment>
</data>
<data name="general_rawDevice" xml:space="preserve">
<value>&lt;raw device&gt;</value>
<comment></comment>
</data>
<data name="general_recoveryModel_bulkLogged" xml:space="preserve">
<value>Bulk-logged</value>
<comment></comment>
</data>
<data name="general_recoveryModel_full" xml:space="preserve">
<value>Full</value>
<comment></comment>
</data>
<data name="general_recoveryModel_simple" xml:space="preserve">
<value>Simple</value>
<comment></comment>
</data>
<data name="general_titleSearchOwner" xml:space="preserve">
<value>Select Database Owner</value>
<comment></comment>
</data>
<data name="leftPane_extendedPropertiesNode_name" xml:space="preserve">
<value>Extended Properties</value>
<comment></comment>
</data>
<data name="leftPane_filegroupsNode_name" xml:space="preserve">
<value>Filegroups</value>
<comment></comment>
</data>
<data name="leftPane_generalNode_name" xml:space="preserve">
<value>General</value>
<comment></comment>
</data>
<data name="leftPane_optionsNode_name" xml:space="preserve">
<value>Options</value>
<comment></comment>
</data>
<data name="leftPane_capabilitiesNode_name" xml:space="preserve">
<value>Configure SLO</value>
<comment></comment>
</data>
<data name="leftPane_topNode_name" xml:space="preserve">
<value>New Database</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_disabled" xml:space="preserve">
<value>None</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_restrictedGrowthByMB" xml:space="preserve">
<value>By {0} MB, Limited to {1} MB</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_restrictedGrowthByPercent" xml:space="preserve">
<value>By {0} percent, Limited to {1} MB </value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unrestrictedGrowthByMB" xml:space="preserve">
<value>By {0} MB, Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unrestrictedGrowthByPercent" xml:space="preserve">
<value>By {0} percent, Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_unlimitedfilestream" xml:space="preserve">
<value>Unlimited</value>
<comment></comment>
</data>
<data name="prototype_autogrowth_limitedfilestream" xml:space="preserve">
<value>Limited to {0} MB</value>
<comment></comment>
</data>
<data name="prototype_db_category_automatic" xml:space="preserve">
<value>Automatic</value>
<comment></comment>
</data>
<data name="prototype_db_category_servicebroker" xml:space="preserve">
<value>Service Broker</value>
<comment></comment>
</data>
<data name="prototype_db_category_collation" xml:space="preserve">
<value>Collation</value>
<comment></comment>
</data>
<data name="prototype_db_category_cursor" xml:space="preserve">
<value>Cursor</value>
<comment></comment>
</data>
<data name="prototype_db_category_misc" xml:space="preserve">
<value>Miscellaneous</value>
<comment></comment>
</data>
<data name="prototype_db_category_recovery" xml:space="preserve">
<value>Recovery</value>
<comment></comment>
</data>
<data name="prototype_db_category_state" xml:space="preserve">
<value>State</value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiNullDefault" xml:space="preserve">
<value>ANSI NULL Default </value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiNulls" xml:space="preserve">
<value>ANSI NULLS Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiPadding" xml:space="preserve">
<value>ANSI Padding Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_ansiWarnings" xml:space="preserve">
<value>ANSI Warnings Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_arithabort" xml:space="preserve">
<value>Arithmetic Abort Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoClose" xml:space="preserve">
<value>Auto Close </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoCreateStatistics" xml:space="preserve">
<value>Auto Create Statistics </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoShrink" xml:space="preserve">
<value>Auto Shrink </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoUpdateStatistics" xml:space="preserve">
<value>Auto Update Statistics </value>
<comment></comment>
</data>
<data name="prototype_db_prop_autoUpdateStatisticsAsync" xml:space="preserve">
<value>Auto Update Statistics Asynchronously</value>
<comment></comment>
</data>
<data name="prototype_db_prop_caseSensitive" xml:space="preserve">
<value>Case Sensitive </value>
<comment></comment>
</data>
<data name="prototype_db_prop_closeCursorOnCommit" xml:space="preserve">
<value>Close Cursor on Commit Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_collation" xml:space="preserve">
<value>Collation</value>
<comment></comment>
</data>
<data name="prototype_db_prop_concatNullYieldsNull" xml:space="preserve">
<value>Concatenate Null Yields Null </value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseCompatibilityLevel" xml:space="preserve">
<value>Database Compatibility Level </value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState" xml:space="preserve">
<value>Database State </value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor" xml:space="preserve">
<value>Default Cursor </value>
<comment></comment>
</data>
<data name="prototype_db_prop_fullTextIndexing" xml:space="preserve">
<value>Full-Text Indexing Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_numericRoundAbort" xml:space="preserve">
<value>Numeric Round-Abort </value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify" xml:space="preserve">
<value>Page Verify </value>
<comment></comment>
</data>
<data name="prototype_db_prop_quotedIdentifier" xml:space="preserve">
<value>Quoted Identifiers Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_readOnly" xml:space="preserve">
<value>Database Read-Only </value>
<comment></comment>
</data>
<data name="prototype_db_prop_recursiveTriggers" xml:space="preserve">
<value>Recursive Triggers Enabled </value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess" xml:space="preserve">
<value>Restrict Access </value>
<comment></comment>
</data>
<data name="prototype_db_prop_selectIntoBulkCopy" xml:space="preserve">
<value>Select Into/Bulk Copy </value>
<comment></comment>
</data>
<data name="prototype_db_prop_honorBrokerPriority" xml:space="preserve">
<value>Honor Broker Priority</value>
<comment></comment>
</data>
<data name="prototype_db_prop_serviceBrokerGuid" xml:space="preserve">
<value>Service Broker Identifier</value>
<comment></comment>
</data>
<data name="prototype_db_prop_brokerEnabled" xml:space="preserve">
<value>Broker Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_truncateLogOnCheckpoint" xml:space="preserve">
<value>Truncate Log on Checkpoint </value>
<comment></comment>
</data>
<data name="prototype_db_prop_dbChaining" xml:space="preserve">
<value>Cross-database Ownership Chaining Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_trustworthy" xml:space="preserve">
<value>Trustworthy</value>
<comment></comment>
</data>
<data name="prototype_db_prop_dateCorrelationOptimization" xml:space="preserve">
<value>Date Correlation Optimization Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_parameterization" xml:space="preserve">
<value>Parameterization</value>
<comment></comment>
</data>
<data name="prototype_db_prop_parameterization_value_forced" xml:space="preserve">
<value>Forced</value>
<comment></comment>
</data>
<data name="prototype_db_prop_parameterization_value_simple" xml:space="preserve">
<value>Simple</value>
<comment></comment>
</data>
<data name="prototype_file_dataFile" xml:space="preserve">
<value>ROWS Data</value>
<comment></comment>
</data>
<data name="prototype_file_logFile" xml:space="preserve">
<value>LOG</value>
<comment></comment>
</data>
<data name="prototype_file_filestreamFile" xml:space="preserve">
<value>FILESTREAM Data</value>
<comment></comment>
</data>
<data name="prototype_file_noFileGroup" xml:space="preserve">
<value>Not Applicable</value>
<comment></comment>
</data>
<data name="prototype_file_defaultpathstring" xml:space="preserve">
<value>&lt;default path&gt;</value>
<comment></comment>
</data>
<data name="title_openConnectionsMustBeClosed" xml:space="preserve">
<value>Open Connections</value>
<comment></comment>
</data>
<data name="warning_openConnectionsMustBeClosed" xml:space="preserve">
<value>To change the database properties, SQL Server must close all other connections to the database. Are you sure you want to change the properties and close all other connections?</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_autoClosed" xml:space="preserve">
<value>AUTO_CLOSED</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_emergency" xml:space="preserve">
<value>EMERGENCY</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_inaccessible" xml:space="preserve">
<value>INACCESSIBLE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_normal" xml:space="preserve">
<value>NORMAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_offline" xml:space="preserve">
<value>OFFLINE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_recovering" xml:space="preserve">
<value>RECOVERING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_recoveryPending" xml:space="preserve">
<value>RECOVERY PENDING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_restoring" xml:space="preserve">
<value>RESTORING</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_shutdown" xml:space="preserve">
<value>SHUTDOWN</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_standby" xml:space="preserve">
<value>STANDBY</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databaseState_value_suspect" xml:space="preserve">
<value>SUSPECT</value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor_value_global" xml:space="preserve">
<value>GLOBAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_defaultCursor_value_local" xml:space="preserve">
<value>LOCAL</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_multiple" xml:space="preserve">
<value>MULTI_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_restricted" xml:space="preserve">
<value>RESTRICTED_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_restrictAccess_value_single" xml:space="preserve">
<value>SINGLE_USER</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_checksum" xml:space="preserve">
<value>CHECKSUM</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_none" xml:space="preserve">
<value>NONE</value>
<comment></comment>
</data>
<data name="prototype_db_prop_pageVerify_value_tornPageDetection" xml:space="preserve">
<value>TORN_PAGE_DETECTION</value>
<comment></comment>
</data>
<data name="prototype_db_prop_varDecimalEnabled" xml:space="preserve">
<value>VarDecimal Storage Format Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_encryptionEnabled" xml:space="preserve">
<value>Encryption Enabled</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databasescopedconfig_value_off" xml:space="preserve">
<value>OFF</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databasescopedconfig_value_on" xml:space="preserve">
<value>ON</value>
<comment></comment>
</data>
<data name="prototype_db_prop_databasescopedconfig_value_primary" xml:space="preserve">
<value>PRIMARY</value>
<comment></comment>
</data>
<data name="error_db_prop_invalidleadingColumns" xml:space="preserve">
<value>For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sphinx" xml:space="preserve">
<value>SQL Server 7.0 (70)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_shiloh" xml:space="preserve">
<value>SQL Server 2000 (80)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_yukon" xml:space="preserve">
<value>SQL Server 2005 (90)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_katmai" xml:space="preserve">
<value>SQL Server 2008 (100)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_denali" xml:space="preserve">
<value>SQL Server 2012 (110)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sql14" xml:space="preserve">
<value>SQL Server 2014 (120)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sql15" xml:space="preserve">
<value>SQL Server 2016 (130)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sql2017" xml:space="preserve">
<value>SQL Server 2017 (140)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sqlv150" xml:space="preserve">
<value>SQL Server 2019 (150)</value>
<comment></comment>
</data>
<data name="compatibilityLevel_sqlv160" xml:space="preserve">
<value>SQL Server 2022 (160)</value>
<comment></comment>
</data>
<data name="general_containmentType_None" xml:space="preserve">
<value>None</value>
<comment></comment>
</data>
<data name="general_containmentType_Partial" xml:space="preserve">
<value>Partial</value>
<comment></comment>
</data>
<data name="filegroups_filestreamFiles" xml:space="preserve">
<value>FILESTREAM Files</value>
<comment></comment>
</data>
<data name="prototype_file_noApplicableFileGroup" xml:space="preserve">
<value>No Applicable Filegroup</value>
<comment></comment>
</data>
</root> </root>

View File

@@ -2662,3 +2662,143 @@ Permission_ImpersonateAnyLogin = Impersonate Any Login
ServiceProviderNotSet = SetServiceProvider() was not called to establish the required service provider ServiceProviderNotSet = SetServiceProvider() was not called to establish the required service provider
ServiceNotFound(string serviceName) = Service {0} was not found in the service provider ServiceNotFound(string serviceName) = Service {0} was not found in the service provider
############################################################################
# Create Database
autogrowth_dialog_title = Change Autogrowth for {0}
autogrowth_dialog_filestreamtitle = Change Maxsize for {0}
autogrowth_dialog_defaulttitle = Change Autogrowth
autogrowth_dialog_defaultfilestreamtitle = Change Maxsize
createDatabase_title = New Database
error_60compatibility = Database properties cannot be set or viewed for databases in 6.0 or 6.5 compatibility mode.
error_cantModifyExistingFilePath = You cannot modify the path for existing database files.
error_databaseAlreadyExists = There is already a database named "{0}" on the server.
error_databaseProperties_title = Database Properties
error_emptyFileName = File name was empty. Provide a file name for the file.
error_fileNameContainsIllegalCharacter = Cannot create a file with name '{0}' because it contains the invalid character '{1}'.
error_fileNameStartsWithSpace = Cannot create a file with name '{0}' because it begins with a space character.
error_whitespaceDatabaseName = A database name cannot consist of all whitespace characters.
filegroup_dialog_defaultFilegroup = Current default filegroup: {0}
filegroup_dialog_title = New Filegroup for {0}
filegroups_default = Default
filegroups_files = Files
filegroups_name = Name
filegroups_readonly = Read-Only
filegroups_autogrowAllFiles = Autogrow All Files
general_autogrowth = Autogrowth / Maxsize
general_builderText = ...
general_default = <default>
general_fileGroup = Filegroup
general_fileName = Logical Name
general_fileType = File Type
general_initialSize = Initial Size (MB)
general_currentSize = Size (MB)
general_newFilegroup = <new filegroup>
general_path = Path
general_physicalFileName = File Name
general_rawDevice = <raw device>
general_recoveryModel_bulkLogged = Bulk-logged
general_recoveryModel_full = Full
general_recoveryModel_simple = Simple
general_titleSearchOwner = Select Database Owner
leftPane_extendedPropertiesNode_name = Extended Properties
leftPane_filegroupsNode_name = Filegroups
leftPane_generalNode_name = General
leftPane_optionsNode_name = Options
leftPane_capabilitiesNode_name = Configure SLO
leftPane_topNode_name = New Database
prototype_autogrowth_disabled = None
prototype_autogrowth_restrictedGrowthByMB = By {0} MB, Limited to {1} MB
prototype_autogrowth_restrictedGrowthByPercent = By {0} percent, Limited to {1} MB
prototype_autogrowth_unrestrictedGrowthByMB = By {0} MB, Unlimited
prototype_autogrowth_unrestrictedGrowthByPercent = By {0} percent, Unlimited
prototype_autogrowth_unlimitedfilestream = Unlimited
prototype_autogrowth_limitedfilestream = Limited to {0} MB
prototype_db_category_automatic = Automatic
prototype_db_category_servicebroker = Service Broker
prototype_db_category_collation = Collation
prototype_db_category_cursor = Cursor
prototype_db_category_misc = Miscellaneous
prototype_db_category_recovery = Recovery
prototype_db_category_state = State
prototype_db_prop_ansiNullDefault = ANSI NULL Default
prototype_db_prop_ansiNulls = ANSI NULLS Enabled
prototype_db_prop_ansiPadding = ANSI Padding Enabled
prototype_db_prop_ansiWarnings = ANSI Warnings Enabled
prototype_db_prop_arithabort = Arithmetic Abort Enabled
prototype_db_prop_autoClose = Auto Close
prototype_db_prop_autoCreateStatistics = Auto Create Statistics
prototype_db_prop_autoShrink = Auto Shrink
prototype_db_prop_autoUpdateStatistics = Auto Update Statistics
prototype_db_prop_autoUpdateStatisticsAsync = Auto Update Statistics Asynchronously
prototype_db_prop_caseSensitive = Case Sensitive
prototype_db_prop_closeCursorOnCommit = Close Cursor on Commit Enabled
prototype_db_prop_collation = Collation
prototype_db_prop_concatNullYieldsNull = Concatenate Null Yields Null
prototype_db_prop_databaseCompatibilityLevel = Database Compatibility Level
prototype_db_prop_databaseState = Database State
prototype_db_prop_defaultCursor = Default Cursor
prototype_db_prop_fullTextIndexing = Full-Text Indexing Enabled
prototype_db_prop_numericRoundAbort = Numeric Round-Abort
prototype_db_prop_pageVerify = Page Verify
prototype_db_prop_quotedIdentifier = Quoted Identifiers Enabled
prototype_db_prop_readOnly = Database Read-Only
prototype_db_prop_recursiveTriggers = Recursive Triggers Enabled
prototype_db_prop_restrictAccess = Restrict Access
prototype_db_prop_selectIntoBulkCopy = Select Into/Bulk Copy
prototype_db_prop_honorBrokerPriority = Honor Broker Priority
prototype_db_prop_serviceBrokerGuid = Service Broker Identifier
prototype_db_prop_brokerEnabled = Broker Enabled
prototype_db_prop_truncateLogOnCheckpoint = Truncate Log on Checkpoint
prototype_db_prop_dbChaining = Cross-database Ownership Chaining Enabled
prototype_db_prop_trustworthy = Trustworthy
prototype_db_prop_dateCorrelationOptimization = Date Correlation Optimization Enabled
prototype_db_prop_parameterization = Parameterization
prototype_db_prop_parameterization_value_forced = Forced
prototype_db_prop_parameterization_value_simple = Simple
prototype_file_dataFile = ROWS Data
prototype_file_logFile = LOG
prototype_file_filestreamFile = FILESTREAM Data
prototype_file_noFileGroup = Not Applicable
prototype_file_defaultpathstring = <default path>
title_openConnectionsMustBeClosed = Open Connections
warning_openConnectionsMustBeClosed = To change the database properties, SQL Server must close all other connections to the database. Are you sure you want to change the properties and close all other connections?
prototype_db_prop_databaseState_value_autoClosed = AUTO_CLOSED
prototype_db_prop_databaseState_value_emergency = EMERGENCY
prototype_db_prop_databaseState_value_inaccessible = INACCESSIBLE
prototype_db_prop_databaseState_value_normal = NORMAL
prototype_db_prop_databaseState_value_offline = OFFLINE
prototype_db_prop_databaseState_value_recovering = RECOVERING
prototype_db_prop_databaseState_value_recoveryPending = RECOVERY PENDING
prototype_db_prop_databaseState_value_restoring = RESTORING
prototype_db_prop_databaseState_value_shutdown = SHUTDOWN
prototype_db_prop_databaseState_value_standby = STANDBY
prototype_db_prop_databaseState_value_suspect = SUSPECT
prototype_db_prop_defaultCursor_value_global = GLOBAL
prototype_db_prop_defaultCursor_value_local = LOCAL
prototype_db_prop_restrictAccess_value_multiple = MULTI_USER
prototype_db_prop_restrictAccess_value_restricted = RESTRICTED_USER
prototype_db_prop_restrictAccess_value_single = SINGLE_USER
prototype_db_prop_pageVerify_value_checksum = CHECKSUM
prototype_db_prop_pageVerify_value_none = NONE
prototype_db_prop_pageVerify_value_tornPageDetection = TORN_PAGE_DETECTION
prototype_db_prop_varDecimalEnabled = VarDecimal Storage Format Enabled
prototype_db_prop_encryptionEnabled = Encryption Enabled
prototype_db_prop_databasescopedconfig_value_off = OFF
prototype_db_prop_databasescopedconfig_value_on = ON
prototype_db_prop_databasescopedconfig_value_primary = PRIMARY
error_db_prop_invalidleadingColumns = For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns
compatibilityLevel_sphinx = SQL Server 7.0 (70)
compatibilityLevel_shiloh = SQL Server 2000 (80)
compatibilityLevel_yukon = SQL Server 2005 (90)
compatibilityLevel_katmai = SQL Server 2008 (100)
compatibilityLevel_denali = SQL Server 2012 (110)
compatibilityLevel_sql14 = SQL Server 2014 (120)
compatibilityLevel_sql15 = SQL Server 2016 (130)
compatibilityLevel_sql2017 = SQL Server 2017 (140)
compatibilityLevel_sqlv150 = SQL Server 2019 (150)
compatibilityLevel_sqlv160 = SQL Server 2022 (160)
general_containmentType_None = None
general_containmentType_Partial = Partial
filegroups_filestreamFiles = FILESTREAM Files
prototype_file_noApplicableFileGroup = No Applicable Filegroup

View File

@@ -7596,6 +7596,691 @@ The Query Processor estimates that implementing the following index could improv
<target state="new">Schema and Data</target> <target state="new">Schema and Data</target>
<note></note> <note></note>
</trans-unit> </trans-unit>
<trans-unit id="autogrowth_dialog_title">
<source>Change Autogrowth for {0}</source>
<target state="new">Change Autogrowth for {0}</target>
<note></note>
</trans-unit>
<trans-unit id="autogrowth_dialog_filestreamtitle">
<source>Change Maxsize for {0}</source>
<target state="new">Change Maxsize for {0}</target>
<note></note>
</trans-unit>
<trans-unit id="autogrowth_dialog_defaulttitle">
<source>Change Autogrowth</source>
<target state="new">Change Autogrowth</target>
<note></note>
</trans-unit>
<trans-unit id="autogrowth_dialog_defaultfilestreamtitle">
<source>Change Maxsize</source>
<target state="new">Change Maxsize</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_shiloh">
<source>SQL Server 2000 (80)</source>
<target state="new">SQL Server 2000 (80)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sphinx">
<source>SQL Server 7.0 (70)</source>
<target state="new">SQL Server 7.0 (70)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_yukon">
<source>SQL Server 2005 (90)</source>
<target state="new">SQL Server 2005 (90)</target>
<note></note>
</trans-unit>
<trans-unit id="createDatabase_title">
<source>New Database</source>
<target state="new">New Database</target>
<note></note>
</trans-unit>
<trans-unit id="error_60compatibility">
<source>Database properties cannot be set or viewed for databases in 6.0 or 6.5 compatibility mode.</source>
<target state="new">Database properties cannot be set or viewed for databases in 6.0 or 6.5 compatibility mode.</target>
<note></note>
</trans-unit>
<trans-unit id="error_cantModifyExistingFilePath">
<source>You cannot modify the path for existing database files.</source>
<target state="new">You cannot modify the path for existing database files.</target>
<note></note>
</trans-unit>
<trans-unit id="error_databaseAlreadyExists">
<source>There is already a database named "{0}" on the server.</source>
<target state="new">There is already a database named "{0}" on the server.</target>
<note></note>
</trans-unit>
<trans-unit id="error_databaseProperties_title">
<source>Database Properties</source>
<target state="new">Database Properties</target>
<note></note>
</trans-unit>
<trans-unit id="error_emptyFileName">
<source>File name was empty. Provide a file name for the file.</source>
<target state="new">File name was empty. Provide a file name for the file.</target>
<note></note>
</trans-unit>
<trans-unit id="error_fileNameContainsIllegalCharacter">
<source>Cannot create a file with name '{0}' because it contains the invalid character '{1}'.</source>
<target state="new">Cannot create a file with name '{0}' because it contains the invalid character '{1}'.</target>
<note></note>
</trans-unit>
<trans-unit id="error_fileNameStartsWithSpace">
<source>Cannot create a file with name '{0}' because it begins with a space character.</source>
<target state="new">Cannot create a file with name '{0}' because it begins with a space character.</target>
<note></note>
</trans-unit>
<trans-unit id="error_whitespaceDatabaseName">
<source>A database name cannot consist of all whitespace characters.</source>
<target state="new">A database name cannot consist of all whitespace characters.</target>
<note></note>
</trans-unit>
<trans-unit id="filegroup_dialog_defaultFilegroup">
<source>Current default filegroup: {0}</source>
<target state="new">Current default filegroup: {0}</target>
<note></note>
</trans-unit>
<trans-unit id="filegroup_dialog_title">
<source>New Filegroup for {0}</source>
<target state="new">New Filegroup for {0}</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_default">
<source>Default</source>
<target state="new">Default</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_files">
<source>Files</source>
<target state="new">Files</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_name">
<source>Name</source>
<target state="new">Name</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_readonly">
<source>Read-Only</source>
<target state="new">Read-Only</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_autogrowAllFiles">
<source>Autogrow All Files</source>
<target state="new">Autogrow All Files</target>
<note></note>
</trans-unit>
<trans-unit id="general_autogrowth">
<source>Autogrowth / Maxsize</source>
<target state="new">Autogrowth / Maxsize</target>
<note></note>
</trans-unit>
<trans-unit id="general_builderText">
<source>...</source>
<target state="new">...</target>
<note></note>
</trans-unit>
<trans-unit id="general_default">
<source>&lt;default&gt;</source>
<target state="new">&lt;default&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileGroup">
<source>Filegroup</source>
<target state="new">Filegroup</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileName">
<source>Logical Name</source>
<target state="new">Logical Name</target>
<note></note>
</trans-unit>
<trans-unit id="general_fileType">
<source>File Type</source>
<target state="new">File Type</target>
<note></note>
</trans-unit>
<trans-unit id="general_initialSize">
<source>Initial Size (MB)</source>
<target state="new">Initial Size (MB)</target>
<note></note>
</trans-unit>
<trans-unit id="general_currentSize">
<source>Size (MB)</source>
<target state="new">Size (MB)</target>
<note></note>
</trans-unit>
<trans-unit id="general_newFilegroup">
<source>&lt;new filegroup&gt;</source>
<target state="new">&lt;new filegroup&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_path">
<source>Path</source>
<target state="new">Path</target>
<note></note>
</trans-unit>
<trans-unit id="general_physicalFileName">
<source>File Name</source>
<target state="new">File Name</target>
<note></note>
</trans-unit>
<trans-unit id="general_rawDevice">
<source>&lt;raw device&gt;</source>
<target state="new">&lt;raw device&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_bulkLogged">
<source>Bulk-logged</source>
<target state="new">Bulk-logged</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_full">
<source>Full</source>
<target state="new">Full</target>
<note></note>
</trans-unit>
<trans-unit id="general_recoveryModel_simple">
<source>Simple</source>
<target state="new">Simple</target>
<note></note>
</trans-unit>
<trans-unit id="general_titleSearchOwner">
<source>Select Database Owner</source>
<target state="new">Select Database Owner</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_extendedPropertiesNode_name">
<source>Extended Properties</source>
<target state="new">Extended Properties</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_filegroupsNode_name">
<source>Filegroups</source>
<target state="new">Filegroups</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_generalNode_name">
<source>General</source>
<target state="new">General</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_optionsNode_name">
<source>Options</source>
<target state="new">Options</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_capabilitiesNode_name">
<source>Configure SLO</source>
<target state="new">Configure SLO</target>
<note></note>
</trans-unit>
<trans-unit id="leftPane_topNode_name">
<source>New Database</source>
<target state="new">New Database</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_disabled">
<source>None</source>
<target state="new">None</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_restrictedGrowthByMB">
<source>By {0} MB, Limited to {1} MB</source>
<target state="new">By {0} MB, Limited to {1} MB</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_restrictedGrowthByPercent">
<source>By {0} percent, Limited to {1} MB </source>
<target state="new">By {0} percent, Limited to {1} MB </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unrestrictedGrowthByMB">
<source>By {0} MB, Unlimited</source>
<target state="new">By {0} MB, Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unrestrictedGrowthByPercent">
<source>By {0} percent, Unlimited</source>
<target state="new">By {0} percent, Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_unlimitedfilestream">
<source>Unlimited</source>
<target state="new">Unlimited</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_autogrowth_limitedfilestream">
<source>Limited to {0} MB</source>
<target state="new">Limited to {0} MB</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_automatic">
<source>Automatic</source>
<target state="new">Automatic</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_servicebroker">
<source>Service Broker</source>
<target state="new">Service Broker</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_collation">
<source>Collation</source>
<target state="new">Collation</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_cursor">
<source>Cursor</source>
<target state="new">Cursor</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_misc">
<source>Miscellaneous</source>
<target state="new">Miscellaneous</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_recovery">
<source>Recovery</source>
<target state="new">Recovery</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_category_state">
<source>State</source>
<target state="new">State</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiNullDefault">
<source>ANSI NULL Default </source>
<target state="new">ANSI NULL Default </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiNulls">
<source>ANSI NULLS Enabled </source>
<target state="new">ANSI NULLS Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiPadding">
<source>ANSI Padding Enabled </source>
<target state="new">ANSI Padding Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_ansiWarnings">
<source>ANSI Warnings Enabled </source>
<target state="new">ANSI Warnings Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_arithabort">
<source>Arithmetic Abort Enabled </source>
<target state="new">Arithmetic Abort Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoClose">
<source>Auto Close </source>
<target state="new">Auto Close </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoCreateStatistics">
<source>Auto Create Statistics </source>
<target state="new">Auto Create Statistics </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoShrink">
<source>Auto Shrink </source>
<target state="new">Auto Shrink </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoUpdateStatistics">
<source>Auto Update Statistics </source>
<target state="new">Auto Update Statistics </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_autoUpdateStatisticsAsync">
<source>Auto Update Statistics Asynchronously</source>
<target state="new">Auto Update Statistics Asynchronously</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_caseSensitive">
<source>Case Sensitive </source>
<target state="new">Case Sensitive </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_closeCursorOnCommit">
<source>Close Cursor on Commit Enabled </source>
<target state="new">Close Cursor on Commit Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_collation">
<source>Collation</source>
<target state="new">Collation</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_concatNullYieldsNull">
<source>Concatenate Null Yields Null </source>
<target state="new">Concatenate Null Yields Null </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseCompatibilityLevel">
<source>Database Compatibility Level </source>
<target state="new">Database Compatibility Level </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState">
<source>Database State </source>
<target state="new">Database State </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor">
<source>Default Cursor </source>
<target state="new">Default Cursor </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_fullTextIndexing">
<source>Full-Text Indexing Enabled </source>
<target state="new">Full-Text Indexing Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_numericRoundAbort">
<source>Numeric Round-Abort </source>
<target state="new">Numeric Round-Abort </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify">
<source>Page Verify </source>
<target state="new">Page Verify </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_quotedIdentifier">
<source>Quoted Identifiers Enabled </source>
<target state="new">Quoted Identifiers Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_readOnly">
<source>Database Read-Only </source>
<target state="new">Database Read-Only </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_recursiveTriggers">
<source>Recursive Triggers Enabled </source>
<target state="new">Recursive Triggers Enabled </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess">
<source>Restrict Access </source>
<target state="new">Restrict Access </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_selectIntoBulkCopy">
<source>Select Into/Bulk Copy </source>
<target state="new">Select Into/Bulk Copy </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_honorBrokerPriority">
<source>Honor Broker Priority</source>
<target state="new">Honor Broker Priority</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_serviceBrokerGuid">
<source>Service Broker Identifier</source>
<target state="new">Service Broker Identifier</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_brokerEnabled">
<source>Broker Enabled</source>
<target state="new">Broker Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_truncateLogOnCheckpoint">
<source>Truncate Log on Checkpoint </source>
<target state="new">Truncate Log on Checkpoint </target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_dbChaining">
<source>Cross-database Ownership Chaining Enabled</source>
<target state="new">Cross-database Ownership Chaining Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_trustworthy">
<source>Trustworthy</source>
<target state="new">Trustworthy</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_dateCorrelationOptimization">
<source>Date Correlation Optimization Enabled</source>
<target state="new">Date Correlation Optimization Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_parameterization">
<source>Parameterization</source>
<target state="new">Parameterization</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_parameterization_value_forced">
<source>Forced</source>
<target state="new">Forced</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_parameterization_value_simple">
<source>Simple</source>
<target state="new">Simple</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_dataFile">
<source>ROWS Data</source>
<target state="new">ROWS Data</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_logFile">
<source>LOG</source>
<target state="new">LOG</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_filestreamFile">
<source>FILESTREAM Data</source>
<target state="new">FILESTREAM Data</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_noFileGroup">
<source>Not Applicable</source>
<target state="new">Not Applicable</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_defaultpathstring">
<source>&lt;default path&gt;</source>
<target state="new">&lt;default path&gt;</target>
<note></note>
</trans-unit>
<trans-unit id="title_openConnectionsMustBeClosed">
<source>Open Connections</source>
<target state="new">Open Connections</target>
<note></note>
</trans-unit>
<trans-unit id="warning_openConnectionsMustBeClosed">
<source>To change the database properties, SQL Server must close all other connections to the database. Are you sure you want to change the properties and close all other connections?</source>
<target state="new">To change the database properties, SQL Server must close all other connections to the database. Are you sure you want to change the properties and close all other connections?</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_autoClosed">
<source>AUTO_CLOSED</source>
<target state="new">AUTO_CLOSED</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_emergency">
<source>EMERGENCY</source>
<target state="new">EMERGENCY</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_inaccessible">
<source>INACCESSIBLE</source>
<target state="new">INACCESSIBLE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_normal">
<source>NORMAL</source>
<target state="new">NORMAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_offline">
<source>OFFLINE</source>
<target state="new">OFFLINE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_recovering">
<source>RECOVERING</source>
<target state="new">RECOVERING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_recoveryPending">
<source>RECOVERY PENDING</source>
<target state="new">RECOVERY PENDING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_restoring">
<source>RESTORING</source>
<target state="new">RESTORING</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_shutdown">
<source>SHUTDOWN</source>
<target state="new">SHUTDOWN</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_standby">
<source>STANDBY</source>
<target state="new">STANDBY</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databaseState_value_suspect">
<source>SUSPECT</source>
<target state="new">SUSPECT</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor_value_global">
<source>GLOBAL</source>
<target state="new">GLOBAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_defaultCursor_value_local">
<source>LOCAL</source>
<target state="new">LOCAL</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_multiple">
<source>MULTI_USER</source>
<target state="new">MULTI_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_restricted">
<source>RESTRICTED_USER</source>
<target state="new">RESTRICTED_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_restrictAccess_value_single">
<source>SINGLE_USER</source>
<target state="new">SINGLE_USER</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_checksum">
<source>CHECKSUM</source>
<target state="new">CHECKSUM</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_none">
<source>NONE</source>
<target state="new">NONE</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_pageVerify_value_tornPageDetection">
<source>TORN_PAGE_DETECTION</source>
<target state="new">TORN_PAGE_DETECTION</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_varDecimalEnabled">
<source>VarDecimal Storage Format Enabled</source>
<target state="new">VarDecimal Storage Format Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_katmai">
<source>SQL Server 2008 (100)</source>
<target state="new">SQL Server 2008 (100)</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_encryptionEnabled">
<source>Encryption Enabled</source>
<target state="new">Encryption Enabled</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databasescopedconfig_value_off">
<source>OFF</source>
<target state="new">OFF</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databasescopedconfig_value_on">
<source>ON</source>
<target state="new">ON</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_db_prop_databasescopedconfig_value_primary">
<source>PRIMARY</source>
<target state="new">PRIMARY</target>
<note></note>
</trans-unit>
<trans-unit id="error_db_prop_invalidleadingColumns">
<source>For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</source>
<target state="new">For the distribution policy HASH, the number of leading hash columns is optional but should be from 1 to 16 columns</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_denali">
<source>SQL Server 2012 (110)</source>
<target state="new">SQL Server 2012 (110)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sql14">
<source>SQL Server 2014 (120)</source>
<target state="new">SQL Server 2014 (120)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sql15">
<source>SQL Server 2016 (130)</source>
<target state="new">SQL Server 2016 (130)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sql2017">
<source>SQL Server 2017 (140)</source>
<target state="new">SQL Server 2017 (140)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sqlv150">
<source>SQL Server 2019 (150)</source>
<target state="new">SQL Server 2019 (150)</target>
<note></note>
</trans-unit>
<trans-unit id="compatibilityLevel_sqlv160">
<source>SQL Server 2022 (160)</source>
<target state="new">SQL Server 2022 (160)</target>
<note></note>
</trans-unit>
<trans-unit id="general_containmentType_None">
<source>None</source>
<target state="new">None</target>
<note></note>
</trans-unit>
<trans-unit id="general_containmentType_Partial">
<source>Partial</source>
<target state="new">Partial</target>
<note></note>
</trans-unit>
<trans-unit id="filegroups_filestreamFiles">
<source>FILESTREAM Files</source>
<target state="new">FILESTREAM Files</target>
<note></note>
</trans-unit>
<trans-unit id="prototype_file_noApplicableFileGroup">
<source>No Applicable Filegroup</source>
<target state="new">No Applicable Filegroup</target>
<note></note>
</trans-unit>
</body> </body>
</file> </file>
</xliff> </xliff>

View File

@@ -0,0 +1,38 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using Microsoft.SqlTools.ServiceLayer.Admin;
using Microsoft.SqlTools.ServiceLayer.Management;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
internal class DatabaseActions : ManagementActionBase
{
private ConfigAction configAction;
private DatabasePrototype prototype;
/// <summary>
/// Handle Database create and update actions
/// </summary>
public DatabaseActions(CDataContainer dataContainer, ConfigAction configAction, DatabasePrototype prototype)
{
this.DataContainer = dataContainer;
this.configAction = configAction;
this.prototype = prototype;
}
/// <summary>
/// Called by the management actions framework to execute the action
/// </summary>
public override void OnRunNow(object sender)
{
if (this.configAction != ConfigAction.Drop)
{
prototype.ApplyChanges();
}
}
}
}

View File

@@ -4,8 +4,19 @@
// //
using System; using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Sdk.Sfc;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Admin;
using static Microsoft.SqlTools.ServiceLayer.Admin.AzureSqlDbHelper;
using Microsoft.SqlTools.ServiceLayer.Connection; using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.Management;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts; using Microsoft.SqlTools.ServiceLayer.ObjectManagement.Contracts;
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
@@ -15,8 +26,53 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
/// </summary> /// </summary>
public class DatabaseHandler : ObjectTypeHandler<DatabaseInfo, DatabaseViewContext> public class DatabaseHandler : ObjectTypeHandler<DatabaseInfo, DatabaseViewContext>
{ {
private const int minimumVersionForWritableCollation = 8;
private const int minimumVersionForRecoveryModel = 8;
private const string serverNotExistsError = "Server was not created for data container";
private readonly Dictionary<CompatibilityLevel, string> displayCompatLevels = new Dictionary<CompatibilityLevel, string>();
private readonly Dictionary<ContainmentType, string> displayContainmentTypes = new Dictionary<ContainmentType, string>();
private readonly Dictionary<RecoveryModel, string> displayRecoveryModels = new Dictionary<RecoveryModel, string>();
private readonly Dictionary<string, CompatibilityLevel> compatLevelEnums = new Dictionary<string, CompatibilityLevel>();
private readonly Dictionary<string, ContainmentType> containmentTypeEnums = new Dictionary<string, ContainmentType>();
private readonly Dictionary<string, RecoveryModel> recoveryModelEnums = new Dictionary<string, RecoveryModel>();
private readonly HashSet<char> illegalFilenameCharacters = new HashSet<char>(new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|' });
public DatabaseHandler(ConnectionService connectionService) : base(connectionService) public DatabaseHandler(ConnectionService connectionService) : base(connectionService)
{ {
displayCompatLevels.Add(CompatibilityLevel.Version70, SR.compatibilityLevel_sphinx);
displayCompatLevels.Add(CompatibilityLevel.Version80, SR.compatibilityLevel_shiloh);
displayCompatLevels.Add(CompatibilityLevel.Version90, SR.compatibilityLevel_yukon);
displayCompatLevels.Add(CompatibilityLevel.Version100, SR.compatibilityLevel_katmai);
displayCompatLevels.Add(CompatibilityLevel.Version110, SR.compatibilityLevel_denali);
displayCompatLevels.Add(CompatibilityLevel.Version120, SR.compatibilityLevel_sql14);
displayCompatLevels.Add(CompatibilityLevel.Version130, SR.compatibilityLevel_sql15);
displayCompatLevels.Add(CompatibilityLevel.Version140, SR.compatibilityLevel_sql2017);
displayCompatLevels.Add(CompatibilityLevel.Version150, SR.compatibilityLevel_sqlv150);
displayCompatLevels.Add(CompatibilityLevel.Version160, SR.compatibilityLevel_sqlv160);
displayContainmentTypes.Add(ContainmentType.None, SR.general_containmentType_None);
displayContainmentTypes.Add(ContainmentType.Partial, SR.general_containmentType_Partial);
displayRecoveryModels.Add(RecoveryModel.Full, SR.general_recoveryModel_full);
displayRecoveryModels.Add(RecoveryModel.BulkLogged, SR.general_recoveryModel_bulkLogged);
displayRecoveryModels.Add(RecoveryModel.Simple, SR.general_recoveryModel_simple);
// Set up maps from displayName to enum type so we can retrieve the equivalent enum types later.
// We can't use a simple Enum.Parse for that since the displayNames get localized.
foreach (CompatibilityLevel key in displayCompatLevels.Keys)
{
compatLevelEnums.Add(displayCompatLevels[key], key);
}
containmentTypeEnums.Add(displayContainmentTypes[ContainmentType.None], ContainmentType.None);
containmentTypeEnums.Add(displayContainmentTypes[ContainmentType.Partial], ContainmentType.Partial);
recoveryModelEnums.Add(displayRecoveryModels[RecoveryModel.Full], RecoveryModel.Full);
recoveryModelEnums.Add(displayRecoveryModels[RecoveryModel.BulkLogged], RecoveryModel.BulkLogged);
recoveryModelEnums.Add(displayRecoveryModels[RecoveryModel.Simple], RecoveryModel.Simple);
} }
public override bool CanHandleType(SqlObjectType objectType) public override bool CanHandleType(SqlObjectType objectType)
@@ -26,17 +82,512 @@ namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
public override Task<InitializeViewResult> InitializeObjectView(InitializeViewRequestParams requestParams) public override Task<InitializeViewResult> InitializeObjectView(InitializeViewRequestParams requestParams)
{ {
throw new NotImplementedException(); // create a default data context and database object
using (var dataContainer = CreateDatabaseDataContainer(requestParams.ConnectionUri, ConfigAction.Create))
{
if (dataContainer.Server == null)
{
throw new InvalidOperationException(serverNotExistsError);
}
try
{
using (var taskHelper = new DatabaseTaskHelper(dataContainer))
using (var context = new DatabaseViewContext(requestParams))
{
var prototype = taskHelper.Prototype;
var azurePrototype = prototype as DatabasePrototypeAzure;
bool isDw = azurePrototype != null && azurePrototype.AzureEdition == AzureEdition.DataWarehouse;
var databaseViewInfo = new DatabaseViewInfo()
{
ObjectInfo = new DatabaseInfo()
};
// azure sql db doesn't have a sysadmin fixed role
var compatibilityLevelEnabled = !isDw &&
(dataContainer.LoggedInUserIsSysadmin ||
dataContainer.Server.ServerType ==
DatabaseEngineType.SqlAzureDatabase);
if (dataContainer.Server.ServerType == DatabaseEngineType.SqlAzureDatabase)
{
// Azure doesn't allow modifying the collation after DB creation
bool collationEnabled = !prototype.Exists;
if (isDw)
{
if (collationEnabled)
{
databaseViewInfo.CollationNames = GetCollationsWithPrototypeCollation(prototype);
}
databaseViewInfo.CompatibilityLevels = GetCompatibilityLevelsAzure(prototype);
}
else
{
if (collationEnabled)
{
databaseViewInfo.CollationNames = GetCollations(dataContainer.Server, prototype, dataContainer.IsNewObject);
}
if (compatibilityLevelEnabled)
{
databaseViewInfo.CompatibilityLevels = GetCompatibilityLevels(dataContainer.SqlServerVersion, prototype);
}
}
}
else
{
databaseViewInfo.CollationNames = GetCollations(dataContainer.Server, prototype, dataContainer.IsNewObject);
if (compatibilityLevelEnabled)
{
databaseViewInfo.CompatibilityLevels = GetCompatibilityLevels(dataContainer.SqlServerVersion, prototype);
}
// These aren't visible when the target DB is on Azure so only populate if it's not an Azure DB
databaseViewInfo.RecoveryModels = GetRecoveryModels(dataContainer.Server, prototype);
databaseViewInfo.ContainmentTypes = GetContainmentTypes(dataContainer.Server, prototype);
}
// Skip adding logins for the Owner field if running against an Azure SQL DB
if (dataContainer.Server.ServerType != DatabaseEngineType.SqlAzureDatabase)
{
var logins = new List<string>();
logins.Add(SR.general_default);
foreach (Login login in dataContainer.Server.Logins)
{
logins.Add(login.Name);
}
databaseViewInfo.LoginNames = logins.ToArray();
}
return Task.FromResult(new InitializeViewResult { ViewInfo = databaseViewInfo, Context = context });
}
}
finally
{
ServerConnection serverConnection = dataContainer.Server.ConnectionContext;
if (serverConnection.IsOpen)
{
serverConnection.Disconnect();
}
}
}
} }
public override Task Save(DatabaseViewContext context, DatabaseInfo obj) public override Task Save(DatabaseViewContext context, DatabaseInfo obj)
{ {
throw new NotImplementedException(); ConfigureDatabase(
context.Parameters.ConnectionUri,
obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.RunNow);
return Task.CompletedTask;
} }
public override Task<string> Script(DatabaseViewContext context, DatabaseInfo obj) public override Task<string> Script(DatabaseViewContext context, DatabaseInfo obj)
{ {
throw new NotImplementedException(); var script = ConfigureDatabase(
context.Parameters.ConnectionUri,
obj,
context.Parameters.IsNewObject ? ConfigAction.Create : ConfigAction.Update,
RunType.ScriptToWindow);
return Task.FromResult(script);
}
private CDataContainer CreateDatabaseDataContainer(string connectionUri, ConfigAction configAction, DatabaseInfo? database = null)
{
ConnectionInfo connectionInfo = this.GetConnectionInfo(connectionUri);
CDataContainer dataContainer = CDataContainer.CreateDataContainer(connectionInfo, databaseExists: configAction != ConfigAction.Create);
if (dataContainer.Server == null)
{
throw new InvalidOperationException(serverNotExistsError);
}
string objectUrn = (configAction != ConfigAction.Create && database != null)
? string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Server/Database[@Name='{0}']",
Urn.EscapeString(database.Name))
: string.Format(System.Globalization.CultureInfo.InvariantCulture,
"Server");
dataContainer.SqlDialogSubject = dataContainer.Server.GetSmoObject(objectUrn);
return dataContainer;
}
private string ConfigureDatabase(string connectionUri, DatabaseInfo database, ConfigAction configAction, RunType runType)
{
if (database.Name == null)
{
throw new ArgumentException("Database name not provided.");
}
using (var dataContainer = CreateDatabaseDataContainer(connectionUri, configAction, database))
{
if (dataContainer.Server == null)
{
throw new InvalidOperationException(serverNotExistsError);
}
try
{
using (var taskHelper = new DatabaseTaskHelper(dataContainer))
{
DatabasePrototype prototype = taskHelper.Prototype;
prototype.Name = database.Name;
// Update database file names now that we have a database name
if (!prototype.HideFileSettings)
{
var sanitizedName = SanitizeFileName(prototype.Name);
var dataFile = prototype.Files[0];
Debug.Assert(dataFile.DatabaseFileType == FileType.Data, "Expected first database file to be a data file for new database prototype.");
dataFile.Name = sanitizedName;
if (prototype.NumberOfLogFiles > 0)
{
var logFile = prototype.Files[1];
Debug.Assert(dataFile.DatabaseFileType == FileType.Log, "Expected first database file to be a log file for new database prototype");
logFile.Name = $"{sanitizedName}_log";
}
}
if (database.Owner != null && database.Owner != SR.general_default)
{
prototype.Owner = database.Owner;
}
if (database.CollationName != null && database.CollationName != SR.general_default)
{
prototype.Collation = database.CollationName;
}
if (database.RecoveryModel != null)
{
prototype.RecoveryModel = recoveryModelEnums[database.RecoveryModel];
}
if (database.CompatibilityLevel != null)
{
prototype.DatabaseCompatibilityLevel = compatLevelEnums[database.CompatibilityLevel];
}
if (prototype is DatabasePrototype110 db110 && database.ContainmentType != null)
{
db110.DatabaseContainmentType = containmentTypeEnums[database.ContainmentType];
}
string sqlScript = string.Empty;
using (var actions = new DatabaseActions(dataContainer, configAction, prototype))
using (var executionHandler = new ExecutonHandler(actions))
{
executionHandler.RunNow(runType, this);
if (executionHandler.ExecutionResult == ExecutionMode.Failure)
{
throw executionHandler.ExecutionFailureException;
}
if (runType == RunType.ScriptToWindow)
{
sqlScript = executionHandler.ScriptTextFromLastRun;
}
}
return sqlScript;
}
}
finally
{
ServerConnection serverConnection = dataContainer.Server.ConnectionContext;
if (serverConnection.IsOpen)
{
serverConnection.Disconnect();
}
}
}
}
/// <summary>
/// Removes invalid characters from a filename string, replacing each invalid character with an underscore.
/// </summary>
private string SanitizeFileName(string fileName)
{
char[] nameChars = fileName.ToCharArray();
for (int i = 0; i < nameChars.Length; i++)
{
if (illegalFilenameCharacters.Contains(nameChars[i]))
{
nameChars[i] = '_';
}
}
return new string(nameChars);
}
private bool IsManagedInstance(Server server)
{
return server?.Information?.DatabaseEngineEdition == DatabaseEngineEdition.SqlManagedInstance;
}
private bool IsArcEnabledManagedInstance(Server server)
{
return server?.Information?.DatabaseEngineEdition == DatabaseEngineEdition.SqlAzureArcManagedInstance;
}
private bool IsAnyManagedInstance(Server server)
{
return (IsManagedInstance(server) || IsArcEnabledManagedInstance(server));
}
private string[] GetCollations(Server server, DatabasePrototype prototype, bool isNewObject)
{
var collationItems = new List<string>();
bool isSphinxServer = (server.VersionMajor < minimumVersionForWritableCollation);
// if we're creating a new database or this is a Sphinx Server, add "<default>" to the dropdown
if (isNewObject || isSphinxServer)
{
collationItems.Add(SR.general_default);
}
// if the server is shiloh or later, add specific collations to the dropdown
if (!isSphinxServer)
{
DataTable serverCollationsTable = server.EnumCollations();
if (serverCollationsTable != null)
{
foreach (DataRow serverCollation in serverCollationsTable.Rows)
{
string collationName = (string)serverCollation["Name"];
collationItems.Add(collationName);
}
}
}
if (prototype.Exists)
{
System.Diagnostics.Debug.Assert(((prototype.Collation != null) && (prototype.Collation.Length != 0)),
"prototype.Collation is null");
System.Diagnostics.Debug.Assert(collationItems.Contains(prototype.Collation),
"prototype.Collation is not in the collation list");
int index = collationItems.FindIndex(collation => collation.Equals(prototype.Collation, StringComparison.InvariantCultureIgnoreCase));
if (index > 0)
{
collationItems.RemoveAt(index);
collationItems.Insert(0, prototype.Collation);
}
}
return collationItems.ToArray();
}
private string[] GetCollationsWithPrototypeCollation(DatabasePrototype prototype)
{
return new string[] { prototype.Collation };
}
private string[] GetContainmentTypes(Server server, DatabasePrototype prototype)
{
if (!(SqlMgmtUtils.IsSql11OrLater(server.ServerVersion)) || IsAnyManagedInstance(server))
{
return Array.Empty<string>();
}
var containmentTypes = new List<string>();
ContainmentType dbContainmentType = ContainmentType.None;
DatabasePrototype110? dp110 = prototype as DatabasePrototype110;
if (dp110 != null)
{
dbContainmentType = dp110.DatabaseContainmentType;
}
containmentTypes.Add(displayContainmentTypes[ContainmentType.None]);
containmentTypes.Add(displayContainmentTypes[ContainmentType.Partial]);
var swapIndex = 0;
switch (dbContainmentType)
{
case ContainmentType.None:
break;
case ContainmentType.Partial:
swapIndex = 1;
break;
default:
Debug.Fail(string.Format(CultureInfo.InvariantCulture, "Unexpected containment type '{0}'", dbContainmentType));
break;
}
if (swapIndex > 0)
{
var value = containmentTypes[swapIndex];
containmentTypes.RemoveAt(swapIndex);
containmentTypes.Insert(0, value);
}
return containmentTypes.ToArray();
}
private string[] GetRecoveryModels(Server server, DatabasePrototype prototype)
{
// if the server is shiloh or later, but not Managed Instance, enable the dropdown
var recoveryModelEnabled = (minimumVersionForRecoveryModel <= server.VersionMajor) && !IsAnyManagedInstance(server);
if (server.GetDisabledProperties().Contains("RecoveryModel") || !recoveryModelEnabled)
{
return Array.Empty<string>();
}
var recoveryModels = new List<string>();
// Note: we still discriminate on IsAnyManagedInstance(server) because GetDisabledProperties()
// was not updated to handle SQL Managed Instance.
if (!IsAnyManagedInstance(server))
{
// add recovery model options to the dropdown
recoveryModels.Add(displayRecoveryModels[RecoveryModel.Full]);
recoveryModels.Add(displayRecoveryModels[RecoveryModel.BulkLogged]);
recoveryModels.Add(displayRecoveryModels[RecoveryModel.Simple]);
}
else
{
if (prototype.OriginalName.Equals("tempdb", StringComparison.CurrentCultureIgnoreCase) && prototype.IsSystemDB)
{
// tempdb supports 'simple recovery' only
recoveryModels.Add(displayRecoveryModels[RecoveryModel.Simple]);
}
else
{
// non-tempdb supports only 'full recovery' model
recoveryModels.Add(displayRecoveryModels[RecoveryModel.Full]);
}
}
if (recoveryModelEnabled)
{
var swapIndex = 0;
switch (prototype.RecoveryModel)
{
case RecoveryModel.BulkLogged:
swapIndex = 1;
break;
case RecoveryModel.Simple:
swapIndex = 2;
break;
default:
Debug.Assert(RecoveryModel.Full == prototype.RecoveryModel, string.Format(CultureInfo.InvariantCulture, "Unknown recovery model '{0}'", prototype.RecoveryModel));
break;
}
if (swapIndex > 0)
{
var value = recoveryModels[swapIndex];
recoveryModels.RemoveAt(swapIndex);
recoveryModels.Insert(0, value);
}
}
return recoveryModels.ToArray();
}
private string[] GetCompatibilityLevelsAzure(DatabasePrototype prototype)
{
// For Azure we loop through all of the possible compatibility levels. We do this because there's only one compat level active on a
// version at a time, but that can change at any point so in order to reduce maintenance required when that happens we'll just find
// the one that matches the current set level and display that
foreach (var level in this.displayCompatLevels.Keys)
{
if (level == prototype.DatabaseCompatibilityLevel)
{
// Azure can't change the compat level so we only populate the current version
return new string[] { this.displayCompatLevels[level] };
}
}
Debug.Fail(string.Format(CultureInfo.InvariantCulture, "Unknown compatibility level '{0}'", prototype.DatabaseCompatibilityLevel));
return Array.Empty<string>();
}
private string[] GetCompatibilityLevels(int sqlServerVersion, DatabasePrototype prototype)
{
// Unlikely that we are hitting such an old SQL Server, but leaving to preserve
// the original semantic of this method.
if (sqlServerVersion < 8)
{
// we do not know this version number, we do not know the possible compatibility levels for the server
return Array.Empty<string>();
}
var compatibilityLevels = new List<string>();
switch (sqlServerVersion)
{
case 8: // Shiloh
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version70]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version80]);
break;
case 9: // Yukon
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version70]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version80]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version90]);
break;
case 10: // Katmai
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version80]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version90]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
break;
case 11: // Denali
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version90]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
break;
case 12: // SQL2014
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version120]);
break;
case 13: // SQL2016
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version120]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version130]);
break;
case 14: // SQL2017
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version120]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version130]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version140]);
break;
case 15: // SQL2019
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version120]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version130]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version140]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version150]);
break;
/* SQL_VBUMP_REVIEW */
default:
// It is either the latest SQL we know about, or some future version of SQL we
// do not know about. We play conservative and only add the compat level we know
// about so far.
// At vBump, add a new case and move the 'default' label there.
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version100]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version110]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version120]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version130]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version140]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version150]);
compatibilityLevels.Add(this.displayCompatLevels[CompatibilityLevel.Version160]);
break;
}
// set the compatability level for this combo box based on the prototype
for (var i = 0; i < compatibilityLevels.Count; i++)
{
var level = compatibilityLevels[i];
var prototypeLevel = this.displayCompatLevels[prototype.DatabaseCompatibilityLevel];
if (level == prototypeLevel)
{
if (i > 0)
{
compatibilityLevels.RemoveAt(i);
compatibilityLevels.Insert(0, level);
}
return compatibilityLevels.ToArray();
}
}
// previous loop did not find the prototype compatibility level in this server's compatability options
// disable the compatability level option
return Array.Empty<string>();
} }
} }
} }

View File

@@ -0,0 +1,18 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
#nullable disable
namespace Microsoft.SqlTools.ServiceLayer.ObjectManagement
{
public class DatabaseViewInfo : SqlObjectViewInfo
{
public string[] LoginNames { get; set; }
public string[] CollationNames { get; set; }
public string[] CompatibilityLevels { get; set; }
public string[] ContainmentTypes { get; set; }
public string[] RecoveryModels { get; set; }
}
}

View File

@@ -0,0 +1,193 @@
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
using System.Threading.Tasks;
using Microsoft.Data.SqlClient;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlTools.ServiceLayer.Connection;
using Microsoft.SqlTools.ServiceLayer.IntegrationTests.Utility;
using Microsoft.SqlTools.ServiceLayer.ObjectManagement;
using Microsoft.SqlTools.ServiceLayer.Test.Common;
using NUnit.Framework;
namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
{
/// <summary>
/// Tests for the Database management component
/// </summary>
public class DatabaseHandlerTests
{
/// <summary>
/// Test the basic Create Database method handler by creating, updating, and then deleting a database.
/// </summary>
[Test]
public async Task DatabaseCreateAndUpdateTest_OnPrem()
{
await RunDatabaseCreateAndUpdateTest(TestServerType.OnPrem);
}
/// <summary>
/// Test the Create Database method handler functionality against an Azure SQL database.
/// </summary>
[Test]
[Ignore("Test is not supported in the integration test pipeline.")]
public async Task DatabaseCreateAndUpdateTest_Azure()
{
await RunDatabaseCreateAndUpdateTest(TestServerType.Azure);
}
private async Task RunDatabaseCreateAndUpdateTest(TestServerType serverType)
{
// setup, drop database if exists.
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master", serverType: serverType);
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo))
{
var server = new Server(new ServerConnection(sqlConn));
var testDatabase = ObjectManagementTestUtils.GetTestDatabaseInfo();
var objUrn = ObjectManagementTestUtils.GetDatabaseURN(testDatabase.Name);
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn);
try
{
// create and update
var parametersForCreation = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", true, SqlObjectType.Database, "", "");
await ObjectManagementTestUtils.SaveObject(parametersForCreation, testDatabase);
Assert.True(databaseExists(testDatabase.Name!, server), $"Expected database '{testDatabase.Name}' was not created succesfully");
var parametersForUpdate = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", false, SqlObjectType.Database, "", objUrn);
await ObjectManagementTestUtils.SaveObject(parametersForUpdate, testDatabase);
// cleanup
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn, throwIfNotExist: true);
Assert.False(databaseExists(testDatabase.Name!, server), $"Database '{testDatabase.Name}' was not dropped succesfully");
}
finally
{
// Cleanup using SMO if Drop didn't work
dropDatabase(server, testDatabase.Name!);
}
}
}
/// <summary>
/// Test that the handler can export the Create Database operation to a SQL script.
/// </summary>
[Test]
public async Task DatabaseScriptTest()
{
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master");
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo))
{
var server = new Server(new ServerConnection(sqlConn));
var testDatabase = ObjectManagementTestUtils.GetTestDatabaseInfo();
var objUrn = ObjectManagementTestUtils.GetDatabaseURN(testDatabase.Name);
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn);
try
{
var parametersForCreation = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", true, SqlObjectType.Database, "", "");
var script = await ObjectManagementTestUtils.ScriptObject(parametersForCreation, testDatabase);
Assert.True(!databaseExists(testDatabase.Name!, server), $"Database should not have been created for scripting operation");
Assert.True(script.ToLowerInvariant().Contains($"create database [{testDatabase.Name!.ToLowerInvariant()}]"));
}
finally
{
// Cleanup database on the off-chance that scripting somehow created the database
dropDatabase(server, testDatabase.Name!);
}
}
}
/// <summary>
/// Test that the handler correctly throws an error when trying to drop a database that doesn't exist.
/// </summary>
[Test]
public async Task DatabaseNotExistsErrorTest()
{
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master");
var testDatabase = ObjectManagementTestUtils.GetTestDatabaseInfo();
var objUrn = ObjectManagementTestUtils.GetDatabaseURN(testDatabase.Name);
try
{
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn, throwIfNotExist: true);
Assert.Fail("Did not throw an exception when trying to drop non-existent database.");
}
catch (FailedOperationException ex)
{
Assert.NotNull(ex.InnerException, "Expected inner exception was null.");
Assert.True(ex.InnerException is MissingObjectException, $"Received unexpected inner exception type: {ex.InnerException!.GetType()}");
}
}
/// <summary>
/// Test that the handler correctly throws an error when trying to create a database with the same name as an existing database.
/// </summary>
[Test]
public async Task DatabaseAlreadyExistsErrorTest()
{
var connectionResult = await LiveConnectionHelper.InitLiveConnectionInfoAsync("master");
using (SqlConnection sqlConn = ConnectionService.OpenSqlConnection(connectionResult.ConnectionInfo))
{
var server = new Server(new ServerConnection(sqlConn));
var testDatabase = ObjectManagementTestUtils.GetTestDatabaseInfo();
var objUrn = ObjectManagementTestUtils.GetDatabaseURN(testDatabase.Name);
await ObjectManagementTestUtils.DropObject(connectionResult.ConnectionInfo.OwnerUri, objUrn);
try
{
var parametersForCreation = ObjectManagementTestUtils.GetInitializeViewRequestParams(connectionResult.ConnectionInfo.OwnerUri, "master", true, SqlObjectType.Database, "", "");
await ObjectManagementTestUtils.SaveObject(parametersForCreation, testDatabase);
Assert.True(databaseExists(testDatabase.Name!, server), $"Expected database '{testDatabase.Name}' was not created succesfully");
await ObjectManagementTestUtils.SaveObject(parametersForCreation, testDatabase);
Assert.Fail("Did not throw an exception when trying to create database with same name.");
}
catch (FailedOperationException ex)
{
Assert.NotNull(ex.InnerException, "Expected inner exception was null.");
Assert.True(ex.InnerException is ExecutionFailureException, $"Received unexpected inner exception type: {ex.InnerException!.GetType()}");
Assert.NotNull(ex.InnerException.InnerException, "Expected inner-inner exception was null.");
Assert.True(ex.InnerException.InnerException is SqlException, $"Received unexpected inner-inner exception type: {ex.InnerException.InnerException!.GetType()}");
}
finally
{
dropDatabase(server, testDatabase.Name!);
}
}
}
private bool databaseExists(string dbName, Server server)
{
server.Databases.Refresh();
bool dbFound = false;
foreach (Database db in server.Databases)
{
if (db.Name == dbName)
{
dbFound = true;
break;
}
}
return dbFound;
}
private void dropDatabase(Server server, string databaseName)
{
server.Databases.Refresh();
foreach (Database db in server.Databases)
{
if (db.Name == databaseName)
{
db.DropIfExists();
break;
}
}
}
}
}

View File

@@ -41,6 +41,11 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
return string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName); return string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName);
} }
internal static string GetDatabaseURN(string name)
{
return string.Format("Server/Database[@Name='{0}']", name);
}
internal static string GetLoginURN(string name) internal static string GetLoginURN(string name)
{ {
return string.Format("Server/Login[@Name='{0}']", name); return string.Format("Server/Login[@Name='{0}']", name);
@@ -56,6 +61,19 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
return string.Format("Server/Credential[@Name = '{0}']", name); return string.Format("Server/Credential[@Name = '{0}']", name);
} }
internal static DatabaseInfo GetTestDatabaseInfo()
{
return new DatabaseInfo()
{
Name = "TestDatabaseName_" + new Random().NextInt64(10000000, 90000000).ToString(),
Owner = "<default>",
CollationName = "SQL_Latin1_General_CP1_CI_AS",
CompatibilityLevel = "SQL Server 2022 (160)",
ContainmentType = "None",
RecoveryModel = "Full"
};
}
internal static LoginInfo GetTestLoginInfo() internal static LoginInfo GetTestLoginInfo()
{ {
return new LoginInfo() return new LoginInfo()
@@ -134,7 +152,7 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
await Service.HandleDisposeViewRequest(new DisposeViewRequestParams { ContextId = parameters.ContextId }, disposeViewRequestContext.Object); await Service.HandleDisposeViewRequest(new DisposeViewRequestParams { ContextId = parameters.ContextId }, disposeViewRequestContext.Object);
} }
internal static async Task ScriptObject(InitializeViewRequestParams parameters, SqlObject obj) internal static async Task<string> ScriptObject(InitializeViewRequestParams parameters, SqlObject obj)
{ {
// Initialize the view // Initialize the view
var initViewRequestContext = new Mock<RequestContext<SqlObjectViewInfo>>(); var initViewRequestContext = new Mock<RequestContext<SqlObjectViewInfo>>();
@@ -143,9 +161,12 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
await Service.HandleInitializeViewRequest(parameters, initViewRequestContext.Object); await Service.HandleInitializeViewRequest(parameters, initViewRequestContext.Object);
// Script the object // Script the object
string script = string.Empty;
var scriptObjectRequestContext = new Mock<RequestContext<string>>(); var scriptObjectRequestContext = new Mock<RequestContext<string>>();
scriptObjectRequestContext.Setup(x => x.SendResult(It.IsAny<string>())) scriptObjectRequestContext
.Returns(Task.FromResult<string>("")); .Setup(x => x.SendResult(It.IsAny<string>()))
.Returns(Task.FromResult<string>(""))
.Callback<string>(scriptResult => script = scriptResult);
await Service.HandleScriptObjectRequest(new ScriptObjectRequestParams { ContextId = parameters.ContextId, Object = JToken.FromObject(obj) }, scriptObjectRequestContext.Object); await Service.HandleScriptObjectRequest(new ScriptObjectRequestParams { ContextId = parameters.ContextId, Object = JToken.FromObject(obj) }, scriptObjectRequestContext.Object);
// Dispose the view // Dispose the view
@@ -153,14 +174,17 @@ namespace Microsoft.SqlTools.ServiceLayer.IntegrationTests.ObjectManagement
disposeViewRequestContext.Setup(x => x.SendResult(It.IsAny<DisposeViewRequestResponse>())) disposeViewRequestContext.Setup(x => x.SendResult(It.IsAny<DisposeViewRequestResponse>()))
.Returns(Task.FromResult<DisposeViewRequestResponse>(new DisposeViewRequestResponse())); .Returns(Task.FromResult<DisposeViewRequestResponse>(new DisposeViewRequestResponse()));
await Service.HandleDisposeViewRequest(new DisposeViewRequestParams { ContextId = parameters.ContextId }, disposeViewRequestContext.Object); await Service.HandleDisposeViewRequest(new DisposeViewRequestParams { ContextId = parameters.ContextId }, disposeViewRequestContext.Object);
return script;
} }
internal static async Task DropObject(string connectionUri, string objectUrn) internal static async Task DropObject(string connectionUri, string objectUrn, bool throwIfNotExist = false)
{ {
var dropParams = new DropRequestParams var dropParams = new DropRequestParams
{ {
ConnectionUri = connectionUri, ConnectionUri = connectionUri,
ObjectUrn = objectUrn ObjectUrn = objectUrn,
ThrowIfNotExist = throwIfNotExist
}; };
var dropRequestContext = new Mock<RequestContext<DropRequestResponse>>(); var dropRequestContext = new Mock<RequestContext<DropRequestResponse>>();