Skip to content

Commit 2e3bfeb

Browse files
committed
brand-new XPlat connection string builder
1 parent 66b1838 commit 2e3bfeb

File tree

6 files changed

+98
-24
lines changed

6 files changed

+98
-24
lines changed

functions/Invoke-DBOQuery.ps1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ function Invoke-DBOQuery {
175175
#Build connection string
176176
#$connString = Get-ConnectionString -Configuration $config -Type $Type
177177
#$dbUpConnection = Get-ConnectionManager -ConnectionString $connString -Type $Type
178+
Write-PSFMessage -Level Debug -Message "Getting the connection object"
178179
$dbUpConnection = Get-ConnectionManager -Configuration $config -Type $Type
179180
$dbUpSqlParser = Get-SqlParser -Type $Type
180181
$status = [DBOpsDeploymentStatus]::new()
@@ -183,6 +184,7 @@ function Invoke-DBOQuery {
183184
if ($null -ne $dbUpConnection.IsScriptOutputLogged -and -Not $config.Silent) {
184185
$dbUpConnection.IsScriptOutputLogged = $true
185186
}
187+
Write-PSFMessage -Level Verbose -Message "Establishing connection with $Type $($config.SqlInstance)"
186188
try {
187189
$managedConnection = $dbUpConnection.OperationStarting($dbUpLog, $null)
188190
}
@@ -214,6 +216,7 @@ function Invoke-DBOQuery {
214216
foreach ($qText in $queryText) {
215217
$queryList += Resolve-VariableToken $qText $config.Variables
216218
}
219+
Write-PSFMessage -Level Debug -Message "Preparing to run $($queryList.Count) queries"
217220
try {
218221
$ds = [System.Data.DataSet]::new()
219222
$qCount = 0

internal/functions/Get-ConnectionString.ps1

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,80 @@ function Get-ConnectionString {
44
[DBOpsConfig]$Configuration,
55
[DBOps.ConnectionType]$Type
66
)
7-
#Build connection string
7+
# Build connection string
88
if (!$Configuration.ConnectionString) {
9-
$CSBuilder = [System.Data.SqlClient.SqlConnectionStringBuilder]::new()
10-
$CSBuilder["Server"] = $Configuration.SqlInstance
11-
if ($Configuration.Database) { $CSBuilder["Database"] = $Configuration.Database }
12-
if ($Configuration.Encrypt) { $CSBuilder["Encrypt"] = $true }
13-
$CSBuilder["Connection Timeout"] = $Configuration.ConnectionTimeout
9+
$csBuilder = switch ($Type) {
10+
SqlServer { [System.Data.SqlClient.SqlConnectionStringBuilder]::new() }
11+
PostgreSQL { [Npgsql.NpgsqlConnectionStringBuilder]::new() }
12+
Oracle { [Oracle.ManagedDataAccess.Client.OracleConnectionStringBuilder]::new() }
13+
MySQL { [MySql.Data.MySqlClient.MySqlConnectionStringBuilder]::new() }
14+
}
15+
# finding all the right connection string properties
16+
$conn = @{}
17+
foreach ($key in 'Server', 'Data Source') {
18+
if ($csBuilder.ContainsKey($key)) { $conn.Server = $key; break }
19+
}
20+
if (-not $conn.Server) {
21+
Stop-PSFFunction -Message "Failed to find a Server property in the connection string object" -EnableException $true
22+
}
1423

15-
if ($Configuration.Credential) {
16-
$CSBuilder["User ID"] = $Configuration.Credential.UserName
17-
$CSBuilder["Password"] = $Configuration.Credential.GetNetworkCredential().Password
24+
foreach ($key in 'Connection Timeout', 'Timeout') {
25+
if ($csBuilder.ContainsKey($key)) { $conn.ConnectionTimeout = $key; break }
1826
}
19-
elseif ($Configuration.Username) {
20-
if ($Password) {
21-
$currentCred = [pscredential]::new($Configuration.Username, $Password)
27+
if (-not $conn.ConnectionTimeout) {
28+
Stop-PSFFunction -Message "Failed to find a Timeout property in the connection string object" -EnableException $true
29+
}
30+
31+
# support for servername:port and trimming
32+
if ($Configuration.SqlInstance -match '^\s*(.+)[:|,]\s*(\d+)\s*$') {
33+
$server = $Matches[1]
34+
$port = $Matches[2]
35+
}
36+
else {
37+
$server = $Configuration.SqlInstance
38+
$port = $null
39+
}
40+
if ($port) {
41+
# check if port is an independent property and set it, otherwise add the port back to the connection string
42+
if ($csBuilder.ContainsKey('Port')) {
43+
$csBuilder[$conn.Server] = $server
44+
$csBuilder.Port = $port
2245
}
2346
else {
47+
if ($Type -eq [DBOps.ConnectionType]::SqlServer) {
48+
$csBuilder[$conn.Server] = "$server,$port"
49+
}
50+
else {
51+
$csBuilder[$conn.Server] = "$server`:$port"
52+
}
53+
}
54+
}
55+
56+
if ($Configuration.Database -and $csBuilder.ContainsKey('Database')) { $csBuilder["Database"] = $Configuration.Database }
57+
if ($Configuration.Encrypt -and $csBuilder.ContainsKey('Encrypt')) { $csBuilder["Encrypt"] = $true }
58+
if ($Configuration.ApplicationName -and $csBuilder.ContainsKey('Application Name')) { $csBuilder["Application Name"] = $Configuration.ApplicationName }
59+
if ($Configuration.ExecutionTimeout -and $csBuilder.ContainsKey('Command Timeout')) { $csBuilder["Command Timeout"] = $Configuration.ExecutionTimeout }
60+
$csBuilder[$conn.ConnectionTimeout] = $Configuration.ConnectionTimeout
61+
# define authentication
62+
if ($Configuration.Credential) {
63+
$csBuilder["User ID"] = $Configuration.Credential.UserName
64+
$csBuilder["Password"] = $Configuration.Credential.GetNetworkCredential().Password
65+
}
66+
elseif ($Configuration.Username) {
67+
$csBuilder["User ID"] = $Configuration.UserName
68+
if ($Configuration.Password) {
2469
$currentCred = [pscredential]::new($Configuration.Username, $Configuration.Password)
70+
$csBuilder["Password"] = $currentCred.GetNetworkCredential().Password
2571
}
26-
$CSBuilder["User ID"] = $currentCred.UserName
27-
$CSBuilder["Password"] = $currentCred.GetNetworkCredential().Password
2872
}
2973
else {
30-
$CSBuilder["Integrated Security"] = $true
31-
}
32-
if ($Type -eq 'SQLServer') {
33-
$CSBuilder["Application Name"] = $Configuration.ApplicationName
74+
if ($csBuilder.ContainsKey('Integrated Security')) {
75+
$csBuilder["Integrated Security"] = $true
76+
}
3477
}
35-
return $CSBuilder.ToString()
78+
# generate the connection string
79+
$connString = $csBuilder.ToString()
80+
return $connString
3681
}
3782
else {
3883
return $Configuration.ConnectionString

tests/Install-DBOPackage.Tests.ps1

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ $fullConfigSource = Join-PSFPath -Normalize "$here\etc\full_config.json"
3434
$testPassword = 'TestPassword'
3535
$encryptedString = $testPassword | ConvertTo-SecureString -Force -AsPlainText | ConvertTo-EncryptedString
3636
$newDbName = "_test_$commandName"
37+
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
38+
$createDatabaseScript = 'IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN CREATE DATABASE [{0}]; END' -f $newDbName
3739

3840
Describe "Install-DBOPackage integration tests" -Tag $commandName, IntegrationTests {
3941
BeforeAll {
4042
if ((Test-Path $workFolder) -and $workFolder -like '*.Tests.dbops') { Remove-Item $workFolder -Recurse }
4143
$null = New-Item $workFolder -ItemType Directory -Force
4244
$null = New-Item $unpackedFolder -ItemType Directory -Force
4345
(Get-Content $fullConfigSource -Raw) -replace 'replaceMe', $encryptedString | Out-File $fullConfig -Force
44-
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
4546
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
47+
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Database master -Query $createDatabaseScript
4648
}
4749
AfterAll {
4850
if ((Test-Path $workFolder) -and $workFolder -like '*.Tests.dbops') { Remove-Item $workFolder -Recurse }
@@ -54,6 +56,8 @@ Describe "Install-DBOPackage integration tests" -Tag $commandName, IntegrationTe
5456
$p1 = New-DBOPackage -ScriptPath $v1scripts -Name "$workFolder\pv1" -Build 1.0 -Force
5557
}
5658
It "should deploy version 1.0 to a new database using -CreateDatabase switch" {
59+
# Drop database and allow the function to create it
60+
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
5761
$testResults = Install-DBOPackage $p1 -CreateDatabase -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Database $newDbName -SchemaVersionTable $logTable -OutputFile "$workFolder\log.txt" -Silent
5862
$testResults.Successful | Should Be $true
5963
$testResults.Scripts.Name | Should Be $v1Journal

tests/Install-DBOSqlScript.Tests.ps1

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,24 @@ $packageFileName = Join-PSFPath -Normalize $workFolder "dbops.package.json"
2929
$cleanupPackageName = Join-PSFPath -Normalize "$here\etc\TempCleanup.zip"
3030
$outFile = Join-PSFPath -Normalize "$here\etc\outLog.txt"
3131
$newDbName = "_test_$commandName"
32+
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
33+
$createDatabaseScript = 'IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN CREATE DATABASE [{0}]; END' -f $newDbName
3234

3335
Describe "Install-DBOSqlScript integration tests" -Tag $commandName, IntegrationTests {
3436
BeforeAll {
3537
if ((Test-Path $workFolder) -and $workFolder -like '*.Tests.dbops') { Remove-Item $workFolder -Recurse }
3638
$null = New-Item $workFolder -ItemType Directory -Force
37-
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
3839
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
40+
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $createDatabaseScript
3941
}
4042
AfterAll {
41-
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database $newDbName -InputFile $cleanupScript
4243
if ((Test-Path $workFolder) -and $workFolder -like '*.Tests.dbops') { Remove-Item $workFolder -Recurse }
4344
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
4445
}
4546
Context "testing regular deployment with CreateDatabase specified" {
4647
It "should deploy version 1.0 to a new database using -CreateDatabase switch" {
48+
# drop the database before installing the package
49+
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
4750
$testResults = Install-DBOSqlScript -ScriptPath $v1scripts -CreateDatabase -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Database $newDbName -SchemaVersionTable $logTable -OutputFile "$workFolder\log.txt" -Silent
4851
$testResults.Successful | Should Be $true
4952
$testResults.Scripts.Name | Should Be (Resolve-Path $v1scripts).Path

tests/Invoke-DBODeployment.Tests.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ $packageFileName = Join-PSFPath -Normalize $workFolder "dbops.package.json"
2929
$cleanupPackageName = Join-PSFPath -Normalize "$here\etc\TempCleanup.zip"
3030
$outFile = Join-PSFPath -Normalize "$here\etc\outLog.txt"
3131
$newDbName = "_test_$commandName"
32+
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
33+
$createDatabaseScript = 'IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN CREATE DATABASE [{0}]; END' -f $newDbName
3234

3335
Describe "Invoke-DBODeployment integration tests" -Tag $commandName, IntegrationTests {
3436
BeforeAll {
@@ -37,8 +39,6 @@ Describe "Invoke-DBODeployment integration tests" -Tag $commandName, Integration
3739
$null = New-Item $unpackedFolder -ItemType Directory -Force
3840
$packageName = New-DBOPackage -Path (Join-Path $workFolder 'tmp.zip') -ScriptPath $tranFailScripts -Build 1.0 -Force
3941
$null = Expand-Archive -Path $packageName -DestinationPath $workFolder -Force
40-
$dropDatabaseScript = 'IF EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{0}]; END' -f $newDbName
41-
$createDatabaseScript = 'IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = ''{0}'') BEGIN CREATE DATABASE [{0}]; END' -f $newDbName
4242
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $dropDatabaseScript
4343
$null = Invoke-DBOQuery -SqlInstance $script:mssqlInstance -Silent -Credential $script:mssqlCredential -Database master -Query $createDatabaseScript
4444
}

tests/referenced.pester.ps1

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Param
2+
(
3+
[string[]]$Path = '.',
4+
[string[]]$Tag
5+
6+
)
7+
$params = @{
8+
Path = $Path | ForEach-Object {
9+
$item = switch -regex ($_) {
10+
'\.Tests\.ps1' { $_ }
11+
default { $_.Replace('.ps1', '.Tests.ps1') }
12+
}
13+
Get-Item $item
14+
}
15+
}
16+
if ($Tag) {
17+
$params += @{ Tag = $Tag}
18+
}
19+
& $PSScriptRoot\manual.pester.ps1 @params

0 commit comments

Comments
 (0)