From f032d15aa8f37fac89e4ebdefe68b278f115a2e9 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Wed, 5 Feb 2025 23:03:43 -0500
Subject: [PATCH 01/20] Updated Docs
---
README.md | 1 +
git_cheatsheet.md | 60 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/README.md b/README.md
index 43d6488..d4a3664 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,7 @@
+
# SqlQueryClass
Provides functionality for executing SQL queries and managing SQL datasets
diff --git a/git_cheatsheet.md b/git_cheatsheet.md
index 1a226a9..557e2ca 100644
--- a/git_cheatsheet.md
+++ b/git_cheatsheet.md
@@ -2,6 +2,53 @@
Photography Co-worker Kevin Hecht (kevin.a.hecht@pwc.com)
+# To Publish Module to PowerShell Gallery
+
+Publish-Module -Path -NuGetApiKey -Repository PSGallery
+
+Publish-Module -Path "C:\Git\SqlQueryClass\dist\SqlQueryClass" -NuGetApiKey "" -Repository PSGallery
+
+Find-Module -Name SqlQueryClass | Install-Module -Scope CurrentUser -AcceptLicense
+
+Find-Module -Name SqlQueryClass | FL
+
+Name : SqlQueryClass
+Version : 0.1.0
+Type : Module
+Description : Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, SqlReader, or NonQuery result object.
+Author : Brooks Vaughn
+CompanyName : BrooksV
+Copyright : (c) Brooks Vaughn. All rights reserved.
+PublishedDate : 2/6/2025 3:43:39 AM
+InstalledDate :
+UpdatedDate :
+LicenseUri : https://github.com/BrooksV/SqlQueryClass/blob/main/LICENSE
+ProjectUri : https://github.com/BrooksV/SqlQueryClass
+IconUri :
+Tags : {PowerShell, Database, SQL, SQLServer…}
+Includes : {[RoleCapability, System.Object[]], [DscResource, System.Object[]], [Cmdlet, System.Object[]], [Workflow, System.Object[]]…}
+PowerShellGetFormatVersion :
+ReleaseNotes :
+Dependencies : {}
+RepositorySourceLocation : https://www.powershellgallery.com/api/v2
+Repository : PSGallery
+PackageManagementProvider : NuGet
+AdditionalMetadata : @{summary=Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, SqlReader, or NonQuery result object.;
+ ItemType=Module; IsPrerelease=false; PackageManagementProvider=NuGet; NormalizedVersion=0.1.0; SourceName=PSGallery; tags=PowerShell Database SQL SQLServer SQLQuery DataAdapter DataSet DataTable
+ PSModule; description=Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, SqlReader, or NonQuery result
+ object.; Authors=Brooks Vaughn; versionDownloadCount=0; GUID=8375edbe-fb0f-4cb6-acb0-9964b45725c0; lastUpdated=2/6/2025 3:43:39 AM -05:00; requireLicenseAcceptance=False; downloadCount=0;
+ isLatestVersion=True; CompanyName=Unknown; Functions=New-SqlQueryDataSet; FileList=SqlQueryClass.nuspec|about_SqlQueryClass.help.txt|SqlQueryClass.psd1|SqlQueryClass.psm1;
+ PowerShellHostVersion=5.1; created=2/6/2025 3:43:39 AM -05:00; isAbsoluteLatestVersion=True; copyright=(c) Brooks Vaughn. All rights reserved.; packageSize=15464; developmentDependency=False;
+ updated=2025-02-06T03:43:39Z; published=2/6/2025 3:43:39 AM -05:00}
+
+
+
+# Code Signing
+
+Get-ChildItem -Path Cert:\CurrentUser -Recurse | FL
+Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert
+Get-ChildItem -Path Cert:\LocalMachine -Recurse | FL
+
# git config commands
- ps.readinglist.md -- Quick Reference Reading list of helpful PowerShell sites, articles, and documents
@@ -310,3 +357,16 @@ git push origin master --force
- **Purpose**: To overwrite the remote `master` branch with your local changes, even if it results in non-fast-forward updates.
- **Example**: Use with caution as it can overwrite changes in the remote repository that others may be relying on.
+
+# 2025-02-05 22:59:55
+
+git pull origin main
+
+git checkout -b features/readme-updates
+git status
+
+git commit -m ""
+
+git commit -a -m "Updated SQL query class and added error handling"
+
+git push
\ No newline at end of file
From b1426aa9d324331e03af3c35b06c472570320b19 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Thu, 6 Feb 2025 01:11:33 -0500
Subject: [PATCH 02/20] Fixed formatting Issues
---
README.md | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index d4a3664..d63c29e 100644
--- a/README.md
+++ b/README.md
@@ -107,7 +107,6 @@ SQLServer Property string SQLServer {get;set;}
TableIndex Property int TableIndex {get;set;}
TableNames Property hashtable TableNames {get;set;}
Tables Property System.Collections.Generic.List`1[[SqlQueryTable, PowerShell Class Assembly, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Tables {get;set;}
-
```
## Summary
@@ -250,7 +249,7 @@ Query : SELECT * FROM INFORMATION_SCHEMA.TABLES
SQLCommand : System.Data.SqlClient.SqlCommand
SqlDataAdapter :
ResultType : DataTable
-Result : {Document, Category, Entity, DocName…}
+Result : {Document, Category, Entity, DocName...}
isDirty : False
QueryFile :
Parent : SqlQueryDataSet
@@ -281,7 +280,8 @@ The the following ModuleTools CmdLets used in the build and maintenance process.
- To skip a test, add `-skip` in describe block of the Pester *.test.ps1 file to skip.
### Folder and Files
-
+
+```powershell
.\SQLQUERYCLASS
│ .gitignore
│ GitHub_Action_Docs.md
@@ -315,6 +315,7 @@ The the following ModuleTools CmdLets used in the build and maintenance process.
Module.Tests.ps1
OutputFiles.Tests.ps1
ScriptAnalyzer.Tests.ps1
+```
All files and folders in the `src` folder, will be published Module.
From 1a2b6b88b778f749ae9c361ccaa4ddad53c89f83 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Thu, 6 Feb 2025 01:27:05 -0500
Subject: [PATCH 03/20] Fixed formatting Issues
---
git_cheatsheet.md | 107 ++++++++++++++++++++++++++++++++++------------
1 file changed, 80 insertions(+), 27 deletions(-)
diff --git a/git_cheatsheet.md b/git_cheatsheet.md
index 557e2ca..2035ac7 100644
--- a/git_cheatsheet.md
+++ b/git_cheatsheet.md
@@ -1,9 +1,12 @@
+# CheetSheet
+
& "C:\Program Files (x86)\Info Keep\info keep.exe"
-Photography Co-worker Kevin Hecht (kevin.a.hecht@pwc.com)
+Photography Co-worker [Kevin Hecht](mailto://kevin.a.hecht@pwc.com)
-# To Publish Module to PowerShell Gallery
+## To Publish Module to PowerShell Gallery
+```powershell
Publish-Module -Path -NuGetApiKey -Repository PSGallery
Publish-Module -Path "C:\Git\SqlQueryClass\dist\SqlQueryClass" -NuGetApiKey "" -Repository PSGallery
@@ -40,16 +43,15 @@ AdditionalMetadata : @{summary=Module that create an instance of a Power
isLatestVersion=True; CompanyName=Unknown; Functions=New-SqlQueryDataSet; FileList=SqlQueryClass.nuspec|about_SqlQueryClass.help.txt|SqlQueryClass.psd1|SqlQueryClass.psm1;
PowerShellHostVersion=5.1; created=2/6/2025 3:43:39 AM -05:00; isAbsoluteLatestVersion=True; copyright=(c) Brooks Vaughn. All rights reserved.; packageSize=15464; developmentDependency=False;
updated=2025-02-06T03:43:39Z; published=2/6/2025 3:43:39 AM -05:00}
+```
-
-
-# Code Signing
+## Code Signing
Get-ChildItem -Path Cert:\CurrentUser -Recurse | FL
Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert
Get-ChildItem -Path Cert:\LocalMachine -Recurse | FL
-# git config commands
+## git config commands
- ps.readinglist.md -- Quick Reference Reading list of helpful PowerShell sites, articles, and documents
@@ -57,7 +59,7 @@ Get-ChildItem -Path Cert:\LocalMachine -Recurse | FL
git config --system core.longpaths true
-### git remote urls
+#### git remote urls
git remote -v
@@ -65,10 +67,13 @@ git remote -v
### To Set your username
+```powershell
git config --global user.name "FIRST_NAME LAST_NAME"
+```
### To Set your email address
+```powershell
git config --global user.email "MY_NAME@example.com"
git config --global user.name "Brooks Vaughn"
@@ -76,6 +81,7 @@ git config --global user.email "18422308+BrooksV@users.noreply.github.com"
git config --worktree user.name "Brooks Vaughn"
git config --global user.email "18422308+BrooksV@users.noreply.github.com"
+```
### Check configuration for your user
@@ -85,23 +91,31 @@ $ cat $HOME/.gitconfig
### Get system value
+```powershell
git config --system --get https.proxy
git config --system --get http.proxy
+```
### Get global value
+```powershell
git config --global --get https.proxy
git config --global --get http.proxy
+```
### Unset system value
-$ git config --system --unset https.proxy
-$ git config --system --unset http.proxy
+```powershell
+git config --system --unset https.proxy
+git config --system --unset http.proxy
+```
### Unset global value
-$ git config --global --unset https.proxy
-$ git config --global --unset http.proxy
+```powershell
+git config --global --unset https.proxy
+git config --global --unset http.proxy
+```
## Proxy Config using Environment Variables
@@ -109,30 +123,39 @@ Your proxy could also be set as an environment variable. Check if your environme
### Linux
+```bash
export http_proxy=http://proxy:8080
export https_proxy=https://proxy:8443
+```
### Windows
+```powershell
set http_proxy http://proxy:8080
set https_proxy https://proxy:8443
+```
## SSL Config
+```powershell
git config --global http.sslVerify
git config --global http.sslVerify true
+```
### Repro Clone SSL Errors
+```powershell
SSL_VERIFY=false
git config --global http.sslVerify false
+```
My agents are running as Network Service too but that wasn't really a problem to use user level config. Here is what I did:
1.Save all the necessary certificates in folder %systemroot%\ServiceProfiles\NetworkService\.gitcerts\.
2.Create a file at %systemroot%\ServiceProfiles\NetworkService\.gitconfig with the following content:
[http "https://tfs.com/"](http "https://tfs.com/")
- sslCAInfo = ~/.gitcerts/certificate.pem
+
+$sslCAInfo = ~/.gitcerts/certificate.pem
[adding-a-corporate-or-self-signed-certificate-authority-to-git-exes-store](https://blogs.msdn.microsoft.com/phkelley/2014/01/20/adding-a-corporate-or-self-signed-certificate-authority-to-git-exes-store/)
@@ -141,7 +164,7 @@ git config --global http.sslBackend schannel
[how-to-make-git-work-with-self-signed-ssl-certificates-on-tfs2018](https://www.benday.com/2017/12/15/how-to-make-git-work-with-self-signed-ssl-certificates-on-tfs2018/)
[fix-git-self-signed-certificate-in-certificate-chain-on-windows](https://mattferderer.com/fix-git-self-signed-certificate-in-certificate-chain-on-windows)
-# Git Repo and Branch Commands
+## Git Repo and Branch Commands
### Reset Local Master
@@ -158,22 +181,24 @@ git checkout main
git reset --hard origin/main
git pull origin main
-If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command.
+If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command.
+```powershell
Example:
git switch -c
Or undo this operation with:
- git switch -
+ git switch -?
+```
## Status and Info Commands
+```powershell
git status
git log
git branch --all
git branch features/
-
git fetch origin
git fetch origin master
git checkout master
@@ -184,76 +209,88 @@ git status
git log
git push
-
git pull
git branch -a
+```
## To Create Branch from Master
+```powershell
git fetch origin master
git checkout master
git pull origin master
git checkout -b features/???
git push --set-upstream origin features/???
git checkout features/???
+```
### Create local branch
+```powershell
git checkout -b features/
git status
git add foo.txt
git commit -m ""
-git commit -a -m "" # ?
+git commit -a -m "" ## ?
git push
+```
### Create Branch on origin (UpStream) to Repository
+```powershell
git push --set-upstream origin features/
+```
### To sync local master
+```powershell
git checkout master
git pull
git checkout features/readme-updates
git merge master ????
+```
-# Notes
+## Notes
Origin is the plcae where the branch was cloned from
+```powershell
git remote add
git add -p
git log --online
npm config set strict-ssl false
+```
+## Git Merging commands
-# Git Merging commands
-
+```powershell
git merge branch master
git status
git log
git push
-
git config --get --local core.filemode
false
git config --local --list
+```
## Commits
+```powershell
git add yaml\???.yml
git commit -m "???"
-git commit -a -m "" # ?
+git commit -a -m "" ## ?
git push
git merge --abort
git branch -a --sort=-committerdate --format='%(HEAD) %(color:yellow)%(refname:short)%(color:reset) - %(color:red)%(objectname:short)%(color:reset) - %(contents:subject) - %(authorname) (%(color:green)%(committerdate:relative)%(color:reset))'
(git reflog > reflog.md) | Invoke-Item
git reflog | Select-String
+```
-### Explanation of what each of those Git commands do
+## Explanation of what each of those Git commands do
### `git add yaml???.yml`
@@ -307,12 +344,14 @@ These commands cover a range of Git operations, from staging and committing chan
## Git Command docs
+```powershell
git remote add upstream
git fetch upstream
git rebase upstream/master
git push origin master --force
+```
-### Explanation of what each of those Git commands does:
+## Explanation of what each of those Git commands does
### `git remote add upstream`
@@ -358,8 +397,9 @@ git push origin master --force
- **Purpose**: To overwrite the remote `master` branch with your local changes, even if it results in non-fast-forward updates.
- **Example**: Use with caution as it can overwrite changes in the remote repository that others may be relying on.
-# 2025-02-05 22:59:55
+## 2025-02-05 22:59:55
+```powershell
git pull origin main
git checkout -b features/readme-updates
@@ -369,4 +409,17 @@ git commit -m ""
git commit -a -m "Updated SQL query class and added error handling"
-git push
\ No newline at end of file
+git push
+```
+
+```powershell
+```
+
+```powershell
+```
+
+```powershell
+```
+
+```powershell
+```
From 7c81a466ae4d7f7da52b0c9253f1a80f7373f7b6 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 01:23:06 -0500
Subject: [PATCH 04/20] Removed ExecuteAsSqlReader, added ExecuteAsDataRows
---
README.md | 11 +-
project.json | 2 +-
src/private/SqlQueryClass.ps1 | 289 ++++++++--------------------------
3 files changed, 78 insertions(+), 224 deletions(-)
diff --git a/README.md b/README.md
index d63c29e..6ae7264 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
SqlQueryClass
-
Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, SqlReader, or NonQuery result object.
+
Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, DataRows, or NonQuery result object.
@@ -79,7 +79,7 @@ Execute Method System.Object Execute(), System.Object Exe
ExecuteAsDataAdapter Method System.Object ExecuteAsDataAdapter(string SqlQuery)
ExecuteAsDataSet Method System.Object ExecuteAsDataSet(string SqlQuery)
ExecuteAsDataTable Method System.Object ExecuteAsDataTable(string SqlQuery)
-ExecuteAsSqlReader Method System.Object ExecuteAsSqlReader(string SqlQuery)
+ExecuteAsDataRows Method System.Object ExecuteAsDataRows(string SqlQuery)
ExecuteNonQuery Method System.Object ExecuteNonQuery(string SqlQuery)
ExecuteQuery Method System.Object ExecuteQuery(string SqlQuery), System.Object ExecuteQuery(string TableName, string SqlQuery)
GetCreateBasicDLL Method System.Object GetCreateBasicDLL(string TableName)
@@ -123,7 +123,6 @@ class SqlQueryDataSet {
[int]$CommandTimeout = 600
[string]$ConnectionString
[object]$SQLConnection
- hidden [object]$SQLReader
[int]$TableIndex = 0
[System.Collections.Generic.List[SqlQueryTable]]$Tables
[System.Collections.Hashtable]$TableNames = @{}
@@ -163,7 +162,11 @@ class SqlQueryTable {
}
```
-The ResultsType property defines how the query will be executed and the DataType for the result. ResultType values are: DataTable; DataAdapter; DataSet; SqlReader; and NonQuery.
+The ResultsType property defines how the query will be executed and the DataType for the result. ResultType values are: DataTable; DataAdapter; DataSet; DataRows; and NonQuery.
+
+ResultType of DataTable and DataRows use the [System.Data.SqlClient.SqlDataReader] approach to load() a DataTable object and return [SqlQueryTable]$table.Result as [System.Data.DataTable] or [Array][System.Data.DataRow]
+
+ResultType of DataAdapter and DataSet returns [SqlQueryTable]$table.Result as [System.Data.DataSet] and retains the SqlDataAdapter used in [SqlQueryTable]$table.SqlDataAdapter
### New-SqlQueryDataSet Examples
diff --git a/project.json b/project.json
index d496839..ca8fa4d 100644
--- a/project.json
+++ b/project.json
@@ -1,7 +1,7 @@
{
"ProjectName": "SqlQueryClass",
"Description": "Module that create an instance of a PowerShell class which is used to execute SQL Queries and manages output as DataTable, DataAdapter, DataSet, SqlReader, or NonQuery result object.",
- "Version": "0.1.0",
+ "Version": "0.1.1",
"Manifest": {
"Author": "Brooks Vaughn",
"PowerShellHostVersion": "5.1",
diff --git a/src/private/SqlQueryClass.ps1 b/src/private/SqlQueryClass.ps1
index c6be761..467ccf3 100644
--- a/src/private/SqlQueryClass.ps1
+++ b/src/private/SqlQueryClass.ps1
@@ -5,7 +5,7 @@
SqlQueryClass.ps1 -- Dot Source file of SQL Query Class definitions for classes [SqlQueryDataSet] and [SqlQueryTable]
.DESCRIPTION
- This script defines two PowerShell classes [SqlQueryDataSet] and [SqlQueryTable] which are used to execute SQL Queries and return the results in a DataTable, DataAdapter, DataSet, SqlReader or NonQuery.
+ This script defines two PowerShell classes [SqlQueryDataSet] and [SqlQueryTable] which are used to execute SQL Queries and return the results in a DataTable, DataAdapter, DataSet, DataRows ([Array]DataRow) or NonQuery.
The parent class, [SqlQueryDataSet], is designed to manage SQL Server connections, execute queries, and methods to manage data.
The child class, [SqlQueryTable], is designed to manage a table SQL query's configuration and query results.
@@ -44,7 +44,7 @@ A Query can be added to the [SqlQueryDataSet] object in the following ways:
$TestQuery.ExecuteAsDataTable($Query)
$TestQuery.ExecuteAsDataAdapter($Query)
$TestQuery.ExecuteAsDataSet($Query)
- $TestQuery.ExecuteAsSqlReader($Query)
+ $TestQuery.ExecuteAsDataRows($Query)
$TestQuery.AddQuery($Query)
$TestQuery.LoadQueryFromFile($PathToSQLFile)
@@ -95,7 +95,7 @@ Helper Methods
$TestQuery.BuildOleDbConnectionString() -- Builds a connection string for OleDb
$TestQuery.BuildConnectionString() -- [Hidden] Builds a connection string for SqlClient used as a fallback when $TestQuery.ConnectionString is missing or fails
$TestQuery.Clear() -- Closes the connection and clears all the properties and collections of the [SqlQueryDataSet] object
-$TestQuery.CloseConnection() -- Closes the SQL Connection and clears the SQLReader
+$TestQuery.CloseConnection() -- Closes the SQL Connection
$TestQuery.GetCreateBasicDLL($TableName) -- Returns a DataTable with the basic structure of a table with the following columns: Id, CreatedOn, CreatedBy, UpdatedOn, UpdatedBy
$TestQuery
$TestQuery
@@ -113,7 +113,7 @@ Execute Method System.Object Execute(), System.Object Exe
ExecuteAsDataAdapter Method System.Object ExecuteAsDataAdapter(string SqlQuery)
ExecuteAsDataSet Method System.Object ExecuteAsDataSet(string SqlQuery)
ExecuteAsDataTable Method System.Object ExecuteAsDataTable(string SqlQuery)
-ExecuteAsSqlReader Method System.Object ExecuteAsSqlReader(string SqlQuery)
+ExecuteAsDataRows Method System.Object ExecuteAsDataRows(string SqlQuery)
ExecuteNonQuery Method System.Object ExecuteNonQuery(string SqlQuery)
ExecuteQuery Method System.Object ExecuteQuery(string SqlQuery), System.Object ExecuteQuery(string TableName, string SqlQuery)
GetCreateBasicDLL Method System.Object GetCreateBasicDLL(string TableName)
@@ -219,7 +219,6 @@ $ConnectionString = "Data Source={0};AttachDbFilename={1};Integrated Security=Tr
# Create a new instance of SqlQueryDataSet
$TestQuery = New-SqlQueryDataSet -SQLServer $SqlServer -Database $DatabaseName -ConnectionString $ConnectionString -DisplayResults $true
-
# There are at least 12 different overloaded Execute methods used execute queries and return results as different object types.
# Example usage of the class
@@ -232,6 +231,13 @@ $TestQuery.Tables[0].Result
$TestQuery.Tables[0].Query = "SELECT * FROM INFORMATION_SCHEMA.TABLES"
$TestQuery.Execute($TestQuery.Tables[0])
+$TestQuery = New-SqlQueryDataSet -SQLServer $SqlServer -Database $DatabaseName -ConnectionString $ConnectionString -DisplayResults $true -TableName 'Category' -Query 'SELECT * FROM [dbo].Category;'
+$TestQuery = New-SqlQueryDataSet -SQLServer $SqlServer -Database $DatabaseName -ConnectionString $ConnectionString -DisplayResults $false
+$TestQuery.ExecuteQuery('Category', 'SELECT * FROM [dbo].Category;')
+$TestQuery.Tables[0].Result[0]
+$TestQuery.DisplayResults = $false
+$TestQuery.Execute($TestQuery.Tables[0])
+
.NOTES
C:\Git\SqlQueryEditor> $TestQuery = [SqlQueryDataSet]::new()
PS C:\Git\SqlQueryEditor> $TestQuery | GM
@@ -249,7 +255,7 @@ Execute Method System.Object Execute(), System.Object Exe
ExecuteAsDataAdapter Method System.Object ExecuteAsDataAdapter(string SqlQuery)
ExecuteAsDataSet Method System.Object ExecuteAsDataSet(string SqlQuery)
ExecuteAsDataTable Method System.Object ExecuteAsDataTable(string SqlQuery)
-ExecuteAsSqlReader Method System.Object ExecuteAsSqlReader(string SqlQuery)
+ExecuteAsDataRows Method System.Object ExecuteAsDataRows(string SqlQuery)
ExecuteNonQuery Method System.Object ExecuteNonQuery(string SqlQuery)
ExecuteQuery Method System.Object ExecuteQuery(string SqlQuery), System.Object ExecuteQuery(string TableName, string SqlQuery)
GetCreateBasicDLL Method System.Object GetCreateBasicDLL(string TableName)
@@ -309,7 +315,7 @@ TableName Property string TableName {get;set;}
#>
-enum ResultType { DataTable; DataAdapter; DataSet; SqlReader; NonQuery; }
+enum ResultType { DataTable; DataRows; DataAdapter; DataSet; NonQuery; }
class SqlQueryTable {
[int]$TableIndex = 0
@@ -333,23 +339,14 @@ class SqlQueryTable {
class SqlQueryDataSet {
[string]$SQLServer
[string]$Database
- # [string]$Query
- # [string]$QueryFile
- # [string]$Path
[int]$ConnectionTimeout = 5
[int]$CommandTimeout = 600
# Connection string keywords: https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx
[string]$ConnectionString
[object]$SQLConnection
- # [object]$SQLCommand
- # [object]$SqlDataAdapter
- hidden [object]$SQLReader
- # [object]$Result
- # [ResultType]$Resulttype = [ResultType]::DataSet
[int]$TableIndex = 0
[System.Collections.Generic.List[SqlQueryTable]]$Tables
[System.Collections.Hashtable]$TableNames = @{}
- # [System.Data.DataTable]$Views
[bool]$DisplayResults = $True
[bool]$KeepAlive = $False
@@ -517,11 +514,6 @@ class SqlQueryDataSet {
# Method
[void] CloseConnection() {
- If ($This.SQLReader -and -not $This.SQLReader.IsClosed) {
- $This.SQLReader.Close()
- $This.SQLReader.Dispose()
- $This.SQLReader = $null
- }
If ($This.SQLConnection) {
$This.SQLConnection.Close()
$This.SQLConnection.Dispose()
@@ -529,26 +521,27 @@ class SqlQueryDataSet {
}
}
+ # Method
+ [System.Data.SqlClient.SqlCommand] GetSqlCommand([string]$query) {
+ $This.OpenConnection()
+ $SQLCommand = $This.SQLConnection.CreateCommand()
+ $SQLCommand.CommandText = $query
+ $SQLCommand.CommandTimeout = $This.CommandTimeout
+ $SQLCommand.Connection = $This.SQLConnection
+ Return $SQLCommand
+ }
+
[void] Clear() {
$This.CloseConnection()
$This.SQLServer = $null
$This.Database = $null
- # $This.Query = $null
- # $This.QueryFile = $null
- # $This.Path = $null
$This.ConnectionTimeout = 5
$This.CommandTimeout = 600
$This.ConnectionString = $null
$This.SQLConnection = $null
- # $This.SQLCommand = $null
- # $This.SqlDataAdapter = $null
- $This.SQLReader = $null
- # $This.ResultType = [ResultType]::DataTable
$This.TableIndex = 0
- # $This.Result = $null
$This.Tables.Clear()
$This.TableNames.Clear()
- # $This.Views = $null
$This.DisplayResults = $True
$This.KeepAlive = $False
}
@@ -560,76 +553,69 @@ class SqlQueryDataSet {
}
# Method
[Object] Execute([SqlQueryTable]$table) {
- $This.OpenConnection()
+ $SQLReader = $null
+ $table.SQLCommand = GetSqlCommand($table.Query)
Try {
- $table.SQLCommand = $This.SQLConnection.CreateCommand()
- $table.SQLCommand.CommandText = $table.Query
- $table.SQLCommand.CommandTimeout = $This.CommandTimeout
- $table.SQLCommand.Connection = $This.SQLConnection
- If ($table.ResultType -eq [ResultType]::DataTable) {
- $This.SQLReader = $table.SQLCommand.ExecuteReader()
- If ($This.SQLReader) {
+ If ($table.ResultType -in @([ResultType]::DataTable, [ResultType]::DataRows)) {
+ $SQLReader = $table.SQLCommand.ExecuteReader()
+ If ($SQLReader) {
$table.Result = [System.Data.DataTable]::new()
- $table.Result.Load($This.SQLReader)
+ $table.Result.Load($SQLReader)
If ($This.DisplayResults) {
- Return $table.Result.Tables[0]
+ If ($table.ResultType -eq [ResultType]::DataTable) {
+ Return ,$table.Result
+ } Else {
+ Return $table.Result
+ }
}
}
} ElseIf ($table.ResultType -eq [ResultType]::DataAdapter) {
- $table.SqlDataAdapter = [System.Data.SqlClient.SqlDataAdapter]::new($table.SQLCommand)
- $SqlCommandBuilder = [System.Data.SqlClient.SqlCommandBuilder]::new($table.SqlDataAdapter)
- $SqlCommandBuilder.DataAdapter = $table.SqlDataAdapter
-
$table.Result = [System.Data.DataSet]::new()
+ $table.SqlDataAdapter = [System.Data.SqlClient.SqlDataAdapter]::new($table.SQLCommand)
[void]$table.SqlDataAdapter.Fill($table.Result)
- $SqlCommandBuilder.DataAdapter = $table.SqlDataAdapter
- $SqlCommandBuilder.QuotePrefix = "["
- $SqlCommandBuilder.QuoteSuffix = "]"
- Try { $table.SqlDataAdapter.DeleteCommand = $SqlCommandBuilder.GetDeleteCommand()
- } Catch {
- Write-Warning "Failed to get DeleteCommand: $_"
- }
+ # $SqlCommandBuilder = [System.Data.SqlClient.SqlCommandBuilder]::new($table.SqlDataAdapter)
+ # $SqlCommandBuilder.DataAdapter = $table.SqlDataAdapter
+ # $SqlCommandBuilder.QuotePrefix = "["
+ # $SqlCommandBuilder.QuoteSuffix = "]"
+ # Try { $table.SqlDataAdapter.DeleteCommand = $SqlCommandBuilder.GetDeleteCommand()
+ # } Catch {
+ # Write-Warning "Failed to get DeleteCommand: $_"
+ # }
+ # Try { $table.SqlDataAdapter.UpdateCommand = $SqlCommandBuilder.GetUpdateCommand()
+ # } Catch {
+ # Write-Warning "Failed to get UpdateCommand: $_"
+ # }
+ # Try { $table.SqlDataAdapter.InsertCommand = $SqlCommandBuilder.GetInsertCommand()
+ # } Catch {
+ # Write-Warning "Failed to get InsertCommand: $_"
+ # }
- Try { $table.SqlDataAdapter.UpdateCommand = $SqlCommandBuilder.GetUpdateCommand()
- } Catch {
- #Write-Warning "Failed to get UpdateCommand: $_"
- }
-
- Try { $table.SqlDataAdapter.InsertCommand = $SqlCommandBuilder.GetInsertCommand()
- } Catch {
- Write-Warning "Failed to get InsertCommand: $_"
- }
If ($This.DisplayResults) {
Return $table.Result.Tables[0]
}
} ElseIf ($table.ResultType -eq [ResultType]::DataSet) {
- $table.SqlDataAdapter = [System.Data.SqlClient.SqlDataAdapter]::new($table.SQLCommand)
$table.Result = [System.Data.DataSet]::new()
+ $table.SqlDataAdapter = [System.Data.SqlClient.SqlDataAdapter]::new($table.SQLCommand)
[void]$table.SqlDataAdapter.Fill($table.Result)
If ($This.DisplayResults) {
Return $table.Result.Tables[0]
}
- } ElseIf ($table.ResultType -eq [ResultType]::SqlReader) {
- $This.SQLReader = $table.SQLCommand.ExecuteReader()
- If ($This.SQLReader) {
- $this.KeepAlive = $true
- $table.Result = $This.SQLReader
- If ($This.DisplayResults) {
- Return $table.Result
- }
- }
} ElseIf ($table.ResultType -eq [ResultType]::NonQuery) {
$table.Result = $table.SQLCommand.ExecuteNonQuery()
Return $table.Result
}
} Catch {
$This.SQLConnection.Close()
- return $(Write-host ($_ | Out-String) -ForegroundColor Red)
+ Return $(Write-host ($_ | Out-String) -ForegroundColor Red)
} Finally {
If (-not $this.KeepAlive) {
$This.CloseConnection()
}
+ If ($SQLReader -and -not $SQLReader.IsClosed) {
+ $SQLReader.Close()
+ $SQLReader.Dispose()
+ }
}
Return $null
}
@@ -720,12 +706,12 @@ class SqlQueryDataSet {
}
# Method
- [Object] ExecuteAsSqlReader([String]$SqlQuery) {
+ [Object] ExecuteAsDataRows([String]$SqlQuery) {
If ($SqlQuery) {
$This.TableIndex = $This.AddQuery($SqlQuery)
}
$table = $This.Tables[$This.TableIndex]
- $table.ResultType = [ResultType]::SqlReader
+ $table.ResultType = [ResultType]::DataRows
Return ($This.Execute($table))
}
@@ -754,6 +740,17 @@ class SqlQueryDataSet {
# ForEach ($row in $dataView) {Write-Host ($row | FT -AutoSize | Out-String).Trim()}
# Write-Host ($dataView | FT -AutoSize | Out-String).Trim()
+ $commandBuilder = [System.Data.SqlClient.SqlCommandBuilder]::new($table.SqlDataAdapter)
+ $table.SqlDataAdapter.UpdateCommand = $commandBuilder.GetUpdateCommand()
+ $table.SqlDataAdapter.InsertCommand = $commandBuilder.GetInsertCommand()
+ $table.SqlDataAdapter.DeleteCommand = $commandBuilder.GetDeleteCommand()
+
+ If ($table.ResultType -in @([ResultType]::DataAdapter,[ResultType]::DataSet)) {
+ $table.SqlDataAdapter.Update($table.Result.Tables[0])
+ } ElseIf ($table.ResultType -eq [ResultType]::DataTable) {
+ $table.SqlDataAdapter.Update($table.Result)
+ }
+
If (-not [String]::IsNullOrEmpty($table.SqlDataAdapter.DeleteCommand)) {
$table.SqlDataAdapter.DeleteCommand.Connection = $This.SQLConnection
}
@@ -921,149 +918,3 @@ class SqlQueryDataSet {
}
}
-
-<#
-$query = "SELECT * FROM [dbo].[Category] ORDER BY Category"
-$query -match '^.*FROM[ \n\r]+(?\w+)[. \n\r]+(\w+)[ \n\r]+(?\w+)$'
-$Matches
-
-$query -match '^.*?(FROM|INTO|JOIN)\s`?(?[^` ]*).*$'
-$Matches
-
-$query -match "\bJOIN\s+(?[a-zA-Z\._\d\[\]]+)\b|\bFROM\s+(?[a-zA-Z\._\d\[\]]+)\b|\bUPDATE\s+(?[a-zA-Z\._\d]+)\b|\bINSERT\s+(?:\bINTO\b)?\s+(?[a-zA-Z\._\d]+)\b|\bTRUNCATE\s+TABLE\s+(?[a-zA-Z\._\d]+)\b|\bDELETE\s+(?:\bFROM\b)?\s+(?[a-zA-Z\._\d]+)\b"
-$Matches
-
-# $query -match '[\s\t]*FROM[\s\t\r\n]([A-Za-z0-9_.]+)[\s\t\r\n]*([A-Za-z0-9_.\[\]]*)[\s\t\r\n]*'
-
-$query = "SELECT * FROM [dbo].[Category] ORDER BY Category"
-$query -match '[\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$'
-$Matches
-
-
-$query = "SELECT *
-FROM [dbo].[Category]
-ORDER BY Category"
-
-$query -match "\bJOIN\s+(?[a-zA-Z\._\d\[\]]+)\b|\bFROM\s+(?[a-zA-Z\._\d\[\]]+)\b|\bUPDATE\s+(?[a-zA-Z\._\d]+)\b|\bINSERT\s+(?:\bINTO\b)?\s+(?[a-zA-Z\._\d]+)\b|\bTRUNCATE\s+TABLE\s+(?[a-zA-Z\._\d]+)\b|\bDELETE\s+(?:\bFROM\b)?\s+(?[a-zA-Z\._\d]+)\b"
-$Matches
-
-
-$query -match '^.*?(FROM|INTO|JOIN)\s`?(?[^` ]*).*$'
-$Matches
-
-[ \n\r]+
-
-$query = "SELECT *
-FROM [dbo].[Category]
-ORDER BY Category"
-
-$query -match '(?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$'
-$Matches
-
-$query = "SELECT *
-FROM [dbo].[Category]
-ORDER BY Category"
-$query -match '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$)'
-$Matches
-
-$query = "SELECT * FROM [dbo].[Category] ORDER BY Category"
-$query -match '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$)'
-$Matches
-
-$query = "SELECT * FROM dbo.Category ORDER BY Category"
-$query -match '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$)'
-$Matches
-
-$query = "SELECT * FROM Category ORDER BY Category"
-$query -match '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$)'
-$Matches
-
-$schemaTable = $Matches.schemaTable
-$schemaTable -match '(?: \[(?[^ \[\] ]+)\] \.)?(?: \[?(?[^ \[\] \.]+)\] ?)$'
-$schemaTable -match '(?i)\bFROM\s+((? \[?[A-Za-z0-9_]+\] ?)\.)?(? \[?[A-Za-z0-9_]+\] ?)'
-
-$schemaTable = '[dbo].[Category]'
-# $schemaTable -match '[\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$'
-$schemaTable -match '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$Matches
-
-$schemaTable = 'dbo.[Category]'
-# $schemaTable -match '[\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$'
-$schemaTable -match '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$Matches
-
-$schemaTable = 'dbo.Category'
-# $schemaTable -match '[\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$'
-$schemaTable -match '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$Matches
-
-$schemaTable = '[Category]'
-$schemaTable -match '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$Matches
-
-$schemaTable = 'Category'
-$schemaTable -match '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$Matches
-
-$pattern = '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$schemaTable = '[dbo].[Category]'
-$schemaTable -match $pattern
-$Matches
-$schemaTable = 'dbo.[Category]'
-$schemaTable -match $pattern
-$Matches
-$schemaTable = '[dbo].Category'
-$schemaTable -match $pattern
-$Matches
-$schemaTable = 'dbo.Category'
-$schemaTable -match $pattern
-$Matches
-$schemaTable = '[Category]'
-$schemaTable -match $pattern
-$Matches
-$schemaTable = 'Category'
-$schemaTable -match $pattern
-$Matches
-
-$pattern = '([\[]?(?[A-Za-z0-9_]+)[\.\[\] ]?$)|([\[]?(?[A-Za-z0-9_]+)[\.\[\]]*(?[A-Za-z0-9_]+)[\.\[\] ]?$)'
-$schemaTableFormats = @('[dbo].[Category]', 'dbo.[Category]', '[dbo].Category', 'dbo.Category', '[Category]', 'Category')
-foreach ($schemaTable in $schemaTableFormats) {
- if ($schemaTable -match $pattern) {
- Write-Output "Match found for: $schemaTable"
- Write-Output "Schema: $($Matches['schema'])"
- Write-Output "Table Name: $($Matches['tableName'])"
- } else {
- Write-Output "No match found for: $schemaTable"
- }
-}
-
-#>
-<# # >
-$SqlQueries = @(
-"SELECT TABLE_NAME `"Name`" FROM [F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF].INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT LIKE '[_]%' ORDER BY TABLE_TYPE, TABLE_NAME;"
-'SELECT * FROM [F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF].[dbo].[Document] ORDER BY Id DESC;',
-'SELECT * FROM [F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF].[dbo].Document ORDER BY Id DESC;',
-'SELECT * FROM [F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF].dbo.Document ORDER BY Id DESC;',
-'SELECT * FROM [F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF].dbo.[Document] ORDER BY Id DESC;',
-'SELECT * FROM F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF.[dbo].[Document] ORDER BY Id DESC;',
-'SELECT * FROM F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF.dbo.[Document] ORDER BY Id DESC;',
-'SELECT * FROM F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF.dbo.Document ORDER BY Id DESC;',
-'SELECT * FROM [dbo].[Document] ORDER BY Id DESC;',
-'SELECT * FROM [dbo].Document ORDER BY Id DESC;',
-'SELECT * FROM dbo.Document ORDER BY Id DESC;',
-'SELECT * FROM dbo.[Document] ORDER BY Id DESC;'
-)
-foreach ($SqlQuery in $SqlQueries) {
- If ($SqlQuery -like '*\*' -and $SqlQuery -like '*.MDF*') {
- # $pattern = '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_\[\]]+)[.]{1}(?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_\[\]]+)[.]{1}(?[A-Za-z0-9_. \[\] ]+).*$)'
- $pattern = '([\s\t]*FROM[\s\t\r\n](?[\[]?[A-Za-z0-9_\:\\]+[\.MDF]{4}[\]]?)[.]{1}(?[A-Za-z0-9_.\[\]]+).*$)'
- # ((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_\[\]]+)[.]{1}(?[A-Za-z0-9_. \[\] ]+).*$)'
- } Else {
- $pattern = '([\s\t]*FROM[\s\t\r\n](?[A-Za-z0-9_.\[\]]+).*$)|((?s)[\s\t]*FROM[\s\t\r\n]+(?[A-Za-z0-9_. \[\] ]+).*$)'
- }
- Write-Host $SqlQuery -ForegroundColor Green
- if ($SqlQuery -match $pattern) {
- $Matches
- }
-}
-#>
From db1637423d1a027c797c2471724a709fbe68ae20 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 01:41:59 -0500
Subject: [PATCH 05/20] Missing $This.GetSqlCommand
---
src/private/SqlQueryClass.ps1 | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/private/SqlQueryClass.ps1 b/src/private/SqlQueryClass.ps1
index 467ccf3..0ccdce5 100644
--- a/src/private/SqlQueryClass.ps1
+++ b/src/private/SqlQueryClass.ps1
@@ -554,7 +554,7 @@ class SqlQueryDataSet {
# Method
[Object] Execute([SqlQueryTable]$table) {
$SQLReader = $null
- $table.SQLCommand = GetSqlCommand($table.Query)
+ $table.SQLCommand = $This.GetSqlCommand($table.Query)
Try {
If ($table.ResultType -in @([ResultType]::DataTable, [ResultType]::DataRows)) {
$SQLReader = $table.SQLCommand.ExecuteReader()
From 6c3f508ce1d5b94cd9c00a397c76291cb1d1f357 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 02:28:30 -0500
Subject: [PATCH 06/20] Added [void]$instance.AddQuery()
---
src/public/New-SqlQueryDataSet.ps1 | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/public/New-SqlQueryDataSet.ps1 b/src/public/New-SqlQueryDataSet.ps1
index d69f603..9643fcc 100644
--- a/src/public/New-SqlQueryDataSet.ps1
+++ b/src/public/New-SqlQueryDataSet.ps1
@@ -52,9 +52,9 @@ function New-SqlQueryDataSet {
} else {
$instance = [SqlQueryDataSet]::new($SQLServer, $Database)
if ([string]::IsNullOrEmpty($TableName)) {
- $instance.AddQuery($Query)
+ [void]$instance.AddQuery($Query)
} else {
- $instance.AddQuery($Query, $TableName)
+ [void]$instance.AddQuery($Query, $TableName)
}
$instance
}
@@ -64,9 +64,9 @@ function New-SqlQueryDataSet {
if (-not [string]::IsNullOrEmpty($Database)) { $instance.Database = $Database }
if ($Query) {
if ([string]::IsNullOrEmpty($TableName)) {
- $instance.AddQuery($Query)
+ [void]$instance.AddQuery($Query)
} else {
- $instance.AddQuery($Query, $TableName)
+ [void]$instance.AddQuery($Query, $TableName)
}
}
$instance
From 728786440d97a00f2cafcd57a1ae09d0bad5bfb3 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 11:03:20 -0500
Subject: [PATCH 07/20] Added ParameterSetName
---
src/private/SqlQueryClass.ps1 | 2 +-
src/public/New-SqlQueryDataSet.ps1 | 48 +++++++++++++++++++++---------
2 files changed, 35 insertions(+), 15 deletions(-)
diff --git a/src/private/SqlQueryClass.ps1 b/src/private/SqlQueryClass.ps1
index 0ccdce5..c6947ed 100644
--- a/src/private/SqlQueryClass.ps1
+++ b/src/private/SqlQueryClass.ps1
@@ -323,7 +323,7 @@ class SqlQueryTable {
[string]$Query = [string]::Empty
[object]$SQLCommand = $null
[object]$SqlDataAdapter = $null
- [ResultType]$ResultType = [ResultType]::NonQuery
+ [ResultType]$ResultType = [ResultType]::DataTable
[object]$Result = $null
[bool]$isDirty = $false
[string]$QueryFile = [string]::Empty
diff --git a/src/public/New-SqlQueryDataSet.ps1 b/src/public/New-SqlQueryDataSet.ps1
index 9643fcc..0321540 100644
--- a/src/public/New-SqlQueryDataSet.ps1
+++ b/src/public/New-SqlQueryDataSet.ps1
@@ -1,25 +1,31 @@
<#
.SYNOPSIS
- Creates and returns an Object instance of the [SqlQueryDataSet] class configured with or without the specified parameters.
+ New-SqlQueryDataSet -- Creates and returns an Object instance of the [SqlQueryDataSet] class configured with or without the specified parameters.
.DESCRIPTION
- This function initializes a new instance of the [SqlQueryDataSet] class based on the provided SQL Server,
- Database, ConnectionString, Query, and TableName.
+ This function initializes a new instance of the [SqlQueryDataSet] class and the resulting object is configured is based which parameters were specified.
+
+ All parameters are optional as the can be configured later using the [SqlQueryDataSet]$object returned when calling $object = New-SqlQueryDataSet
+ When using $SQLServer and $Database, both must be specified together. The [SqlQueryDataSet] class will auto generate a SQL ConnectionString.
+ Specifying $ConnectionString overrides auto generation even when $SQLServer and $Database are also specified.
+
Based on which parameters are passed, this CmdLet will use one of the overloaded class constructors and configure instance settings with the other parameters:
- [SqlQueryDataSet]::new()
- [SqlQueryDataSet]::new(string SQLServer, string Database)
- [SqlQueryDataSet]::new(string SQLServer, string Database, string Query)
+
.PARAMETER SQLServer
- The name of the SQL Server.
+ The name or address of the SQL Server to connect to. This parameter is optional, but when used, must be specified with $Database.
.PARAMETER Database
- The name of the Database.
+ The name of the database to connect to on the specified SQL Server. This parameter is also optional, but when used, must be specified with $SQLServer.
.PARAMETER ConnectionString
- The connection string for the SQL Server.
+ The full connection string to use for connecting to the SQL Server. This parameter is optional and provides an alternative to specifying $SQLServer and $Database separately.
.PARAMETER Query
- The SQL query to be executed.
+ The SQL query to execute against the database. This parameter is optional, only configures the query settings, and does not trigger execution. Best when used with $TableName.
.PARAMETER TableName
- The name of the table to store the query results.
+ Unique identifier that names the configuration of this Query. This parameter is optional and a $TableName will be parsed from only simple queries which is why its best to specify with $Query.
.PARAMETER DisplayResults
- Boolean flag to display the results. Default is true which effects query executions by outputting the Results property contents to standard out.
+ Boolean flag indicating whether to display the query results. The default value is $true.
+ The [SqlQueryDataSet] class uses this flag to output content to standard out when executing content generating methods such as Execute().
.EXAMPLE
$result = New-SqlQueryDataSet -SQLServer "myServer" -Database "myDB" -Query "SELECT * FROM myTable"
.EXAMPLE
@@ -31,19 +37,33 @@
#>
function New-SqlQueryDataSet {
- # Suppress PSScriptAnalyzer rule about ShouldProcess
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
-
- [CmdletBinding()]
+ [CmdletBinding(DefaultParameterSetName = 'ServerDatabase')]
param (
+ [Parameter(ParameterSetName = 'ServerDatabase', Mandatory = $false)]
+ [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
[string]$SQLServer,
+
+ [Parameter(ParameterSetName = 'ServerDatabase', Mandatory = $false)]
+ [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
[string]$Database,
+
+ [Parameter(ParameterSetName = 'ConnectionString', Mandatory = $false)]
+ [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
[string]$ConnectionString,
+
+ [Parameter(Mandatory = $false)]
[string]$Query,
+
+ [Parameter(Mandatory = $false)]
[string]$TableName,
+
+ [Parameter(Mandatory = $false)]
[bool]$DisplayResults = $true
)
-
+
+ # Suppress PSScriptAnalyzer rule about ShouldProcess
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
+
$SqlQueryInstance = if ([string]::IsNullOrEmpty($SQLServer) -and [string]::IsNullOrEmpty($ConnectionString) -and [string]::IsNullOrEmpty($Database)) {
[SqlQueryDataSet]::new()
} elseif (-not [string]::IsNullOrEmpty($SQLServer) -and -not [string]::IsNullOrEmpty($Database)) {
From 22dac775d22e48ccfbe6a98707a46606537e5472 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 15:54:57 -0500
Subject: [PATCH 08/20] Added Test Database and Pester test
---
src/public/New-SqlQueryDataSet.ps1 | 80 ++++++------
tests/New-SqlQueryDataSets.tests.ps1 | 178 +++++++++++++++++++++++++++
tests/TestDatabase1.parameters.psd1 | 7 ++
3 files changed, 228 insertions(+), 37 deletions(-)
create mode 100644 tests/New-SqlQueryDataSets.tests.ps1
create mode 100644 tests/TestDatabase1.parameters.psd1
diff --git a/src/public/New-SqlQueryDataSet.ps1 b/src/public/New-SqlQueryDataSet.ps1
index 0321540..00eda08 100644
--- a/src/public/New-SqlQueryDataSet.ps1
+++ b/src/public/New-SqlQueryDataSet.ps1
@@ -13,6 +13,10 @@
- [SqlQueryDataSet]::new(string SQLServer, string Database)
- [SqlQueryDataSet]::new(string SQLServer, string Database, string Query)
+ Explanation of Parameter Sets:
+ - **`ServerDatabase`**: This parameter set allows the user to specify the SQL Server and Database separately without needing a full connection string.
+ - **`ServerDatabaseWithConnectionString`**: This parameter set allows the user to provide both the SQL Server and Database separately, or use a connection string.
+ - **`ConnectionString`**: This parameter set allows the user to provide a connection string directly.
.PARAMETER SQLServer
The name or address of the SQL Server to connect to. This parameter is optional, but when used, must be specified with $Database.
.PARAMETER Database
@@ -26,10 +30,14 @@
.PARAMETER DisplayResults
Boolean flag indicating whether to display the query results. The default value is $true.
The [SqlQueryDataSet] class uses this flag to output content to standard out when executing content generating methods such as Execute().
+.FUNCTIONALITY
+ Creates and initializes an Instance of [SqlQueryDataSet] class
+.OUTPUTS
+ Object of [SqlQueryDataSet] class
.EXAMPLE
$result = New-SqlQueryDataSet -SQLServer "myServer" -Database "myDB" -Query "SELECT * FROM myTable"
.EXAMPLE
- $result = New-SqlQueryDataSet -ConnectionString "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;" -Query "SELECT * FROM myTable" -DisplayResults $false
+ $result = New-SqlQueryDataSet -ConnectionString "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;" -Query "SELECT * FROM myTable" -TableName myTable -DisplayResults $false
.NOTES
Author: Brooks Vaughn
Date: 2025-02-01
@@ -38,20 +46,22 @@
function New-SqlQueryDataSet {
[CmdletBinding(DefaultParameterSetName = 'ServerDatabase')]
+ # Suppress PSScriptAnalyzer rule about ShouldProcess
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
+
param (
- [Parameter(ParameterSetName = 'ServerDatabase', Mandatory = $false)]
- [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
+ [Parameter(Mandatory = $false)]
[string]$SQLServer,
- [Parameter(ParameterSetName = 'ServerDatabase', Mandatory = $false)]
- [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
+ [Parameter(Mandatory = $false)]
+ [ValidateScript({ if ($SQLServer -and -not $_) { throw "Database must be provided if SQLServer is specified." } else { $true } })]
[string]$Database,
- [Parameter(ParameterSetName = 'ConnectionString', Mandatory = $false)]
- [Parameter(ParameterSetName = 'ServerDatabaseWithConnectionString', Mandatory = $false)]
+ [Parameter(Mandatory = $false)]
[string]$ConnectionString,
[Parameter(Mandatory = $false)]
+ [ValidateScript({ if ($TableName -and -not $_) { throw "Query must be provided if TableName is specified." } else { $true } })]
[string]$Query,
[Parameter(Mandatory = $false)]
@@ -61,39 +71,35 @@ function New-SqlQueryDataSet {
[bool]$DisplayResults = $true
)
- # Suppress PSScriptAnalyzer rule about ShouldProcess
- [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
+ # Function logic here
+ if ($SQLServer -and -not $Database) {
+ Write-Warning "Database must be provided if SQLServer is specified."
+ }
- $SqlQueryInstance = if ([string]::IsNullOrEmpty($SQLServer) -and [string]::IsNullOrEmpty($ConnectionString) -and [string]::IsNullOrEmpty($Database)) {
- [SqlQueryDataSet]::new()
- } elseif (-not [string]::IsNullOrEmpty($SQLServer) -and -not [string]::IsNullOrEmpty($Database)) {
- if ([string]::IsNullOrEmpty($Query)) {
- [SqlQueryDataSet]::new($SQLServer, $Database)
- } else {
- $instance = [SqlQueryDataSet]::new($SQLServer, $Database)
- if ([string]::IsNullOrEmpty($TableName)) {
- [void]$instance.AddQuery($Query)
- } else {
- [void]$instance.AddQuery($Query, $TableName)
- }
- $instance
- }
+ if ($Database -and -not $SQLServer) {
+ Write-Warning "SQLServer must be provided if Database is specified."
+ }
+
+ if ($TableName -and -not $Query) {
+ Write-Warning "Query must be provided if TableName is specified."
+ }
+
+ $instance = $null
+ if (-not [string]::IsNullOrEmpty($SQLServer) -and -not [string]::IsNullOrEmpty($Database)) {
+ $instance = [SqlQueryDataSet]::new($SQLServer, $Database)
} else {
$instance = [SqlQueryDataSet]::new()
- if (-not [string]::IsNullOrEmpty($SQLServer)) { $instance.SQLServer = $SQLServer }
- if (-not [string]::IsNullOrEmpty($Database)) { $instance.Database = $Database }
- if ($Query) {
- if ([string]::IsNullOrEmpty($TableName)) {
- [void]$instance.AddQuery($Query)
- } else {
- [void]$instance.AddQuery($Query, $TableName)
- }
+ }
+ if (-not [string]::IsNullOrEmpty($Query)) {
+ if (-not [string]::IsNullOrEmpty($TableName)) {
+ [void]$instance.AddQuery($Query, $TableName)
+ } else {
+ [void]$instance.AddQuery($Query)
}
- $instance
}
-
- if ($ConnectionString) { $SqlQueryInstance.ConnectionString = $ConnectionString }
- $SqlQueryInstance.DisplayResults = $DisplayResults
-
- return $SqlQueryInstance
+ if (-not [string]::IsNullOrEmpty($ConnectionString)) { $instance.ConnectionString = $ConnectionString }
+ if (-not [string]::IsNullOrEmpty($SQLServer)) { $instance.SQLServer = $SQLServer }
+ if (-not [string]::IsNullOrEmpty($Database)) { $instance.Database = $Database }
+ $instance.DisplayResults = $DisplayResults
+ return $instance
}
diff --git a/tests/New-SqlQueryDataSets.tests.ps1 b/tests/New-SqlQueryDataSets.tests.ps1
new file mode 100644
index 0000000..9e9e27b
--- /dev/null
+++ b/tests/New-SqlQueryDataSets.tests.ps1
@@ -0,0 +1,178 @@
+Describe 'New-SqlQueryDataSet' {
+ BeforeAll {
+ $data = Get-MTProjectInfo
+ # Import-Module -Name "$($data.ProjectName)" -Verbose -Force
+ Import-Module "$($data.ManifestFilePSD1)" -Verbose -Force
+ $fsoParamFile = [System.IO.FileInfo]("$($data.ProjectRoot)/test1.parameters.psd1")
+ $params = @{}
+ If ($fsoParamFile.Exists) {
+ $params = Import-PowerShellDataFile -Path $fsoParamFile.FullName
+ Write-Host ("Loaded Parameters from: $($fsoParamFile.FullName)")
+ }
+ Write-Host ("Parameters: $($params | Out-String)")
+ }
+
+ Context 'When using No Parameters' {
+ It 'Should create an instance with No Parameters' {
+ $result = New-SqlQueryDataSet
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -BeNullOrEmpty
+ $result.SQLServer | Should -BeNullOrEmpty
+ $result.ConnectionString | Should -BeNullOrEmpty
+ $result.Tables | Should -BeNullOrEmpty
+ $result.TableNames | Should -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 0
+ }
+ }
+
+ Context 'When using SQLServer' {
+ It 'Should create an instance with SQLServer' {
+ $result = New-SqlQueryDataSet -SQLServer $params.SqlServer
+ $result | Should -Not -BeNullOrEmpty
+ $result.SQLServer | Should -Be $params.SqlServer
+ $result.Database | Should -BeNullOrEmpty
+ }
+ }
+
+ Context 'When using Database' {
+ It 'Should create an instance with Database' {
+ $result = New-SqlQueryDataSet -Database $params.Database
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -Be $params.Database
+ $result.SQLServer | Should -BeNullOrEmpty
+ }
+ }
+
+ Context 'When using SQLServer and Database' {
+ It 'Should create an instance with SQLServer and Database' {
+ $result = New-SqlQueryDataSet -SQLServer $params.SqlServer -Database $params.Database
+ $result | Should -Not -BeNullOrEmpty
+ $result.SQLServer | Should -Be $params.SqlServer
+ $result.Database | Should -Be $params.Database
+ }
+ }
+
+ Context 'When using ConnectionString' {
+ It 'Should create an instance with ConnectionString' {
+ $result = New-SqlQueryDataSet -ConnectionString $params.ConnectionString
+ $result | Should -Not -BeNullOrEmpty
+ $result.ConnectionString | Should -Be $params.ConnectionString
+ }
+ }
+
+ Context 'When using ConnectionString SQLServer and Database' {
+ It 'Should create an instance with ConnectionString, SQLServer, and Database' {
+ $result = New-SqlQueryDataSet -SQLServer $params.SqlServer -Database $params.Database -ConnectionString $params.ConnectionString
+ $result | Should -Not -BeNullOrEmpty
+ $result.ConnectionString | Should -Be $params.ConnectionString
+ $result.SQLServer | Should -Be $params.SqlServer
+ $result.Database | Should -Be $params.Database
+ }
+ }
+
+ Context 'When using SQLServer, Database, and Query' {
+ It 'Should create an instance with SQLServer, Database, and Query' {
+ $result = New-SqlQueryDataSet -SQLServer $params.SqlServer -Database $params.Database -Query "SELECT * FROM myTable"
+ $result | Should -Not -BeNullOrEmpty
+ $result.SQLServer | Should -Be $params.SqlServer
+ $result.Database | Should -Be $params.Database
+ $result.TableIndex | Should -Be 0
+ $result.Tables | Should -Not -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 1
+ $result.Tables[$result.TableIndex].TableIndex | Should -Be $result.TableIndex
+ $result.Tables[$result.TableIndex].TableName | Should -Be "myTable"
+ $result.Tables[$result.TableIndex].Query | Should -Be "SELECT * FROM myTable"
+ }
+ }
+
+ Context 'When using ConnectionString and Query' {
+ It 'Should create an instance with ConnectionString and Query' {
+ $result = New-SqlQueryDataSet -ConnectionString $params.ConnectionString -Query $params.Query
+ $result | Should -Not -BeNullOrEmpty
+ $result.ConnectionString | Should -Be $params.ConnectionString
+ $result.TableIndex | Should -Be 0
+ $result.Tables | Should -Not -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 1
+ $result.Tables[$result.TableIndex].TableIndex | Should -Be $result.TableIndex
+ $result.Tables[$result.TableIndex].TableName | Should -Be "TABLES"
+ $result.Tables[$result.TableIndex].Query | Should -Be $params.Query
+ $result.Tables[$result.TableIndex].ResultType | Should -Be 'DataTable'
+ }
+ }
+
+ Context 'When using ConnectionString, Query, and TableName' {
+ It 'Should create an instance with ConnectionString and Query' {
+ $result = New-SqlQueryDataSet -ConnectionString $params.ConnectionString -Query $params.Query -TableName $params.TableName
+ $result | Should -Not -BeNullOrEmpty
+ $result.ConnectionString | Should -Be $params.ConnectionString
+ $result.TableIndex | Should -Be 0
+ $result.Tables | Should -Not -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 1
+ $result.Tables[$result.TableIndex].TableIndex | Should -Be $result.TableIndex
+ $result.Tables[$result.TableIndex].TableName | Should -Be $params.TableName
+ $result.Tables[$result.TableIndex].Query | Should -Be $params.Query
+ $result.Tables[$result.TableIndex].ResultType | Should -Be 'DataTable'
+ }
+ }
+
+ Context 'When using Query and TableName' {
+ It 'Should create an instance with Query and TableName' {
+ $result = New-SqlQueryDataSet -Query $params.Query -TableName $params.TableName
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -BeNullOrEmpty
+ $result.SQLServer | Should -BeNullOrEmpty
+ $result.ConnectionString | Should -BeNullOrEmpty
+ $result.TableIndex | Should -Be 0
+ $result.Tables | Should -Not -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 1
+ $result.Tables[$result.TableIndex].TableIndex | Should -Be $result.TableIndex
+ $result.Tables[$result.TableIndex].TableName | Should -Be $params.TableName
+ $result.Tables[$result.TableIndex].Query | Should -Be $params.Query
+ $result.Tables[$result.TableIndex].ResultType | Should -Be 'DataTable'
+ }
+ }
+
+ Context 'When using Query' {
+ It 'Should create an instance with Query' {
+ $result = New-SqlQueryDataSet -Query $params.Query
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -BeNullOrEmpty
+ $result.SQLServer | Should -BeNullOrEmpty
+ $result.ConnectionString | Should -BeNullOrEmpty
+ $result.TableIndex | Should -Be 0
+ $result.Tables | Should -Not -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 1
+ $result.Tables[$result.TableIndex].TableIndex | Should -Be $result.TableIndex
+ $result.Tables[$result.TableIndex].TableName | Should -Be 'TABLES'
+ $result.Tables[$result.TableIndex].Query | Should -Be $params.Query
+ $result.Tables[$result.TableIndex].ResultType | Should -Be 'DataTable'
+ }
+ }
+
+ Context 'When using TableName' {
+ It 'Should create an instance with no configuration as TableName is ignored without Query' {
+ $result = New-SqlQueryDataSet -TableName $params.TableName
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -BeNullOrEmpty
+ $result.SQLServer | Should -BeNullOrEmpty
+ $result.ConnectionString | Should -BeNullOrEmpty
+ $result.Tables | Should -BeNullOrEmpty
+ $result.TableNames | Should -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 0
+ }
+ }
+
+ Context 'When using DisplayResults' {
+ It 'Should create an instance with DisplayResults set to false' {
+ $result = New-SqlQueryDataSet -DisplayResults $false
+ $result | Should -Not -BeNullOrEmpty
+ $result.Database | Should -BeNullOrEmpty
+ $result.SQLServer | Should -BeNullOrEmpty
+ $result.ConnectionString | Should -BeNullOrEmpty
+ $result.Tables | Should -BeNullOrEmpty
+ $result.TableNames | Should -BeNullOrEmpty
+ $result.TableNames.Count | Should -Be 0
+ $result.DisplayResults | Should -Be $false
+ }
+ }
+}
diff --git a/tests/TestDatabase1.parameters.psd1 b/tests/TestDatabase1.parameters.psd1
new file mode 100644
index 0000000..7513dd9
--- /dev/null
+++ b/tests/TestDatabase1.parameters.psd1
@@ -0,0 +1,7 @@
+@{
+ "ConnectionString" = "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=DATABASE1.MDF;Integrated Security=True";
+ "TableName" = "DBTable";
+ "SqlServer" = "(localdb)\MSSQLLocalDB";
+ "Database" = "DATABASE1.MDF";
+ "Query" = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = `'BASE TABLE`' ORDER BY TABLE_SCHEMA, TABLE_NAME;"
+}
From 10c2fb4a670500af5a0253b61b04be1f614ead4f Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 22:11:46 -0500
Subject: [PATCH 09/20] Added Database Maintenance Functions
---
src/public/Dismount-Database.ps1 | 20 +++++++++++
src/public/Get-DatabaseTables.ps1 | 14 ++++++++
src/public/Get-Databases.ps1 | 16 +++++++++
src/public/Invoke-DatabaseNonQuery.ps1 | 32 +++++++++++++++++
src/public/Invoke-DatabaseQuery.ps1 | 49 ++++++++++++++++++++++++++
src/public/Mount-Database.ps1 | 20 +++++++++++
tests/New-SqlQueryDataSets.tests.ps1 | 43 ++++++++++++++++++++--
tests/TestDatabase1.parameters.psd1 | 4 +--
8 files changed, 194 insertions(+), 4 deletions(-)
create mode 100644 src/public/Dismount-Database.ps1
create mode 100644 src/public/Get-DatabaseTables.ps1
create mode 100644 src/public/Get-Databases.ps1
create mode 100644 src/public/Invoke-DatabaseNonQuery.ps1
create mode 100644 src/public/Invoke-DatabaseQuery.ps1
create mode 100644 src/public/Mount-Database.ps1
diff --git a/src/public/Dismount-Database.ps1 b/src/public/Dismount-Database.ps1
new file mode 100644
index 0000000..a2d58c6
--- /dev/null
+++ b/src/public/Dismount-Database.ps1
@@ -0,0 +1,20 @@
+Function Dismount-Database {
+ Param (
+ $connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True",
+ $Database = 'TestDatabase1',
+ [Switch]$Quiet
+ )
+ Write-Warning "`nDetaching Database: ($Database)"
+ $NonQuery = "EXEC sp_detach_db '$Database'"
+ $Splat = @{connectionString = $connectionString; NonQuery = $NonQuery}
+ # Remove any null value parameters to use called function's default value
+ $Splat.Keys.Where({-not $Splat[$_]}).ForEach({$Splat.Remove($_)})
+ Invoke-DatabaseNonQuery @Splat -Quiet:$Quiet
+}
+<# Usage Example: # >
+$Error.Clear()
+# Dismount-Database
+# Dismount-Database -Database:$null
+Dismount-Database -Database 'TestDataBase1'
+Get-Databases
+#>
diff --git a/src/public/Get-DatabaseTables.ps1 b/src/public/Get-DatabaseTables.ps1
new file mode 100644
index 0000000..d3a1275
--- /dev/null
+++ b/src/public/Get-DatabaseTables.ps1
@@ -0,0 +1,14 @@
+Function Get-DatabaseTables {
+ Param (
+ $connectionString,
+ $query = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;",
+ [Switch]$Quiet
+ )
+ $Splat = @{ connectionString = $connectionString; query = $query }
+ # Remove any null value parameters to use called function's default value
+ $Splat.Keys.Where({-not $Splat[$_]}).ForEach({$Splat.Remove($_)})
+ Invoke-DatabaseQuery @Splat -Quiet:$Quiet
+}
+<# Usage Examples: # >
+Get-DatabaseTables
+#>
diff --git a/src/public/Get-Databases.ps1 b/src/public/Get-Databases.ps1
new file mode 100644
index 0000000..f099a9d
--- /dev/null
+++ b/src/public/Get-Databases.ps1
@@ -0,0 +1,16 @@
+Function Get-Databases {
+ Param (
+ $connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True",
+ $query = "SELECT name FROM sys.databases;",
+ [Switch]$Quiet
+ )
+ $Splat = @{connectionString = $connectionString; query = $query}
+ # Remove any null value parameters to use called function's default value
+ $Splat.Keys.Where({-not $Splat[$_]}).ForEach({$Splat.Remove($_)})
+ Invoke-DatabaseQuery @Splat -Quiet:$Quiet
+}
+<# Usage Examples # >
+Get-Databases
+Get-Databases -Quiet
+Get-Databases -connectionString:$null
+#>
\ No newline at end of file
diff --git a/src/public/Invoke-DatabaseNonQuery.ps1 b/src/public/Invoke-DatabaseNonQuery.ps1
new file mode 100644
index 0000000..198602a
--- /dev/null
+++ b/src/public/Invoke-DatabaseNonQuery.ps1
@@ -0,0 +1,32 @@
+Function Invoke-DatabaseNonQuery {
+ Param (
+ $connectionString = "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Git\SqlQueryClass\tests\TestDatabase1.mdf;Integrated Security=True",
+ $NonQuery,
+ [Switch]$Quiet
+ )
+ If ([String]::IsNullOrWhiteSpace($NonQuery)) {
+ Throw "Parameter -NonQuery cannot be null or empty"
+ }
+ If (-Not $Quiet) {
+ Write-Host "`nUsing ConnectionString: ($connectionString)"
+ Write-Host ("Executing Database NonQuery: $($NonQuery | Out-String)").Trim()
+ }
+ Try {
+ # Create and open the connection
+ $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
+ $connection.Open()
+ # Create a command to attach the database
+ $attachCommand = $connection.CreateCommand()
+ $attachCommand.CommandText = $NonQuery
+ $attachCommand.ExecuteNonQuery()
+ } Catch {
+ Write-host ($_ | Out-String) -ForegroundColor Red
+ } Finally {
+ # Close connection
+ $connection.Close()
+ }
+}
+<# Usage Example: # >
+$Error.Clear()
+Invoke-DatabaseNonQuery -NonQuery "EXEC sp_detach_db 'NORTHWIND'"
+#>
diff --git a/src/public/Invoke-DatabaseQuery.ps1 b/src/public/Invoke-DatabaseQuery.ps1
new file mode 100644
index 0000000..4c9dbbc
--- /dev/null
+++ b/src/public/Invoke-DatabaseQuery.ps1
@@ -0,0 +1,49 @@
+Function Invoke-DatabaseQuery {
+ Param (
+ $connectionString = "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Git\SqlQueryClass\tests\TestDatabase1.mdf;Integrated Security=True",
+ $query,
+ [Switch]$Quiet
+ )
+ If ([String]::IsNullOrWhiteSpace($Query)) {
+ Throw "Parameter -Query cannot be null or empty"
+ }
+ If (-Not $Quiet) {
+ Write-Host "`nUsing ConnectionString: ($connectionString)"
+ Write-Host ("Executing SQL Query: $($Query | Out-String)").Trim()
+ }
+ $SQLReader = $null
+ $Result = $null
+ Try {
+ # Create and open the connection
+ $connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
+ $connection.Open()
+
+ # Create the command
+ $command = $connection.CreateCommand()
+ $command.CommandText = $query
+ $command.CommandTimeout = 600
+
+ # Execute the command and read the results
+ $SQLReader = $command.ExecuteReader()
+ If ($SQLReader) {
+ $Result = [System.Data.DataTable]::new()
+ $Result.Load($SQLReader)
+ }
+ # Write-Host ($Result.Rows | Out-String)
+ Return ,$Result
+ } Catch {
+ Write-host ($_ | Out-String) -ForegroundColor Red
+ } Finally {
+ # Close the reader and the connection
+ If ($SQLReader) {
+ $SQLReader.Close()
+ }
+ $connection.Close()
+ }
+}
+<# Usage Example: # >
+Invoke-DatabaseQuery -connectionString 'Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Git\SqlQueryClass\tests\TestDatabase1.mdf;Integrated Security=True' -query 'SELECT database_id, name, compatibility_level FROM sys.databases;'
+Invoke-DatabaseQuery -query "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;"
+Invoke-DatabaseQuery -query "SELECT * FROM SqlQuery;"
+Invoke-DatabaseQuery -query "SELECT * FROM SqlQueryParms;"
+#>
diff --git a/src/public/Mount-Database.ps1 b/src/public/Mount-Database.ps1
new file mode 100644
index 0000000..9c2b4f8
--- /dev/null
+++ b/src/public/Mount-Database.ps1
@@ -0,0 +1,20 @@
+Function Mount-Database {
+ Param (
+ $connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True",
+ $Database = 'TestDatabase1',
+ $DatabaseFilePath = 'C:\Git\SqlQueryClass\tests\TestDatabase1.mdf',
+ [Switch]$Quiet
+ )
+ Write-Warning "`nAttaching Database: ($Database) with Database File ($DatabaseFilePath)"
+ $Query = "CREATE DATABASE $Database ON (FILENAME = '$DatabaseFilePath') FOR ATTACH"
+ $Splat = @{ connectionString = $connectionString; query = $query }
+ # Remove any null value parameters to use called function's default value
+ $Splat.Keys.Where({-not $Splat[$_]}).ForEach({$Splat.Remove($_)})
+ Invoke-DatabaseQuery @Splat -Quiet:$Quiet
+}
+<# Usage Example: # >
+$Error.Clear()
+Mount-Database
+Get-Databases
+# Mount-Database -Database 'TestDataBase1' -DatabaseFilePath 'C:\Git\SqlQueryClass\tests\TestDatabase1.mdf'
+#>
diff --git a/tests/New-SqlQueryDataSets.tests.ps1 b/tests/New-SqlQueryDataSets.tests.ps1
index 9e9e27b..73ff4ee 100644
--- a/tests/New-SqlQueryDataSets.tests.ps1
+++ b/tests/New-SqlQueryDataSets.tests.ps1
@@ -3,11 +3,14 @@ Describe 'New-SqlQueryDataSet' {
$data = Get-MTProjectInfo
# Import-Module -Name "$($data.ProjectName)" -Verbose -Force
Import-Module "$($data.ManifestFilePSD1)" -Verbose -Force
- $fsoParamFile = [System.IO.FileInfo]("$($data.ProjectRoot)/test1.parameters.psd1")
+ $fsoParamFile = [System.IO.FileInfo]("$($data.ProjectRoot)/tests/TestDatabase1.parameters.psd1")
$params = @{}
If ($fsoParamFile.Exists) {
+ Write-Host ("Loading Parameters from: $($fsoParamFile.FullName)")
$params = Import-PowerShellDataFile -Path $fsoParamFile.FullName
- Write-Host ("Loaded Parameters from: $($fsoParamFile.FullName)")
+ $DatabasePath = "$($data.ProjectRoot)/tests/$($params.Database)"
+ $params.ConnectionString = $params.ConnectionString -replace "$($params.Database)",$DatabasePath
+ $params.Database = $DatabasePath
}
Write-Host ("Parameters: $($params | Out-String)")
}
@@ -176,3 +179,39 @@ Describe 'New-SqlQueryDataSet' {
}
}
}
+
+
+# Create a new SQL Server connection
+$connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"
+$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
+$connection.Open()
+
+# Create a command to detach the database
+$detachCommand = $connection.CreateCommand()
+$detachCommand.CommandText = "EXEC sp_detach_db 'DATABASE1'"
+$detachCommand.ExecuteNonQuery()
+$connection.Close()
+
+# Define the source and destination paths
+$sourcePath = "F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF"
+$destinationPath = "C:\Git\SqlQueryClass\tests\TestDatabase1.mdf"
+
+# Move and rename the file
+Move-Item -Path $sourcePath -Destination $destinationPath
+
+# Create a new SQL Server connection
+$connection.Open()
+
+# Create a command to attach the database
+$attachCommand = $connection.CreateCommand()
+$attachCommand.CommandText = @"
+CREATE DATABASE TestDatabase1
+ON (FILENAME = 'C:\Git\SqlQueryClass\tests\TestDatabase1.mdf')
+FOR ATTACH
+"@
+$attachCommand.ExecuteNonQuery()
+$connection.Close()
+
+$ConnectionString = 'Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Git\SqlQueryClass\tests\TestDatabase1.mdf;Integrated Security=True'
+
+
diff --git a/tests/TestDatabase1.parameters.psd1 b/tests/TestDatabase1.parameters.psd1
index 7513dd9..0582095 100644
--- a/tests/TestDatabase1.parameters.psd1
+++ b/tests/TestDatabase1.parameters.psd1
@@ -1,7 +1,7 @@
@{
- "ConnectionString" = "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=DATABASE1.MDF;Integrated Security=True";
+ "ConnectionString" = "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=TestDatabase1.mdf;Integrated Security=True";
"TableName" = "DBTable";
"SqlServer" = "(localdb)\MSSQLLocalDB";
- "Database" = "DATABASE1.MDF";
+ "Database" = "TestDatabase1.mdf";
"Query" = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = `'BASE TABLE`' ORDER BY TABLE_SCHEMA, TABLE_NAME;"
}
From eb727536ce6607622af43fcdf5e984a8c517cd95 Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Fri, 7 Feb 2025 22:27:29 -0500
Subject: [PATCH 10/20] Refactored Function Names
---
src/public/Dismount-Database.ps1 | 2 +-
.../{Get-Databases.ps1 => Get-Database.ps1} | 8 ++---
...tabaseTables.ps1 => Get-DatabaseTable.ps1} | 4 +--
src/public/Mount-Database.ps1 | 2 +-
tests/New-SqlQueryDataSets.tests.ps1 | 36 -------------------
5 files changed, 8 insertions(+), 44 deletions(-)
rename src/public/{Get-Databases.ps1 => Get-Database.ps1} (82%)
rename src/public/{Get-DatabaseTables.ps1 => Get-DatabaseTable.ps1} (91%)
diff --git a/src/public/Dismount-Database.ps1 b/src/public/Dismount-Database.ps1
index a2d58c6..539ad4f 100644
--- a/src/public/Dismount-Database.ps1
+++ b/src/public/Dismount-Database.ps1
@@ -16,5 +16,5 @@ $Error.Clear()
# Dismount-Database
# Dismount-Database -Database:$null
Dismount-Database -Database 'TestDataBase1'
-Get-Databases
+Get-Database
#>
diff --git a/src/public/Get-Databases.ps1 b/src/public/Get-Database.ps1
similarity index 82%
rename from src/public/Get-Databases.ps1
rename to src/public/Get-Database.ps1
index f099a9d..6c1bf3c 100644
--- a/src/public/Get-Databases.ps1
+++ b/src/public/Get-Database.ps1
@@ -1,4 +1,4 @@
-Function Get-Databases {
+Function Get-Database {
Param (
$connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True",
$query = "SELECT name FROM sys.databases;",
@@ -10,7 +10,7 @@ Function Get-Databases {
Invoke-DatabaseQuery @Splat -Quiet:$Quiet
}
<# Usage Examples # >
-Get-Databases
-Get-Databases -Quiet
-Get-Databases -connectionString:$null
+Get-Database
+Get-Database -Quiet
+Get-Database -connectionString:$null
#>
\ No newline at end of file
diff --git a/src/public/Get-DatabaseTables.ps1 b/src/public/Get-DatabaseTable.ps1
similarity index 91%
rename from src/public/Get-DatabaseTables.ps1
rename to src/public/Get-DatabaseTable.ps1
index d3a1275..bd2f433 100644
--- a/src/public/Get-DatabaseTables.ps1
+++ b/src/public/Get-DatabaseTable.ps1
@@ -1,4 +1,4 @@
-Function Get-DatabaseTables {
+Function Get-DatabaseTable {
Param (
$connectionString,
$query = "SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' ORDER BY TABLE_SCHEMA, TABLE_NAME;",
@@ -10,5 +10,5 @@ Function Get-DatabaseTables {
Invoke-DatabaseQuery @Splat -Quiet:$Quiet
}
<# Usage Examples: # >
-Get-DatabaseTables
+Get-DatabaseTable
#>
diff --git a/src/public/Mount-Database.ps1 b/src/public/Mount-Database.ps1
index 9c2b4f8..ab7f595 100644
--- a/src/public/Mount-Database.ps1
+++ b/src/public/Mount-Database.ps1
@@ -15,6 +15,6 @@ Function Mount-Database {
<# Usage Example: # >
$Error.Clear()
Mount-Database
-Get-Databases
+Get-Database
# Mount-Database -Database 'TestDataBase1' -DatabaseFilePath 'C:\Git\SqlQueryClass\tests\TestDatabase1.mdf'
#>
diff --git a/tests/New-SqlQueryDataSets.tests.ps1 b/tests/New-SqlQueryDataSets.tests.ps1
index 73ff4ee..05104fb 100644
--- a/tests/New-SqlQueryDataSets.tests.ps1
+++ b/tests/New-SqlQueryDataSets.tests.ps1
@@ -179,39 +179,3 @@ Describe 'New-SqlQueryDataSet' {
}
}
}
-
-
-# Create a new SQL Server connection
-$connectionString = "Data Source=(localdb)\MSSQLLocalDB;Integrated Security=True"
-$connection = New-Object System.Data.SqlClient.SqlConnection($connectionString)
-$connection.Open()
-
-# Create a command to detach the database
-$detachCommand = $connection.CreateCommand()
-$detachCommand.CommandText = "EXEC sp_detach_db 'DATABASE1'"
-$detachCommand.ExecuteNonQuery()
-$connection.Close()
-
-# Define the source and destination paths
-$sourcePath = "F:\DATA\BILLS\PSSCRIPTS\SCANMYBILLS\DATABASE1.MDF"
-$destinationPath = "C:\Git\SqlQueryClass\tests\TestDatabase1.mdf"
-
-# Move and rename the file
-Move-Item -Path $sourcePath -Destination $destinationPath
-
-# Create a new SQL Server connection
-$connection.Open()
-
-# Create a command to attach the database
-$attachCommand = $connection.CreateCommand()
-$attachCommand.CommandText = @"
-CREATE DATABASE TestDatabase1
-ON (FILENAME = 'C:\Git\SqlQueryClass\tests\TestDatabase1.mdf')
-FOR ATTACH
-"@
-$attachCommand.ExecuteNonQuery()
-$connection.Close()
-
-$ConnectionString = 'Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=C:\Git\SqlQueryClass\tests\TestDatabase1.mdf;Integrated Security=True'
-
-
From ad77e957d4178fe9b67d70c7de0f774fb01fd8bd Mon Sep 17 00:00:00 2001
From: Brooks Vaughn <18422308+BrooksV@users.noreply.github.com>
Date: Sat, 8 Feb 2025 01:05:28 -0500
Subject: [PATCH 11/20] Readme Updates
---
README.md | 177 ++++++++++++++++++++++++++++++++++--------------------
1 file changed, 112 insertions(+), 65 deletions(-)
diff --git a/README.md b/README.md
index 6ae7264..b9baa67 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ Import-Module -Name ".\dist\SqlQueryClass\SqlQueryClass.psd1" -Force -verbose
- Tested with PowerShell 5.1 and 7.5x
- No known dependencies for usage
+- VS Code and clone [Brooks Vaughn's SqlQueryClass](https://github.com/BrooksV/SqlQueryClass) Repository
- Module build process uses [Manjunath Beli's](https://github.com/belibug) [ModuleTools](https://github.com/belibug) module.
## ToDo
@@ -57,59 +58,78 @@ New-SqlQueryDataSet helper function is used to creates an instance of the [SqlQu
It is best to read the details in the details `.\src\private\SqlQueryClass.ps1` and in `.\src\public\New-SqlQueryDataSet.ps1` files.
+## How Build `SqlQueryClass` Module
+
+### Setup
+
+- Uses SQL Express but should work with other SQL Databases with proper connection strings and credentials
+- Requires VS Code
+- For Contributors, Fork the [SqlQueryClass](https://github.com/BrooksV/SqlQueryClass) repository
+- Clone the repository or fork to local pc. I like using c:\git as my local repository folder. Subfolder `SqlQueryClass` will be created with the GiHib repository contents
+- Install [Manjunath Beli's ModuleTools](https://github.com/belibug/ModuleTools) module as the module build process uses ModuleTools
+- - Find-Module -Name ModuleTools | Install-Module -Scope CurrentUser -Verbose
+- Note that a sample SQL Express database file (.\tests\TestDatabase1.mdf) is included for pester tests. The database configuration is set in .\tests\TestDatabase1.parameters.psd1
+
+#### Source Files used in the Module
+
+- Public functions that are exported, are separate files in the .\src\public folder.
+- Private functions that are local to the Module, are separate files in the .\src\private folder.
+- - Class Definitions and Enums are not accessible outside of the Module and cannot be accessed directly like Public Functions are. This is a PowerShell limitation.
+- - - Classes [SqlQueryDataSet] and [SqlQueryDataSetParms] and enum ResultType used in the Module are defined in file .\src\private\SqlQueryClass.ps1 file. The classes have properties and methods used to maintain a Database connections and result sets making it useful WPF Data binding.
+- Resources are files and folders in the .\src\resources folder that needs to be included with the Manifest and Module
+
+#### `SqlQueryClass` Module Build Process
+
+- Create a branch for your changes
+- Update the build version using Update-MTModuleVersion (Find-Module -Name ModuleTools)
+- Commit your changes to the branch
+- Run the Pester Teats using Invoke-MTTest (Find-Module -Name ModuleTools)
+- Build the Module output using Invoke-MTBuild -Verbose (Find-Module -Name ModuleTools)
+- - Outputs to the .\dist\SqlQueryClass folder
+- - Combines the file contents of the files in Public and Private folder into .\dist\SqlQueryClass\SqlQueryClass.psd1 and exports the Public Functions
+- - Generates the .\dist\SqlQueryClass\SqlQueryClass.psd1 Manifest file from the settings in .\project.json
+- - Resources (.\src\resources) folder content is copied to .\dist\SqlQueryClass folder
+- Run the Pester Teats using Invoke-MTTest (Find-Module -Name ModuleTools)
+- Make corrections, repeat the build process
+- For Contributors
+- - Create an Issue if one does not exist that addresses the proposed changes
+- - Upstream your branch
+- - Create a Pull request
+
+#### Publishing `SqlQueryClass` Module to GitHub
+
+
+
+- .\dist\SqlQueryClass\SqlQueryClass.psd1
+- Resources are files and folders in the .\src\resources folder that gets copied to the .\dist\SqlQueryClass folder
+
+
+SqlQueryClass.ps1
+
+
### New-SqlQueryDataSet Helper Function to Create Class Instance
The main cmdlet provided by this module is New-SqlQueryDataSet, which returns an object instance of [SqlQueryDataSet] class. Note that all the parameters are optional.
```powershell
$testQuery = New-SqlQueryDataSet [[-SQLServer] ] [[-Database] ] [[-ConnectionString] ] [[-Query] ] [[-TableName] ] [[-DisplayResults] ] []
+```
-$testquery | GM
+#### Other Helper Functions in the SqlQueryClass Module
- TypeName: SqlQueryDataSet
-
-Name MemberType Definition
----- ---------- ----------
-AddQuery Method int AddQuery(string Query), int AddQuery(string Query, string TableName)
-BuildOleDbConnectionString Method string BuildOleDbConnectionString()
-Clear Method void Clear()
-CloseConnection Method void CloseConnection()
-Equals Method bool Equals(System.Object obj)
-Execute Method System.Object Execute(), System.Object Execute(SqlQueryTable table), System.Object Execute(int TableIndex), System.Object Execute(string SqlQuery), System.Object Execute(ResultType ResultType)
-ExecuteAsDataAdapter Method System.Object ExecuteAsDataAdapter(string SqlQuery)
-ExecuteAsDataSet Method System.Object ExecuteAsDataSet(string SqlQuery)
-ExecuteAsDataTable Method System.Object ExecuteAsDataTable(string SqlQuery)
-ExecuteAsDataRows Method System.Object ExecuteAsDataRows(string SqlQuery)
-ExecuteNonQuery Method System.Object ExecuteNonQuery(string SqlQuery)
-ExecuteQuery Method System.Object ExecuteQuery(string SqlQuery), System.Object ExecuteQuery(string TableName, string SqlQuery)
-GetCreateBasicDLL Method System.Object GetCreateBasicDLL(string TableName)
-GetCreateDDL Method System.Object GetCreateDDL(string TableName)
-GetDBTableIndexes Method System.Object GetDBTableIndexes(string TableName)
-GetDBTableIndexesV17 Method System.Object GetDBTableIndexesV17(string TableName)
-GetDBTableSchema Method System.Object GetDBTableSchema(string TableName)
-GetHashCode Method int GetHashCode()
-GetTableFromQuery Method System.Object GetTableFromQuery(string Query)
-GetTableFromTableName Method System.Object GetTableFromTableName(string TableName)
-GetType Method type GetType()
-LoadQueryFromFile Method void LoadQueryFromFile(string Path)
-OpenConnection Method void OpenConnection()
-ParseSQLQuery Method System.Object ParseSQLQuery(string Query)
-SaveChanges Method System.Object SaveChanges()
-ToString Method string ToString()
-CommandTimeout Property int CommandTimeout {get;set;}
-ConnectionString Property string ConnectionString {get;set;}
-ConnectionTimeout Property int ConnectionTimeout {get;set;}
-Database Property string Database {get;set;}
-DisplayResults Property bool DisplayResults {get;set;}
-KeepAlive Property bool KeepAlive {get;set;}
-SQLConnection Property System.Object SQLConnection {get;set;}
-SQLServer Property string SQLServer {get;set;}
-TableIndex Property int TableIndex {get;set;}
-TableNames Property hashtable TableNames {get;set;}
-Tables Property System.Collections.Generic.List`1[[SqlQueryTable, PowerShell Class Assembly, Version=1.0.0.1, Culture=neutral, PublicKeyToken=null]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e Tables {get;set;}
+```powershell
+Get-Command -Module SqlQueryClass -Syntax
+
+Dismount-Database [[-connectionString]