diff --git a/Docs/Clear-SqlMessage.md b/Docs/Clear-SqlMessage.md index 5f7f75c..673eb3e 100644 --- a/Docs/Clear-SqlMessage.md +++ b/Docs/Clear-SqlMessage.md @@ -23,10 +23,10 @@ Clear-SqlMessage removes all informational messages generated by Invoke-SqlScala ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Clear-SqlMessage ``` -{{ Add example description here }} +Clear the message queue for the connection ## PARAMETERS diff --git a/Docs/Close-SqlConnection.md b/Docs/Close-SqlConnection.md index f02d7e3..2c37c55 100644 --- a/Docs/Close-SqlConnection.md +++ b/Docs/Close-SqlConnection.md @@ -23,10 +23,10 @@ Closes the connection and disposes of the underlying object. This will also rol ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Close-SqlConnection ``` -{{ Add example description here }} +Closes the sql connection. ## PARAMETERS diff --git a/Docs/Complete-SqlTransaction.md b/Docs/Complete-SqlTransaction.md index a63243a..f31e060 100644 --- a/Docs/Complete-SqlTransaction.md +++ b/Docs/Complete-SqlTransaction.md @@ -13,7 +13,7 @@ Complete a SQL transaction. ## SYNTAX ``` -Complete-SqlTransaction [-ConnectionName ] [-WhatIf] [-Confirm] [] +Complete-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION @@ -23,10 +23,10 @@ Complete (COMMIT) a SQL transaction. ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Complete-SqlTransaction ``` -{{ Add example description here }} +Commits the SQL transaction ## PARAMETERS @@ -39,7 +39,7 @@ Parameter Sets: (All) Aliases: cn Required: False -Position: Named +Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False diff --git a/Docs/Get-SqlConnection.md b/Docs/Get-SqlConnection.md index dc24599..18579e4 100644 --- a/Docs/Get-SqlConnection.md +++ b/Docs/Get-SqlConnection.md @@ -23,10 +23,10 @@ Gets the underlying provider connection object for the current connection or for ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Get-SqlConnection ``` -{{ Add example description here }} +Returns the provider-specific Connection object. ## PARAMETERS diff --git a/Docs/Get-SqlMessage.md b/Docs/Get-SqlMessage.md index d1c62c2..168708d 100644 --- a/Docs/Get-SqlMessage.md +++ b/Docs/Get-SqlMessage.md @@ -26,10 +26,10 @@ SQL Server, if you use Print or Raiserror without the "NoWait", then messages wi ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Get-SqlMessage ``` -{{ Add example description here }} +Returns all the messages in the queue. ## PARAMETERS diff --git a/Docs/Get-SqlTransaction.md b/Docs/Get-SqlTransaction.md index 2da051a..37baecb 100644 --- a/Docs/Get-SqlTransaction.md +++ b/Docs/Get-SqlTransaction.md @@ -23,10 +23,10 @@ Gets the underlying provider transaction object for the current connection or fo ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Get-SqlTransaction ``` -{{ Add example description here }} +Returns the provider specific transaction object. ## PARAMETERS diff --git a/Docs/Invoke-SqlBulkCopy.md b/Docs/Invoke-SqlBulkCopy.md index f134d20..2a79258 100644 --- a/Docs/Invoke-SqlBulkCopy.md +++ b/Docs/Invoke-SqlBulkCopy.md @@ -12,25 +12,20 @@ Executes a bulk copy between two connections. ## SYNTAX -### hashtable (Default) -``` -Invoke-SqlBulkCopy [-SourceConnectionName ] [-DestinationConnectionName ] - [-ColumnMap ] [-BatchSize ] [-BatchTimeout ] [-Notify] [-WhatIf] [-Confirm] - [] -``` - -### table +### table (Default) ``` Invoke-SqlBulkCopy [-SourceConnectionName ] [-DestinationConnectionName ] [-DestinationTable ] -SourceTable [-ColumnMap ] [-BatchSize ] - [-BatchTimeout ] [-Notify] [-WhatIf] [-Confirm] [] + [-BatchTimeout ] [-Notify] [-NotifyAction ] [-WhatIf] [-Confirm] + [] ``` ### query ``` Invoke-SqlBulkCopy [-SourceConnectionName ] [-DestinationConnectionName ] -DestinationTable -SourceQuery [-SourceParameters ] [-ColumnMap ] - [-BatchSize ] [-BatchTimeout ] [-Notify] [-WhatIf] [-Confirm] [] + [-BatchSize ] [-BatchTimeout ] [-Notify] [-NotifyAction ] + [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION @@ -47,13 +42,6 @@ Returns number of rows copied. ## EXAMPLES -### Example 1 -```powershell -PS C:\> {{ Add example code here }} -``` - -{{ Add example description here }} - ## PARAMETERS ### -BatchSize @@ -158,6 +146,22 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -NotifyAction +Provide a scriptblock to be executed after every BatchSize number of rows are inserted. +Scriptblock will be called with the number of rows inserted so far. + +```yaml +Type: System.Action`1[System.Int64] +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -SourceConnectionName User defined name for connection where data will be queried from. diff --git a/Docs/Invoke-SqlQuery.md b/Docs/Invoke-SqlQuery.md index 72a4ddb..28da318 100644 --- a/Docs/Invoke-SqlQuery.md +++ b/Docs/Invoke-SqlQuery.md @@ -49,6 +49,14 @@ PS C:\> Invoke-SqlQuery -Query "SELECT * FROM TABLE WHERE col1=@id' AND colb > @ Runs a simple query with parameters +### Example 3 +```powershell +PS C:\> $obj = [PSCustomObject]@{id = 1; sd = (Get-date)} +PS C:\> $obj | Invoke-SqlQuery -Query "SELECT * FROM TABLE WHERE col1=@id' AND colb > @someDate" +``` + +Runs a simple query, passing in parameters via object + ## PARAMETERS ### -AsDataTable diff --git a/Docs/Invoke-SqlScalar.md b/Docs/Invoke-SqlScalar.md index 0f2cd1f..6ce5d09 100644 --- a/Docs/Invoke-SqlScalar.md +++ b/Docs/Invoke-SqlScalar.md @@ -34,7 +34,22 @@ Executes a Scalar query against the targeted connection. If the sql statement g PS C:\> Invoke-SqlScalar -Query "SELECT Count(1) FROM TABLE" ``` -{{ Add example description here }} +Simple Scalar query + +### Example 2 +```powershell +PS C:\> Invoke-SqlQuery -Query "SELECT Count(1) FROM TABLE WHERE colb > @someDate" -Parameters @{someDate = (Get-Date)} +``` + +Simple Scalar query with parameters + +### Example 3 +```powershell +PS C:\> $obj = [PSCustomObject]@{sd = (Get-date)} +PS C:\> $obj | Invoke-SqlScalar -Query "SELECT Count(1) FROM TABLE WHERE colb> @sd" +``` + +Simple Scalar query with parameters populated by object ## PARAMETERS diff --git a/Docs/Invoke-SqlUpdate.md b/Docs/Invoke-SqlUpdate.md index 3b3f746..86634c7 100644 --- a/Docs/Invoke-SqlUpdate.md +++ b/Docs/Invoke-SqlUpdate.md @@ -42,6 +42,14 @@ PS C:\> Invoke-SqlUpdate -Query "UPDATE employees SET salary = @val WHERE manage Updates the employee table setting the salary to 999999 for all rows with managerid of 549 +### Example 2 +```powershell +PS C:\> $obj = [PSCustomObject]@{id = 549; val = 999999} +PS C:\> $obj | Invoke-SqlUpdate -Query "UPDATE employees SET salary = @val WHERE manager = @id" +``` + +Updates the employee table setting the salary to 999999 for all rows with managerid of 549 using an object + ## PARAMETERS ### -Command diff --git a/Docs/Open-MySqlConnection.md b/Docs/Open-MySqlConnection.md index 45c33fd..af2ef06 100644 --- a/Docs/Open-MySqlConnection.md +++ b/Docs/Open-MySqlConnection.md @@ -35,10 +35,10 @@ MySqlConnector: High Performance .NET MySQL Driver @ https://mysqlconnector.net/ ### Example 1 ```powershell -PS C:\> {{ Add example code here }} +PS C:\> Open-MySqlConnection -server 'localhost' -database 'DBname' -Credential (Get-Credential) ``` -{{ Add example description here }} +Opens a connection to localhost using a credential retrieved from the user. ## PARAMETERS @@ -174,7 +174,7 @@ VerifyFull: Always use SSL. Validates CA and hostname. Type: String Parameter Sets: default Aliases: -Accepted values: Disabled, Preferred, Required, VerifyCA, VerifyFull +Accepted values: None, Preferred, Required, VerifyCA, VerifyFull Required: False Position: Named @@ -190,7 +190,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ### System.String ### System.Int32 -### SimplySql.Common.SslMode ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS diff --git a/Docs/Open-OracleConnection.md b/Docs/Open-OracleConnection.md index 1d726c3..402026e 100644 --- a/Docs/Open-OracleConnection.md +++ b/Docs/Open-OracleConnection.md @@ -145,7 +145,7 @@ Determines the elevated privileges the connection has: SYSDBA, SYSOPER, SYSASM. Type: String Parameter Sets: (All) Aliases: -Accepted values: None, SYSDBA, SYSOPER, SYSASM +Accepted values: None, SYSASM, SYSDBA, SYSOPER Required: False Position: Named @@ -206,7 +206,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ### System.String ### System.Int32 -### SimplySql.Common.ConnectionOracle+OraclePrivilege ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS diff --git a/Docs/Open-PostGreConnection.md b/Docs/Open-PostGreConnection.md index f13a48d..78fbf0a 100644 --- a/Docs/Open-PostGreConnection.md +++ b/Docs/Open-PostGreConnection.md @@ -192,7 +192,7 @@ VerifyFull: Always use SSL. Validates CA and hostname. Type: String Parameter Sets: default Aliases: -Accepted values: Disabled, Preferred, Required, VerifyCA, VerifyFull +Accepted values: Disable, Prefer, Require, VerifyCA, VerifyFull Required: False Position: Named @@ -208,8 +208,6 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ### System.String ### System.Int32 -### SimplySql.Common.SslMode -### System.Management.Automation.SwitchParameter ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS diff --git a/Docs/Set-SqlConnection.md b/Docs/Set-SqlConnection.md index efbf79d..181c8a4 100644 --- a/Docs/Set-SqlConnection.md +++ b/Docs/Set-SqlConnection.md @@ -8,7 +8,7 @@ schema: 2.0.0 # Set-SqlConnection ## SYNOPSIS -{{ Fill in the Synopsis }} +Set options on the SqlConnection. ## SYNTAX @@ -18,7 +18,7 @@ Set-SqlConnection [-ConnectionName ] [[-Database] ] [-CommandTim ``` ## DESCRIPTION -{{ Fill in the Description }} +Set Database and/or Command Timeout for the SqlConnection. Changing the database may not be valid for all providers. ## EXAMPLES @@ -62,7 +62,7 @@ Accept wildcard characters: False ``` ### -Database -{{ Fill Database Description }} +The database to connect to. ```yaml Type: String diff --git a/Docs/Show-SqlConnection.md b/Docs/Show-SqlConnection.md index e9c6c9f..0d208b7 100644 --- a/Docs/Show-SqlConnection.md +++ b/Docs/Show-SqlConnection.md @@ -8,7 +8,7 @@ schema: 2.0.0 # Show-SqlConnection ## SYNOPSIS -{{ Fill in the Synopsis }} +Lists the current SqlConnection. ## SYNTAX @@ -23,7 +23,7 @@ Show-SqlConnection [-All] [] ``` ## DESCRIPTION -{{ Fill in the Description }} +Lists the current SqlConnection information or outputs a list of all SqlConnections currently active. ## EXAMPLES @@ -37,7 +37,7 @@ PS C:\> {{ Add example code here }} ## PARAMETERS ### -All -{{ Fill All Description }} +If present, will return list of all connection names. ```yaml Type: SwitchParameter diff --git a/Docs/SimplySql.md b/Docs/SimplySql.md index c39dc6b..bea73ab 100644 --- a/Docs/SimplySql.md +++ b/Docs/SimplySql.md @@ -57,16 +57,16 @@ Open a connection to a SQL Server. Open a connection to a SQLite database file. ### [Set-SqlConnection](Set-SqlConnection.md) -{{ Fill in the Synopsis }} +Set options on the SqlConnection. ### [Show-SqlConnection](Show-SqlConnection.md) -{{ Fill in the Synopsis }} +Lists the current SqlConnection. ### [Start-SqlTransaction](Start-SqlTransaction.md) -{{ Fill in the Synopsis }} +Start a sql transaction. ### [Test-SqlConnection](Test-SqlConnection.md) -{{ Fill in the Synopsis }} +Tests to see if there is a connection. ### [Undo-SqlTransaction](Undo-SqlTransaction.md) Undo a SQL transaction. diff --git a/Docs/Start-SqlTransaction.md b/Docs/Start-SqlTransaction.md index a11420d..22d5aa1 100644 --- a/Docs/Start-SqlTransaction.md +++ b/Docs/Start-SqlTransaction.md @@ -8,16 +8,16 @@ schema: 2.0.0 # Start-SqlTransaction ## SYNOPSIS -{{ Fill in the Synopsis }} +Start a sql transaction. ## SYNTAX ``` -Start-SqlTransaction [-ConnectionName ] [-WhatIf] [-Confirm] [] +Start-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION -{{ Fill in the Description }} +Start (BEGIN) a sql transaction. ## EXAMPLES @@ -39,7 +39,7 @@ Parameter Sets: (All) Aliases: cn Required: False -Position: Named +Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False diff --git a/Docs/Test-SqlConnection.md b/Docs/Test-SqlConnection.md index 7dc5372..a2ab6a3 100644 --- a/Docs/Test-SqlConnection.md +++ b/Docs/Test-SqlConnection.md @@ -8,7 +8,7 @@ schema: 2.0.0 # Test-SqlConnection ## SYNOPSIS -{{ Fill in the Synopsis }} +Tests to see if there is a connection. ## SYNTAX @@ -23,7 +23,7 @@ Test-SqlConnection [-All] [] ``` ## DESCRIPTION -{{ Fill in the Description }} +Tests to see if there is a connection, use the -All switch to determine if there are any connections. ## EXAMPLES @@ -37,7 +37,7 @@ PS C:\> {{ Add example code here }} ## PARAMETERS ### -All -{{ Fill All Description }} +Returns true if there are any connections, otherwise false. ```yaml Type: SwitchParameter @@ -67,7 +67,7 @@ Accept wildcard characters: False ``` ### -Detailed -{{ Fill Detailed Description }} +If present, will only return return if connection is found and in an Open state. ```yaml Type: SwitchParameter diff --git a/Docs/Undo-SqlTransaction.md b/Docs/Undo-SqlTransaction.md index 4f50425..b5b6beb 100644 --- a/Docs/Undo-SqlTransaction.md +++ b/Docs/Undo-SqlTransaction.md @@ -13,7 +13,7 @@ Undo a SQL transaction. ## SYNTAX ``` -Undo-SqlTransaction [-ConnectionName ] [-WhatIf] [-Confirm] [] +Undo-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION @@ -39,7 +39,7 @@ Parameter Sets: (All) Aliases: cn Required: False -Position: Named +Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False diff --git a/ModuleManifest/SimplySql.psd1 b/ModuleManifest/SimplySql.psd1 index a745222..02cbec1 100644 --- a/ModuleManifest/SimplySql.psd1 +++ b/ModuleManifest/SimplySql.psd1 @@ -3,7 +3,7 @@ # # Generated by: Mithrandyr # -# Generated on: 6/14/2024 +# Generated on: 12/12/2024 # @{ @@ -12,7 +12,7 @@ RootModule = 'SimplySql.Cmdlets.dll' # Version number of this module. -ModuleVersion = '2.0.4.75' +ModuleVersion = '2.1.0.96' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/README.md b/README.md index cd3a70a..ca20ad1 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,21 @@ This module requires PowerShell Version 5.0 or greater ## Database Providers -- Microsoft Sql Server : [Microsoft.Data.SqlClient 5.1.5](https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.1.5) -- MySQL : [MySqlConnector 2.3.7](https://www.nuget.org/packages/MySqlConnector/2.3.7) -- Oracle : [Oracle.ManagedDataAccess.Core 2.19.230](https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/2.19.230) (this is the latest version supporting .NET Standard 2.0) -- SQLite : [System.Data.SQLite.Core 1.0.118](https://www.nuget.org/packages/System.Data.SQLite.Core/1.0.118) -- PostgreSQL : [Npgsql (8.0.3)](https://www.nuget.org/packages/Npgsql/8.0.3) +- Microsoft Sql Server : [Microsoft.Data.SqlClient 5.2.2](https://www.nuget.org/packages/Microsoft.Data.SqlClient/5.2.2) +- MySQL : [MySqlConnector 2.4.0](https://www.nuget.org/packages/MySqlConnector/2.4.0) +- Oracle : [Oracle.ManagedDataAccess.Core 2.19.250](https://www.nuget.org/packages/Oracle.ManagedDataAccess.Core/2.19.250) (this is the latest version supporting .NET Standard 2.0) +- SQLite : [System.Data.SQLite.Core 1.0.119](https://www.nuget.org/packages/System.Data.SQLite.Core/1.0.119) +- PostgreSQL : [Npgsql (8.0.6)](https://www.nuget.org/packages/Npgsql/8.0.6) ## Latest Version +## 2.1.0 +* Updated some packages that had vulnerabilities +* Updated Provider Packages +* Added `-NotifyAction` back in and updated tests to test for this +* Changed how the `/bin/` folder is built, this should create .NET Framework or .NET Core dlls and hopefully fix the MySqlConnector issue with .NET Standard packages. + +## 2.0.4 +* Fixing issue with incorrect query results when querying only some columns of a primary key table ## 2.0.3 * Providers updated. diff --git a/Tests/mssql.tests.ps1 b/Tests/mssql.tests.ps1 index 8dd5518..c9bd541 100644 --- a/Tests/mssql.tests.ps1 +++ b/Tests/mssql.tests.ps1 @@ -1,13 +1,14 @@ -$ErrorActionPreference +$ErrorActionPreference = "Stop" + Describe "MSSQL" { BeforeAll { - $srvName = "xbags\SQLEXPRESS" + $srvName = "$($env:COMPUTERNAME)\SQLEXPRESS" + if($srvName -eq "\SQLEXPRESS") { $srvName = "$($env:NAME)\SQLEXPRESS" } #pscore on non-windows $c = [pscredential]::new("simplysql", (ConvertTo-SecureString -Force -AsPlainText "simplysql")) $connHT = @{ DataSource = $srvName Credential = $c } - Open-SqlConnection @connHT Invoke-SqlUpdate "IF EXISTS (SELECT * FROM sys.databases WHERE name = 'test') DROP DATABASE test; CREATE DATABASE test" | Should -Be -1 Close-SqlConnection @@ -52,13 +53,6 @@ Describe "MSSQL" { Invoke-SqlScalar -Query "SELECT GETDATE()" | Should -BeOfType System.DateTime } - It "Invoke-SqlQuery (No ResultSet Warning)" { - Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" - Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w - Invoke-SqlUpdate -Query "DROP TABLE temp" - $w | Should -BeLike "Query returned no resultset.*" - } - It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query ";WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) @@ -74,53 +68,82 @@ Describe "MSSQL" { FROM tally" | Should -Be 65536 } - It "Invoke-SqlQuery" { - Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" | - Measure-Object | - Select-Object -ExpandProperty Count | - Should -Be 1000 - } + Context "Invoke-SqlQuery" { + It "No ResultSet Warning" { + Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" + Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w + Invoke-SqlUpdate -Query "DROP TABLE temp" + $w | Should -BeLike "Query returned no resultset.*" + } + + It "Normal" { + Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" | + Measure-Object | + Select-Object -ExpandProperty Count | + Should -Be 1000 + } - It "Invoke-SqlQuery (with Primary Key)" { - Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null + It "With Primary Key" { + Invoke-SqlUpdate -Query "CREATE TABLE #tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO #tmpPK SELECT 'A', 1" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO #tmpPK SELECT 'A', 2" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO #tmpPK SELECT 'B', 3" | Out-Null - Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | + Invoke-SqlQuery -Query "SELECT col1 FROM #tmpPK" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 3 - } + } - It "Invoke-SqlQuery (multiple columns of same name)" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery (multiple columns of same name) -stream" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name with -stream" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery -stream" { - Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" -Stream | - Measure-Object | - Select-Object -ExpandProperty Count | - Should -Be 1000 + It "With -stream" { + Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" -Stream | + Measure-Object | + Select-Object -ExpandProperty Count | + Should -Be 1000 + } } + Context "Invoke-SqlBulkCopy" { + It "Normal" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable2 FROM tmpTable WHERE 1=2" + Open-SqlConnection @connHT -ConnectionName bcp + Set-SqlConnection -Database test -ConnectionName bcp + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 | + Should -Be 65536 + } - It "Invoke-SqlBulkCopy" { - Invoke-SqlUpdate -Query "SELECT * INTO tmpTable2 FROM tmpTable WHERE 1=2" - Open-SqlConnection @connHT -ConnectionName bcp - Set-SqlConnection -Database test -ConnectionName bcp + It "With -Notify" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable20 FROM tmpTable WHERE 1=2" + Open-SqlConnection @connHT -ConnectionName bcp + Set-SqlConnection -Database test -ConnectionName bcp + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -Notify | + Should -Be 65536 + } + + It "With -NotifyAction" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable10 FROM tmpTable WHERE 1=2" + Open-SqlConnection @connHT -ConnectionName bcp + Set-SqlConnection -Database test -ConnectionName bcp - Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -Notify | - Should -Be 65536 + $result = @{val = 0 } + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -NotifyAction { param($rows) $result.val = $rows } + $result.val | Should -Be 65536 + } } Context "Transaction..." { @@ -183,7 +206,7 @@ Describe "MSSQL" { Context "Validations..." { It "Handles JSON as PSObject" { - Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress)} | Should -Be "[1,2,3,4,5]" + Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress) } | Should -Be "[1,2,3,4,5]" } } } \ No newline at end of file diff --git a/Tests/mysql.tests.ps1 b/Tests/mysql.tests.ps1 index 3490f2a..9018664 100644 --- a/Tests/mysql.tests.ps1 +++ b/Tests/mysql.tests.ps1 @@ -1,6 +1,8 @@ +$ErrorActionPreference = "Stop" Describe "MySql" { BeforeAll { - $srvName = "xbags" + $srvName = $env:COMPUTERNAME + if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = $env:NAME } #pscore on non-windows $u = "root" $p = "root" $db = "mysql" @@ -29,6 +31,8 @@ Describe "MySql" { Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest; DROP TABLE IF EXISTS $db.tmpTable; DROP TABLE IF EXISTS $db.tmpTable2; + DROP TABLE IF EXISTS $db.tmpTable20; + DROP TABLE IF EXISTS $db.tmpTable21; DROP TABLE IF EXISTS $db.tmpTable3; DROP TABLE IF EXISTS $db.tmpPK; DROP VIEW IF EXISTS $db.generator_64k; @@ -57,26 +61,27 @@ Describe "MySql" { Invoke-SqlScalar -Query "SELECT Now()" | Should -BeOfType System.DateTime } - It "Invoke-SqlQuery (No ResultSet Warning)" { - Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" - Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w - Invoke-SqlUpdate -Query "DROP TABLE temp" - $w | Should -BeLike "Query returned no resultset.*" - } - It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query " - CREATE TABLE $db.tmpTable (colDec REAL, colInt Int, colText varchar(36)); - INSERT INTO $db.tmpTable - SELECT rand() AS colDec - , CAST(rand() * 1000000000 AS SIGNED) AS colInt - , uuid() AS colText - FROM $db.generator_64k" | Should -Be 65536 - + CREATE TABLE $db.tmpTable (colDec REAL, colInt Int, colText varchar(36)); + INSERT INTO $db.tmpTable + SELECT rand() AS colDec + , CAST(rand() * 1000000000 AS SIGNED) AS colInt + , uuid() AS colText + FROM $db.generator_64k" | Should -Be 65536 + } - It "Invoke-SqlQuery" { - Invoke-SqlQuery -Query " + Context "Invoke-SqlQuery" { + It "No ResultSet Warning" { + Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" + Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w + Invoke-SqlUpdate -Query "DROP TABLE temp" + $w | Should -BeLike "Query returned no resultset.*" + } + + It "Normal" { + Invoke-SqlQuery -Query " SELECT rand() AS colDec , CAST(rand() * 1000000000 AS SIGNED) AS colInt , uuid() AS colText @@ -85,36 +90,36 @@ Describe "MySql" { Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 - } + } - It "Invoke-SqlQuery (with Primary Key)" { - Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null + It "With Primary Key" { + Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null - Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | + Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 3 - } + } - It "Invoke-SqlQuery (multiple columns of same name)" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery (multiple columns of same name) -stream" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name With -stream" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery -stream" { - Invoke-SqlQuery -Query " + It "With -stream" { + Invoke-SqlQuery -Query " SELECT rand() AS colDec , CAST(rand() * 1000000000 AS SIGNED) AS colInt , uuid() AS colText @@ -123,19 +128,49 @@ Describe "MySql" { Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 + } } - It "Invoke-SqlBulkCopy" { - $query = "SELECT rand() AS colDec + Context "Invoke-SqlBulkCopy" { + It "Normal" { + $query = "SELECT rand() AS colDec , CAST(rand() * 1000000000 AS SIGNED) AS colInt , uuid() AS colText FROM $db.generator_64k" - Open-MySqlConnection -ConnectionName bcp -Server $srvName -Database mysql -Credential $c - Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE $db.tmpTable2 (colDec REAL, colInt INTEGER, colText TEXT)" + Open-MySqlConnection -ConnectionName bcp -Server $srvName -Database mysql -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE $db.tmpTable2 (colDec REAL, colInt INTEGER, colText TEXT)" - Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable2" -Notify | + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable2" | Should -Be 65536 + } + + It "With -Notify" { + $query = "SELECT rand() AS colDec + , CAST(rand() * 1000000000 AS SIGNED) AS colInt + , uuid() AS colText + FROM $db.generator_64k" + + Open-MySqlConnection -ConnectionName bcp -Server $srvName -Database mysql -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE $db.tmpTable20 (colDec REAL, colInt INTEGER, colText TEXT)" + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable20" -Notify | + Should -Be 65536 + } + + It "With -NotifyAction" { + $query = "SELECT rand() AS colDec + , CAST(rand() * 1000000000 AS SIGNED) AS colInt + , uuid() AS colText + FROM $db.generator_64k" + + Open-MySqlConnection -ConnectionName bcp -Server $srvName -Database mysql -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE $db.tmpTable21 (colDec REAL, colInt INTEGER, colText TEXT)" + + $result = @{val = 0 } + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable21" -NotifyAction { param($rows) $result.val = $rows } + $result.val | Should -Be 65536 + } } Context "Transaction..." { @@ -165,14 +200,14 @@ Describe "MySql" { It "Invoke-SqlQuery" { Start-SqlTransaction - { Invoke-SqlScalar "SELECT 1" -ea Stop} | Should -Not -Throw + { Invoke-SqlScalar "SELECT 1" -ea Stop } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlUpdate" { Invoke-SqlUpdate "CREATE TABLE transactionTest (id int)" Start-SqlTransaction - { Invoke-SqlUpdate "INSERT INTO transactionTest VALUES (1)" -ea Stop} | Should -Not -Throw + { Invoke-SqlUpdate "INSERT INTO transactionTest VALUES (1)" -ea Stop } | Should -Not -Throw Undo-SqlTransaction Invoke-SqlScalar "SELECT Count(1) FROM transactionTest" | Should -Be 0 Invoke-SqlUpdate "DROP TABLE transactionTest" @@ -182,14 +217,14 @@ Describe "MySql" { Context "PipelineInput..." { It "Invoke-SqlScalar" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlScalar "SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlScalar "SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } It "Invoke-SqlQuery" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } @@ -197,7 +232,7 @@ Describe "MySql" { It "Invoke-SqlScalar" { { Invoke-SqlUpdate "CREATE TABLE t(x varchar(255))" -ErrorAction Stop - [PSCustomObject]@{Name="test"} | Invoke-SqlUpdate "INSERT INTO t SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlUpdate "INSERT INTO t SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw @@ -206,7 +241,7 @@ Describe "MySql" { Context "Validations..." { It "Handles JSON as PSObject" { - Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress)} | Should -Be "[1,2,3,4,5]" + Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress) } | Should -Be "[1,2,3,4,5]" } } } diff --git a/Tests/oracle.tests.ps1 b/Tests/oracle.tests.ps1 index d9c4f75..d94f99e 100644 --- a/Tests/oracle.tests.ps1 +++ b/Tests/oracle.tests.ps1 @@ -1,6 +1,8 @@ +$ErrorActionPreference = "Stop" Describe "Oracle" { BeforeAll { - $srvName = "xbags" + $srvName = $env:COMPUTERNAME + if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = $env:NAME } #pscore on non-windows $u = "hr" $p = "hr" $c = [pscredential]::new($u, (ConvertTo-SecureString -Force -AsPlainText $p)) @@ -9,7 +11,7 @@ Describe "Oracle" { AfterEach { Show-SqlConnection -all | Close-SqlConnection } AfterAll { Open-OracleConnection -DataSource $srvName -ServiceName xe -Credential $c - foreach($tbl in @("transactionTest", "tmpTable", "tmpTable2","t", "tmpPK")) { + foreach ($tbl in @("transactionTest", "tmpTable", "tmpTable2", "t", "tmpPK")) { $query = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE $tbl'; EXCEPTION @@ -43,19 +45,12 @@ Describe "Oracle" { } It "Positional Binding" { - $result = Invoke-SqlQuery "SELECT :a AS First, :b AS Second, :c AS Third FROM dual" -Parameters @{c="Third";a="First";b="Second"} + $result = Invoke-SqlQuery "SELECT :a AS First, :b AS Second, :c AS Third FROM dual" -Parameters @{c = "Third"; a = "First"; b = "Second" } $result.First | Should -Be "First" $result.Second | Should -Be "Second" $result.Third | Should -Be "Third" } - It "Invoke-SqlQuery (No ResultSet Warning)" { - Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" - Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w - Invoke-SqlUpdate -Query "DROP TABLE temp" - $w | Should -BeLike "Query returned no resultset.*" - } - It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query "CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText varchar(20))" Invoke-SqlUpdate -Query "INSERT INTO tmpTable @@ -68,8 +63,16 @@ Describe "Oracle" { Invoke-SqlUpdate -Query "DROP TABLE tmpTable" } - It "Invoke-SqlQuery" { - Invoke-SqlQuery -Query "SELECT dbms_random.random /1000000000000. AS colDec + Context "Invoke-SqlQuery" { + It "No ResultSet Warning" { + Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" + Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w + Invoke-SqlUpdate -Query "DROP TABLE temp" + $w | Should -BeLike "Query returned no resultset.*" + } + + It "Normal" { + Invoke-SqlQuery -Query "SELECT dbms_random.random /1000000000000. AS colDec , dbms_random.random AS colInt , dbms_random.string('x',20) AS colText FROM dual @@ -77,36 +80,36 @@ Describe "Oracle" { Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 - } + } - It "Invoke-SqlQuery (with Primary Key)" { - Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2))" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1 FROM dual" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2 FROM dual" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3 FROM dual" | Out-Null + It "With Primary Key" { + Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2))" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1 FROM dual" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2 FROM dual" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3 FROM dual" | Out-Null - Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | + Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 3 - } + } - It "Invoke-SqlQuery (multiple columns of same name)" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual" - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual" + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery (multiple columns of same name) -stream" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual" -Stream - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name With -stream" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a FROM dual" -Stream + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery -stream" { - Invoke-SqlQuery -Stream -Query "SELECT dbms_random.random /1000000000000. AS colDec + It "With -stream" { + Invoke-SqlQuery -Stream -Query "SELECT dbms_random.random /1000000000000. AS colDec , dbms_random.random AS colInt , dbms_random.string('x',20) AS colText FROM dual @@ -114,22 +117,57 @@ Describe "Oracle" { Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 + } } - It "Invoke-SqlBulkCopy" -Tag bulkcopy { - $query = "SELECT dbms_random.random /1000000000000. AS colDec + Context "Invoke-SqlBulkCopy" { + It "Normal" -Tag bulkcopy { + $query = "SELECT dbms_random.random /1000000000000. AS colDec , dbms_random.random AS colInt , dbms_random.string('x',20) AS colText FROM dual CONNECT BY ROWNUM <= 65536" - Open-OracleConnection -ConnectionName bcp -DataSource $srvName -ServiceName xe -Credential $c - Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable2 (colDec NUMBER(38,10), colInt INTEGER, colText varchar(20))" + Open-OracleConnection -ConnectionName bcp -DataSource $srvName -ServiceName xe -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable2 (colDec NUMBER(38,10), colInt INTEGER, colText varchar(20))" - Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -Notify | + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 | Should -Be 65536 - Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" + Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" + } + + It "With -Notify" -Tag bulkcopy { + $query = "SELECT dbms_random.random /1000000000000. AS colDec + , dbms_random.random AS colInt + , dbms_random.string('x',20) AS colText + FROM dual + CONNECT BY ROWNUM <= 65536" + + Open-OracleConnection -ConnectionName bcp -DataSource $srvName -ServiceName xe -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable2 (colDec NUMBER(38,10), colInt INTEGER, colText varchar(20))" + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -Notify | + Should -Be 65536 + + Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" + } + + It "With -NotifyAction" -Tag bulkcopy { + $query = "SELECT dbms_random.random /1000000000000. AS colDec + , dbms_random.random AS colInt + , dbms_random.string('x',20) AS colText + FROM dual + CONNECT BY ROWNUM <= 65536" + + Open-OracleConnection -ConnectionName bcp -DataSource $srvName -ServiceName xe -Credential $c + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable2 (colDec NUMBER(38,10), colInt INTEGER, colText varchar(20))" + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -Notify | + Should -Be 65536 + + Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" + } } Context "Transaction..." { @@ -145,7 +183,7 @@ Describe "Oracle" { Start-SqlTransaction -ConnectionName bcp Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -Notify | - Should -Be 65536 + Should -Be 65536 Invoke-SqlScalar -ConnectionName bcp -Query "SELECT COUNT(1) FROM tmpTable2" | Should -Be 65536 Undo-SqlTransaction -ConnectionName bcp Invoke-SqlScalar -ConnectionName bcp -Query "SELECT COUNT(1) FROM tmpTable2" | Should -Be 0 @@ -154,13 +192,13 @@ Describe "Oracle" { It "Invoke-SqlScalar" { Start-SqlTransaction - { Invoke-SqlScalar "SELECT 1 FROM dual" -ea Stop} | Should -Not -Throw + { Invoke-SqlScalar "SELECT 1 FROM dual" -ea Stop } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlQuery" { Start-SqlTransaction - { Invoke-SqlScalar "SELECT 1 FROM dual" -ea Stop} | Should -Not -Throw + { Invoke-SqlScalar "SELECT 1 FROM dual" -ea Stop } | Should -Not -Throw Undo-SqlTransaction } @@ -177,14 +215,14 @@ Describe "Oracle" { Context "PipelineInput..." { It "Invoke-SqlScalar" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlScalar "SELECT :Name FROM dual" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlScalar "SELECT :Name FROM dual" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "SELECT :Name FROM dual" -ErrorAction Stop } | Should -Not -Throw } It "Invoke-SqlQuery" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlQuery "SELECT :Name FROM dual" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlQuery "SELECT :Name FROM dual" -ErrorAction Stop Get-ChildItem | Invoke-SqlQuery "SELECT :Name FROM dual" -ErrorAction Stop } | Should -Not -Throw } @@ -192,7 +230,7 @@ Describe "Oracle" { It "Invoke-SqlScalar" { { Invoke-SqlUpdate "CREATE TABLE t(x varchar(255))" -ErrorAction Stop - [PSCustomObject]@{Name="test"} | Invoke-SqlUpdate "INSERT INTO t SELECT :Name FROM dual" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlUpdate "INSERT INTO t SELECT :Name FROM dual" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT :Name FROM dual"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw @@ -201,7 +239,7 @@ Describe "Oracle" { Context "Validations..." { It "Handles JSON as PSObject" { - Invoke-SqlScalar "SELECT :json FROM dual" -Parameters @{json = (1..5 | ConvertTo-Json -Compress)} | Should -Be "[1,2,3,4,5]" + Invoke-SqlScalar "SELECT :json FROM dual" -Parameters @{json = (1..5 | ConvertTo-Json -Compress) } | Should -Be "[1,2,3,4,5]" } } } diff --git a/Tests/postgre.tests.ps1 b/Tests/postgre.tests.ps1 index 205424c..bf3048e 100644 --- a/Tests/postgre.tests.ps1 +++ b/Tests/postgre.tests.ps1 @@ -1,9 +1,11 @@ +$ErrorActionPreference = "Stop" Describe "PostGre" { BeforeEach { Open-PostGreConnection -Server $srvName -Database $db -Credential $c } AfterEach { Show-SqlConnection -all | Close-SqlConnection } - BeforeAll{ + BeforeAll { #warm up connection - $srvName = "xbags" + $srvName = $env:COMPUTERNAME #pscore on non-windows + if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = $env:NAME } $u = "postgres" $p = "postgres" $db = "postgres" @@ -13,7 +15,7 @@ Describe "PostGre" { } AfterAll { Open-PostGreConnection -Server $srvName -Database $db -Credential $c - Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, t, tmpPK;" + Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, tmpTable21, tmpTable22, t, tmpPK;" Close-SqlConnection } @@ -35,13 +37,6 @@ Describe "PostGre" { Invoke-SqlScalar -Query "SELECT Now()" | Should -BeOfType System.DateTime } - It "Invoke-SqlQuery (No ResultSet Warning)" { - Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" - Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w - Invoke-SqlUpdate -Query "DROP TABLE temp" - $w | Should -BeLike "Query returned no resultset.*" - } - It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query "CREATE TABLE tmpTable (colDec decimal, colInt Int, colText varchar(50))" Invoke-SqlUpdate -Query ";WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) @@ -57,53 +52,81 @@ Describe "PostGre" { , CAST(Random() AS VARCHAR(50)) AS colText FROM tally" | Should -Be 65536 } - - It "Invoke-SqlQuery" { - Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" | + Context "Invoke-SqlQuery" { + It "No ResultSet Warning" { + Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" + Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w + Invoke-SqlUpdate -Query "DROP TABLE temp" + $w | Should -BeLike "Query returned no resultset.*" + } + It "Normal" { + Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 - } + } - It "Invoke-SqlQuery (with Primary Key)" { - Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null + It "With Primary Key" { + Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null - Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | + Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 3 - } + } - It "Invoke-SqlQuery (multiple columns of same name)" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery (multiple columns of same name) -stream" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name With -stream" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery -stream" { - Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" -Stream | + It "With -stream" { + Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" -Stream | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 + } } - - It "Invoke-SqlBulkCopy" { - Invoke-SqlUpdate -Query "SELECT * INTO tmpTable2 FROM tmpTable WHERE 1=2" - Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c - Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -Notify | + + Context "Invoke-SqlBulkCopy" { + It "Normal" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable2 FROM tmpTable WHERE 1=2" + Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 | + Should -Be 65536 + Close-SqlConnection -ConnectionName bcp + } + + It "With -Notify" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable21 FROM tmpTable WHERE 1=2" + Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable21 -Notify | Should -Be 65536 - Close-SqlConnection -ConnectionName bcp + Close-SqlConnection -ConnectionName bcp + } + + It "With -NotifyAction" { + Invoke-SqlUpdate -Query "SELECT * INTO tmpTable22 FROM tmpTable WHERE 1=2" + Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c + + $result = @{val = 0 } + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable22 -NotifyAction { param($rows) $result.val = $rows } + $result.val | Should -Be 65536 + + Close-SqlConnection -ConnectionName bcp + } } Context "Transaction..." { @@ -113,27 +136,27 @@ Describe "PostGre" { Start-SqlTransaction -ConnectionName bcp Invoke-SqlUpdate -Query "SELECT * INTO tmpTable3 FROM tmpTable WHERE 1=2" -ConnectionName bcp { Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable3 -Notify | - Should -Be 65536} | Should -Not -Throw + Should -Be 65536 } | Should -Not -Throw Undo-SqlTransaction -ConnectionName bcp - { Invoke-SqlScalar -ConnectionName bcp -Query "SELECT COUNT(1) FROM tmpTable3" -ea Stop} | Should -Throw + { Invoke-SqlScalar -ConnectionName bcp -Query "SELECT COUNT(1) FROM tmpTable3" -ea Stop } | Should -Throw } It "Invoke-SqlScalar" { Start-SqlTransaction - { Invoke-SqlScalar "SELECT 1" -ea Stop} | Should -Not -Throw + { Invoke-SqlScalar "SELECT 1" -ea Stop } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlQuery" { Start-SqlTransaction - { Invoke-SqlScalar "SELECT 1" -ea Stop} | Should -Not -Throw + { Invoke-SqlScalar "SELECT 1" -ea Stop } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlUpdate" { Start-SqlTransaction - { Invoke-SqlUpdate "CREATE TABLE transactionTest (id int)" -ea Stop} | Should -Not -Throw + { Invoke-SqlUpdate "CREATE TABLE transactionTest (id int)" -ea Stop } | Should -Not -Throw Undo-SqlTransaction { Invoke-SqlScalar "SELECT 1 FROM transactionTest" -ea Stop } | Should -Throw } @@ -142,14 +165,14 @@ Describe "PostGre" { Context "PipelineInput..." { It "Invoke-SqlScalar" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlScalar "SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlScalar "SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "SELECT @Name " -ErrorAction Stop } | Should -Not -Throw } It "Invoke-SqlQuery" { { - [PSCustomObject]@{Name="test"} | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } @@ -157,7 +180,7 @@ Describe "PostGre" { It "Invoke-SqlScalar" { { Invoke-SqlUpdate "CREATE TABLE t(x varchar(255))" -ErrorAction Stop - [PSCustomObject]@{Name="test"} | Invoke-SqlUpdate "INSERT INTO t SELECT @Name" -ErrorAction Stop + [PSCustomObject]@{Name = "test" } | Invoke-SqlUpdate "INSERT INTO t SELECT @Name" -ErrorAction Stop Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw @@ -166,7 +189,7 @@ Describe "PostGre" { Context "Validations..." { It "Handles JSON as PSObject" { - Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress)} | Should -Be "[1,2,3,4,5]" + Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress) } | Should -Be "[1,2,3,4,5]" } } } \ No newline at end of file diff --git a/Tests/sqlite.tests.ps1 b/Tests/sqlite.tests.ps1 index ba1dc0a..1aa3bae 100644 --- a/Tests/sqlite.tests.ps1 +++ b/Tests/sqlite.tests.ps1 @@ -1,3 +1,4 @@ +$ErrorActionPreference = "Stop" Describe "SQLite" { BeforeEach { Open-SQLiteConnection } AfterEach { Show-SqlConnection -all | Close-SqlConnection } @@ -16,13 +17,6 @@ Describe "SQLite" { Invoke-SqlScalar -Query "SELECT 1" | Should -BeOfType System.Int64 } - It "Invoke-SqlQuery (No ResultSet Warning)" { - Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" - Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w - Invoke-SqlUpdate -Query "DROP TABLE temp" - $w | Should -BeLike "Query returned no resultset.*" - } - It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query " CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText TEXT) @@ -40,9 +34,16 @@ Describe "SQLite" { Invoke-SqlUpdate -Query "DROP TABLE tmpTable" | Out-Null } - - It "Invoke-SqlQuery" { - Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) + + Context "Invoke-SqlQuery" { + It "No ResultSet Warning" { + Invoke-SqlUpdate -Query "CREATE TABLE temp (cola int)" + Invoke-SqlQuery -Query "INSERT INTO temp VALUES (1)" -WarningAction SilentlyContinue -WarningVariable w + Invoke-SqlUpdate -Query "DROP TABLE temp" + $w | Should -BeLike "Query returned no resultset.*" + } + It "Normal" { + Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) , c(n) AS (SELECT 1 FROM b CROSS JOIN b AS x) , d(n) AS (SELECT 1 FROM c CROSS JOIN c AS x) @@ -53,39 +54,39 @@ Describe "SQLite" { , hex(randomblob(20)) AS colText FROM f LIMIT 1000" | - Measure-Object | - Select-Object -ExpandProperty Count | - Should -Be 1000 - } + Measure-Object | + Select-Object -ExpandProperty Count | + Should -Be 1000 + } - It "Invoke-SqlQuery (with Primary Key)" { - Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null - Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null + It "With Primary Key" { + Invoke-SqlUpdate -Query "CREATE TABLE tmpPK (col1 varchar(25), col2 int, PRIMARY KEY (col1, col2));" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 1" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'A', 2" | Out-Null + Invoke-SqlUpdate -Query "INSERT INTO tmpPK SELECT 'B', 3" | Out-Null - Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | + Invoke-SqlQuery -Query "SELECT col1 FROM tmpPK" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 3 - } + } - It "Invoke-SqlQuery (multiple columns of same name)" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery (multiple columns of same name) -stream" { - $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream - $val.a | Should -Be 1 - $val.a1 | Should -Be 2 - $val.a2 | Should -Be 3 - } + It "Multiple columns of same name With -stream" { + $val = Invoke-SqlQuery "SELECT 1 AS a, 2 AS a, 3 AS a" -Stream + $val.a | Should -Be 1 + $val.a1 | Should -Be 2 + $val.a2 | Should -Be 3 + } - It "Invoke-SqlQuery -stream" { - Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) + It "With -stream" { + Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) , c(n) AS (SELECT 1 FROM b CROSS JOIN b AS x) , d(n) AS (SELECT 1 FROM c CROSS JOIN c AS x) @@ -96,13 +97,56 @@ Describe "SQLite" { , hex(randomblob(20)) AS colText FROM f LIMIT 1000" -Stream | - Measure-Object | - Select-Object -ExpandProperty Count | - Should -Be 1000 + Measure-Object | + Select-Object -ExpandProperty Count | + Should -Be 1000 + } } + Context "Invoke-SqlBulkCopy" { + It "Normal" { + $query = "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) + , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) + , c(n) AS (SELECT 1 FROM b CROSS JOIN b AS x) + , d(n) AS (SELECT 1 FROM c CROSS JOIN c AS x) + , e(n) AS (SELECT 1 FROM d CROSS JOIN d AS x) + , f(n) AS (SELECT 1 FROM d CROSS JOIN d AS x) + SELECT random()/1000000000000. AS colDec + , random() AS colInt + , hex(randomblob(20)) AS colText + FROM f" + + Open-SQLiteConnection -ConnectionName bcp -DataSource "$home\temp.db" + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText TEXT)" + + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable | + Should -Be 65536 + + Close-SqlConnection -ConnectionName bcp + } + + It "With -Notify" { + $query = "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) + , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) + , c(n) AS (SELECT 1 FROM b CROSS JOIN b AS x) + , d(n) AS (SELECT 1 FROM c CROSS JOIN c AS x) + , e(n) AS (SELECT 1 FROM d CROSS JOIN d AS x) + , f(n) AS (SELECT 1 FROM d CROSS JOIN d AS x) + SELECT random()/1000000000000. AS colDec + , random() AS colInt + , hex(randomblob(20)) AS colText + FROM f" + + Open-SQLiteConnection -ConnectionName bcp -DataSource "$home\temp.db" + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable21 (colDec REAL, colInt INTEGER, colText TEXT)" - It "Invoke-SqlBulkCopy" { - $query = "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable21 -Notify | + Should -Be 65536 + + Close-SqlConnection -ConnectionName bcp + } + + It "With -NotifyAction" { + $query = "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) , b(n) AS (SELECT 1 FROM a CROSS JOIN a AS x) , c(n) AS (SELECT 1 FROM b CROSS JOIN b AS x) , d(n) AS (SELECT 1 FROM c CROSS JOIN c AS x) @@ -113,13 +157,15 @@ Describe "SQLite" { , hex(randomblob(20)) AS colText FROM f" - Open-SQLiteConnection -ConnectionName bcp -DataSource "$home\temp.db" - Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText TEXT)" + Open-SQLiteConnection -ConnectionName bcp -DataSource "$home\temp.db" + Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable22 (colDec REAL, colInt INTEGER, colText TEXT)" - Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable -Notify | - Should -Be 65536 + $result = @{val = 0 } + Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable22 -NotifyAction { param($rows) $result.val = $rows } + $result.val | Should -Be 65536 - Close-SqlConnection -ConnectionName bcp + Close-SqlConnection -ConnectionName bcp + } } Context "PipelineInput..." { @@ -194,7 +240,7 @@ Describe "SQLite" { Context "Validations..." { It "Handles JSON as PSObject" { - Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress)} | Should -Be "[1,2,3,4,5]" + Invoke-SqlScalar "SELECT @json" -Parameters @{json = (1..5 | ConvertTo-Json -Compress) } | Should -Be "[1,2,3,4,5]" } } } \ No newline at end of file diff --git a/runTests.ps1 b/runTests.ps1 index 2a6669d..04c66b2 100644 --- a/runTests.ps1 +++ b/runTests.ps1 @@ -1,6 +1,6 @@ param( [ValidateSet("pwsh","powershell")][string]$env = "pwsh" - , [ValidateSet("mssql","mysql","postgre","oracle","sqlite")][string[]]$Tests + , [ValidateSet("mssql","mysql","postgre","oracle","sqlite")][string[]]$Tests = @("mssql","mysql","postgre","oracle","sqlite") , [switch]$Interactive ) diff --git a/source/SimplySql.Cmdlets/Cmdlets/InvokeSqlBulkCopy.vb b/source/SimplySql.Cmdlets/Cmdlets/InvokeSqlBulkCopy.vb index e534855..8181ddf 100644 --- a/source/SimplySql.Cmdlets/Cmdlets/InvokeSqlBulkCopy.vb +++ b/source/SimplySql.Cmdlets/Cmdlets/InvokeSqlBulkCopy.vb @@ -1,4 +1,4 @@ - + Public Class InvokeSqlBulkCopy Inherits PSCmdlet #Region "Parameters" @@ -39,6 +39,8 @@ Public Class InvokeSqlBulkCopy Public Property Notify As SwitchParameter + + Public Property NotifyAction As Action(Of Long) #End Region Protected Overrides Sub EndProcessing() @@ -62,8 +64,10 @@ Public Class InvokeSqlBulkCopy Try Dim srcReader = Engine.GetConnection(SourceConnectionName).GetDataReader(singleQuery, SourceParameters) - Dim notifyAction As Action(Of Long) = Nothing - If Notify Then notifyAction = Sub(x) WriteProgress(New ProgressRecord(0, "SimplySql BulkCopy", DestinationTable) With {.CurrentOperation = $"Insert {x} rows."}) + + If NotifyAction Is Nothing AndAlso Notify.IsPresent Then + NotifyAction = Sub(x) WriteProgress(New ProgressRecord(0, "SimplySql BulkCopy", DestinationTable) With {.CurrentOperation = $"Insert {x} rows."}) + End If WriteObject(Engine.GetConnection(DestinationConnectionName).BulkLoad(srcReader, DestinationTable, ColumnMap, BatchSize, BatchTimeout, notifyAction)) Catch ex As Exception ErrorOperationFailed(ex, DestinationConnectionName) diff --git a/source/SimplySql.Cmdlets/ContextHandling.vb b/source/SimplySql.Cmdlets/ContextHandling.vb index 866b0e3..5e530ea 100644 --- a/source/SimplySql.Cmdlets/ContextHandling.vb +++ b/source/SimplySql.Cmdlets/ContextHandling.vb @@ -8,7 +8,8 @@ Public Class ContextHandling AppPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) BinPath = Path.Combine(AppPath, "bin") AssemblyList = Directory.EnumerateFiles(BinPath, "*.dll").Select(Function(file) IO.Path.GetFileNameWithoutExtension(file).ToLower).ToList - PlatformAssemblyList = Directory.GetDirectories(BinPath).SelectMany(Function(dir) Directory.EnumerateFiles(dir)).Select(Function(file) IO.Path.GetFileNameWithoutExtension(file).ToLower).Distinct.ToList + FrameworkList = Directory.EnumerateFiles(Path.Combine(BinPath, "PS5"), "*.dll").Select(Function(file) IO.Path.GetFileNameWithoutExtension(file).ToLower).ToList + CoreList = Directory.EnumerateFiles(Path.Combine(BinPath, "PS7"), "*.dll").Select(Function(file) IO.Path.GetFileNameWithoutExtension(file).ToLower).ToList End Sub Public Sub OnImport() Implements IModuleAssemblyInitializer.OnImport @@ -22,43 +23,69 @@ Public Class ContextHandling Private Shared ReadOnly AppPath As String Private Shared ReadOnly BinPath As String Private Shared ReadOnly AssemblyList As IReadOnlyList(Of String) + Private Shared ReadOnly FrameworkList As IReadOnlyList(Of String) + Private Shared ReadOnly CoreList As IReadOnlyList(Of String) Private Shared ReadOnly PlatformAssemblyList As IReadOnlyList(Of String) Private Shared IsEngineLoaded As Boolean = False Private Shared Function HandleResolveEvent(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly Dim asmName = New AssemblyName(args.Name) - Dim asmPath As String = String.Empty #If DEBUG Then Console.WriteLine($"{Environment.NewLine}ASSEMBLY LOAD: '{asmName}' BECAUSE '{args.RequestingAssembly}'{Environment.NewLine}") #End If If asmName.Name.Equals("SimplySql.Engine", StringComparison.OrdinalIgnoreCase) Then - IsEngineLoaded = True - Return Assembly.LoadFile(Path.Combine(BinPath, "SimplySql.Engine.dll")) + Dim asmPath = FindFile(asmName.Name) + If asmPath IsNot Nothing Then + IsEngineLoaded = True + Return Assembly.LoadFile(asmPath) + Else + Throw New FileLoadException("Cannot find 'SimplySql.Engine'", asmPath) + End If End If If IsEngineLoaded Then - If AssemblyList.Contains(asmName.Name.ToLower) Then - asmPath = Path.Combine(BinPath, $"{asmName.Name}.dll") - ElseIf PlatformAssemblyList.Contains(asmName.Name.ToLower) Then - If RuntimeInformation.IsOSPlatform(OSPlatform.OSX) Then - asmPath = Path.Combine(BinPath, "osx-x64", $"{asmName.Name}.dll") - ElseIf RuntimeInformation.IsOSPlatform(OSPlatform.Linux) Then - asmPath = Path.Combine(BinPath, "linux-x64", $"{asmName.Name}.dll") + Dim asmPath = FindFile(asmName.Name) + If asmPath IsNot Nothing Then Return Assembly.LoadFile(asmPath) + End If + + Return Nothing + End Function + + Private Shared Function FindFile(asmName As String) As String + If AssemblyList.Contains(asmName.ToLower) Then + Return Path.Combine(BinPath, $"{asmName}.dll") + Else + If Environment.Version.Major = 4 Then 'PS 5.1 + If FrameworkList.Contains(asmName.ToLower) Then + Return Path.Combine(BinPath, "PS5", $"{asmName}.dll") Else If Environment.Is64BitProcess Then - asmPath = Path.Combine(BinPath, $"win-x64\{asmName.Name}.dll") + Dim filePath = Path.Combine(BinPath, "PS5", "win-x64", $"{asmName}.dll") + If IO.File.Exists(filePath) Then Return filePath Else - asmPath = Path.Combine(BinPath, $"win-x86\{asmName.Name}.dll") + Dim filePath = Path.Combine(BinPath, "PS5", "win-x86", $"{asmName}.dll") + If IO.File.Exists(filePath) Then Return filePath + End If + End If + Else 'PS 6+ + If CoreList.Contains(asmName.ToLower) Then + Return Path.Combine(BinPath, "PS7", $"{asmName}.dll") + Else + If RuntimeInformation.IsOSPlatform(OSPlatform.Linux) Then + Dim filePath = Path.Combine(BinPath, "PS7", "linux-x64", $"{asmName}.dll") + If IO.File.Exists(filePath) Then Return filePath + ElseIf RuntimeInformation.IsOSPlatform(OSPlatform.OSX) Then + Dim filePath = Path.Combine(BinPath, "PS7", "osx-x64", $"{asmName}.dll") + If IO.File.Exists(filePath) Then Return filePath + Else + Dim filePath = Path.Combine(BinPath, "PS7", "win-x64", $"{asmName}.dll") + If IO.File.Exists(filePath) Then Return filePath End If End If - End If - If Not String.IsNullOrWhiteSpace(asmPath) Then - Return Assembly.LoadFile(asmPath) End If End If - Return Nothing End Function End Class \ No newline at end of file diff --git a/source/SimplySql.Cmdlets/ProviderCmdlets/OpenMySqlConnection.vb b/source/SimplySql.Cmdlets/ProviderCmdlets/OpenMySqlConnection.vb index 387f9cf..68174f0 100644 --- a/source/SimplySql.Cmdlets/ProviderCmdlets/OpenMySqlConnection.vb +++ b/source/SimplySql.Cmdlets/ProviderCmdlets/OpenMySqlConnection.vb @@ -29,7 +29,7 @@ Public Class OpenMySqlConnection - + Public Property SSLMode As String = "Preferred" diff --git a/source/SimplySql.Cmdlets/SimplySql.Cmdlets.vbproj b/source/SimplySql.Cmdlets/SimplySql.Cmdlets.vbproj index 548dacb..9e17eca 100644 --- a/source/SimplySql.Cmdlets/SimplySql.Cmdlets.vbproj +++ b/source/SimplySql.Cmdlets/SimplySql.Cmdlets.vbproj @@ -6,6 +6,7 @@ 2.0.0 False latest-minimum + Library diff --git a/source/SimplySql.Engine/MSSQL/MSSQLProvider.vb b/source/SimplySql.Engine/MSSQL/MSSQLProvider.vb index faac790..efb8f4f 100644 --- a/source/SimplySql.Engine/MSSQL/MSSQLProvider.vb +++ b/source/SimplySql.Engine/MSSQL/MSSQLProvider.vb @@ -65,6 +65,8 @@ Public Class MSSQLProvider End If bcp.WriteToServer(dataReader) + + If notify IsNot Nothing Then notify.Invoke(bcp.RowsCopied) Return bcp.RowsCopied End Using End Using diff --git a/source/SimplySql.Engine/MySQL/MySqlProvider.vb b/source/SimplySql.Engine/MySQL/MySqlProvider.vb index db0f8fe..009906f 100644 --- a/source/SimplySql.Engine/MySQL/MySqlProvider.vb +++ b/source/SimplySql.Engine/MySQL/MySqlProvider.vb @@ -63,6 +63,8 @@ Public Class MySqlProvider Dim result = bcp.WriteToServer(dataReader) result.Warnings.ToList.ForEach(Sub(w) Messages.Enqueue(New SqlMessage(w.Message))) + + If notify IsNot Nothing Then notify.Invoke(result.RowsInserted) Return result.RowsInserted End Using End Function diff --git a/source/SimplySql.Engine/Oracle/OracleProvider.vb b/source/SimplySql.Engine/Oracle/OracleProvider.vb index 62f3715..2df1c97 100644 --- a/source/SimplySql.Engine/Oracle/OracleProvider.vb +++ b/source/SimplySql.Engine/Oracle/OracleProvider.vb @@ -76,7 +76,7 @@ Public Class OracleProvider Dim rowsCopied As Long = 0 AddHandler bcp.OracleRowsCopied, Sub(sender As Object, e As OracleRowsCopiedEventArgs) rowsCopied += 1 - If rowsCopied Mod batchSize = 0 Then + If rowsCopied Mod batchSize = 0 AndAlso notify IsNot Nothing Then notify.Invoke(rowsCopied) End If End Sub @@ -131,7 +131,7 @@ Public Class OracleProvider Me.Messages.Enqueue(New SqlMessage(e.Message)) End Sub #Region "Shared" - Private Function MapOracleType(netType As String) As OracleDbType + Private Shared Function MapOracleType(netType As String) As OracleDbType 'FROM: https://docs.oracle.com/en/database/oracle///oracle-database/23/odpnt/featOraCommand.html#GUID-BBEF52D9-E4E3-4A9C-93F5-3E408A83FC04 Select Case netType.ToLower Case "system.boolean" diff --git a/source/SimplySql.Engine/PostGre/PostGreProvider.vb b/source/SimplySql.Engine/PostGre/PostGreProvider.vb index a6d5a87..29c2bd8 100644 --- a/source/SimplySql.Engine/PostGre/PostGreProvider.vb +++ b/source/SimplySql.Engine/PostGre/PostGreProvider.vb @@ -75,12 +75,11 @@ Public Class PostGreProvider End If Next - If notify IsNot Nothing Then - If iteration Mod batchSize = 0 Then - notify.Invoke(iteration) - End If + If iteration Mod batchSize = 0 AndAlso notify IsNot Nothing Then + notify.Invoke(iteration) End If End While + If notify IsNot Nothing Then notify.Invoke(iteration) Return bulk.Complete() End Using End Using diff --git a/source/SimplySql.Engine/ProviderBase.vb b/source/SimplySql.Engine/ProviderBase.vb index c1e5357..a5ced12 100644 --- a/source/SimplySql.Engine/ProviderBase.vb +++ b/source/SimplySql.Engine/ProviderBase.vb @@ -228,6 +228,7 @@ Public MustInherit Class ProviderBase End Try End Using End Using + If notify IsNot Nothing Then notify.Invoke(batchIteration) Return batchIteration End Function diff --git a/source/SimplySql.Engine/SimplySql.Engine.vbproj b/source/SimplySql.Engine/SimplySql.Engine.vbproj index c13a960..a807b70 100644 --- a/source/SimplySql.Engine/SimplySql.Engine.vbproj +++ b/source/SimplySql.Engine/SimplySql.Engine.vbproj @@ -2,12 +2,12 @@ SimplySql.Engine - netstandard2.0 + netstandard2.0;net47;net6.0 2.0.0 False True latest-minimum - SimplySql.Common=False,Microsoft.VisualBasic=True,System=True,System.Collections=True,System.Collections.Generic=True,System.Diagnostics=True,System.Linq=True,System.Xml.Linq=True,System.Threading.Tasks=True,SimplySql.Engine=True + Microsoft.VisualBasic=True,System=True,System.Collections=True,System.Collections.Generic=True,System.Diagnostics=True,System.Linq=True,System.Xml.Linq=True,System.Threading.Tasks=True,SimplySql.Engine=True @@ -19,14 +19,17 @@ - - - - - + + + + + + - + + + diff --git a/source/source.build.ps1 b/source/source.build.ps1 index 7cc12e7..3f0a543 100644 --- a/source/source.build.ps1 +++ b/source/source.build.ps1 @@ -1,60 +1,111 @@ -param([version]$Version = "2.0.0", [switch]$DebugOnly, [switch]$SkipDedup, [validateset("win-x64","linux-x64")][string]$env="win-x64") +param([version]$Version = "2.0.0", [switch]$DebugOnly, [switch]$SkipDedup) if(-not [bool](Get-ChildItem alias:\).where({$_.name -eq "hv"})) { New-Alias -Name HV -Value (Resolve-Path ..\HandleVerbose.ps1) } -$Script:envList = @($env) +#$Script:envList = @($env) +$Script:envList = @( + [PSCustomObject]@{framework="net47"; env="win-x86"; output="output\bin\PS5\win-x86"} + [PSCustomObject]@{framework="net47"; env="win-x64"; output="output\bin\PS5\win-x64"} + [PSCustomObject]@{framework="net6.0"; env="win-x64"; output="output\bin\PS7\win-x64"} + [PSCustomObject]@{framework="net6.0"; env="linux-x64"; output="output\bin\PS7\linux-x64"} + [PSCustomObject]@{framework="net6.0"; env="osx-x64"; output="output\bin\PS7\osx-x64"} +) -task Clean { remove output } - -task Build { - $configuration = "Release" - if($DebugOnly) { $configuration = "debug"} - - exec { dotnet publish "SimplySql.Cmdlets" -c $Configuration -o "output\bin" -p:Version=$Version -p:AssemblyVersion=$version} | HV "Building SimplySql.Cmdlets ($version)" "." - - Move-Item "output\bin\SimplySql.Cmdlets.*" -Destination "output" - Remove-Item "output\bin\" -Exclude "SimplySql.*" -Recurse - - if(-not $DebugOnly) { $Script:envList += @("win-x86", "linux-x64", "osx-x64")} - foreach($env in $Script:envList) { - exec { dotnet publish "SimplySql.Cmdlets" -c $Configuration -r $env -o "output\bin\$env"} | HV "Building PlatformSpecific Dependencies $env" "." - Remove-Item "output\bin\$env" -Include "SimplySql.*" -Recurse - } -} - -Task DeDup { - if(-not $DebugOnly -and -not $SkipDedup) { - $first = $Script:envList[0] +function dedup([string]$Path) { + Write-Host " DeDuplicate: $Path" + [string[]]$list = Get-ChildItem -Path $Path -Name -Directory | + ForEach-Object { Join-Path $Path $_ } + if($list.Count -eq 1) { + Move-Item -Path (Join-Path $list[0] -ChildPath "*") -Destination $path + Remove-Item $list[0] + } elseif($list.count -gt 1) { $safeFiles = @{} - Get-ChildItem -Path "output\bin\$first" | + $first = $list[0] + Write-Host " --$($first | Split-Path -Leaf)" -NoNewline + Get-ChildItem -Path $first | Where-Object Name -ne "System.Data.SQLite.dll" | #always exclude this SQLite dll because of native interop binding + Where-Object Name -ne "SQLite.Interop.dll" | #always exclude this SQLite dll because of native interop binding Get-FileHash | ForEach-Object { $name = $_.Path | Split-Path -Leaf $safeFiles[$name] = $_.Hash + Write-Host "." -NoNewline } + Write-Host "!" - Write-Host " ." -NoNewline - - foreach($second in $Script:envList | Select-Object -Skip 1) { - $retain = $safeFiles.Keys | - Where-Object { Test-Path "output\bin\$second\$_" } | - Where-Object { $safeFiles[$_] -eq (Get-FileHash "output\bin\$second\$_").Hash } + #run Dedup + foreach($second in $list | Select-Object -Skip 1) { + Write-Host " --$($second | Split-Path -Leaf)" -NoNewline + $retain = $safeFiles.Keys | + Where-Object { Test-Path (Join-Path $second $_) } | + Where-Object { $safeFiles[$_] -eq (Get-FileHash (Join-Path $second $_)).Hash } $toRemove = $safeFiles.Keys | Where-Object {$_ -notin $retain} - $toRemove | ForEach-Object { $safeFiles.remove($_) } - - Write-Host "." -NoNewline + $toRemove | ForEach-Object { + $safeFiles.remove($_) + Write-Host "." -NoNewline + } + Write-Host "!" } + #cleanup foreach($file in $safeFiles.Keys) { - Move-Item "output\bin\$first\$file" "output\bin" - foreach($second in $Script:envList | Select-Object -Skip 1) { - Remove-Item "output\bin\$second\$file" + Move-Item "$first\$file" "$path" + foreach($second in $list | Select-Object -Skip 1) { + $f = Join-Path $second $file + if(Test-Path $f) { Remove-Item $f } } } - Write-Host + + $list | + Where-Object { @(Get-ChildItem $_).Count -eq 0 } | + Remove-Item # remove empty folders + } +} + +task Clean { remove output } + +task Build { + $configuration = "Release" + if($DebugOnly) { $configuration = "debug"} + + exec { dotnet publish "SimplySql.Cmdlets" -c $configuration -o "output\bin" -p:Version=$Version -p:AssemblyVersion=$version} | HV "Building SimplySql.Cmdlets ($version)" "." + + Move-Item "output\bin\SimplySql.Cmdlets.*" -Destination "output" + Remove-Item "output\bin\*" #-Exclude "SimplySql.*" -Recurse + + if($DebugOnly) { $Script:envList = $Script:envList | Where-Object env -eq "win-x64" } + foreach($env in $Script:envList) { + #exec { dotnet publish "SimplySql.Cmdlets" -c $Configuration -r $env -o "output\bin\$env"} | HV "Building PlatformSpecific Dependencies $env" "." + exec { + dotnet publish "SimplySql.Engine" -c $configuration -r $env.env -f $env.framework -o $env.output + } | HV "Building PlatformSpecific Dependencies $($env.env) ($($env.framework))" "." + + Get-ChildItem -Path $env.output -Directory | Remove-Item -Recurse + #exec { dotnet publish "SimplySql.Cmdlets" -c $Configuration -r $env } | HV "Building PlatformSpecific Dependencies $env" "." + #Remove-Item "output\bin\$env" -Include "SimplySql.*" -Recurse + } + + #remove PDB/json + Get-ChildItem -Path .\output\* -Include "*.pdb", "*.json" -Recurse | Remove-Item + + #get SQLite Interops... + exec { dotnet build "SimplySql.Engine" -c $configuration } | HV "SQLite Interop" "." + if (Test-Path ".\output\bin\PS5\win-x86\" -PathType Container) { + Copy-Item ".\SimplySql.Engine\bin\$configuration\net47\x86\SQLite.Interop.dll" -Destination ".\output\bin\PS5\win-x86" + } + if (Test-Path ".\output\bin\PS5\win-x64\" -PathType Container) { + Copy-Item ".\SimplySql.Engine\bin\$configuration\net47\x64\SQLite.Interop.dll" -Destination ".\output\bin\PS5\win-x64" + } + Get-ChildItem -Path ".\SimplySql.Engine\bin" -Directory | Remove-Item -Recurse +} + +Task DeDup { + if(-not $SkipDedup) { + dedup ".\output\bin\PS5" + dedup ".\output\bin\PS7" + dedup ".\output\bin" } }