diff --git a/ModuleManifest/SimplySql.psd1 b/ModuleManifest/SimplySql.psd1 index 0cba785..a745222 100644 --- a/ModuleManifest/SimplySql.psd1 +++ b/ModuleManifest/SimplySql.psd1 @@ -3,7 +3,7 @@ # # Generated by: Mithrandyr # -# Generated on: 5/11/2024 +# Generated on: 6/14/2024 # @{ @@ -12,7 +12,7 @@ RootModule = 'SimplySql.Cmdlets.dll' # Version number of this module. -ModuleVersion = '2.0.3.73' +ModuleVersion = '2.0.4.75' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/Tests/mssql.tests.ps1 b/Tests/mssql.tests.ps1 index ae9a86a..8dd5518 100644 --- a/Tests/mssql.tests.ps1 +++ b/Tests/mssql.tests.ps1 @@ -80,6 +80,32 @@ Describe "MSSQL" { 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 + + 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 "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 "Invoke-SqlQuery -stream" { Invoke-SqlQuery -Query "SELECT TOP 1000 * FROM tmpTable" -Stream | diff --git a/Tests/mysql.tests.ps1 b/Tests/mysql.tests.ps1 index 48495ee..3490f2a 100644 --- a/Tests/mysql.tests.ps1 +++ b/Tests/mysql.tests.ps1 @@ -30,6 +30,7 @@ Describe "MySql" { DROP TABLE IF EXISTS $db.tmpTable; DROP TABLE IF EXISTS $db.tmpTable2; DROP TABLE IF EXISTS $db.tmpTable3; + DROP TABLE IF EXISTS $db.tmpPK; DROP VIEW IF EXISTS $db.generator_64k; DROP VIEW IF EXISTS $db.generator_256; DROP VIEW IF EXISTS $db.generator_16;" @@ -86,6 +87,32 @@ Describe "MySql" { 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 + + 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 "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 "Invoke-SqlQuery -stream" { Invoke-SqlQuery -Query " SELECT rand() AS colDec diff --git a/Tests/oracle.tests.ps1 b/Tests/oracle.tests.ps1 index f334690..d9c4f75 100644 --- a/Tests/oracle.tests.ps1 +++ b/Tests/oracle.tests.ps1 @@ -9,7 +9,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")) { + foreach($tbl in @("transactionTest", "tmpTable", "tmpTable2","t", "tmpPK")) { $query = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE $tbl'; EXCEPTION @@ -79,6 +79,32 @@ Describe "Oracle" { 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 + + 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 "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 "Invoke-SqlQuery -stream" { Invoke-SqlQuery -Stream -Query "SELECT dbms_random.random /1000000000000. AS colDec , dbms_random.random AS colInt diff --git a/Tests/postgre.tests.ps1 b/Tests/postgre.tests.ps1 index d3cdddc..205424c 100644 --- a/Tests/postgre.tests.ps1 +++ b/Tests/postgre.tests.ps1 @@ -13,7 +13,7 @@ Describe "PostGre" { } AfterAll { Open-PostGreConnection -Server $srvName -Database $db -Credential $c - Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, t;" + Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, t, tmpPK;" Close-SqlConnection } @@ -65,6 +65,32 @@ Describe "PostGre" { 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 + + 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 "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 "Invoke-SqlQuery -stream" { Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" -Stream | Measure-Object | diff --git a/Tests/sqlite.tests.ps1 b/Tests/sqlite.tests.ps1 index 9d65f1b..ba1dc0a 100644 --- a/Tests/sqlite.tests.ps1 +++ b/Tests/sqlite.tests.ps1 @@ -57,6 +57,32 @@ Describe "SQLite" { 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 + + 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 "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 "Invoke-SqlQuery -stream" { Invoke-SqlQuery -Query "WITH a(n) AS (SELECT 1 UNION ALL SELECT 1) diff --git a/source/SimplySql.Cmdlets/DataReaderToPSObject.vb b/source/SimplySql.Cmdlets/DataReaderToPSObject.vb index e2916e8..12705b9 100644 --- a/source/SimplySql.Cmdlets/DataReaderToPSObject.vb +++ b/source/SimplySql.Cmdlets/DataReaderToPSObject.vb @@ -8,8 +8,12 @@ Public Class DataReaderToPSObject Dim columns = map.CreateMappings(theDataReader) While theDataReader.Read Dim pso As New PSObject - + Dim nameList As New Dictionary(Of String, Integer) For Each col In columns + + + + If theDataReader.IsDBNull(col.Ordinal) Then pso.Properties.Add(New PSNoteProperty(col.Name, Nothing), True) Else @@ -62,7 +66,18 @@ Public Class DataReaderToPSObject Public Name As String Public Type As String Shared Function CreateMappings(dr As IDataReader) As Generic.List(Of map) - Return Linq.Enumerable.Range(0, dr.FieldCount).Select(Function(ord) New map With {.Ordinal = ord, .Name = dr.GetName(ord), .Type = dr.GetFieldType(ord).ToString}).ToList + Dim nameList As New Dictionary(Of String, Integer) + Return Linq.Enumerable.Range(0, dr.FieldCount).Select(Function(ord) + Dim n As String = dr.GetName(ord) + Dim ni As Integer + If nameList.TryGetValue(n, ni) Then + nameList(n) += 1 + n += ni.ToString + Else + nameList.Add(n, 1) + End If + Return New map With {.Ordinal = ord, .Name = n, .Type = dr.GetFieldType(ord).ToString} + End Function).ToList End Function Shared Function CreateFunction(dr As IDataReader) As Func(Of IDataRecord, PSObject) diff --git a/source/SimplySql.Engine/ProviderBase.vb b/source/SimplySql.Engine/ProviderBase.vb index a326de3..c1e5357 100644 --- a/source/SimplySql.Engine/ProviderBase.vb +++ b/source/SimplySql.Engine/ProviderBase.vb @@ -99,7 +99,27 @@ Public MustInherit Class ProviderBase Using dr As IDataReader = cmd.ExecuteReader Do Dim dt As New DataTable - dt.Load(dr) + Dim nameList As New Dictionary(Of String, Integer) + For i As Integer = 0 To dr.FieldCount - 1 + Dim n As String = dr.GetName(i) + Dim ni As Integer = 0 + If nameList.TryGetValue(n, ni) Then + nameList(n) += 1 + n += ni.ToString + Else + nameList.Add(n, 1) + End If + dt.Columns.Add(n, dr.GetFieldType(i)) + Next + + ' Read data and add rows + While dr.Read() + Dim row As DataRow = dt.NewRow() + For i As Integer = 0 To dr.FieldCount - 1 + row(i) = dr(i) + Next + dt.Rows.Add(row) + End While If dt.Rows.Count > 0 Then ds.Tables.Add(dt) Loop While Not dr.IsClosed AndAlso dr.NextResult() End Using