Skip to content

Commit 5ef5abf

Browse files
Merge pull request #65 from webmd-health-services/develop
0.18.0
2 parents 83e8a5c + 0d89589 commit 5ef5abf

17 files changed

+581
-177
lines changed

CHANGELOG.md

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
1+
<!--markdownlint-disable MD012 no-multiple-blanks -->
2+
<!--markdownlint-disable MD024 no-duplicate-heading/no-duplicate-header -->
3+
4+
# 0.18.0
5+
6+
* Fixed: Rivet doesn't use the CommandTimeout property in rivet.json configuration file.
7+
* `Export-Migration` will now allow references to objects in databases that have been applied before it.
8+
* The `DatabaseOrder` setting in the rivet.json file has been removed in favor of a new `Databases` property that should
9+
be the ordered-list of databases to migrate.
10+
* `Export-Migration` will now include extended properties on schemas, views, and view columns.
11+
112

213
# 0.17.0
314

4-
## Changes
15+
## Changes
516

617
* When initializing a database, Rivet now runs the migrations found in the schema.ps1 file, which contains the baseline
718
database schema upon which all migrations should be applied. You can use the `Checkpoint-Migration` function to create
@@ -12,10 +23,10 @@ a baseline `schema.ps1` file for your database(s).
1223

1324
* Updated `Checkpoint-Migration` function:
1425

15-
* The `schema.ps1` file generated from `Checkpoint-Migration` is saved to the Migrations directory of each database
16-
that is being checkpointed.
17-
* Only migrations that have been applied to the database will be exported to the `schema.ps1` file.
18-
* Migrations that have been checkpointed will be removed from the Migrations directory.
26+
* The `schema.ps1` file generated from `Checkpoint-Migration` is saved to the Migrations directory of each database
27+
that is being checkpointed.
28+
* Only migrations that have been applied to the database will be exported to the `schema.ps1` file.
29+
* Migrations that have been checkpointed will be removed from the Migrations directory.
1930

2031

2132
# 0.15.0
@@ -114,7 +125,7 @@ order. See `help about_Rivet_Configuration` for more information.
114125
## Enhancements
115126

116127
* Created `Merge-Migration` function for creating cumulative, roll up migrations.
117-
128+
118129

119130
# 0.7.0
120131

@@ -151,7 +162,7 @@ for half a second.
151162
* Obsoleted the parameter sets of the `Remove-CheckConstraint`, `Remove-DefaulConstraint`, `Remove-ForeignKey`,
152163
`Remove-Index`, `Remove-PrimaryKey`, and `Remove-UniqueKey` operations that use an inferred constraint/index name.
153164
These operations now expect the name of the constraint/index to drop with the `Name` parameter.
154-
* Improved object model so that customizing index/constraint names is easier.
165+
* Improved object model so that customizing index/constraint names is easier.
155166
* Added `about_Rivet_Cookbook` help topic to showing how to customize index/constraint names.
156167
* Updated and improved the `about_Rivet_Plugins` help topic.
157168
* Obsoleted the `Enable-ForeignKey` and `Disable-ForeignKey` operations. Use the `Enable-Constraint` and
@@ -167,8 +178,8 @@ multiple names, IDs, or file names).
167178

168179
* Results from `Invoke-SqlScript` operations cause silent error when formatted as a table.
169180
* Path to rivet.json file not showing in an error message when using implicit path.
170-
171-
181+
182+
172183
# 0.5.1
173184

174185
## Enhancements
@@ -181,8 +192,8 @@ all operations.
181192
## Bug Fixes
182193

183194
* Get-Migration fails when run from Convert-Migration: it doesn't know the path to use to load migrations from.
184-
185-
195+
196+
186197
# 0.5.0
187198

188199
## Enhancements
@@ -203,7 +214,7 @@ output replaces the old Write-Host output).
203214
* NOCHECK parameter has been added to `Add-ForeignKey` and `Add-CheckConstraint` operations
204215
* `Disable-CheckConstraint` and `Enable-CheckConstraint` functions have been added.
205216
* `Disable-ForeignKey` and `Enable-ForeignKey` functions have been added.
206-
217+
207218
## Bug Fixes
208219

209220
* Convert-Migration.ps1 generates incorrect SQL if a migration removes then re-adds a column.
@@ -229,7 +240,7 @@ output replaces the old Write-Host output).
229240
* `Get-RivetConfig` is now a publicly exposed function. Use this method to parse a Rivet JSON configuration file.
230241
It returns a `Rivet.Configuration.Configuration` object.
231242

232-
243+
233244
# 0.3.0
234245

235246
## Enhancements
@@ -263,4 +274,4 @@ option. See `about_Rivet_Configuration` for more information.
263274
* Rivet now updates its internal objects using migrations (i.e. it is now self-migrating). It uses (and reserves)
264275
migration IDs below 01000000000000. If you have migrations with these IDs, you'll need to give them new IDs and update
265276
IDs in any rivet.Migrations table that uses that ID.
266-
* Migration name maximum length increased to 241 characters (the theoretical maximum allowed by Windows).
277+
* Migration name maximum length increased to 241 characters (the theoretical maximum allowed by Windows).

Rivet/Functions/Checkpoint-Migration.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function Checkpoint-Migration
6666
}
6767

6868
Write-Debug "Checkpoint-Migration: Exporting migration on database $($databaseItem.Name)"
69-
$migration = Export-Migration -SqlServerName $settings.SqlServerName -Database $databaseItem.Name
69+
$migration = Export-Migration -SqlServerName $settings.SqlServerName -Database $databaseItem.Name -ConfigFilePath $ConfigFilePath
7070
$migration = $migration -join [Environment]::NewLine
7171
Set-Content -Path $OutputPath -Value $migration
7272

Rivet/Functions/Convert-FileInfoToMigration.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ function Convert-FileInfoToMigration
5858
continue
5959
}
6060

61+
# Set CommandTimeout on operation to value from Rivet configuration.
62+
$operationItem.CommandTimeout = $Configuration.CommandTimeout
63+
6164
$pluginParameter = @{ Migration = $m ; Operation = $_ }
6265

6366
[Rivet.Operations.Operation[]]$operations = & {

Rivet/Functions/Export-Migration.ps1

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,47 @@ function Export-Migration
88
.DESCRIPTION
99
The `Export-Migration` function exports database objects, schemas, and data types as a Rivet migration. By default, it exports *all* non-system, non-Rivet objects, data types, and schemas. You can filter specific objects by passing their full name to the `Include` parameter. Wildcards are supported. Objects are matched on their schema *and* name.
1010
11-
Extended properties are *not* exported, except table and column descriptions.
12-
1311
.EXAMPLE
1412
Export-Migration -SqlServerName 'some\instance' -Database 'database'
1513
1614
Demonstrates how to export an entire database.
1715
#>
1816
[CmdletBinding()]
1917
param(
20-
[Parameter(Mandatory)]
21-
[string]
2218
# The connection string for the database to connect to.
23-
$SqlServerName,
24-
2519
[Parameter(Mandatory)]
26-
[string]
27-
# The database to connect to.
28-
$Database,
20+
[String] $SqlServerName,
2921

30-
[string[]]
22+
# The database to connect to.
23+
[Parameter(Mandatory)]
24+
[String] $Database,
25+
3126
# The names of the objects to export. Must include the schema if exporting a specific object. Wildcards supported.
3227
#
3328
# The default behavior is to export all non-system objects.
34-
$Include,
29+
[String[]] $Include,
30+
31+
# The name of the environment whose settings to return. If not provided, uses the default settings.
32+
[String] $Environment,
3533

36-
[string[]]
3734
# The names of any objects *not* to export. Matches the object name *and* its schema name, i.e. `schema.name`. Wildcards supported.
38-
$Exclude,
35+
[String[]] $Exclude,
3936

40-
[string[]]
41-
[ValidateSet('CheckConstraint','DataType','DefaultConstraint','ForeignKey','Function','Index','PrimaryKey','Schema','StoredProcedure','Synonym','Table','Trigger','UniqueKey','View','XmlSchema')]
4237
# Any object types to exclude.
43-
$ExcludeType,
38+
[ValidateSet('CheckConstraint','DataType','DefaultConstraint','ForeignKey','Function','Index','PrimaryKey','Schema','StoredProcedure','Synonym','Table','Trigger','UniqueKey','View','XmlSchema')]
39+
[String[]] $ExcludeType,
4440

45-
[Switch]
46-
$NoProgress
41+
# The path to the Rivet configuration file to load. Defaults to `rivet.json` in the current directory.
42+
[String] $ConfigFilePath,
43+
44+
[Switch] $NoProgress
4745
)
4846

4947
Set-StrictMode -Version 'Latest'
5048
Use-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState
5149

50+
[Rivet.Configuration.Configuration]$settings = Get-RivetConfig -Path $ConfigFilePath -Environment $Environment
51+
5252
$pops = New-Object 'Collections.Generic.Stack[string]'
5353
$popsHash = @{}
5454
$exportedObjects = @{ }
@@ -971,9 +971,17 @@ where
971971

972972
if( $externalDependencies.ContainsKey($object.object_id) )
973973
{
974-
Write-Warning -Message ('Unable to export {0} {1}: it depends on external object {2}.' -f $object.type_desc,$object.full_name,$externalDependencies[$object.object_id])
975-
$exportedObjects[$object.object_id] = $true
976-
continue
974+
$indexOfReferencedDatabase = [array]::IndexOf($settings.Databases.Name, $externalDependencies[$object.object_id].DatabaseName)
975+
$indexOfCurrentDatabase = [array]::IndexOf($settings.Databases.Name, $Database)
976+
977+
# If the external depenedency's database does not get applied BEFORE the current database, do not allow
978+
# references to the external dependency.
979+
if( ($indexOfReferencedDatabase -gt $indexOfCurrentDatabase) -or ($indexOfReferencedDatabase -lt 0) -or ($indexOfCurrentDatabase -lt 0) )
980+
{
981+
Write-Warning -Message ('Unable to export {0} {1}: it depends on external object {2}.' -f $object.type_desc,$object.full_name,$externalDependencies[$object.object_id].ExternalName)
982+
$exportedObjects[$object.object_id] = $true
983+
continue
984+
}
977985
}
978986

979987
switch ($object.type_desc)
@@ -1163,12 +1171,18 @@ where
11631171
-- SCHEMAS
11641172
select
11651173
sys.schemas.name,
1166-
sys.sysusers.name as owner
1174+
sys.sysusers.name as owner,
1175+
sys.extended_properties.value as description
11671176
from
11681177
sys.schemas
11691178
join
11701179
sys.sysusers
1171-
on sys.schemas.principal_id = sys.sysusers.uid'
1180+
on sys.schemas.principal_id = sys.sysusers.uid
1181+
left join
1182+
sys.extended_properties
1183+
on sys.extended_properties.class = 3
1184+
and sys.extended_properties.major_id = sys.schemas.schema_id
1185+
and sys.extended_properties.name = ''MS_Description'''
11721186
function Export-Schema
11731187
{
11741188
param(
@@ -1187,9 +1201,14 @@ from
11871201
{
11881202
return
11891203
}
1204+
$description = $schema.description
1205+
if( $description )
1206+
{
1207+
$description = ' -Description ''{0}''' -f ($description -replace '''','''''')
1208+
}
11901209

11911210
Write-ExportingMessage -Schema $Object.schema_name -Type Schema
1192-
' Add-Schema -Name ''{0}'' -Owner ''{1}''' -f $schema.name,$schema.owner
1211+
' Add-Schema -Name ''{0}'' -Owner ''{1}''{2}' -f $schema.name,$schema.owner, $description
11931212
$exportedSchemas[$schema.name] = $true
11941213
Push-PopOperation ('Remove-Schema -Name ''{0}''' -f $schema.name)
11951214
}
@@ -1534,8 +1553,22 @@ where
15341553
Write-ExportingMessage -Schema $Object.schema_name -Name $Object.name -Type View
15351554
if( $view -match $createPreambleRegex )
15361555
{
1556+
$description = $Object.description
1557+
if( $description )
1558+
{
1559+
$description = ' -Description ''{0}''' -f ($description -replace '''','''''')
1560+
}
1561+
15371562
$view = $view -replace $createPreambleRegex,''
1538-
' Add-View{0} -Name ''{1}'' -Definition @''{2}{3}{2}''@' -f $schema,$Object.name,[Environment]::NewLine,$view
1563+
' Add-View{0} -Name ''{1}''{2} -Definition @''{3}{4}{3}''@' -f $schema,$Object.name,$description,[Environment]::NewLine,$view
1564+
1565+
# Get view's columns that have extended properties
1566+
$viewColumns = Invoke-Query -Query $columnsQuery | Where-Object { $_.object_id -eq $Object.object_id -and $_.description }
1567+
foreach( $column in $viewColumns )
1568+
{
1569+
$colDescription = ' -Description ''{0}''' -f ($column.description -replace '''','''''')
1570+
' Add-ExtendedProperty -SchemaName ''{0}'' -ViewName ''{1}'' -ColumnName ''{2}'' -Value {3}' -f $Object.schema_name,$Object.object_name,$column.column_name,$colDescription
1571+
}
15391572
}
15401573
else
15411574
{
@@ -1796,7 +1829,7 @@ where
17961829
if( $objectTypes -contains 'SQL_TRIGGER' )
17971830
{
17981831
$triggers = Invoke-Query -Query $triggersQuery
1799-
$triggers | ForEach-Object { $triggersByID[$_.object_id] = $_ }
1832+
$triggers | ForEach-Object { $triggersByID[$_.object_id] = $_ }
18001833
$triggers | Group-Object -Property 'parent_id' | ForEach-Object { $triggersByTable[[int]$_.Name] = $_.Group }
18011834
}
18021835

@@ -1806,7 +1839,7 @@ where
18061839
$uniqueKeys = Invoke-Query -Query $uniqueKeysQuery
18071840
$uniqueKeys | ForEach-Object { $uniqueKeysByID[$_.object_id] = $_ }
18081841
$uniqueKeys | Group-Object -Property 'parent_object_id' | ForEach-Object { $uniqueKeysByTable[[int]$_.Name] = $_.Group }
1809-
1842+
18101843
# UNIQUE KEY COLUMNS
18111844
$uniqueKeyColumns = Invoke-Query -Query $uniqueKeysColumnsQuery
18121845
$uniqueKeyColumns | Group-Object -Property 'object_id' | ForEach-Object { $uniqueKeyColumnsByObjectID[[int]$_.Name] = $_.Group }
@@ -1862,7 +1895,7 @@ where
18621895

18631896
if( $row.referenced_server_name -or ($row.referenced_database_name -ne $null -and $row.referenced_database_name -ne $Database) )
18641897
{
1865-
$externalDependencies[$row.referencing_id] = $externalName
1898+
$externalDependencies[$row.referencing_id] = @{ ExternalName = $externalName; DatabaseName = $row.referenced_database_name }
18661899
}
18671900
else
18681901
{
@@ -1882,21 +1915,21 @@ where
18821915
$schemas
18831916
$indexes
18841917
$dataTypes
1885-
} |
1886-
Measure-Object |
1918+
} |
1919+
Measure-Object |
18871920
Select-Object -ExpandProperty 'Count'
18881921

18891922
if( $writeProgress )
18901923
{
1891-
Write-Progress -Activity $activity
1924+
Write-Progress -Activity $activity
18921925
}
18931926

1894-
$timer |
1927+
$timer |
18951928
Add-Member -Name 'ExportCount' -Value 0 -MemberType NoteProperty -PassThru |
18961929
Add-Member -MemberType NoteProperty -Name 'Activity' -Value $activity -PassThru |
18971930
Add-Member -MemberType NoteProperty -Name 'CurrentOperation' -Value '' -PassThru |
18981931
Add-Member -MemberType NoteProperty -Name 'TotalCount' -Value $totalOperationCount
1899-
1932+
19001933
if( $writeProgress )
19011934
{
19021935
# Write-Progress is *expensive*. Only do it if the user is interactive and only every 1/10th of a second.

Rivet/Functions/Get-RivetConfig.ps1

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ function Get-RivetConfig
270270
$targetDatabases = @{ }
271271
}
272272

273-
$order = Get-ConfigProperty -Name 'DatabaseOrder' -AsArray
273+
$order = Get-ConfigProperty -Name 'Databases' -AsArray
274274
$pluginModules = Get-ConfigProperty -Name 'PluginModules' -AsArray
275275

276276
[Rivet.Configuration.Configuration]$configuration =
@@ -285,22 +285,30 @@ function Get-RivetConfig
285285
# Get user-specified databases first
286286
if( $Database )
287287
{
288-
$Database |
288+
return $Database |
289289
Add-Member -MemberType ScriptProperty -Name Name -Value { $this } -PassThru |
290290
Add-Member -MemberType ScriptProperty -Name FullName -Value { Join-Path -Path $configuration.DatabasesRoot -ChildPath $this.Name } -PassThru
291291
}
292-
else
293-
{
294-
# Then get all of them in the order requested
295-
if( $order )
292+
293+
# Default alphabetical order
294+
if (-not $order)
295+
{
296+
return Get-ChildItem -Path $configuration.DatabasesRoot -Directory
297+
}
298+
299+
# User specified order
300+
foreach( $dbName in $order )
301+
{
302+
$dbPath = Join-Path -Path $configuration.DatabasesRoot -ChildPath $dbName
303+
if (-not (Test-Path -Path $dbPath -PathType Container))
296304
{
297-
foreach( $dbName in $order )
305+
if (-not [wildcardpattern]::ContainsWildcardCharacters($dbName))
298306
{
299-
Get-ChildItem -Path $configuration.DatabasesRoot -Filter $dbName -Directory
307+
Write-ValidationError "database named ""$($dbName)"" at ""$($dbPath)"" does not exist"
300308
}
309+
continue
301310
}
302-
303-
Get-ChildItem -Path $configuration.DatabasesRoot -Exclude $order -Directory
311+
Get-Item -Path $dbPath
304312
}
305313
} |
306314
Select-Object -Property Name,FullName -Unique |

0 commit comments

Comments
 (0)