Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 278 additions & 0 deletions samples/features/sql-data-sync/UpdateSyncSchema.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
using namespace Microsoft.Azure.Commands.Sql.DataSync.Model
using namespace System.Collections.Generic
param (
[Parameter(Mandatory=$true)][string]$SubscriptionId = "",
[Parameter(Mandatory=$true)][string]$ResourceGroupName = "",
[Parameter(Mandatory=$true)][string]$ServerName = "",
[Parameter(Mandatory=$true)][string]$DatabaseName = "",
[Parameter(Mandatory=$true)][string]$SyncGroupName = "",
[string]$MemberName = "",
[int]$TimeoutInSeconds = 900,
[switch]$RefreshDatabaseSchema = $false,
[switch]$AddAllTables = $false,
[string]$TablesAndColumnsToAdd = "",
[string]$TablesAndColumnsToRemove = "")

$TablesAndColumnsToAddList = [System.Collections.ArrayList]::new($TablesAndColumnsToAdd.Split(","))
$TablesAndColumnsToRemoveList = [System.Collections.ArrayList]::new($TablesAndColumnsToRemove.Split(","))
$TempFile = $env:TEMP+"\syncSchema.json"

##login to Azure account
add-azurermaccount

##select the subscription
select-azurermsubscription -SubscriptionId $SubscriptionId

##get sync group and check if sync group exists
$SyncGroup = Get-AzureRmSqlSyncGroup -ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-Name $SyncGroupName

if ($SyncGroup -eq $null)
{
Write-Host "Sync group $SyncGroupName is not found."
exit;
}

##if member name specified, check if member exists
if ($MemberName -ne "")
{
$SyncMember = Get-AzureRmSqlSyncMember -ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-SyncGroupName $SyncGroupName `
-Name $MemberName
if ($SyncMember -eq $null)
{
Write-Error "Sync member $MemberName is not found."
exit;
}
}


## Refresh database schema if -RefreshDatabaseSchema is specified
$DatabaseSchema = ""
if ($RefreshDatabaseSchema)
{
$StartTime = Get-Date
if ($MemberName -eq "")
{
Write-Host "Refreshing database schema from hub database"
Update-AzureRmSqlSyncSchema -ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-SyncGroupName $SyncGroupName
}
else
{
Write-Host "Refreshing database schema from member $MemberName"
Update-AzureRmSqlSyncSchema -ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-SyncGroupName $SyncGroupName `
-SyncMemberName $MemberName
}

## Wait until the database schema is refreshed
$TimeoutTimeSpan = New-TimeSpan -Start $StartTime -End $StartTime
$IsSucceeded = $false
While ($TimeoutTimeSpan.TotalSeconds -le $TimeoutInSeconds)
{
Start-Sleep -s 10

if ($MemberName -eq "")
{
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-ResourceGroupName $ResourceGroupName
}
else
{
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-ResourceGroupName $ResourceGroupName `
-SyncMemberName $MemberName
}

if ($DatabaseSchema.LastUpdateTime -gt $StartTime.ToUniversalTime())
{
Write-Host "Database schema succeeded"
$IsSucceeded = $true
break;
}
}

if (-not $IsSucceeded)
{
Write-Error "Refresh failed or timeout"
exit;
}
}
else
{
if ($MemberName -eq "")
{
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-ResourceGroupName $ResourceGroupName
}
else
{
$DatabaseSchema = Get-AzureRmSqlSyncSchema -SyncGroupName $SyncGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-ResourceGroupName $ResourceGroupName `
-SyncMemberName $MemberName
}
}

if ($DatabaseSchema.LastUpdateTime -eq $null)
{
Write-Error "Database schema is not available. Refresh the database schema by specify -RefreshDatabaseSchema"
Exit;
}

## Remove specified tables and columns from sync schema
## Also remove tables and columns which is not defined in the database if database schema is refreshed
$TablesToRemove = New-Object "System.Collections.Generic.List[AzureSqlSyncGroupSchemaTableModel]";
foreach ($TableSchema in $SyncGroup.Schema.Tables)
{
$TableInDatabase = $DatabaseSchema.Tables | ? QuotedName -eq $TableSchema.QuotedName

if ($TablesAndColumnsToRemoveList.Contains($TableSchema.QuotedName) -or $TableInDatabase -eq $null)
{
$TablesToRemove.Add($TableSchema);
}
else
{
$ColumnsToRemove = New-Object "System.Collections.Generic.List[AzureSqlSyncGroupSchemaColumnModel]";
foreach($ColumnSchema in $TableSchema.Columns)
{
$ColumnInTable = $TableInDatabase[0].Columns | ? QuotedName -eq $ColumnSchema.QuotedName
$FullName = $TableSchema.QuotedName+"."+$ColumnSchema.QuotedName
if ($TablesAndColumnsToRemoveList.Contains($FullName) -or $ColumnInTable -eq $null)
{
$ColumnsToRemove.Add($ColumnSchema);
}
}

if ($ColumnsToRemove.Count -gt 0)
{
foreach ($ColumnToRemove in $ColumnsToRemove)
{
$FullName = $TableSchema.QuotedName+"."+$ColumnToRemove.QuotedName
Write-Host "$FullName is being removed from sync schema"
$TableSchema.Columns.Remove($ColumnToRemove);
}
}
}
}

if ($TablesToRemove.Count -gt 0)
{
foreach ($TableToRemove in $TablesToRemove)
{
Write-Host $TableToRemove.QuotedName" is being removed from sync schema"
$SyncGroup.Schema.Tables.Remove($TableToRemove);
}
}

## Add specified tables and columns to the sync schema
foreach ($TableSchema in $DatabaseSchema.Tables)
{
## Reuse if the table already exists in the schema; Otherwise, create a new one
$newTableSchema = $SyncGroup.Schema.Tables | ? QuotedName -eq $TableSchema.QuotedName
$AddNewTable = $false
if ($newTableSchema -eq $null)
{
$AddNewTable = $true
$newTableSchema = [AzureSqlSyncGroupSchemaTableModel]::new()
$newTableSchema.QuotedName = $TableSchema.QuotedName
$newTableSchema.Columns = [List[AzureSqlSyncGroupSchemaColumnModel]]::new();
}

## If the table name is specified, add all valid columns
$addAllColumns = $false
if ($AddAllTables -or $TablesAndColumnsToAddList.Contains($TableSchema.QuotedName))
{
## If the table is not supported, move to next table
if ($TableSchema.HasError)
{
$fullTableName = $TableSchema.QuotedName
Write-Host "Can't add table $fullTableName to the sync schema" -foregroundcolor "Red"
Write-Host $TableSchema.ErrorId -foregroundcolor "Red"
continue;
}
else
{
$addAllColumns = $true
}
}

## Add columns
foreach($columnSchema in $TableSchema.Columns)
{
$fullColumnName = $TableSchema.QuotedName + "." + $columnSchema.QuotedName
if ($addAllColumns -or $TablesAndColumnsToAddList.Contains($fullColumnName))
{
## If the column already exists in the sync schema or not supported, ignore
$Column = $newTableSchema.Columns | ? QuotedName -eq $columnSchema.QuotedName
if ($Column -ne $null)
{
Write-Host "Column $fullColumnName is already in the schema"
}
elseif ((-not $addAllColumns) -and $TableSchema.HasError)
{
Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
Write-Host $tableSchema.ErrorId -foregroundcolor "Red"
}
elseif ((-not $addAllColumns) -and $columnSchema.HasError)
{
Write-Host "Can't add column $fullColumnName to the sync schema" -foregroundcolor "Red"
Write-Host $columnSchema.ErrorId -foregroundcolor "Red"
}
else
{
Write-Host "Adding $fullColumnName to the sync schema"
$newColumnSchema = [AzureSqlSyncGroupSchemaColumnModel]::new()
$newColumnSchema.QuotedName = $columnSchema.QuotedName
$newColumnSchema.DataSize = $columnSchema.DataSize
$newColumnSchema.DataType = $columnSchema.DataType
$newTableSchema.Columns.Add($newColumnSchema)
}
}
}
if ($newTableSchema.Columns.Count -gt 0 -and $AddNewTable)
{
$SyncGroup.Schema.Tables.Add($newTableSchema)
}
}

## Update the master sync member name if database metadata is from the member
if ($MemberName -ne "")
{
$SyncGroup.Schema.MasterSyncMemberName = $MemberName
}
else
{
$SyncGroup.Schema.MasterSyncMemberName = $null
}

$schemaString = $SyncGroup.Schema | ConvertTo-Json -depth 5 -Compress

# workaround a powershell bug if the PowerShell version is too early
$schemaString = $schemaString.Replace('"Tables"', '"tables"').Replace('"Columns"', '"columns"').Replace('"QuotedName"', '"quotedName"').Replace('"MasterSyncMemberName"','"masterSyncMemberName"')

Write-Host "Write the schema to $TempFile"
$schemaString | Out-File $TempFile

# Update the sync schema
Update-AzureRmSqlSyncGroup -ResourceGroupName $ResourceGroupName `
-ServerName $ServerName `
-DatabaseName $DatabaseName `
-Name $SyncGroupName `
-SchemaFile $TempFile