Skip to content

Commit 9c342dd

Browse files
authored
Merge pull request #86 from sqlcollaborative/feature/tokens
Configurable variable tokens
2 parents 9eee49a + b7096a8 commit 9c342dd

File tree

5 files changed

+52
-15
lines changed

5 files changed

+52
-15
lines changed

dbops.psm1

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,32 @@ Register-PSFConfigValidation -Name "connectionType" -ScriptBlock {
116116
return $Result
117117
}
118118

119+
Register-PSFConfigValidation -Name "tokenRegex" -ScriptBlock {
120+
Param (
121+
$Value
122+
)
123+
$failMessage = "Should contain capture group (token)"
124+
$Result = New-Object PSObject -Property @{
125+
Success = $True
126+
Value = $null
127+
Message = ""
128+
}
129+
try {
130+
if (([string]$Value) -is [string] -and [string]$Value -like '*(token)*') {
131+
$Result.Value = [string]$Value
132+
}
133+
else {
134+
$Result.Message = $failMessage
135+
$Result.Success = $False
136+
}
137+
}
138+
catch {
139+
$Result.Message = "Failed to convert value to string. $failMessage"
140+
$Result.Success = $False
141+
}
142+
return $Result
143+
}
144+
119145
# defining defaults
120146

121147
Set-PSFConfig -FullName dbops.ApplicationName -Value "dbops" -Initialize -Description "Application name in the connection string"
@@ -145,7 +171,8 @@ Set-PSFConfig -FullName dbops.mail.Subject -Value "DBOps deployment status" -Ini
145171
Set-PSFConfig -FullName dbops.security.encryptionkey -Value "~/.dbops.key" -Initialize -Description "Path to a custom encryption key used to encrypt/decrypt passwords. The key should be a binary file with a length of 128, 192 or 256 bits. Key will be generated automatically if not exists."
146172
Set-PSFConfig -FullName dbops.security.usecustomencryptionkey -Value ($PSVersionTable.Platform -eq 'Unix') -Validation bool -Initialize -Description "Determines whether to use a custom encryption key for storing passwords. Enabled by default only on Unix platforms."
147173
Set-PSFConfig -FullName dbops.rdbms.type -Value 'SqlServer' -Validation connectionType -Initialize -Description "Assumes a certain RDBMS as a default one for each command. SQLServer by default"
148-
Set-PSFConfig -FullName dbops.package.slim -Value $false -Validation bool -Initialize -Description "Decides whether to make the packages 'slim' and omit module files when creating the package. Default: false."
174+
Set-PSFConfig -FullName dbops.package.slim -Value $false -Validation bool -Initialize -Description "Decides whether to make the packages 'slim' and omit module files when creating the package. Default: `$false"
175+
Set-PSFConfig -FullName dbops.config.variabletoken -Value "\#\{(token)\}" -Validation tokenRegex -Initialize -Description "Variable replacement token. Regex string that will be replaced with values from -Variables parameters. Default: \#\{(token)\}"
149176

150177
# extensions for SMO
151178
$typeData = Get-TypeData -TypeName 'Microsoft.SqlServer.Management.Smo.Database'
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
1-
Function Get-VariableTokens {
1+
Function Get-VariableToken {
22
<#
33
.SYNOPSIS
44
Get a list of #{tokens} from the string
5-
5+
66
.DESCRIPTION
77
Returns an array of tokens that matches token regex #{token}
8-
8+
99
.PARAMETER InputString
1010
String to run regex against
11-
11+
1212
.EXAMPLE
1313
Get-VariableTokens '#{foo} myString #{bar}' # returns @('foo','bar')
1414
#>
1515
Param (
16-
[string]$InputString
16+
[string]$InputString,
17+
[string]$RegexString
1718
)
18-
[regex]::matches($InputString, "\#\{([a-zA-Z0-9.]*)\}") | ForEach-Object { $_.Groups[1].Value }
19+
[regex]::matches($InputString, $RegexString) | ForEach-Object { $_.Groups[1].Value }
1920
}

internal/functions/Resolve-VariableToken.ps1

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,21 @@
1818
[CmdletBinding()]
1919
Param (
2020
[object[]]$InputObject,
21-
[object]$Runtime
21+
[object]$Runtime,
22+
[string]$TokenRegex = (Get-DBODefaultSetting -Name config.variabletoken -Value)
2223
)
2324
foreach ($obj in $InputObject) {
2425
if ($obj -is [string]) {
2526
$output = $obj
26-
foreach ($token in (Get-VariableTokens $obj)) {
27+
foreach ($token in (Get-VariableToken -InputString $obj -RegexString $TokenRegex.Replace('token', '[a-zA-Z0-9\.]+'))) {
2728
#Replace variables found in the config
28-
$tokenRegEx = "\#\{$token\}"
29+
$tokenRegExString = $TokenRegex.Replace('token', [Regex]::Escape($token))
2930
if ($Runtime) {
3031
if ($Runtime -is [hashtable]) { $variableList = $Runtime.Keys }
3132
else { $variableList = $Runtime.psobject.Properties.Name }
3233
if ($variableList -contains $token) {
3334
Write-PSFMessage -Level Debug -Message "Replacing token $token"
34-
$output = $output -replace $tokenRegEx, $Runtime.$token
35+
$output = $output -replace $tokenRegExString, $Runtime.$token
3536
}
3637
}
3738
}

internal/json/dbops.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"Internal": [
5151
"internal\\classes\\DBOps.enums.ps1",
5252
"internal\\functions\\Get-DbopsFile.ps1",
53-
"internal\\functions\\Get-VariableTokens.ps1",
53+
"internal\\functions\\Get-VariableToken.ps1",
5454
"internal\\functions\\Resolve-VariableToken.ps1",
5555
"internal\\functions\\Get-NewBuildNumber.ps1",
5656
"internal\\functions\\Get-ExternalLibrary.ps1",

tests/Invoke-DBOQuery.Tests.ps1

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,18 @@ Describe "Invoke-DBOQuery tests" -Tag $commandName, IntegrationTests {
134134
}
135135
It "should run the query with custom variables" {
136136
$query = "SELECT '#{Test}' AS A, '#{Test2}' AS B UNION ALL SELECT '3' AS A, '4' AS B"
137-
$result = Invoke-DBOQuery -Query $query -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -As DataTable -Variables @{ Test = '1'; Test2 = '2'}
137+
$result = Invoke-DBOQuery -Query $query -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -As DataTable -Variables @{ Test = '1'; Test2 = '2' }
138138
$result.A | Should -Be '1', '3'
139139
$result.B | Should -Be '2', '4'
140140
}
141+
It "should run the query with custom variables and custom token template" {
142+
Set-PSFConfig -FullName dbops.config.variabletoken -Value '\$(token)\$'
143+
$query = "SELECT '`$Test`$' AS A, '`$Test2`$' AS B UNION ALL SELECT '3' AS A, '4' AS B"
144+
$result = Invoke-DBOQuery -Query $query -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -As DataTable -Variables @{ Test = '1'; Test2 = '2' }
145+
$result.A | Should -Be '1', '3'
146+
$result.B | Should -Be '2', '4'
147+
(Get-PSFConfig -FullName dbops.config.variabletoken).ResetValue()
148+
}
141149
It "should connect to the server from a custom variable" {
142150
$query = "SELECT 1 AS A, 2 AS B UNION ALL SELECT 3 AS A, 4 AS B"
143151
$result = Invoke-DBOQuery -Query $query -SqlInstance '#{srv}' -Credential $script:mssqlCredential -As DataTable -Variables @{ Srv = $script:mssqlInstance }
@@ -146,7 +154,7 @@ Describe "Invoke-DBOQuery tests" -Tag $commandName, IntegrationTests {
146154
}
147155
It "should run the query with custom parameters" {
148156
$query = "SELECT @p1 AS A, @p2 AS B"
149-
$result = Invoke-DBOQuery -Query $query -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Parameter @{ p1 = '1'; p2 = 'string'}
157+
$result = Invoke-DBOQuery -Query $query -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Parameter @{ p1 = '1'; p2 = 'string' }
150158
$result.A | Should -Be 1
151159
$result.B | Should -Be string
152160
}
@@ -192,7 +200,7 @@ Describe "Invoke-DBOQuery tests" -Tag $commandName, IntegrationTests {
192200
}
193201
It "should throw a connection timeout error" {
194202
$query = "SELECT 1/0"
195-
{ $result = Invoke-DBOQuery -Query $query -SqlInstance localhost:6493 -Credential $script:mssqlCredential -ConnectionTimeout 1} | Should throw "The server was not found or was not accessible"
203+
{ $result = Invoke-DBOQuery -Query $query -SqlInstance localhost:6493 -Credential $script:mssqlCredential -ConnectionTimeout 2 } | Should throw "The server was not found or was not accessible"
196204
}
197205
It "should fail when parameters are of a wrong type" {
198206
{ Invoke-DBOQuery -Query 'SELECT 1/@foo' -SqlInstance $script:mssqlInstance -Credential $script:mssqlCredential -Parameter @{ foo = 'bar' } -Silent } | Should throw 'Conversion failed'

0 commit comments

Comments
 (0)