Skip to content

Commit 6c4fbd1

Browse files
authored
New-SqlDscDatabase: Add IsLedger parameter (#2350)
1 parent 8ababf9 commit 6c4fbd1

File tree

6 files changed

+84
-10
lines changed

6 files changed

+84
-10
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
command with the `-DatabaseSnapshotBaseName` parameter.
2323
- Removed parameter `DefaultSchema`. Default schema is a user-level property,
2424
not a database-level property. See [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
25+
- Removed parameter `IsLedger`. Ledger status is read-only after database creation.
26+
Use `New-SqlDscDatabase` with the `-IsLedger` parameter to create ledger databases
27+
[issue #2351](https://github.com/dsccommunity/SqlServerDsc/issues/2351).
2528

2629
### Added
2730

@@ -58,6 +61,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5861
database snapshots, enabling control over file placement for snapshots (sparse
5962
files) and custom filegroup/datafile configuration for regular databases
6063
([issue #2341](https://github.com/dsccommunity/SqlServerDsc/issues/2341)).
64+
- Added `IsLedger` parameter to support creating ledger databases at creation time.
65+
Ledger status is read-only after database creation and can only be set when
66+
creating a new database ([issue #2351](https://github.com/dsccommunity/SqlServerDsc/issues/2351)).
6167
- Added public command `Set-SqlDscDatabaseOwner` to change the owner of a SQL Server
6268
database [issue #2177](https://github.com/dsccommunity/SqlServerDsc/issues/2177).
6369
This command uses the SMO `SetOwner()` method and supports both `ServerObject`

source/Public/New-SqlDscDatabase.ps1

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@
3333
.PARAMETER OwnerName
3434
Specifies the name of the login that should be the owner of the database.
3535
36+
.PARAMETER IsLedger
37+
Specifies whether to create a ledger database. Ledger databases provide
38+
tamper-evidence capabilities and are immutable once created. This parameter
39+
can only be set during database creation - ledger status cannot be changed
40+
after the database is created. This parameter requires SQL Server 2022
41+
(version 16) or later, or Azure SQL Database.
42+
3643
.PARAMETER DatabaseSnapshotBaseName
3744
Specifies the name of the source database from which to create a snapshot.
3845
When this parameter is specified, a database snapshot will be created instead
@@ -138,6 +145,10 @@ function New-SqlDscDatabase
138145
[System.String]
139146
$OwnerName,
140147

148+
[Parameter(ParameterSetName = 'Database')]
149+
[System.Boolean]
150+
$IsLedger,
151+
141152
[Parameter(Mandatory = $true, ParameterSetName = 'Snapshot')]
142153
[ValidateNotNullOrEmpty()]
143154
[System.String]
@@ -255,6 +266,24 @@ function New-SqlDscDatabase
255266
}
256267
}
257268

269+
# Validate IsLedger if specified (requires SQL Server 2022+)
270+
if ($PSBoundParameters.ContainsKey('IsLedger'))
271+
{
272+
if ($ServerObject.VersionMajor -lt 16)
273+
{
274+
$errorMessage = $script:localizedData.Database_IsLedgerNotSupported -f $ServerObject.InstanceName, $ServerObject.VersionMajor
275+
276+
$PSCmdlet.ThrowTerminatingError(
277+
[System.Management.Automation.ErrorRecord]::new(
278+
[System.InvalidOperationException]::new($errorMessage),
279+
'NSD0007', # cspell: disable-line
280+
[System.Management.Automation.ErrorCategory]::InvalidOperation,
281+
$IsLedger
282+
)
283+
)
284+
}
285+
}
286+
258287
# Validate source database exists when creating a snapshot
259288
if ($PSCmdlet.ParameterSetName -eq 'Snapshot')
260289
{
@@ -312,6 +341,11 @@ function New-SqlDscDatabase
312341
{
313342
$sqlDatabaseObjectToCreate.CompatibilityLevel = $CompatibilityLevel
314343
}
344+
345+
if ($PSBoundParameters.ContainsKey('IsLedger'))
346+
{
347+
$sqlDatabaseObjectToCreate.IsLedger = $IsLedger
348+
}
315349
}
316350

317351
# Add FileGroups if provided (applies to both regular databases and snapshots)

source/Public/Set-SqlDscDatabaseProperty.ps1

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,6 @@
135135
.PARAMETER IsFullTextEnabled
136136
Specifies whether full-text search is enabled.
137137
138-
.PARAMETER IsLedger
139-
Specifies whether the database is a ledger database.
140-
141138
.PARAMETER IsParameterizationForced
142139
Specifies whether forced parameterization is enabled for the database.
143140
@@ -312,6 +309,11 @@
312309
class. To create database snapshots, use the `New-SqlDscDatabaseSnapshot` or
313310
`New-SqlDscDatabase` command with the `-DatabaseSnapshotBaseName` parameter.
314311
312+
- **IsLedger**: Specifies whether the database is a ledger database. Ledger
313+
status can only be set during database creation using the `New-SqlDscDatabase`
314+
command with the `-IsLedger` parameter. Once a database is created, its ledger
315+
status cannot be changed.
316+
315317
There are some database properties that require method calls instead of direct
316318
property assignment and will be supported through separate commands, e.g.
317319
`Set-SqlDscDatabaseDefaultFileGroup`.
@@ -439,10 +441,6 @@ function Set-SqlDscDatabaseProperty
439441
[System.Boolean]
440442
$IsFullTextEnabled,
441443

442-
[Parameter()]
443-
[System.Boolean]
444-
$IsLedger,
445-
446444
[Parameter()]
447445
[System.Boolean]
448446
$IsParameterizationForced,

source/en-US/SqlServerDsc.strings.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ ConvertFrom-StringData @'
358358
Database_InvalidCompatibilityLevel = The specified compatibility level '{0}' is not a valid compatibility level for the instance '{1}'.
359359
Database_InvalidCollation = The specified collation '{0}' is not a valid collation for the instance '{1}'.
360360
Database_CatalogCollationNotSupported = The parameter CatalogCollation is not supported on SQL Server instance '{0}' with version '{1}'. This parameter requires SQL Server 2019 (version 15) or later.
361+
Database_IsLedgerNotSupported = The parameter IsLedger is not supported on SQL Server instance '{0}' with version '{1}'. This parameter requires SQL Server 2022 (version 16) or later.
361362
Database_SnapshotSourceDatabaseNotFound = The source database '{0}' for the database snapshot does not exist on instance '{1}'.
362363
Database_CreatingSnapshot = Creating database snapshot '{0}' from source database '{1}'.
363364
Database_Create_ShouldProcessVerboseDescription = Creating the database '{0}' on the instance '{1}'.

tests/Unit/Public/New-SqlDscDatabase.Tests.ps1

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
7373
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'RecoveryModel' -Value $null -Force
7474
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'Collation' -Value $null -Force
7575
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'CompatibilityLevel' -Value $null -Force
76+
$mockDatabaseObject | Add-Member -MemberType 'NoteProperty' -Name 'IsLedger' -Value $false -Force
7677
$mockDatabaseObject | Add-Member -MemberType 'ScriptMethod' -Name 'Create' -Value {
7778
# Mock implementation
7879
} -Force
@@ -102,6 +103,24 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
102103
$result.CompatibilityLevel | Should -Be 'Version150'
103104
}
104105

106+
It 'Should create a ledger database with IsLedger set to true' {
107+
# Create a mock server for SQL Server 2022 (version 16) which supports IsLedger
108+
$mockServerObject2022 = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'
109+
$mockServerObject2022 | Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value 'TestInstance2022' -Force
110+
$mockServerObject2022 | Add-Member -MemberType 'NoteProperty' -Name 'VersionMajor' -Value 16 -Force
111+
$mockServerObject2022 | Add-Member -MemberType 'ScriptProperty' -Name 'Databases' -Value {
112+
return @{} | Add-Member -MemberType 'ScriptMethod' -Name 'Refresh' -Value {
113+
# Mock implementation
114+
} -PassThru -Force
115+
} -Force
116+
117+
$result = New-SqlDscDatabase -ServerObject $mockServerObject2022 -Name 'LedgerDatabase' -IsLedger $true -Force
118+
119+
$result | Should -Not -BeNullOrEmpty
120+
$result.Name | Should -Be 'LedgerDatabase'
121+
$result.IsLedger | Should -BeTrue
122+
}
123+
105124
It 'Should throw error when database already exists' {
106125
$mockServerObjectWithExistingDb = New-Object -TypeName 'Microsoft.SqlServer.Management.Smo.Server'
107126
$mockServerObjectWithExistingDb | Add-Member -MemberType 'NoteProperty' -Name 'InstanceName' -Value 'TestInstance' -Force
@@ -151,13 +170,23 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
151170
$errorRecord.CategoryInfo.Category | Should -Be 'InvalidArgument'
152171
$errorRecord.CategoryInfo.TargetName | Should -Be 'InvalidCollation'
153172
}
173+
174+
It 'Should throw error when IsLedger is used on SQL Server version older than 2022' {
175+
$errorRecord = { New-SqlDscDatabase -ServerObject $mockServerObject -Name 'TestDB' -IsLedger $true -Force } |
176+
Should -Throw -ExpectedMessage '*IsLedger is not supported*' -PassThru
177+
178+
$errorRecord.Exception.Message | Should -BeLike '*IsLedger is not supported*'
179+
$errorRecord.FullyQualifiedErrorId | Should -Be 'NSD0007,New-SqlDscDatabase'
180+
$errorRecord.CategoryInfo.Category | Should -Be 'InvalidOperation'
181+
$errorRecord.CategoryInfo.TargetName | Should -Be 'True'
182+
}
154183
}
155184

156185
Context 'Parameter validation' {
157186
It 'Should have the correct parameters in parameter set Database' -ForEach @(
158187
@{
159188
ExpectedParameterSetName = 'Database'
160-
ExpectedParameters = '-ServerObject <Server> -Name <string> [-Collation <string>] [-CatalogCollation <CatalogCollationType>] [-CompatibilityLevel <string>] [-RecoveryModel <string>] [-OwnerName <string>] [-FileGroup <DatabaseFileGroupSpec[]>] [-Force] [-Refresh] [-WhatIf] [-Confirm] [<CommonParameters>]'
189+
ExpectedParameters = '-ServerObject <Server> -Name <string> [-Collation <string>] [-CatalogCollation <CatalogCollationType>] [-CompatibilityLevel <string>] [-RecoveryModel <string>] [-OwnerName <string>] [-IsLedger <bool>] [-FileGroup <DatabaseFileGroupSpec[]>] [-Force] [-Refresh] [-WhatIf] [-Confirm] [<CommonParameters>]'
161190
}
162191
) {
163192
$result = (Get-Command -Name 'New-SqlDscDatabase').ParameterSets |
@@ -203,6 +232,12 @@ Describe 'New-SqlDscDatabase' -Tag 'Public' {
203232
$snapshotSetAttribute = $parameterInfo.Attributes | Where-Object { $_.ParameterSetName -eq 'Snapshot' }
204233
$snapshotSetAttribute.Mandatory | Should -BeTrue
205234
}
235+
236+
It 'Should have IsLedger as a parameter in Database parameter set' {
237+
$parameterInfo = (Get-Command -Name 'New-SqlDscDatabase').Parameters['IsLedger']
238+
$databaseSetAttribute = $parameterInfo.Attributes | Where-Object { $_.ParameterSetName -eq 'Database' }
239+
$databaseSetAttribute | Should -Not -BeNullOrEmpty
240+
}
206241
}
207242

208243
Context 'When creating a database snapshot' {

0 commit comments

Comments
 (0)