Skip to content

Commit

Permalink
Merge pull request #65 from webmd-health-services/develop
Browse files Browse the repository at this point in the history
0.18.0
  • Loading branch information
splatteredbits authored Feb 18, 2023
2 parents 83e8a5c + 0d89589 commit 5ef5abf
Show file tree
Hide file tree
Showing 17 changed files with 581 additions and 177 deletions.
39 changes: 25 additions & 14 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
<!--markdownlint-disable MD012 no-multiple-blanks -->
<!--markdownlint-disable MD024 no-duplicate-heading/no-duplicate-header -->

# 0.18.0

* Fixed: Rivet doesn't use the CommandTimeout property in rivet.json configuration file.
* `Export-Migration` will now allow references to objects in databases that have been applied before it.
* The `DatabaseOrder` setting in the rivet.json file has been removed in favor of a new `Databases` property that should
be the ordered-list of databases to migrate.
* `Export-Migration` will now include extended properties on schemas, views, and view columns.


# 0.17.0

## Changes
## Changes

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

* Updated `Checkpoint-Migration` function:

* The `schema.ps1` file generated from `Checkpoint-Migration` is saved to the Migrations directory of each database
that is being checkpointed.
* Only migrations that have been applied to the database will be exported to the `schema.ps1` file.
* Migrations that have been checkpointed will be removed from the Migrations directory.
* The `schema.ps1` file generated from `Checkpoint-Migration` is saved to the Migrations directory of each database
that is being checkpointed.
* Only migrations that have been applied to the database will be exported to the `schema.ps1` file.
* Migrations that have been checkpointed will be removed from the Migrations directory.


# 0.15.0
Expand Down Expand Up @@ -114,7 +125,7 @@ order. See `help about_Rivet_Configuration` for more information.
## Enhancements

* Created `Merge-Migration` function for creating cumulative, roll up migrations.


# 0.7.0

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

* Results from `Invoke-SqlScript` operations cause silent error when formatted as a table.
* Path to rivet.json file not showing in an error message when using implicit path.


# 0.5.1

## Enhancements
Expand All @@ -181,8 +192,8 @@ all operations.
## Bug Fixes

* Get-Migration fails when run from Convert-Migration: it doesn't know the path to use to load migrations from.


# 0.5.0

## Enhancements
Expand All @@ -203,7 +214,7 @@ output replaces the old Write-Host output).
* NOCHECK parameter has been added to `Add-ForeignKey` and `Add-CheckConstraint` operations
* `Disable-CheckConstraint` and `Enable-CheckConstraint` functions have been added.
* `Disable-ForeignKey` and `Enable-ForeignKey` functions have been added.

## Bug Fixes

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


# 0.3.0

## Enhancements
Expand Down Expand Up @@ -263,4 +274,4 @@ option. See `about_Rivet_Configuration` for more information.
* Rivet now updates its internal objects using migrations (i.e. it is now self-migrating). It uses (and reserves)
migration IDs below 01000000000000. If you have migrations with these IDs, you'll need to give them new IDs and update
IDs in any rivet.Migrations table that uses that ID.
* Migration name maximum length increased to 241 characters (the theoretical maximum allowed by Windows).
* Migration name maximum length increased to 241 characters (the theoretical maximum allowed by Windows).
2 changes: 1 addition & 1 deletion Rivet/Functions/Checkpoint-Migration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function Checkpoint-Migration
}

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

Expand Down
3 changes: 3 additions & 0 deletions Rivet/Functions/Convert-FileInfoToMigration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ function Convert-FileInfoToMigration
continue
}

# Set CommandTimeout on operation to value from Rivet configuration.
$operationItem.CommandTimeout = $Configuration.CommandTimeout

$pluginParameter = @{ Migration = $m ; Operation = $_ }

[Rivet.Operations.Operation[]]$operations = & {
Expand Down
99 changes: 66 additions & 33 deletions Rivet/Functions/Export-Migration.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,47 @@ function Export-Migration
.DESCRIPTION
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.
Extended properties are *not* exported, except table and column descriptions.
.EXAMPLE
Export-Migration -SqlServerName 'some\instance' -Database 'database'
Demonstrates how to export an entire database.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]
# The connection string for the database to connect to.
$SqlServerName,

[Parameter(Mandatory)]
[string]
# The database to connect to.
$Database,
[String] $SqlServerName,

[string[]]
# The database to connect to.
[Parameter(Mandatory)]
[String] $Database,

# The names of the objects to export. Must include the schema if exporting a specific object. Wildcards supported.
#
# The default behavior is to export all non-system objects.
$Include,
[String[]] $Include,

# The name of the environment whose settings to return. If not provided, uses the default settings.
[String] $Environment,

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

[string[]]
[ValidateSet('CheckConstraint','DataType','DefaultConstraint','ForeignKey','Function','Index','PrimaryKey','Schema','StoredProcedure','Synonym','Table','Trigger','UniqueKey','View','XmlSchema')]
# Any object types to exclude.
$ExcludeType,
[ValidateSet('CheckConstraint','DataType','DefaultConstraint','ForeignKey','Function','Index','PrimaryKey','Schema','StoredProcedure','Synonym','Table','Trigger','UniqueKey','View','XmlSchema')]
[String[]] $ExcludeType,

[Switch]
$NoProgress
# The path to the Rivet configuration file to load. Defaults to `rivet.json` in the current directory.
[String] $ConfigFilePath,

[Switch] $NoProgress
)

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

[Rivet.Configuration.Configuration]$settings = Get-RivetConfig -Path $ConfigFilePath -Environment $Environment

$pops = New-Object 'Collections.Generic.Stack[string]'
$popsHash = @{}
$exportedObjects = @{ }
Expand Down Expand Up @@ -971,9 +971,17 @@ where

if( $externalDependencies.ContainsKey($object.object_id) )
{
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])
$exportedObjects[$object.object_id] = $true
continue
$indexOfReferencedDatabase = [array]::IndexOf($settings.Databases.Name, $externalDependencies[$object.object_id].DatabaseName)
$indexOfCurrentDatabase = [array]::IndexOf($settings.Databases.Name, $Database)

# If the external depenedency's database does not get applied BEFORE the current database, do not allow
# references to the external dependency.
if( ($indexOfReferencedDatabase -gt $indexOfCurrentDatabase) -or ($indexOfReferencedDatabase -lt 0) -or ($indexOfCurrentDatabase -lt 0) )
{
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)
$exportedObjects[$object.object_id] = $true
continue
}
}

switch ($object.type_desc)
Expand Down Expand Up @@ -1163,12 +1171,18 @@ where
-- SCHEMAS
select
sys.schemas.name,
sys.sysusers.name as owner
sys.sysusers.name as owner,
sys.extended_properties.value as description
from
sys.schemas
join
sys.sysusers
on sys.schemas.principal_id = sys.sysusers.uid'
on sys.schemas.principal_id = sys.sysusers.uid
left join
sys.extended_properties
on sys.extended_properties.class = 3
and sys.extended_properties.major_id = sys.schemas.schema_id
and sys.extended_properties.name = ''MS_Description'''
function Export-Schema
{
param(
Expand All @@ -1187,9 +1201,14 @@ from
{
return
}
$description = $schema.description
if( $description )
{
$description = ' -Description ''{0}''' -f ($description -replace '''','''''')
}

Write-ExportingMessage -Schema $Object.schema_name -Type Schema
' Add-Schema -Name ''{0}'' -Owner ''{1}''' -f $schema.name,$schema.owner
' Add-Schema -Name ''{0}'' -Owner ''{1}''{2}' -f $schema.name,$schema.owner, $description
$exportedSchemas[$schema.name] = $true
Push-PopOperation ('Remove-Schema -Name ''{0}''' -f $schema.name)
}
Expand Down Expand Up @@ -1534,8 +1553,22 @@ where
Write-ExportingMessage -Schema $Object.schema_name -Name $Object.name -Type View
if( $view -match $createPreambleRegex )
{
$description = $Object.description
if( $description )
{
$description = ' -Description ''{0}''' -f ($description -replace '''','''''')
}

$view = $view -replace $createPreambleRegex,''
' Add-View{0} -Name ''{1}'' -Definition @''{2}{3}{2}''@' -f $schema,$Object.name,[Environment]::NewLine,$view
' Add-View{0} -Name ''{1}''{2} -Definition @''{3}{4}{3}''@' -f $schema,$Object.name,$description,[Environment]::NewLine,$view

# Get view's columns that have extended properties
$viewColumns = Invoke-Query -Query $columnsQuery | Where-Object { $_.object_id -eq $Object.object_id -and $_.description }
foreach( $column in $viewColumns )
{
$colDescription = ' -Description ''{0}''' -f ($column.description -replace '''','''''')
' Add-ExtendedProperty -SchemaName ''{0}'' -ViewName ''{1}'' -ColumnName ''{2}'' -Value {3}' -f $Object.schema_name,$Object.object_name,$column.column_name,$colDescription
}
}
else
{
Expand Down Expand Up @@ -1796,7 +1829,7 @@ where
if( $objectTypes -contains 'SQL_TRIGGER' )
{
$triggers = Invoke-Query -Query $triggersQuery
$triggers | ForEach-Object { $triggersByID[$_.object_id] = $_ }
$triggers | ForEach-Object { $triggersByID[$_.object_id] = $_ }
$triggers | Group-Object -Property 'parent_id' | ForEach-Object { $triggersByTable[[int]$_.Name] = $_.Group }
}

Expand All @@ -1806,7 +1839,7 @@ where
$uniqueKeys = Invoke-Query -Query $uniqueKeysQuery
$uniqueKeys | ForEach-Object { $uniqueKeysByID[$_.object_id] = $_ }
$uniqueKeys | Group-Object -Property 'parent_object_id' | ForEach-Object { $uniqueKeysByTable[[int]$_.Name] = $_.Group }

# UNIQUE KEY COLUMNS
$uniqueKeyColumns = Invoke-Query -Query $uniqueKeysColumnsQuery
$uniqueKeyColumns | Group-Object -Property 'object_id' | ForEach-Object { $uniqueKeyColumnsByObjectID[[int]$_.Name] = $_.Group }
Expand Down Expand Up @@ -1862,7 +1895,7 @@ where

if( $row.referenced_server_name -or ($row.referenced_database_name -ne $null -and $row.referenced_database_name -ne $Database) )
{
$externalDependencies[$row.referencing_id] = $externalName
$externalDependencies[$row.referencing_id] = @{ ExternalName = $externalName; DatabaseName = $row.referenced_database_name }
}
else
{
Expand All @@ -1882,21 +1915,21 @@ where
$schemas
$indexes
$dataTypes
} |
Measure-Object |
} |
Measure-Object |
Select-Object -ExpandProperty 'Count'

if( $writeProgress )
{
Write-Progress -Activity $activity
Write-Progress -Activity $activity
}

$timer |
$timer |
Add-Member -Name 'ExportCount' -Value 0 -MemberType NoteProperty -PassThru |
Add-Member -MemberType NoteProperty -Name 'Activity' -Value $activity -PassThru |
Add-Member -MemberType NoteProperty -Name 'CurrentOperation' -Value '' -PassThru |
Add-Member -MemberType NoteProperty -Name 'TotalCount' -Value $totalOperationCount

if( $writeProgress )
{
# Write-Progress is *expensive*. Only do it if the user is interactive and only every 1/10th of a second.
Expand Down
28 changes: 18 additions & 10 deletions Rivet/Functions/Get-RivetConfig.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ function Get-RivetConfig
$targetDatabases = @{ }
}

$order = Get-ConfigProperty -Name 'DatabaseOrder' -AsArray
$order = Get-ConfigProperty -Name 'Databases' -AsArray
$pluginModules = Get-ConfigProperty -Name 'PluginModules' -AsArray

[Rivet.Configuration.Configuration]$configuration =
Expand All @@ -285,22 +285,30 @@ function Get-RivetConfig
# Get user-specified databases first
if( $Database )
{
$Database |
return $Database |
Add-Member -MemberType ScriptProperty -Name Name -Value { $this } -PassThru |
Add-Member -MemberType ScriptProperty -Name FullName -Value { Join-Path -Path $configuration.DatabasesRoot -ChildPath $this.Name } -PassThru
}
else
{
# Then get all of them in the order requested
if( $order )

# Default alphabetical order
if (-not $order)
{
return Get-ChildItem -Path $configuration.DatabasesRoot -Directory
}

# User specified order
foreach( $dbName in $order )
{
$dbPath = Join-Path -Path $configuration.DatabasesRoot -ChildPath $dbName
if (-not (Test-Path -Path $dbPath -PathType Container))
{
foreach( $dbName in $order )
if (-not [wildcardpattern]::ContainsWildcardCharacters($dbName))
{
Get-ChildItem -Path $configuration.DatabasesRoot -Filter $dbName -Directory
Write-ValidationError "database named ""$($dbName)"" at ""$($dbPath)"" does not exist"
}
continue
}

Get-ChildItem -Path $configuration.DatabasesRoot -Exclude $order -Directory
Get-Item -Path $dbPath
}
} |
Select-Object -Property Name,FullName -Unique |
Expand Down
Loading

0 comments on commit 5ef5abf

Please sign in to comment.