Repository: mithrandyr/SimplySql Branch: master Commit: 3f6ca0716fb8 Files: 86 Total size: 260.9 KB Directory structure: gitextract_huu3fidt/ ├── .gitignore ├── Docs/ │ ├── Clear-SqlMessage.md │ ├── Close-SqlConnection.md │ ├── Complete-SqlTransaction.md │ ├── Get-SqlConnection.md │ ├── Get-SqlMessage.md │ ├── Get-SqlTransaction.md │ ├── Invoke-SqlBulkCopy.md │ ├── Invoke-SqlQuery.md │ ├── Invoke-SqlScalar.md │ ├── Invoke-SqlUpdate.md │ ├── Open-MySqlConnection.md │ ├── Open-OracleConnection.md │ ├── Open-PostGreConnection.md │ ├── Open-SQLConnection.md │ ├── Open-SQLiteConnection.md │ ├── Set-SqlConnection.md │ ├── Show-SqlConnection.md │ ├── SimplySql.md │ ├── Start-SqlTransaction.md │ ├── Test-SqlConnection.md │ ├── Undo-SqlTransaction.md │ └── about_SimplySql.md ├── HandleVerbose.ps1 ├── LICENSE ├── ModuleManifest/ │ └── SimplySql.psd1 ├── README.md ├── Tests/ │ ├── mssql.tests.ps1 │ ├── mysql.tests.ps1 │ ├── oracle.tests.ps1 │ ├── postgre.tests.ps1 │ └── sqlite.tests.ps1 ├── VersionHistory.md ├── default.build.ps1 ├── developmentideas.txt ├── runTests.ps1 └── source/ ├── ConstructModule.ps1 ├── SimplySql.Cmdlets/ │ ├── Cmdlets/ │ │ ├── ClearSqlMessage.vb │ │ ├── CloseSqlConnection.vb │ │ ├── CompleteSqlTransaction.vb │ │ ├── GetSqlConnection.vb │ │ ├── GetSqlMessage.vb │ │ ├── GetSqlTransaction.vb │ │ ├── InvokeSqlBulkCopy.vb │ │ ├── InvokeSqlQuery.vb │ │ ├── InvokeSqlScalar.vb │ │ ├── InvokeSqlUpdate.vb │ │ ├── SetSqlConnection.vb │ │ ├── ShowSqlConnection.vb │ │ ├── StartSqlTransaction.vb │ │ ├── TestSqlConnection.vb │ │ └── UndoSqlTransaction.vb │ ├── ContextHandling.vb │ ├── DataReaderToPSObject.vb │ ├── Dry.vb │ ├── My Project/ │ │ ├── Application.myapp │ │ └── launchSettings.json │ ├── ProviderCmdlets/ │ │ ├── OpenMySqlConnection.vb │ │ ├── OpenOracleConnection.vb │ │ ├── OpenPostGreConnection.vb │ │ ├── OpenSQLiteConnection.vb │ │ └── OpenSqlConnection.vb │ └── SimplySql.Cmdlets.vbproj ├── SimplySql.Engine/ │ ├── Dry.vb │ ├── ISimplySqlProvider.vb │ ├── Logic.vb │ ├── MSSQL/ │ │ ├── ConnectionMSSQL.vb │ │ └── MSSQLProvider.vb │ ├── My Project/ │ │ └── Application.myapp │ ├── MySQL/ │ │ ├── ConnectionMySql.vb │ │ └── MySqlProvider.vb │ ├── Oracle/ │ │ ├── ConnectionOracle.vb │ │ └── OracleProvider.vb │ ├── PostGre/ │ │ ├── ConnectionPostGre.vb │ │ └── PostGreProvider.vb │ ├── ProviderBase.vb │ ├── SQLite/ │ │ ├── ConnectionSQLite.vb │ │ └── SQLiteProvider.vb │ ├── SimplySql.Engine.vbproj │ ├── SqlMessage.vb │ ├── ValidateConnectionResult.vb │ └── baseConnectionDetail.vb ├── source.build.ps1 ├── source.sln ├── thoughts.txt └── wsl.ps1 ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ #this directory is created by the build script but should not be committed to the repo Output/ #binarysrc/packages/* ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore # User-specific files *.rsuser *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files mono_crash.* # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ [Ww][Ii][Nn]32/ [Aa][Rr][Mm]/ [Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ [Ll]ogs/ # Visual Studio 2015/2017 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # Visual Studio 2017 auto generated files Generated\ Files/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml nunit-*.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # Benchmark Results BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ # ASP.NET Scaffolding ScaffoldingReadMe.txt # StyleCop StyleCopReport.xml # Files built by Visual Studio *_i.c *_p.c *_h.h *.ilk *.meta *.obj *.iobj *.pch *.pdb *.ipdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *_wpftmp.csproj *.log *.tlog *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # Visual Studio Trace Files *.e2e # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # AxoCover is a Code Coverage Tool .axoCover/* !.axoCover/settings.json # Coverlet is a free, cross platform Code Coverage Tool coverage*.json coverage*.xml coverage*.info # Visual Studio code coverage results *.coverage *.coveragexml # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # Note: Comment the next line if you want to checkin your web deploy settings, # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # NuGet Symbol Packages *.snupkg # The packages folder can be ignored because of Package Restore **/[Pp]ackages/* # except build/, which is used as an MSBuild target. !**/[Pp]ackages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/[Pp]ackages/repositories.config # NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt *.appx *.appxbundle *.appxupload # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !?*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.jfm *.pfx *.publishsettings orleans.codegen.cs # Including strong name files can present a security risk # (https://github.com/github/gitignore/pull/2483#issue-259490424) #*.snk # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm ServiceFabricBackup/ *.rptproj.bak # SQL Server files *.mdf *.ldf *.ndf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings *.rptproj.rsuser *- [Bb]ackup.rdl *- [Bb]ackup ([0-9]).rdl *- [Bb]ackup ([0-9][0-9]).rdl # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat node_modules/ # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) *.vbw # Visual Studio 6 auto-generated project file (contains which files were open etc.) *.vbp # Visual Studio 6 workspace and project file (working project files containing files to include in project) *.dsw *.dsp # Visual Studio 6 technical files *.ncb *.aps # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # CodeRush personal settings .cr/personal # Python Tools for Visual Studio (PTVS) __pycache__/ *.pyc # Cake - Uncomment if you are using it # tools/** # !tools/packages.config # Tabs Studio *.tss # Telerik's JustMock configuration file *.jmconfig # BizTalk build output *.btp.cs *.btm.cs *.odx.cs *.xsd.cs # OpenCover UI analysis results OpenCover/ # Azure Stream Analytics local run output ASALocalRun/ # MSBuild Binary and Structured Log *.binlog # NVidia Nsight GPU debugger configuration file *.nvuser # MFractors (Xamarin productivity tool) working folder .mfractor/ # Local History for Visual Studio .localhistory/ # Visual Studio History (VSHistory) files .vshistory/ # BeatPulse healthcheck temp database healthchecksdb # Backup folder for Package Reference Convert tool in Visual Studio 2017 MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ # Fody - auto-generated XML schema FodyWeavers.xsd # VS Code files for those working on multiple tools .vscode/* !.vscode/settings.json !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json *.code-workspace # Local History for Visual Studio Code .history/ # Windows Installer files from build outputs *.cab *.msi *.msix *.msm *.msp # JetBrains Rider *.sln.iml ================================================ FILE: Docs/Clear-SqlMessage.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Clear-SqlMessage ## SYNOPSIS Clears all available informational messages. ## SYNTAX ``` Clear-SqlMessage [-ConnectionName ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Clear-SqlMessage removes all informational messages generated by Invoke-SqlScalar, Invoke-SqlQuery, or Invoke-SqlUpdate. Not all providers support informational messages. ## EXAMPLES ### Example 1 ```powershell PS C:\> Clear-SqlMessage ``` Clear the message queue for the connection ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Close-SqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Close-SqlConnection ## SYNOPSIS Closes the SqlConnection. ## SYNTAX ``` Close-SqlConnection [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Closes the connection and disposes of the underlying object. This will also rollback the current transaction if there is one. Can specify which SqlConnection with the -ConnectionName parameter. Cmdlet supports piping connectionNames. ## EXAMPLES ### Example 1 ```powershell PS C:\> Close-SqlConnection ``` Closes the sql connection. ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Complete-SqlTransaction.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Complete-SqlTransaction ## SYNOPSIS Complete a SQL transaction. ## SYNTAX ``` Complete-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Complete (COMMIT) a SQL transaction. ## EXAMPLES ### Example 1 ```powershell PS C:\> Complete-SqlTransaction ``` Commits the SQL transaction ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Get-SqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Get-SqlConnection ## SYNOPSIS Gets the underlying provider connection object. ## SYNTAX ``` Get-SqlConnection [-ConnectionName ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Gets the underlying provider connection object for the current connection or for the connection name specified. ## EXAMPLES ### Example 1 ```powershell PS C:\> Get-SqlConnection ``` Returns the provider-specific Connection object. ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Get-SqlMessage.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Get-SqlMessage ## SYNOPSIS Returns any available informational messages. ## SYNTAX ``` Get-SqlMessage [-ConnectionName ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Get-SqlMessage returns any informational messages generated by Invoke-SqlScalar, Invoke-SqlQuery, or Invoke-SqlUpdate. Not all providers support informational messages. SQL Server, if you use Print or Raiserror without the "NoWait", then messages will be batched to 8kb and then sent. To get messages immediately sent, your query needs to use: RAISERROR('your message', 10,1) WITH NOWAIT ## EXAMPLES ### Example 1 ```powershell PS C:\> Get-SqlMessage ``` Returns all the messages in the queue. ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Get-SqlTransaction.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Get-SqlTransaction ## SYNOPSIS Gets the underlying provider transaction object. ## SYNTAX ``` Get-SqlTransaction [-ConnectionName ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Gets the underlying provider transaction object for the current connection or for the connection name specified. ## EXAMPLES ### Example 1 ```powershell PS C:\> Get-SqlTransaction ``` Returns the provider specific transaction object. ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Invoke-SqlBulkCopy.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Invoke-SqlBulkCopy ## SYNOPSIS Executes a bulk copy between two connections. ## SYNTAX ### table (Default) ``` Invoke-SqlBulkCopy [-SourceConnectionName ] [-DestinationConnectionName ] [-DestinationTable ] -SourceTable [-ColumnMap ] [-BatchSize ] [-BatchTimeout ] [-Notify] [-NotifyAction ] [-WhatIf] [-Confirm] [] ``` ### query ``` Invoke-SqlBulkCopy [-SourceConnectionName ] [-DestinationConnectionName ] -DestinationTable -SourceQuery [-SourceParameters ] [-ColumnMap ] [-BatchSize ] [-BatchTimeout ] [-Notify] [-NotifyAction ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Executes a bulk copy operation between two connections. This is highly optimized if the destination has a managed bulkcopy implemenation, otherwise it is only generally optimized. For example, SQL Server has a bulk copy class (SqlBulkCopy) that is easily implemented and provides an efficient means of inserting data into SQL Server. The default implemenation, if the provider does not provider a managed bulk copy mechanism is to prepare the sql insert, and wrap multiple inserts into a single transaction (batching). This provides a significant performance improvement over looping with Invoke-SqlUpdate. CONSIDERATIONS * You must specify either a SourceConnectionName or DestinationConnectionName, whichever one is not specified will use 'default', not specifying either will cause an error. * If you don't specify DestinationTable, it will use SourceTable; however DestinationTable is required if you use SourceQuery. * If you specify ColumnMap and Source Table, then the select against the SourceConnection will be limited to the columns you specified in ColumnMap. Returns number of rows copied. ## EXAMPLES ## PARAMETERS ### -BatchSize How many inserts are batched together at one time. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 500 Accept pipeline input: False Accept wildcard characters: False ``` ### -BatchTimeout How long, in seconds, that each batch can take. Defaults to the command timeout for the source connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ColumnMap Key is the column name in the source connection. Value is the column name in the destination connection. ```yaml Type: Hashtable Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -DestinationConnectionName User defined name for connection where data will be inserted to. ```yaml Type: String Parameter Sets: (All) Aliases: DstCN Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DestinationTable The name of the table to write to in the destination connection. If not specified, will be taken from SourceTable parameter. ```yaml Type: String Parameter Sets: table Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ```yaml Type: String Parameter Sets: query Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Notify If present, as each batch completes a progress notification will be generated with the total number of rows inserted so far. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None 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. ```yaml Type: String Parameter Sets: (All) Aliases: SrcCN Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SourceParameters Parameters needed for the source query. ```yaml Type: Hashtable Parameter Sets: query Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SourceQuery The query to determine the source data, instead of specifying a table. ```yaml Type: String[] Parameter Sets: query Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SourceTable The name of the table in the source connection. ```yaml Type: String Parameter Sets: table Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.String[] ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Invoke-SqlQuery.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Invoke-SqlQuery ## SYNOPSIS Executes a query and returns data. ## SYNTAX ### object (Default) ``` Invoke-SqlQuery [-ConnectionName ] [-Query] [-CommandTimeout ] [[-ParamObject] ] [-Stream] [-AsDataTable] [-UseTypesFromProvider] [-WhatIf] [-Confirm] [] ``` ### hashtable ``` Invoke-SqlQuery [-ConnectionName ] [-Query] [-Parameters] [-CommandTimeout ] [-Stream] [-AsDataTable] [-UseTypesFromProvider] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Executes a query against the targeted connection and returns the data. This can handle multiple result sets (if underlying provider supports it). If there are multiple result sets, the output is datatables, otherwise datarows. If the -Stream switch is used, only the first result set is returned and the output is a PSObject for each row in the result set. Supports piping in objects, which will be converted to parameters and the query will be executed for once for each object piped in. ## EXAMPLES ### Example 1 ```powershell PS C:\> Invoke-SqlQuery -Query "SELECT * FROM TABLE" ``` Run a simple query and return the output ### Example 2 ```powershell PS C:\> Invoke-SqlQuery -Query "SELECT * FROM TABLE WHERE col1=@id' AND colb > @someDate" -Parameters @{id = 1; someDate = (Get-Date)} ``` 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 Forces the return objects to be one or more datatables. If combined with -Stream, -AsDataTable will be ignored. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -CommandTimeout The timeout, in seconds, for this SQL statement, defaults to the command timeout for the SqlConnection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Parameters Parameters required by the query. Key matches the parameter name, Value is the value of the parameter. ```yaml Type: Hashtable Parameter Sets: hashtable Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ParamObject The object that contains the parameters for the query, member names match the parameter name. ```yaml Type: PSObject Parameter Sets: object Aliases: Required: False Position: 1 Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ### -Query SQL statement to run. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 0 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Stream Uses a datareader to stream PSObject representing the results of the query to the pipeline, results will appear as soon as the connection begins returning data. Only returns the first resultset if there are multiples. If combined with -AsDataTable, -AsDataTable will be ignored. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -UseTypesFromProvider Will attempt to return the provider specific data types instead of standard .NET datatypes. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: ProviderTypes Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Management.Automation.PSObject ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Invoke-SqlScalar.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Invoke-SqlScalar ## SYNOPSIS Executes a Scalar query. ## SYNTAX ### object (Default) ``` Invoke-SqlScalar [-ConnectionName ] [-Query] [-CommandTimeout ] [[-ParamObject] ] [-WhatIf] [-Confirm] [] ``` ### hashtable ``` Invoke-SqlScalar [-ConnectionName ] [-Query] [-Parameters] [-CommandTimeout ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Executes a Scalar query against the targeted connection. If the sql statement generates multiple rows and/or columns, only the first column of the first row is returned. ## EXAMPLES ### Example 1 ```powershell PS C:\> Invoke-SqlScalar -Query "SELECT Count(1) FROM TABLE" ``` 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 ### -CommandTimeout The timeout, in seconds, for this SQL statement, defaults to the command timeout for the SqlConnection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Parameters Parameters required by the query. Key matches the parameter name, Value is the value of the parameter. ```yaml Type: Hashtable Parameter Sets: hashtable Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ParamObject The object that contains the parameters for the query, member names match the parameter name. ```yaml Type: PSObject Parameter Sets: object Aliases: Required: False Position: 1 Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ### -Query SQL statement to run. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 0 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: default Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Management.Automation.PSObject ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Invoke-SqlUpdate.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Invoke-SqlUpdate ## SYNOPSIS Executes a query and returns number of record affected. ## SYNTAX ### object (Default) ``` Invoke-SqlUpdate [-ConnectionName ] [-Query] [-CommandTimeout ] [[-ParamObject] ] [-WhatIf] [-Confirm] [] ``` ### hashtable ``` Invoke-SqlUpdate [-ConnectionName ] [-Query] [-Parameters] [-CommandTimeout ] [-WhatIf] [-Confirm] [] ``` ### cmd ``` Invoke-SqlUpdate [-ConnectionName ] [-Query] [-CommandTimeout ] -Command [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Executes a query against the targeted connection and returns the the number of records affected. ## EXAMPLES ### Example 1 ```powershell PS C:\> Invoke-SqlUpdate -Query "UPDATE employees SET salary = @val WHERE manager = @managerId" -Parameters @{val = 999999; managerId = 549} ``` 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 a Data.DbCommand object to execute (or a provider specific version). ```yaml Type: IDbCommand Parameter Sets: cmd Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -CommandTimeout The timeout, in seconds, for this SQL statement, defaults to the command timeout for the SqlConnection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Parameters Parameters required by the query. Key matches the parameter name, Value is the value of the parameter. ```yaml Type: Hashtable Parameter Sets: hashtable Aliases: Required: True Position: 1 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ParamObject The object that contains the parameters for the query, member names match the parameter name. ```yaml Type: PSObject Parameter Sets: object Aliases: Required: False Position: 1 Default value: None Accept pipeline input: True (ByValue) Accept wildcard characters: False ``` ### -Query SQL statement to run. ```yaml Type: String[] Parameter Sets: (All) Aliases: Required: True Position: 0 Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Management.Automation.PSObject ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Open-MySqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Open-MySqlConnection ## SYNOPSIS Open a connection to a MySql Database. ## SYNTAX ### default (Default) ``` Open-MySqlConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-Database] ] [-Port ] [-SSLMode ] [[-Credential] ] [-Additional ] [] ``` ### conn ``` Open-MySqlConnection [-ConnectionName ] [-CommandTimeout ] [[-Credential] ] -ConnectionString [] ``` ## DESCRIPTION Open a connection to a MySql Database. MySqlConnector: High Performance .NET MySQL Driver @ https://mysqlconnector.net/ .NET Provider @ https://www.nuget.org/packages/MySqlConnector/ ## EXAMPLES ### Example 1 ```powershell PS C:\> Open-MySqlConnection -server 'localhost' -database 'DBname' -Credential (Get-Credential) ``` Opens a connection to localhost using a credential retrieved from the user. ## PARAMETERS ### -Additional Hashtable to provide additional connection parameters. ```yaml Type: Hashtable Parameter Sets: default Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 30 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionString Specifies a provider specific connectionstring to be used. ```yaml Type: String Parameter Sets: conn Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Credential A PSCredential object providing the proper credentials to access to the datasource (if required). ```yaml Type: PSCredential Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Database Database name. ```yaml Type: String Parameter Sets: default Aliases: InitialCatalog Required: False Position: 1 Default value: mysql Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Port Port to connect on, if different from default (3306). ```yaml Type: Int32 Parameter Sets: default Aliases: Required: False Position: Named Default value: 3306 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Server The Server for the connection. ```yaml Type: String Parameter Sets: default Aliases: Host Required: False Position: 0 Default value: localhost Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SSLMode Which SLLMode to use (defaults to Preferred) Disabled: (equivalent to 'None') Do not use SSL. Preferred: Use SSL if the server supports it. Required: Always use SSL. Deny connection if server does not support SSL. Does not validate CA or hostname. VerifyCA: Always use SSL. Validates the CA but tolerates hostname mismatch. VerifyFull: Always use SSL. Validates CA and hostname. ```yaml Type: String Parameter Sets: default Aliases: Accepted values: None, Preferred, Required, VerifyCA, VerifyFull Required: False Position: Named Default value: Preferred Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Open-OracleConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Open-OracleConnection ## SYNOPSIS Open a connection to a Oracle Database. ## SYNTAX ### default (Default) ``` Open-OracleConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-ServiceName] ] [-Port ] [-Privilege ] [[-Credential] ] [-Additional ] [] ``` ### tns ``` Open-OracleConnection [-ConnectionName ] [-CommandTimeout ] -TnsName [-Privilege ] [[-Credential] ] [-Additional ] [] ``` ### conn ``` Open-OracleConnection [-ConnectionName ] [-CommandTimeout ] [-Privilege ] -ConnectionString [] ``` ## DESCRIPTION Open a connection to a Oracle Database. Oracle Managed Data Access @ http://www.oracle.com/technetwork/topics/dotnet/index-085163.html Provider for .NET @ https://www.nuget.org/packages/Oracle.ManagedDataAccess ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -Additional Hashtable to provide additional connection parameters. ```yaml Type: Hashtable Parameter Sets: default, tns Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 30 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionString Specifies a provider specific connectionstring to be used. ```yaml Type: String Parameter Sets: conn Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Credential A PSCredential object providing the proper credentials to access to the datasource (if required). ```yaml Type: PSCredential Parameter Sets: default, tns Aliases: Required: False Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Port Port to connect on, if different from default (1521). ```yaml Type: Int32 Parameter Sets: default Aliases: Required: False Position: Named Default value: 1521 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Privilege Determines the elevated privileges the connection has: SYSDBA, SYSOPER, SYSASM. By default, none. ```yaml Type: String Parameter Sets: (All) Aliases: Accepted values: None, SYSASM, SYSDBA, SYSOPER Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Server The datasource for the connection. ```yaml Type: String Parameter Sets: default Aliases: Host, DataSource Required: False Position: 0 Default value: localhost Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ServiceName Oracle ServiceName (SID). ```yaml Type: String Parameter Sets: default Aliases: Required: False Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -TnsName The TnsName to connect to. ```yaml Type: String Parameter Sets: tns Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Open-PostGreConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Open-PostGreConnection ## SYNOPSIS Open a connection to a PostGre Database. ## SYNTAX ### default (Default) ``` Open-PostGreConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-Database] ] [-Port ] [-MaxAutoPrepare ] [-SSLMode ] [[-Credential] ] [-Additional ] [] ``` ### conn ``` Open-PostGreConnection [-ConnectionName ] [-CommandTimeout ] [[-Credential] ] -ConnectionString [] ``` ## DESCRIPTION Open a connection to a PostGre Database. PostGreSQL @ https://www.postgresql.org/ PostGre via Npgsql @ http://www.npgsql.org/ .NET Provider @ https://www.nuget.org/packages/Npgsql Geometry: http://www.npgsql.org/doc/types/nts.html ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -Additional Hashtable to provide additional connection parameters. ```yaml Type: Hashtable Parameter Sets: default Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 30 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionString Specifies a provider specific connectionstring to be used. ```yaml Type: String Parameter Sets: conn Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Credential A PSCredential object providing the proper credentials to access to the datasource (if required). ```yaml Type: PSCredential Parameter Sets: (All) Aliases: Required: False Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Database Database name. ```yaml Type: String Parameter Sets: default Aliases: InitialCatalog Required: False Position: 1 Default value: postgres Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -MaxAutoPrepare The maximum number SQL statements that can be automatically prepared at any given point. Beyond this number the least-recently-used statement will be recycled. Zero disables automatic preparation. DEFAULTS TO 25. ```yaml Type: Int32 Parameter Sets: default Aliases: Required: False Position: Named Default value: 25 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Port Port to connect on, if different from default (5432). ```yaml Type: Int32 Parameter Sets: default Aliases: Required: False Position: Named Default value: 5432 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Server The Server for the connection. ```yaml Type: String Parameter Sets: default Aliases: Host Required: False Position: 0 Default value: localhost Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -SSLMode Which SLLMode to use (defaults to Preferred) Disabled: Do not use SSL. Preferred: Use SSL if the server supports it. Required: Always use SSL. Deny connection if server does not support SSL. Does not validate CA or hostname. VerifyCA: Always use SSL. Validates the CA but tolerates hostname mismatch. VerifyFull: Always use SSL. Validates CA and hostname. ```yaml Type: String Parameter Sets: default Aliases: Accepted values: Disable, Prefer, Require, VerifyCA, VerifyFull Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ### System.Management.Automation.PSCredential ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Open-SQLConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Open-SQLConnection ## SYNOPSIS Open a connection to a SQL Server. ## SYNTAX ### default (Default) ``` Open-SQLConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-Database] ] [-Additional ] [] ``` ### credential ``` Open-SQLConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-Database] ] [[-Credential] ] [-AzureAD] [-Additional ] [] ``` ### token ``` Open-SQLConnection [-ConnectionName ] [-CommandTimeout ] [[-Server] ] [[-Database] ] [-AzureToken ] [-Additional ] [] ``` ### conn ``` Open-SQLConnection [-ConnectionName ] [-CommandTimeout ] [[-Credential] ] [-AzureToken ] -ConnectionString [] ``` ## DESCRIPTION Open a connection to a SQL Server. Default authentication is Integrated Windows Authetication. Microsoft.Data.SqlClient. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -Additional Hashtable to provide additional connection parameters. ```yaml Type: Hashtable Parameter Sets: default, credential, token Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -AzureAD Use this when connecting to an Azure SQL Database and you are using Azure AD credentials. You can specify the credentials by passing in a credential object to the Credential parameter. ```yaml Type: SwitchParameter Parameter Sets: credential Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -AzureToken Pass in Azure Token (make sure you use the proper resource). If your token begins with "bearer " that will be stripped off first. ```yaml Type: String Parameter Sets: token, conn Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 30 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionString Specifies a provider specific connectionstring to be used. ```yaml Type: String Parameter Sets: conn Aliases: Required: True Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Credential A PSCredential object providing the proper credentials to access to the datasource (if required). ```yaml Type: PSCredential Parameter Sets: credential, conn Aliases: Required: False Position: 2 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Database The database to connect to. ```yaml Type: String Parameter Sets: default, credential, token Aliases: SqlDatabase, InitialCatalog Required: False Position: 1 Default value: master Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Server The server to connect to ```yaml Type: String Parameter Sets: default, credential, token Aliases: SqlInstance, SqlServer, DataSource Required: False Position: 0 Default value: localhost Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ### System.Management.Automation.PSCredential ### System.Management.Automation.SwitchParameter ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Open-SQLiteConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Open-SQLiteConnection ## SYNOPSIS Open a connection to a SQLite database file. ## SYNTAX ### default (Default) ``` Open-SQLiteConnection [-ConnectionName ] [-CommandTimeout ] [[-DataSource] ] [[-Password] ] [-Additional ] [] ``` ### conn ``` Open-SQLiteConnection [-ConnectionName ] [-CommandTimeout ] [-ConnectionString ] [] ``` ## DESCRIPTION Open a connection to a SQLite database file. SQLite Development Team @ https://sqlite.org/ .NET Provider @ http://system.data.sqlite.org/ ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -Additional Hashtable to provide additional connection parameters. ```yaml Type: Hashtable Parameter Sets: default Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: 30 Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionString Specifies a provider specific connectionstring to be used. ```yaml Type: String Parameter Sets: conn Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -DataSource The datasource for the connection. ```yaml Type: String Parameter Sets: default Aliases: FilePath Required: False Position: 0 Default value: :memory: Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Password Password for the database file. ```yaml Type: String Parameter Sets: default Aliases: Required: False Position: 1 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ### System.Collections.Hashtable ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Set-SqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Set-SqlConnection ## SYNOPSIS Set options on the SqlConnection. ## SYNTAX ``` Set-SqlConnection [-ConnectionName ] [[-Database] ] [-CommandTimeout ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Set Database and/or Command Timeout for the SqlConnection. Changing the database may not be valid for all providers. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -CommandTimeout The default command timeout to be used for all commands executed against this connection. ```yaml Type: Int32 Parameter Sets: (All) Aliases: Required: False Position: Named Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: Named Default value: default Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Database The database to connect to. ```yaml Type: String Parameter Sets: (All) Aliases: Required: False Position: 0 Default value: None Accept pipeline input: True (ByPropertyName) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ### System.Int32 ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Show-SqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Show-SqlConnection ## SYNOPSIS Lists the current SqlConnection. ## SYNTAX ### single (Default) ``` Show-SqlConnection [[-ConnectionName] ] [] ``` ### all ``` Show-SqlConnection [-All] [] ``` ## DESCRIPTION Lists the current SqlConnection information or outputs a list of all SqlConnections currently active. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -All If present, will return list of all connection names. ```yaml Type: SwitchParameter Parameter Sets: all Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: single Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/SimplySql.md ================================================ --- Module Name: SimplySql Module Guid: 71b1095f-dcb6-497d-8b47-a69c284aec64 Download Help Link: {{ Update Download Link }} Help Version: {{ Please enter version of help manually (X.X.X.X) format }} Locale: en-US --- # SimplySql Module ## Description SimplySql - Talking to relational databases the PowerShell way. Simple commands... Powerful opportunities. ## SimplySql Cmdlets ### [Clear-SqlMessage](Clear-SqlMessage.md) Clears all available informational messages. ### [Close-SqlConnection](Close-SqlConnection.md) Closes the SqlConnection. ### [Complete-SqlTransaction](Complete-SqlTransaction.md) Complete a SQL transaction. ### [Get-SqlConnection](Get-SqlConnection.md) Gets the underlying provider connection object. ### [Get-SqlMessage](Get-SqlMessage.md) Returns any available informational messages. ### [Get-SqlTransaction](Get-SqlTransaction.md) Gets the underlying provider transaction object. ### [Invoke-SqlBulkCopy](Invoke-SqlBulkCopy.md) Executes a bulk copy between two connections. ### [Invoke-SqlQuery](Invoke-SqlQuery.md) Executes a query and returns data. ### [Invoke-SqlScalar](Invoke-SqlScalar.md) Executes a Scalar query. ### [Invoke-SqlUpdate](Invoke-SqlUpdate.md) Executes a query and returns number of record affected. ### [Open-MySqlConnection](Open-MySqlConnection.md) Open a connection to a MySql Database. ### [Open-OracleConnection](Open-OracleConnection.md) Open a connection to a Oracle Database. ### [Open-PostGreConnection](Open-PostGreConnection.md) Open a connection to a PostGre Database. ### [Open-SQLConnection](Open-SQLConnection.md) Open a connection to a SQL Server. ### [Open-SQLiteConnection](Open-SQLiteConnection.md) Open a connection to a SQLite database file. ### [Set-SqlConnection](Set-SqlConnection.md) Set options on the SqlConnection. ### [Show-SqlConnection](Show-SqlConnection.md) Lists the current SqlConnection. ### [Start-SqlTransaction](Start-SqlTransaction.md) Start a sql transaction. ### [Test-SqlConnection](Test-SqlConnection.md) Tests to see if there is a connection. ### [Undo-SqlTransaction](Undo-SqlTransaction.md) Undo a SQL transaction. ================================================ FILE: Docs/Start-SqlTransaction.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Start-SqlTransaction ## SYNOPSIS Start a sql transaction. ## SYNTAX ``` Start-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Start (BEGIN) a sql transaction. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Test-SqlConnection.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Test-SqlConnection ## SYNOPSIS Tests to see if there is a connection. ## SYNTAX ### single (Default) ``` Test-SqlConnection [[-ConnectionName] ] [-Detailed] [] ``` ### all ``` Test-SqlConnection [-All] [] ``` ## DESCRIPTION Tests to see if there is a connection, use the -All switch to determine if there are any connections. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -All Returns true if there are any connections, otherwise false. ```yaml Type: SwitchParameter Parameter Sets: all Aliases: Required: True Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: single Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Detailed If present, will only return return if connection is found and in an Open state. ```yaml Type: SwitchParameter Parameter Sets: single Aliases: Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/Undo-SqlTransaction.md ================================================ --- external help file: SimplySql.Cmdlets.dll-Help.xml Module Name: SimplySql online version: schema: 2.0.0 --- # Undo-SqlTransaction ## SYNOPSIS Undo a SQL transaction. ## SYNTAX ``` Undo-SqlTransaction [[-ConnectionName] ] [-WhatIf] [-Confirm] [] ``` ## DESCRIPTION Undo (ROLLBACK) a SQL transaction. ## EXAMPLES ### Example 1 ```powershell PS C:\> {{ Add example code here }} ``` {{ Add example description here }} ## PARAMETERS ### -ConnectionName User defined name for connection. ```yaml Type: String Parameter Sets: (All) Aliases: cn Required: False Position: 0 Default value: default Accept pipeline input: True (ByPropertyName, ByValue) Accept wildcard characters: False ``` ### -Confirm Prompts you for confirmation before running the cmdlet. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: cf Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### -WhatIf Shows what would happen if the cmdlet runs. The cmdlet is not run. ```yaml Type: SwitchParameter Parameter Sets: (All) Aliases: wi Required: False Position: Named Default value: None Accept pipeline input: False Accept wildcard characters: False ``` ### CommonParameters This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). ## INPUTS ### System.String ## OUTPUTS ### System.Object ## NOTES ## RELATED LINKS ================================================ FILE: Docs/about_SimplySql.md ================================================ # SimplySql ## about_SimplySql # SHORT DESCRIPTION SimplySql - Talking to relational databases the PowerShell way. Simple commands... Powerful opportunities. # LONG DESCRIPTION SimplySql is a module that provides an intuitive set of cmdlets for talking to databases that abstracts the vendor specifics, allowing you to focus on getting work done. The basic pattern is to connect to a database, execute one or more sql statements and then close your database connection. This module provides cmdlets that map to this basic pattern. Open/Close/Show/Test/Set/Get -SqlConnection - Open/Close cmdlets enable you to connect to databases in straightforward terms without worrying about differences between database vendors. There is a specific "Open-*" cmdlet for each provider. (Open-SqlConnection, Open-SQLiteConnection, Open-OracleConnection, Open-PostGreConnection, Open-MySqlConnection). - Show/Test cmdlets allow you to see what connections are currently active in your powershell session and see specific details about those connections. - Set cmdlet allows you to change the default commandTimeout and the database/catalog in use (if the provider supports it). - Get cmdlet returns the underlying connection object itself. Invoke- SqlScalar/SqlQuery/SqlUpdate - These cmdlets allow you to execute sql statements against the database connections that you have opened. Any type of statement can be used with any cmdlet, but the output is tailored to specific types of activity. - SqlScalar is great for returning a single value. - SqlQuery is used for returning one or more result sets (output is DataRow for single resultset and Table for multiple resultsets). You can use the switch -Stream to return PSObject instead of DataRow. - SqlUpdate is used for making modifications (insert, update, delete, etc) and its output is the number of rows effected. Get/Clear -SqlMessage - These cmdlets provider access to informational messages, if the provider supports them. - Get will return the messages generated by Invoke-SqlScalar/SqlQuery/SqlUpdate cmdlets. Messages are consumed as they are read and can be cleared, without reading, by calling the Clear cmdlet. - The messages are timestamped to when they were received by calling command (and not necessarily when they were generated on the server since many implementations are Asynchronous.) Invoke-SqlBulkCopy - This is intended to make moving data from one connection to another connection (even cross vendor) simple.  This is highly optimized for all providers. Start/Complete/Undo -SqlTransaction - These cmdlets provide a simple way to wrap Invoke-Sql* (except for SqlBulkCopy) into a transaction and then either commit or rollback. - Complete-SqlTransaction maps to COMMIT and Undo-SqlTransaction maps to ROLLBACK. # EXAMPLES ```powershell Open-SQLiteConnection Invoke-SqlUpdate -Query "CREATE TABLE test (path text, size real, created datetime)" | Out-Null $InsertQuery = "INSERT INTO test (path, size, created) VALUES (@path, @size, @created)" [int]$recordsInserted = 0 Get-ChildItem -Recurse | ForEach-Object { $recordsInserted += Invoke-SqlUpdate -Query $InsertQuery -Parameters @{ path = $_.FullName size = $_.Length created = $_.CreationTime } } Write-Host "Insert $recordsInserted" $query = "SELECT * FROM test WHERE size > @size or created < @dt" Invoke-SqlQuery -Query $query -Parameters @{ size = 100kb dt = (Get-Date).AddYears(-2) } -Stream Close-SqlConnection ``` # SEE ALSO about_SimplySql_Providers # KEYWORDS SimplySql ================================================ FILE: HandleVerbose.ps1 ================================================ [cmdletBinding()] param([parameter(Position=0)][string]$Summary, [parameter(position=1)][string]$StepValue, [parameter(ValueFromPipeline)]$thisItem) begin { if ($VerbosePreference -ne "Continue" -and -not [string]::IsNullOrWhiteSpace($summary)){ Write-Host " $Summary..." -NoNewline } } process { if($VerbosePreference -eq "Continue") { $thisItem } elseif(-not [string]::IsNullOrWhiteSpace($StepValue)) { Write-Host $StepValue -NoNewline} } end { if ($VerbosePreference -ne "Continue" -and -not [string]::IsNullOrWhiteSpace($summary)){ Write-Host "Done!" } } ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2020 Mithrandyr Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: ModuleManifest/SimplySql.psd1 ================================================ # # Module manifest for module 'SimplySql' # # Generated by: Mithrandyr # # Generated on: 4/28/2026 # @{ # Script module or binary module file associated with this manifest. RootModule = 'SimplySql.Cmdlets.dll' # Version number of this module. ModuleVersion = '2.2.0.106' # Supported PSEditions # CompatiblePSEditions = @() # ID used to uniquely identify this module GUID = '71b1095f-dcb6-497d-8b47-a69c284aec64' # Author of this module Author = 'Mithrandyr' # Company or vendor of this module CompanyName = 'SolarNet' # Copyright statement for this module Copyright = '(c) 2022 Mithrandyr. All rights reserved.' # Description of the functionality provided by this module Description = 'Querying SQL (SQL Server, Oracle, PostgreSql, SQLite, & mySql) the PowerShell way: simple commands... powerful opportunities. SimplySql is a module that provides an intuitive set of cmdlets for talking to databases that abstracts the vendor specifics, allowing you to focus on getting work done. The basic pattern is to connect to a database, execute one or more sql statements and then close your database connection. This module provides cmdlets that map to this basic pattern. Each provider has its own Open-*Connection cmdlet -> Open-SqlConnection, Open-SQLiteConnection, Open-OracleConnection, Open-PostGreConnection, Open-MySqlConnection. The rest of the commands are provider agnostic. Open/Close/Show/Test/Set/Get -SqlConnection >> Control as many active connections as you want. Invoke- SqlScalar/SqlQuery/SqlUpdate >> Interact with those connections. Get/Clear -SqlMessage >> Get Informational messages, if provider supports it. Invoke-SqlBulkCopy >> Bulk Dataload from one connection to another. Start/Complete/Undo -SqlTransaction >> Utilize transactions!' # Minimum version of the Windows PowerShell engine required by this module PowerShellVersion = '5.0' # Name of the Windows PowerShell host required by this module # PowerShellHostName = '' # Minimum version of the Windows PowerShell host required by this module # PowerShellHostVersion = '' # Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # DotNetFrameworkVersion = '' # Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. # CLRVersion = '' # Processor architecture (None, X86, Amd64) required by this module # ProcessorArchitecture = '' # Modules that must be imported into the global environment prior to importing this module # RequiredModules = @() # Assemblies that must be loaded prior to importing this module # RequiredAssemblies = @() # Script files (.ps1) that are run in the caller's environment prior to importing this module. # ScriptsToProcess = @() # Type files (.ps1xml) to be loaded when importing this module # TypesToProcess = @() # Format files (.ps1xml) to be loaded when importing this module # FormatsToProcess = @() # Modules to import as nested modules of the module specified in RootModule/ModuleToProcess # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. FunctionsToExport = @() # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = 'Clear-SqlMessage', 'Close-SqlConnection', 'Complete-SqlTransaction', 'Get-SqlConnection', 'Get-SqlMessage', 'Get-SqlTransaction', 'Invoke-SqlBulkCopy', 'Invoke-SqlQuery', 'Invoke-SqlScalar', 'Invoke-SqlUpdate', 'Open-MySqlConnection', 'Open-OracleConnection', 'Open-PostGreConnection', 'Open-SQLConnection', 'Open-SQLiteConnection', 'Set-SqlConnection', 'Show-SqlConnection', 'Start-SqlTransaction', 'Test-SqlConnection', 'Undo-SqlTransaction' # Variables to export from this module # VariablesToExport = @() # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. AliasesToExport = 'csc', 'isq', 'iss', 'isu', 'ssc', 'tsc' # DSC resources to export from this module # DscResourcesToExport = @() # List of all modules packaged with this module # ModuleList = @() # List of all files packaged with this module # FileList = @() # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = 'SQL','SQLite','Database','Oracle','MySql','PostGre','Npgsql','MSSQL' # A URL to the license for this module. LicenseUri = 'https://github.com/mithrandyr/SimplySql/blob/master/LICENSE' # A URL to the main website for this project. ProjectUri = 'https://github.com/mithrandyr/SimplySql' # A URL to an icon representing this module. # IconUri = '' # ReleaseNotes of this module ReleaseNotes = 'Currently Supporting Microsoft SQL, SQLite, MySql, PostGre and Oracle. Check project repository for full Release Notes. Latest addition is support for PostGIS Geometry datatype in PostGreSQL.' # Prerelease string of this module # Prerelease = '' # Flag to indicate whether the module requires explicit user acceptance for install/update/save # RequireLicenseAcceptance = $false # External dependent modules of this module # ExternalModuleDependencies = @() } # End of PSData hashtable } # End of PrivateData hashtable # HelpInfo URI of this module # HelpInfoURI = '' # Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. # DefaultCommandPrefix = '' } ================================================ FILE: README.md ================================================ # SimplySql ## Introduction [![Powershell Gallery](https://img.shields.io/powershellgallery/v/SimplySql.svg)](https://www.powershellgallery.com/packages/SimplySql/) [![PowerShell Gallery](https://img.shields.io/powershellgallery/dt/SimplySql.svg)](https://www.powershellgallery.com/packages/SimplySql/) **Update (2/8/2024):** V2 is Released!!!. Querying SQL (SQL Server, Oracle, PostgreSql, SQLite, & mySql) the PowerShell way: simple commands... powerful opportunities. SimplySql is a module that provides an intuitive set of cmdlets for talking to databases that abstracts the vendor specifics, allowing you to focus on getting work done. The basic pattern is to connect to a database, invoke one or more sql statements and then close your database connection. This module provides cmdlets that map to this basic pattern. Each Provider has its own 'Open-*Connection' cmdlet, but the remaining cmdlets are provider agnostic (MSSQL: Open-SqlConnection, Oracle: Open-OracleConnection, SQLite: Open-SQLiteConnection, etc). You can have multiple connections open, just distinguish them through the use of the -ConnectionName parameter on every command (if no ConnectionName is specified, it defaults to 'default'). ```Powershell Open-*Connection -DataSource "SomeServer" -InitialCatalog "SomeDB" $data = Invoke-SqlQuery -query "SELECT * FROM someTable" #or using parameters $data = Invoke-SqlQuery -query "SELECT * FROM someTable WHERE someCol = @var" -Parameters @{var = 'a value'} Close-SqlConnection ``` See the [Wiki](https://github.com/mithrandyr/SimplySql/wiki) for more details ## Breaking Changes for 2.0 - UserName/Password parameters are no longer present on `Open-*Connection` cmdlets. Instead, provide a PSCredential object. ## Status It has been released to PowerShellGallery. Installation is as simple as Install-Module SimplySql -Scope CurrentUser This module requires PowerShell Version 5.0 or greater ## Database Providers - 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.2.0 * Added support for OSX-ARM64 thanks to @johnnygtech * Fixed an issue with -ColumnMap on Invoke-SqlBulkCopy ## 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. * Minor changes to -Privilege and -SSLMode (Oracle and MySql/PostGre respectively), changed from ENUM to STRING ### 2.0.0 * First release to support Windows PowerShell 5.1, PS Core and PS7. * Migrated the base provider class to .Net & all providers * Updated to latest versions of providers (that support .NET Standard 2.0) * Leveraged Optimized BulkCopy functionality in each provider. [View Version History](VersionHistory.md) ================================================ FILE: Tests/mssql.tests.ps1 ================================================ $ErrorActionPreference = "Stop" Describe "MSSQL" { BeforeAll { $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 } AfterAll { Open-SqlConnection @connHT -Database master @(isq "sp_who2" | ? dbname -eq test | % spid).foreach({ isu "KILL $_" }) Invoke-SqlUpdate "DROP Database Test" | Should -Be -1 Close-SqlConnection } BeforeEach { Open-SqlConnection @connHT -Database "test" } AfterEach { Show-SqlConnection -all | Close-SqlConnection } It "Test ConnectionString Switch" { { $connStr = "Data Source=$srvName;TrustServerCertificate=true" if ($connHT.ContainsKey("Credential")) { Open-SqlConnection -ConnectionString $connStr -ConnectionName Test -Credential $connHT.Credential -ErrorAction Stop } else { Open-SqlConnection -ConnectionString "$connStr;Integrated Security=SSPI" -ConnectionName Test -ErrorAction Stop } Close-SqlConnection -ConnectionName Test } | Should -Not -Throw } It "Test Integrated Security" { if ($PSVersionTable.PSEdition -eq "Desktop" -or $PSVersionTable.Platform -like "Win*") { { Open-SqlConnection -Server $srvName -ConnectionName "Test" -ErrorAction Stop Close-SqlConnection -ConnectionName "Test" } | Should -Not -Throw } else { Set-ItResult -Skipped -Because "Environment does not support Windows Integrated Auth" } } It "Invoke-SqlScalar" { Invoke-SqlScalar -Query "SELECT GETDATE()" | Should -BeOfType System.DateTime } 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) , 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) , tally(n) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM f) SELECT RAND(n) AS colDec , CAST(RAND(n*n / 4) * 1000000 AS int) AS colInt , CAST(NEWID() AS VARCHAR(50)) AS colText INTO tmpTable FROM tally" | Should -Be 65536 } 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 "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 "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 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 "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 "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 $result = @{val = 0 } Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -NotifyAction { param($rows) $result.val = $rows } $result.val | Should -Be 65536 } It "With -ColumnMap" { Invoke-SqlUpdate -Query "SELECT * INTO tmpTable11 FROM tmpTable WHERE 1=2" Open-SqlConnection @connHT -ConnectionName bcp Set-SqlConnection -Database test -ConnectionName bcp $columns = @{colDec = "colDec"; colInt = "colInt"; colText = "colText"} Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable2 -ColumnMap $columns | Should -Be 65536 } } Context "Transaction..." { It "Invoke-SqlBulkCopy" { Open-SqlConnection @connHT -ConnectionName bcp -Database test 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 -ea Stop | Should -Be 65536 } | Should -Not -Throw Undo-SqlTransaction -ConnectionName bcp { Invoke-SqlScalar -Query "SELECT COUNT(1) FROM tmpTable3" -ea Stop } | Should -Throw } It "Invoke-SqlScalar" { Start-SqlTransaction { 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 Undo-SqlTransaction } It "Invoke-SqlUpdate" { Start-SqlTransaction { Invoke-SqlUpdate "CREATE TABLE transactionTest (id int)" -ea Stop } | Should -Not -Throw Undo-SqlTransaction { Invoke-SqlScalar "SELECT 1 FROM transactionTest" -ea Stop } | Should -Throw } } Context "PipelineInput..." { It "Invoke-SqlScalar" { { [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 Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } 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 Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw } } 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]" } } } ================================================ FILE: Tests/mysql.tests.ps1 ================================================ $ErrorActionPreference = "Stop" Describe "MySql" { BeforeAll { $srvName = $env:COMPUTERNAME if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = "{0}." -f $env:NAME } #pscore on non-windows $u = "root" $p = "root" $db = "mysql" $c = [pscredential]::new($u, (ConvertTo-SecureString -Force -AsPlainText $p)) Open-MySqlConnection -Server $srvName -Database $db -Credential $c Invoke-SqlUpdate -Query "CREATE OR REPLACE VIEW $db.generator_16 AS SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15; CREATE OR REPLACE VIEW $db.generator_256 AS SELECT ( ( hi.n << 4 ) | lo.n ) AS n FROM $db.generator_16 lo, $db.generator_16 hi; CREATE OR REPLACE VIEW $db.generator_64k AS SELECT ( ( hi.n << 8 ) | lo.n ) AS n FROM $db.generator_256 lo, $db.generator_256 hi;" | Out-Null Close-SqlConnection } AfterAll { Open-MySqlConnection -Server $srvName -Database $db -Credential $c 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.tmpTable22; 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;" Close-SqlConnection } BeforeEach { Open-MySqlConnection -Server $srvName -Database $db -Credential $c } AfterEach { Show-SqlConnection -all | Close-SqlConnection } It "Test ConnectionString Switch " { { Open-MySqlConnection -ConnectionString "server=$srvName;database=$db;port=3306;user id=$u;password=$p;useaffectedrows=True;allowuservariables=True;sslmode=none" -ConnectionName Test -ea Stop Close-SqlConnection -ConnectionName Test } | Should -Not -Throw } It "UserName/Password Are Removed" { { Open-MySqlConnection -Server $srvName -UserName $u -Password $p -Database $db -ConnectionName test Close-SqlConnection -ConnectionName test } | Should -Throw } It "Invoke-SqlScalar" { Invoke-SqlScalar -Query "SELECT Now()" | Should -BeOfType System.DateTime } 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 } 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 FROM $db.generator_64k LIMIT 1000" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 } 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" | Measure-Object | Select-Object -ExpandProperty Count | 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 "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 "With -stream" { Invoke-SqlQuery -Query " SELECT rand() AS colDec , CAST(rand() * 1000000000 AS SIGNED) AS colInt , uuid() AS colText FROM $db.generator_64k LIMIT 1000" -Stream | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 } } 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)" 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 } It "With -ColumnMap" { $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.tmpTable22 (colDec REAL, colInt INTEGER, colText TEXT)" $columns = @{colDec = "colDec"; colInt = "colInt"; colText = "colText"} Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable22" -ColumnMap $columns | Should -Be 65536 } } Context "Transaction..." { It "Invoke-SqlBulkCopy" { $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.tmpTable3 (colDec REAL, colInt INTEGER, colText TEXT)" Start-SqlTransaction bcp Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable "$db.tmpTable3" -Notify | Should -Be 65536 Invoke-SqlScalar -Query "SELECT COUNT(1) FROM $db.tmpTable3" -cn bcp | Should -Be 65536 Undo-SqlTransaction bcp Invoke-SqlScalar -Query "SELECT COUNT(1) FROM $db.tmpTable3" -cn bcp | Should -Be 0 } It "Invoke-SqlScalar" { Start-SqlTransaction { 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 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 Undo-SqlTransaction Invoke-SqlScalar "SELECT Count(1) FROM transactionTest" | Should -Be 0 Invoke-SqlUpdate "DROP TABLE transactionTest" } } Context "PipelineInput..." { It "Invoke-SqlScalar" { { [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 Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } 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 Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw } } 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]" } } } <# http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator#mysql_generator_code #> ================================================ FILE: Tests/oracle.tests.ps1 ================================================ $ErrorActionPreference = "Stop" Describe "Oracle" { BeforeAll { $srvName = $env:COMPUTERNAME if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = "{0}." -f $env:NAME } #pscore on non-windows $u = "hr" $p = "hr" $c = [pscredential]::new($u, (ConvertTo-SecureString -Force -AsPlainText $p)) } BeforeEach { Open-OracleConnection -DataSource $srvName -ServiceName xe -Credential $c } AfterEach { Show-SqlConnection -all | Close-SqlConnection } AfterAll { Open-OracleConnection -DataSource $srvName -ServiceName xe -Credential $c foreach ($tbl in @("transactionTest", "tmpTable", "tmpTable2", "t", "tmpPK")) { $query = "BEGIN EXECUTE IMMEDIATE 'DROP TABLE $tbl'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF; END;" Invoke-SqlUpdate $query | Out-Null } Close-SqlConnection } It "Test ConnectionString Switch" { { $connstr = 'USER ID={0};PASSWORD={1};DATA SOURCE="(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={2})(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=xe)))";STATEMENT CACHE SIZE=5;' -f $u, $p, $srvName Open-OracleConnection -ConnectionName Test -ConnectionString $connstr -ea Stop Close-SqlConnection -ConnectionName Test } | Should -Not -Throw } It "UserName/Password Are Removed" { { Open-OracleConnection -DataSource $srvName -ServiceName xe -UserName $u -Password $p -ConnectionName test Close-SqlConnection -ConnectionName test } | Should -Throw } It "Invoke-SqlScalar" { Invoke-SqlScalar -Query "SELECT 1 FROM DUAL" | Should -BeOfType System.Decimal } 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.First | Should -Be "First" $result.Second | Should -Be "Second" $result.Third | Should -Be "Third" } It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query "CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText varchar(20))" Invoke-SqlUpdate -Query "INSERT INTO tmpTable 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" | Should -Be 65536 Invoke-SqlUpdate -Query "DROP TABLE tmpTable" } 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 CONNECT BY ROWNUM <= 1000" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 } 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" | Measure-Object | Select-Object -ExpandProperty Count | 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 "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 "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 CONNECT BY ROWNUM <= 1000" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 } } 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))" Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 | Should -Be 65536 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" } It "With -ColumnMap" -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))" $columns = @{colDec = "colDec"; colInt = "colInt"; colText = "colText"} Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -ColumnMap $columns | Should -Be 65536 Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" } } Context "Transaction..." { It "Invoke-SqlBulkCopy" -Tag bulkcopytransaction { $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))" Start-SqlTransaction -ConnectionName bcp Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable2 -Notify | 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 Invoke-SqlUpdate -ConnectionName bcp -Query "DROP TABLE tmpTable2" } It "Invoke-SqlScalar" { Start-SqlTransaction { 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 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 Undo-SqlTransaction Invoke-SqlScalar "SELECT Count(1) FROM transactionTest" | Should -Be 0 Invoke-SqlUpdate "DROP TABLE transactionTest" } } Context "PipelineInput..." { It "Invoke-SqlScalar" { { [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 Get-ChildItem | Invoke-SqlQuery "SELECT :Name FROM dual" -ErrorAction Stop } | Should -Not -Throw } 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 Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT :Name FROM dual"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw } } 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]" } } } <# requires that the predefined account HR is unlocked and has password hr using oracle 11.2g Express instance #> ================================================ FILE: Tests/postgre.tests.ps1 ================================================ $ErrorActionPreference = "Stop" Describe "PostGre" { BeforeEach { Open-PostGreConnection -Server $srvName -Database $db -Credential $c } AfterEach { Show-SqlConnection -all | Close-SqlConnection } BeforeAll { #warm up connection $srvName = $env:COMPUTERNAME #pscore on non-windows if([string]::IsNullOrWhiteSpace($srvName)) { $srvName = "{0}." -f $env:NAME } $u = "postgres" $p = "postgres" $db = "postgres" $c = [pscredential]::new($u, (ConvertTo-SecureString -Force -AsPlainText $p)) Open-PostGreConnection -Server $srvName -Database $db -Credential $c Close-SqlConnection } AfterAll { Open-PostGreConnection -Server $srvName -Database $db -Credential $c Invoke-SqlUpdate "DROP TABLE IF EXISTS transactionTest, tmpTable, tmpTable2, tmpTable21, tmpTable22, tmpTable23, t, tmpPK;" Close-SqlConnection } It "Test ConnectionString Switch" { { Open-PostGreConnection -ConnectionString "Max Auto Prepare=25;Host=$srvName;Database=$db;Port=5432;Username=$u;password=$p" -ConnectionName Test -ea Stop Close-SqlConnection -ConnectionName Test } | Should -Not -Throw } It "UserName/Password Are Removed" { { Open-PostGreConnection -Server $srvName -Database $db -UserName $u -Password $p -ConnectionName test Close-SqlConnection -ConnectionName test } | Should -Throw } It "Invoke-SqlScalar" { Invoke-SqlScalar -Query "SELECT Now()" | Should -BeOfType System.DateTime } 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) , 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) , tally(n) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM f) INSERT INTO tmpTable SELECT random() AS colDec , CAST(random() * 1000000 AS int) AS colInt , CAST(Random() AS VARCHAR(50)) AS colText FROM tally" | Should -Be 65536 } 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 "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 "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 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 "With -stream" { Invoke-SqlQuery -Query "SELECT * FROM tmpTable LIMIT 1000" -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-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 } 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 } It "With -ColumnMap" { Invoke-SqlUpdate -Query "SELECT * INTO tmpTable23 FROM tmpTable WHERE 1=2" Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c $columns = @{colDec = "colDec"; colInt = "colInt"; colText = "colText"} Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceTable tmpTable -DestinationTable tmpTable23 -ColumnMap $columns | Should -Be 65536 Close-SqlConnection -ConnectionName bcp } } Context "Transaction..." { It "Invoke-SqlBulkCopy" { Open-PostGreConnection -Server $srvName -Database $db -ConnectionName bcp -Credential $c 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 Undo-SqlTransaction -ConnectionName bcp { 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 Undo-SqlTransaction } It "Invoke-SqlQuery" { Start-SqlTransaction { 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 Undo-SqlTransaction { Invoke-SqlScalar "SELECT 1 FROM transactionTest" -ea Stop } | Should -Throw } } Context "PipelineInput..." { It "Invoke-SqlScalar" { { [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 Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } 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 Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw } } 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]" } } } ================================================ FILE: Tests/sqlite.tests.ps1 ================================================ $ErrorActionPreference = "Stop" Describe "SQLite" { BeforeEach { Open-SQLiteConnection } AfterEach { Show-SqlConnection -all | Close-SqlConnection } AfterAll { Remove-Item "$home\temp.db" } It "Test ConnectionString Switch" { { Open-SQLiteConnection -ConnectionString "Data Source=:memory:" -ConnectionName Test -ea Stop Close-SqlConnection -ConnectionName Test } | Should -Not -Throw } It "Invoke-SqlScalar" { Invoke-SqlScalar -Query "SELECT 1" | Should -BeOfType System.Int64 } It "Invoke-SqlUpdate" { Invoke-SqlUpdate -Query " CREATE TABLE tmpTable (colDec REAL, colInt INTEGER, colText TEXT) ;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) INSERT INTO tmpTable SELECT random()/1000000000000. AS colDec , random() AS colInt , hex(randomblob(20)) AS colText FROM f" | Should -Be 65536 Invoke-SqlUpdate -Query "DROP TABLE tmpTable" | Out-Null } 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) , 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 LIMIT 1000" | Measure-Object | Select-Object -ExpandProperty Count | Should -Be 1000 } 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" | Measure-Object | Select-Object -ExpandProperty Count | 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 "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 "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) , 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 LIMIT 1000" -Stream | 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)" 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) , 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 tmpTable22 (colDec REAL, colInt INTEGER, colText TEXT)" $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 } It "With -ColumnMap" { $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 tmpTable23 (colDec REAL, colInt INTEGER, colText TEXT)" $columns = @{colDec = "colDec"; colInt = "colInt"; colText = "colText"} Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable -ColumnMap $columns | Should -Be 65536 Close-SqlConnection -ConnectionName bcp } } Context "PipelineInput..." { It "Invoke-SqlBulkCopy" { $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" Start-SqlTransaction -ConnectionName bcp Invoke-SqlUpdate -ConnectionName bcp -Query "CREATE TABLE tmpTable3 (colDec REAL, colInt INTEGER, colText TEXT)" { Invoke-SqlBulkCopy -DestinationConnectionName bcp -SourceQuery $query -DestinationTable tmpTable3 -Notify | Should -Be 65536 } | Should -Not -Throw Undo-SqlTransaction -ConnectionName bcp { Invoke-SqlScalar -ConnectionName bcp -Query "SELECT COUNT(1) FROM tmpTable3" -ea Stop } | Should -Throw } It "Invoke-SqlScalar" { Start-SqlTransaction { Invoke-SqlScalar "SELECT 1" } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlQuery" { Start-SqlTransaction { Invoke-SqlScalar "SELECT 1" } | Should -Not -Throw Undo-SqlTransaction } It "Invoke-SqlUpdate" { Start-SqlTransaction { Invoke-SqlUpdate "CREATE TABLE transactionTest (id int)" -ea Stop } | Should -Not -Throw Undo-SqlTransaction { Invoke-SqlScalar "SELECT 1 FROM transactionTest" -ea Stop } | Should -Throw } } Context "PipelineInput..." { It "Invoke-SqlScalar" { { [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 Get-ChildItem | Invoke-SqlQuery "SELECT @Name" -ErrorAction Stop } | Should -Not -Throw } 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 Get-ChildItem | Invoke-SqlScalar "INSERT INTO t SELECT @Name"-ErrorAction Stop Invoke-SqlUpdate "DROP TABLE t" -ErrorAction Stop } | Should -Not -Throw } } 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]" } } } ================================================ FILE: VersionHistory.md ================================================ # Version History ### 1.9.1 * Updating SQLite library. Interop Version: 1.0.117.0 & SQLite Server Version: 3.40.0 thanks @JediNite ### 1.9.0 * Updated classes to use `::new()` constructor. thanks @joalcorn * Updated MySql provider to use new library (8.0.28). thanks @twerthi ### 1.8.0 * Minor Update, enhancing progress notifications for Invoke-SqlBulkCopy, you can now specify -NotifyAction and pass in a scriptblock ### 1.7.0 * Minor update to expose the transaction object to the user via the new `Get-SqlTransaction` cmdlet. ### 1.6.2 * added support for .Net Framework 4.6.1 (included library 'DataReaderToPSObject' is compiled against .Net Standard 2.0 which requires shims on .Net 4.6.1). (@jantari) ### 1.6.1 * added support for Azure Token authentication to SQL Server ### 1.6.0 * Updated DataReaderToObject.dll (@ili101) * Added -TrustServerCertificate to Open-PostgreConnection (@ili101) * Added -ProviderTypes to Invoke-SqlQuery (@ili1010) ### 1.5.9 * Fixed issue with `Open-OracleConnection` help (@PaulWalkerUK) * Added -AsDataTable to Open-SqlQuery (@ili101) * Added -TrustSSL to Open-PostGreConnection, allowing for self-signed certificates (@ili101) * Updated -ConnectionName parameter on all cmdlets to no longer allow null or empty strings. * Added better handling around SqlTransactions when an error is thrown (for SQL Server this happens when the server takes longer than the connectionTimeout, however the transaction action (COMMIT or ROLLBACK) still goes through properly). * Added default value ("postgres") to -Database for Open-PostGreConnection. * Added -DBAPrivilege to Open-OracleConnection to allow connecting as SYSOPER or SYSDBA. ### 1.5.4 * Fixed issue with loading the Geometry npgsql extension (Npgsql.NetTopologySuite) when database in connection string did not have PostGIS installed. * Automatically load geometry npgsql extension on database switch and on re-opening the connection (if current database has PostGIS installed). ### 1.5.3 * Fixed issue with Geometry not being supported in PostGre provider. ### 1.5.2 * Fixed issue with OracleProvider -- binding by position rather than by parameter name. (@Abrechnung1) ### 1.5.1 * Updated tests for Pester v4 * Fixed issue with transactions for MSSQL. * Fixed issue with ```Show-SqlConnection -all | Close-SqlConnection``` when there are no open connections. * Updated MySql Provider to 8.0.12, added parameter for SSLmode * Updated SQLite provider to 1.0.109.1 * Updated Oracle provider to 18.3 (added support for oracleCredential) * Updated PostGre provider (npgsql) to 4.0.2 ### 1.4.1 * Added support for SSL connections to PostGre provider. ### 1.4.0 * Added support for PSCredential on MySql, Oracle and PostGre providers, marking UserName/Password as deprecated. Sql Provider already had support, added deprecation warning. SQLite only has -Password, no change to this provider. ### 1.3.8 * Fixed issue with Invoke-SqlQuery throwing an error when there is no resultset, now creates a warning. * Added Pester tests to cover this scenario. ### 1.3.7 * Fixed issue with SqlConnection not accepting ConnectionStrings (root issue, you can't assign a connection string to an existing SqlConnectionStringBuilder.) * Fixed issue with MySqlConnection and PostGreConnection, can't assign connection string to *ConnectionStringBuilder, instead simply create the connection object if connectionstring is passed in. ### 1.3.6 * Fixed issue with -Parameters on Invoke-SqlQuery/Scalar/Update, passing in '$false' as a value was failing to pass anything at all. ### 1.3.5 * Fixed issue with Postgre that got released in version 1.3.4. ### 1.3.4 * Updated help: cmdlets and the about_* files (about_SimplySql & about SimplySql_Providers). * Updated provider DLLs for PostGre, MySql, and SQLite. ### 1.3.3 * Fixed issue where -ConnectionString was not working properly with the Oracle Provider. ### 1.3.2 * Fixed issue with help missing from the open-*connection cmdlets. * removed unnecessary files from the Functions subfolder. ### 1.3.1 * Fixed minor issues with SQLBulkCopy: -notify is not required and if SQLBulkCopy errors, Identity Insert will be turned off. ### 1.3.0 * Added support for Azure AD auth for Azure SQL Dbs * Fix issue in PostGre when using the -stream parameter and querying scalar data without a table, select "1, 2, 3" ### 1.2.0 * Updated providers ### 1.1.1 * Removed a debugging message from the base Provider.BulkLoad method (only showed up in sqlite) * Added functionality to retrieve the underlying provider connection object via Get-SqlConnection (gsc) * Updated information in the about files. ### 1.1.0 * Added support for non standard column names (ie those that might include spaces, etc) in Invoke-SqlBulkCopy. * Changed Open-MySqlConnection to no longer require setting the database, defaults to "mysql" ================================================ FILE: default.build.ps1 ================================================ param([version]$Version, [switch]$CommitRevision, [ValidateSet("Major", "Minor", "Build")][string]$Increment) New-Alias -Name HV -Value (Resolve-Path HandleVerbose.ps1) -Force if(-not $version) { $Script:Version = [Version](Import-PowerShellDataFile -Path "ModuleManifest\SimplySql.psd1")["ModuleVersion"] switch ($Increment) { "Major" { $Script:Version = [version]::new($version.Major + 1, 0, 0, $version.Revision + 1) } "Minor" { $Script:Version = [version]::new($version.Major, $version.Minor + 1, 0, $version.Revision + 1) } "Build" { $Script:Version = [version]::new($version.Major, $version.Minor, $version.Build + 1, $version.Revision + 1) } default { $Script:Version = [version]::new($version.Major, $version.Minor, $version.Build, $version.Revision + 1) } } } task Clean { remove "output" } task Build { Invoke-Build -File "source\source.build.ps1" -Version $Version} task ComposeModule { if(-not (Test-Path "output\SimplySql" -PathType Container)) { New-Item "Output\SimplySql" -ItemType Directory | Out-Null } }, copyManifest, copyBinaries, updateManifest, GenerateDocs task GenerateDocs { Start-Job -ScriptBlock { Set-Location $using:BuildRoot Import-Module ".\output\SimplySql" -Verbose:$false if(-not (Test-Path "docs")) { New-MarkdownHelp -Module SimplySql -OutputFolder Docs -AlphabeticParamsOrder -WithModulePage New-MarkdownAboutHelp -OutputFolder Docs -AboutName "SimplySql" } else { Update-MarkdownHelpModule -Path "Docs" -AlphabeticParamsOrder -Force -RefreshModulePage -UpdateInputOutput } New-ExternalHelp -Path "Docs" -OutputPath ".\output\SimplySql\en-US" -Force } | Receive-Job -Wait -AutoRemoveJob | ForEach-Object { " $($_.Name)" } | HV "Generating Module Documentation" "." } task copyManifest { #Base Module Files Copy-Item "ModuleManifest\SimplySql.psd1" -Destination "output\SimplySql" -Force } task copyBinaries { #Copy files for engine Copy-Item "source\output\*.dll" -Destination "output\SimplySql" -Force Copy-Item "source\output\bin" -Destination "output\SimplySql" -Filter "*.dll" -Recurse -Force } task updateManifest { Import-Module PowerShellGet -Verbose:$false $cmdlets = Start-Job -ScriptBlock { Set-Location $using:BuildRoot Import-Module ".\Output\SimplySql\SimplySql.Cmdlets.dll" Get-Command -Module SimplySql.Cmdlets } | Receive-Job -AutoRemoveJob -wait | Sort-Object name | ForEach-Object name Update-ModuleManifest -Path "Output\SimplySql\SimplySql.psd1" -ModuleVersion $version -CmdletsToExport $cmdlets Copy-Item -Path "Output\SimplySql\SimplySql.psd1" -Destination "ModuleManifest\SimplySql.psd1" } task revisionCommit { exec { git commit "ModuleManifest/SimplySql.psd1" -m "Updating version To $version" } | HV "Incrementing Version ($version) and Git Commit" } -If $CommitRevision task . Clean, Build, ComposeModule, revisionCommit ================================================ FILE: developmentideas.txt ================================================ Eventually make the wiki Project in github reference the /docs subfolder https://stackoverflow.com/a/76144369 EXAMPLE cmds: git clone https://github.com/youName/ProjectName.wiki docs git submodule add https://github.com/youName/ProjectName.wiki docs git submodule update --init ORACLE InfoMessage https://stackoverflow.com/questions/193107/print-text-in-oracle-sql-developer-sql-worksheet-window Always roll version (minor) forward by 1 when updating provider nuget packages. --------- TODO: + PSObjectDataReader in .NET - update sqlBulkcopy to take objects directly / andor to take datareader directly? - or create full fleged provider for objects? (maybe using datatable as backend?) + Allow invoke-SqlQuery/SqlUpdate to take objects as input (translate to parameters) -- single or multiple objects? (probably single only) ---- Better Information : https://devblogs.microsoft.com/powershell/resolving-powershell-module-assembly-dependency-conflicts/#quick-fixes-and-their-limitations ---- ================================================ FILE: runTests.ps1 ================================================ param( [ValidateSet("pwsh","powershell")][string]$env = "pwsh" , [ValidateSet("mssql","mysql","postgre","oracle","sqlite")][string[]]$Tests = @("mssql","mysql","postgre","oracle","sqlite") , [switch]$Interactive ) $arglist = @() $arglist += "-NoProfile", "-NoLogo" if($Interactive){ $arglist += "-NoExit" } $arglist += "-Command function prompt {'TESTING> '}; Import-Module .\Output\SimplySql; 'SimplySql Version: {0}' -f (Get-Module SimplySql | Select-Object -ExpandProperty Version)" if($tests.count -gt 0) { $arglist += "; Invoke-Pester @({0}) -output detailed" -f ($Tests.ForEach({"'.\Tests\$_.tests.ps1'"}) -join ", ") } Start-Process -FilePath $env -ArgumentList $arglist -NoNewWindow -Wait -WorkingDirectory $PSScriptRoot ================================================ FILE: source/ConstructModule.ps1 ================================================ Invoke-Build -DebugOnly $PSModuleAutoLoadingPreference = "none" Import-Module .\Output\SimplySql.Cmdlets.dll -Verbose Import-Module microsoft.powershell.security Write-Host " call 'RunTests' to execute pester tests..." function RunTests([ValidateSet("mssql","mysql","postgre","oracle","sqlite")][string[]]$Tests = @("mssql","mysql","postgre","oracle","sqlite")) { Import-Module Pester $testsToRun = ($Tests.ForEach({"..\Tests\$_.tests.ps1"}) -join ", ") Invoke-Pester @($testsToRun) -output detailed } ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/ClearSqlMessage.vb ================================================  Public Class ClearSqlMessage Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName) Then Try Engine.Logic.GetConnection(ConnectionName).ClearMessages() WriteVerbose($"SQL Messages cleared from '{ConnectionName}'.") Catch nse As NotSupportedException WriteWarning(nse.Message) Catch ex As Exception WriteWarning($"[{ConnectionName}] {ex.Message}") End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/CloseSqlConnection.vb ================================================  <[Alias]("csc")> Public Class CloseSqlConnection Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName) Then Try Engine.Logic.CloseAndRemoveConnection(ConnectionName) WriteVerbose($"SQL Connection '{ConnectionName}' closed.") Catch ex As Exception ErrorOperationFailed(ex, ConnectionName, ErrorCategory.CloseError) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/CompleteSqlTransaction.vb ================================================  Public Class CompleteSqlTransaction Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Commit a Sql Transaction") Then Dim conn = Engine.Logic.GetConnection(ConnectionName) Try conn.CommitTransaction() Catch ex As Exception If conn.Connection.State = Data.ConnectionState.Closed Then conn.Connection.Open() ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/GetSqlConnection.vb ================================================  Public Class GetSqlConnection Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Get Sql Connection") Then Try WriteObject(Engine.Logic.GetConnection(ConnectionName).Connection) Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/GetSqlMessage.vb ================================================  Public Class GetSqlMessage Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Get Sql Messages") Then Dim conn = Engine.Logic.GetConnection(ConnectionName) Try Do While conn.HasMessages WriteObject(conn.GetMessage) Loop Catch nse As NotSupportedException WriteWarning(nse.Message) Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/GetSqlTransaction.vb ================================================  Public Class GetSqlTransaction Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Get Sql Transaction") Then Try WriteObject(Engine.Logic.GetConnection(ConnectionName).Transaction) Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/InvokeSqlBulkCopy.vb ================================================  Public Class InvokeSqlBulkCopy Inherits PSCmdlet #Region "Parameters" <[Alias]("SrcCN")> Public Property SourceConnectionName As String = "default" <[Alias]("DstCN")> Public Property DestinationConnectionName As String = "default" Public Property DestinationTable As String Public Property SourceTable As String Public Property SourceQuery As String() Public Property SourceParameters As Hashtable Public Property ColumnMap As Hashtable Public Property BatchSize As Integer = 500 ")> Public Property BatchTimeout As Integer = -1 Public Property Notify As SwitchParameter Public Property NotifyAction As Action(Of Long) #End Region Protected Overrides Sub EndProcessing() If SourceConnectionName.Equals(DestinationConnectionName, StringComparison.OrdinalIgnoreCase) Then Dim ex As New ArgumentException($"You cannot use the same connection for both the source and destination ({SourceConnectionName}).", NameOf(DestinationConnectionName)) WriteError(New ErrorRecord(ex, MyInvocation.MyCommand.Name, ErrorCategory.InvalidArgument, DestinationConnectionName)) Else If ValidateConnection(SourceConnectionName) And ValidateConnection(DestinationConnectionName) Then If Me.ShouldProcess(DestinationConnectionName, $"Execute bulkloading into '{DestinationTable}'") Then Dim singleQuery As String, columnDict As New Dictionary(Of String, String)(StringComparer.OrdinalIgnoreCase) If ColumnMap IsNot Nothing Then For Each de As DictionaryEntry In ColumnMap columnDict.Add(de.Key.ToString, de.Value.ToString) Next Else columnDict = Nothing End If If ParameterSetName = "table" Then Dim queryColumns As String = "*" If columnDict IsNot Nothing Then queryColumns = String.Join(", ", columnDict.Keys.ToArray) End If singleQuery = $"SELECT {queryColumns} FROM {SourceTable}" If String.IsNullOrWhiteSpace(DestinationTable) Then DestinationTable = SourceTable Else singleQuery = String.Join(Environment.NewLine, SourceQuery) End If Try Dim srcReader = Engine.GetConnection(SourceConnectionName).GetDataReader(singleQuery, SourceParameters) 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, columnDict, BatchSize, BatchTimeout, NotifyAction)) Catch ex As Exception ErrorOperationFailed(ex, DestinationConnectionName) Finally If Notify Then WriteProgress(New ProgressRecord(0, "SimplySql BulkCopy", DestinationTable) With {.RecordType = ProgressRecordType.Completed}) End Try End If End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/InvokeSqlQuery.vb ================================================  <[Alias]("isq")> Public Class InvokeSqlQuery Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property Query As String() Public Property Parameters As Hashtable ")> Public Property CommandTimeout As Integer = -1 Public Property ParamObject As PSObject Public Property Stream As SwitchParameter Public Property AsDataTable As SwitchParameter <[Alias]("ProviderTypes")> Public Property UseTypesFromProvider As SwitchParameter #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then Dim singleQuery As String = String.Join(Environment.NewLine, Query) If Me.ShouldProcess(ConnectionName, $"Execute '{singleQuery}'") Then If ParameterSetName.Equals("object", StringComparison.OrdinalIgnoreCase) AndAlso ParamObject IsNot Nothing Then Parameters = ParamObject.ConvertToHashtable End If Try If Stream.IsPresent Then Using dr = Engine.Logic.GetConnection(ConnectionName).GetDataReader(singleQuery, Parameters, CommandTimeout) WriteObject(dr.ConvertToPSObject, True) End Using Else Using ds = Engine.Logic.GetConnection(ConnectionName).GetDataSet(singleQuery, CommandTimeout, Parameters, UseTypesFromProvider.IsPresent) If ds.Tables.Count = 0 Then WriteWarning("Query returned no resultset. This occurs when the query has no select statement or invokes a stored procedure that does not return a resultset. Use 'Invoke-SqlUpdate' to avoid this warning.") ElseIf ds.Tables.Count > 1 OrElse AsDataTable.IsPresent Then WriteObject(ds.Tables, True) Else WriteObject(ds.Tables(0).Rows, True) End If End Using End If Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/InvokeSqlScalar.vb ================================================  <[Alias]("iss")> Public Class InvokeSqlScalar Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property Query As String() Public Property Parameters As Hashtable ")> Public Property CommandTimeout As Integer = -1 Public Property ParamObject As PSObject #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then Dim singleQuery As String = String.Join(Environment.NewLine, Query) If Me.ShouldProcess(ConnectionName, $"Execute '{singleQuery}'") Then If ParameterSetName.Equals("object", StringComparison.OrdinalIgnoreCase) AndAlso ParamObject IsNot Nothing Then Parameters = ParamObject.ConvertToHashtable End If Try WriteObject(Engine.Logic.GetConnection(ConnectionName).GetScalar(singleQuery, CommandTimeout, Parameters)) Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/InvokeSqlUpdate.vb ================================================ Imports System.Data <[Alias]("isu")> Public Class InvokeSqlUpdate Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property Query As String() Public Property Parameters As Hashtable ")> Public Property CommandTimeout As Integer = -1 Public Property ParamObject As PSObject Public Property Command As IDbCommand #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then Dim conn = Engine.Logic.GetConnection(ConnectionName) If ParameterSetName = "cmd" AndAlso Me.ShouldProcess(ConnectionName, $"Execute '{Command.CommandText}'") Then Try WriteObject(conn.Update(Command)) WriteVerbose($"Executed command on '{ConnectionName}'.") Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try Else Dim singleQuery As String = String.Join(Environment.NewLine, Query) If ParameterSetName.Equals("object", StringComparison.OrdinalIgnoreCase) AndAlso ParamObject IsNot Nothing Then Parameters = ParamObject.ConvertToHashtable End If If Me.ShouldProcess(ConnectionName, $"Execute '{singleQuery}'") Then Try WriteObject(conn.Update(singleQuery, CommandTimeout, Parameters)) WriteVerbose($"Executed query on '{ConnectionName}'.") Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/SetSqlConnection.vb ================================================  Public Class SetSqlConnection Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property Database As String Public Property CommandTimeout As Integer = -1 #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If CommandTimeout > 0 AndAlso Me.ShouldProcess(ConnectionName, $"Change CommandTimeout to '{CommandTimeout}'") Then Engine.Logic.GetConnection(ConnectionName).CommandTimeout = CommandTimeout End If If Not String.IsNullOrEmpty(Database) AndAlso Me.ShouldProcess(ConnectionName, $"Change Database to '{Database}'") Then Try Engine.Logic.GetConnection(ConnectionName).ChangeDatabase(Database) Catch nse As NotSupportedException WriteWarning(nse.Message) Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/ShowSqlConnection.vb ================================================  <[Alias]("ssc")> Public Class ShowSqlConnection Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property All As SwitchParameter #End Region Protected Overrides Sub EndProcessing() If All.IsPresent Then WriteObject(Engine.Logic.Connections.Keys, True) Else If Engine.Logic.ConnectionExists(ConnectionName, False) = Engine.ValidateConnectionResult.Found Then Dim connInfo As New PSObject() For Each de As DictionaryEntry In Engine.Logic.GetConnection(ConnectionName).ConnectionInfo connInfo.Properties.Add(New PSNoteProperty(de.Key, de.Value)) Next WriteObject(connInfo) End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/StartSqlTransaction.vb ================================================  Public Class StartSqlTransaction Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Begin a Sql Transaction") Then Try Engine.Logic.GetConnection(ConnectionName).BeginTransaction() Catch ex As Exception ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/TestSqlConnection.vb ================================================  <[Alias]("tsc")> Public Class TestSqlConnection Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property All As SwitchParameter Public Property Detailed As SwitchParameter #End Region Protected Overrides Sub EndProcessing() If All.IsPresent Then WriteObject(Engine.Logic.Connections.Count > 0) Else If Detailed Then WriteObject(Engine.Logic.ConnectionExists(ConnectionName)) Else WriteObject(Engine.Logic.ConnectionExists(ConnectionName, False) = Engine.ValidateConnectionResult.Found) End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/Cmdlets/UndoSqlTransaction.vb ================================================  Public Class UndoSqlTransaction Inherits PSCmdlet #Region "Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" #End Region Protected Overrides Sub ProcessRecord() If ValidateConnection(ConnectionName) Then If Me.ShouldProcess(ConnectionName, "Rollback a Sql Transaction") Then Dim conn = Engine.Logic.GetConnection(ConnectionName) Try conn.RollbackTransaction() Catch ex As Exception If conn.Connection.State = Data.ConnectionState.Closed Then conn.Connection.Open() ErrorOperationFailed(ex, ConnectionName) End Try End If End If End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/ContextHandling.vb ================================================ Imports System.Reflection Imports System.IO Imports System.Runtime.InteropServices Public Class ContextHandling Implements IModuleAssemblyInitializer, IModuleAssemblyCleanup Shared Sub New() 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 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 AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf HandleResolveEvent End Sub Public Sub OnRemove(psModuleInfo As PSModuleInfo) Implements IModuleAssemblyCleanup.OnRemove RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf HandleResolveEvent End Sub 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) '#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 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 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 Dim filePath = Path.Combine(BinPath, "PS5", "win-x64", $"{asmName}.dll") If IO.File.Exists(filePath) Then Return filePath Else 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 arch As String = RuntimeInformation.OSArchitecture.ToString().ToLower() Dim filePath = Path.Combine(BinPath, "PS7", $"osx-{arch}", $"{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 End If Return Nothing End Function End Class ================================================ FILE: source/SimplySql.Cmdlets/DataReaderToPSObject.vb ================================================ Imports System.Data Imports System.Data.Common Imports System.Linq.Expressions Public Class DataReaderToPSObject Shared Iterator Function Convert(theDataReader As IDataReader) As IEnumerable(Of PSObject) Do 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 Select Case col.Type Case "System.Boolean" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetBoolean(col.Ordinal)), True) Case "System.Byte" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetByte(col.Ordinal)), True) Case "System.Char" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetChar(col.Ordinal)), True) Case "System.DateTime" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetDateTime(col.Ordinal)), True) Case "System.Decimal" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetDecimal(col.Ordinal)), True) Case "System.Double" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetDouble(col.Ordinal)), True) Case "System.Single" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetFloat(col.Ordinal)), True) Case "System.Guid" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetGuid(col.Ordinal)), True) Case "System.Int16" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetInt16(col.Ordinal)), True) Case "System.Int32" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetInt32(col.Ordinal)), True) Case "System.Int64" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetInt64(col.Ordinal)), True) Case "System.String" pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetString(col.Ordinal)), True) Case Else pso.Properties.Add(New PSNoteProperty(col.Name, theDataReader.GetValue(col.Ordinal))) End Select End If Next Yield pso End While Loop While theDataReader.NextResult End Function Shared Iterator Function ConvertUsingExpressionTree(theDataReader As IDataReader) As IEnumerable(Of PSObject) Do Dim convertFunction = map.CreateFunction(theDataReader) While theDataReader.Read Yield convertFunction(theDataReader) End While Loop While theDataReader.NextResult End Function Friend Class map Public Ordinal As Integer = 0 Public Name As String Public Type As String Shared Function CreateMappings(dr As IDataReader) As Generic.List(Of map) 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) Dim expList = New List(Of Expression) Dim columns = map.CreateMappings(dr) Dim paramDR = Expression.Parameter(GetType(IDataRecord), "dr") Dim varPso = Expression.Variable(GetType(PSObject), "pso") expList.Add(Expression.Assign(varPso, Expression.[New](GetType(PSObject)))) 'Dim pso = New PSObject Dim psoProperties = Expression.Property(varPso, GetType(PSObject).GetProperty("Properties")) Dim methodPsoPropertiesAdd = GetType(PSMemberInfoCollection(Of PSPropertyInfo)).GetMethod("Add", {GetType(PSNoteProperty)}) For Each col In columns Dim psnName = Expression.Constant(col.Name, GetType(String)) Dim psnValue = Expression.Call(paramDR, GetType(IDataRecord).GetMethod("GetValue"), {Expression.Constant(col.Ordinal)}) Dim noteProperty = Expression.[New](GetType(PSNoteProperty).GetConstructor({GetType(String), GetType(Object)}), {psnName, psnValue}) expList.Add(Expression.Call(psoProperties, methodPsoPropertiesAdd, {noteProperty})) ' pso.Members.Add(New PSNoteProperty(col.Name, dr.GetValue(col.Ordinal)) Next expList.Add(varPso) ' return pso Return Expression.Lambda(Of Func(Of IDataRecord, PSObject))(Expression.Block({varPso}, expList), paramDR).Compile End Function End Class End Class ================================================ FILE: source/SimplySql.Cmdlets/Dry.vb ================================================ Imports System.Globalization Imports System.Runtime.CompilerServices Imports System.Runtime.Serialization Module Dry Function ValidateConnection(this As PSCmdlet, connectionName As String, Optional validateIsOpen As Boolean = True) As Boolean Dim result = Engine.ConnectionExists(connectionName, validateIsOpen) Select Case result Case Engine.ValidateConnectionResult.NotFound this.WriteError(New ErrorRecord(New ConnectionNotFound(connectionName), this.MyInvocation.MyCommand.Name, ErrorCategory.ObjectNotFound, connectionName)) Return False Case Engine.ValidateConnectionResult.NotOpen this.WriteError(New ErrorRecord(New ConnectionNotOpen(connectionName), this.MyInvocation.MyCommand.Name, ErrorCategory.ResourceUnavailable, connectionName)) Return False Case Engine.ValidateConnectionResult.Found, Engine.ValidateConnectionResult.Open Return True Case Else Throw New NotImplementedException($"ValidateConnectionResult '{result}' is not implemented!") End Select End Function Sub ErrorOperationFailed(this As PSCmdlet, ex As Exception, connectionName As String, Optional errCategory As ErrorCategory = ErrorCategory.InvalidOperation) this.WriteError(New ErrorRecord(ex, this.MyInvocation.MyCommand.Name, errCategory, connectionName)) End Sub Function ConvertToHashtable(this As PSObject, Optional ignoreNull As Boolean = True) As Hashtable Dim ht As New Hashtable Dim propQuery = this.Properties.Where(Function(prop) prop.MemberType = PSMemberTypes.Property Or prop.MemberType = PSMemberTypes.AliasProperty Or prop.MemberType = PSMemberTypes.NoteProperty).AsQueryable If ignoreNull Then propQuery = propQuery.Where(Function(prop) prop.Value IsNot Nothing) Dim nValue As Object For Each prop In propQuery nValue = prop.Value If TypeOf nValue Is PSObject Then nValue = DirectCast(nValue, PSObject).BaseObject If Type.GetTypeCode(nValue.GetType()) = TypeCode.Object Then If TypeOf nValue Is Xml.XmlNode Then nValue = DirectCast(nValue, Xml.XmlNode).OuterXml Else nValue = nValue.ToString() End If End If ht.Add(prop.Name, nValue) Next Return ht End Function Function ConvertToPSObject(this As Data.IDataReader) As IEnumerable(Of PSObject) Return DataReaderToPSObject.Convert(this) End Function End Module #Region "Exceptions" Public Class ConnectionNotFound Inherits Exception Public ReadOnly Property ConnectionName As String Sub New(connectionName As String) MyBase.New($"Connection '{connectionName}' does not exist.") Me.ConnectionName = connectionName End Sub Public Sub New(connectionName As String, innerException As Exception) MyBase.New($"Connection '{connectionName}' does not exist.", innerException) Me.ConnectionName = connectionName End Sub End Class Public Class ConnectionNotOpen Inherits Exception Public ReadOnly Property ConnectionName As String Sub New(connectionName As String) MyBase.New($"Connection '{connectionName}' is not open.") Me.ConnectionName = connectionName End Sub Public Sub New(connectionName As String, innerException As Exception) MyBase.New($"Connection '{connectionName}' is not open.", innerException) Me.ConnectionName = connectionName End Sub End Class #End Region ================================================ FILE: source/SimplySql.Cmdlets/My Project/Application.myapp ================================================ true Form1 false 0 true 0 true ================================================ FILE: source/SimplySql.Cmdlets/My Project/launchSettings.json ================================================ { "profiles": { "PWSH": { "commandName": "Executable", "executablePath": "pwsh", "commandLineArgs": "-noexit -nologo -noprofile -file \"ConstructModule.ps1\"", "workingDirectory": "..\\" }, "Powershell": { "commandName": "Executable", "executablePath": "powershell", "commandLineArgs": "-noexit -nologo -noprofile -file \"ConstructModule.ps1\"", "workingDirectory": "..\\" }, "WSL": { "commandName": "Executable", "executablePath": "wsl", "commandLineArgs": "pwsh", "workingDirectory": "..\\", } } } ================================================ FILE: source/SimplySql.Cmdlets/ProviderCmdlets/OpenMySqlConnection.vb ================================================  Public Class OpenMySqlConnection Inherits PSCmdlet #Region "Cmdlet Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property CommandTimeout As Integer = 30 <[Alias]("Host")> Public Property Server As String = "localhost" <[Alias]("InitialCatalog")> Public Property Database As String = "mysql" Public Property Port As Integer = 3306 Public Property SSLMode As String = "Preferred" Public Property Credential As PSCredential Public Property Additional As Hashtable Public Property ConnectionString As String #End Region Protected Overrides Sub ProcessRecord() Try If Engine.Logic.ConnectionExists(ConnectionName) Then Engine.Logic.CloseAndRemoveConnection(ConnectionName) End If Dim connDetail As New Engine.ConnectionMySql(ConnectionName, CommandTimeout) If Credential IsNot Nothing Then connDetail.SetAuthCredential(Credential) If Me.ParameterSetName = "conn" Then connDetail.ConnectionString = ConnectionString Else With connDetail .Server = Server .Database = Database .Port = Port .SslMode = SSLMode .Additional = Additional End With End If Engine.Logic.OpenAndAddConnection(connDetail) WriteVerbose($"{ConnectionName} (MySqlConnection) opened.") Catch ex As Exception WriteError(New ErrorRecord(ex, "OpenMySQLConnection.Error", ErrorCategory.OpenError, ConnectionName)) End Try End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/ProviderCmdlets/OpenOracleConnection.vb ================================================ Imports System.DirectoryServices.ActiveDirectory Imports System.Runtime.InteropServices.ComTypes Public Class OpenOracleConnection Inherits PSCmdlet #Region "Cmdlet Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property CommandTimeout As Integer = 30 <[Alias]("Host", "DataSource")> Public Property Server As String = "localhost" Public Property ServiceName As String Public Property Port As Integer = 1521 Public Property TnsName As String Public Property Privilege As String = "None" Public Property Credential As PSCredential Public Property Additional As Hashtable Public Property ConnectionString As String #End Region Protected Overrides Sub ProcessRecord() Try If Engine.Logic.ConnectionExists(ConnectionName) Then Engine.Logic.CloseAndRemoveConnection(ConnectionName) End If Dim connDetail As New Engine.ConnectionOracle(ConnectionName, CommandTimeout) If Credential IsNot Nothing Then connDetail.SetAuthCredential(Credential) Select Case ParameterSetName Case "conn" connDetail.ConnectionString = ConnectionString Case "tns" connDetail.TnsName = TnsName connDetail.Additional = Additional Case Else With connDetail .Host = Server .ServiceName = ServiceName .Port = Port .Privilege = Privilege .Additional = Additional End With End Select Engine.Logic.OpenAndAddConnection(connDetail) WriteVerbose($"{ConnectionName} (OracleConnection) opened.") Catch ex As Exception WriteError(New ErrorRecord(ex, "OpenOracleConnection.Error", ErrorCategory.OpenError, ConnectionName)) End Try End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/ProviderCmdlets/OpenPostGreConnection.vb ================================================  Public Class OpenPostGreConnection Inherits PSCmdlet #Region "Cmdlet Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property CommandTimeout As Integer = 30 <[Alias]("Host")> Public Property Server As String = "localhost" <[Alias]("InitialCatalog")> Public Property Database As String = "postgres" Public Property Port As Integer = 5432 Public Property MaxAutoPrepare As Integer = 25 Public Property SSLMode As String = "Prefer" Public Property Credential As PSCredential Public Property Additional As Hashtable Public Property ConnectionString As String #End Region Protected Overrides Sub ProcessRecord() Try If Engine.Logic.ConnectionExists(ConnectionName) Then Engine.Logic.CloseAndRemoveConnection(ConnectionName) End If Dim connDetail As New Engine.ConnectionPostGre(ConnectionName, CommandTimeout) With {.Additional = Additional} If Credential IsNot Nothing Then connDetail.SetAuthCredential(Credential) If Me.ParameterSetName = "conn" Then connDetail.ConnectionString = ConnectionString Else With connDetail .Host = Server .Database = Database .Port = Port .MaxAutoPrepare = MaxAutoPrepare .SslMode = SSLMode .Additional = Additional End With End If Engine.Logic.OpenAndAddConnection(connDetail) WriteVerbose($"{ConnectionName} (PostGreConnection) opened.") Catch ex As Exception WriteError(New ErrorRecord(ex, "OpenPostGreConnection.Error", ErrorCategory.OpenError, ConnectionName)) End Try End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/ProviderCmdlets/OpenSQLiteConnection.vb ================================================  Public Class OpenSQLiteConnection Inherits PSCmdlet #Region "Cmdlet Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property CommandTimeout As Integer = 30 <[Alias]("FilePath")> Public Property DataSource As String = ":memory:" Public Property Password As String Public Property Additional As Hashtable Public Property ConnectionString As String #End Region Protected Overrides Sub ProcessRecord() Try If Engine.Logic.ConnectionExists(ConnectionName) Then Engine.Logic.CloseAndRemoveConnection(ConnectionName) End If Dim connDetail As New Engine.ConnectionSQLite(ConnectionName, CommandTimeout) If Me.ParameterSetName = "conn" Then connDetail.ConnectionString = ConnectionString Else If Not DataSource.Equals(":memory:", StringComparison.OrdinalIgnoreCase) Then DataSource = Me.GetUnresolvedProviderPathFromPSPath(DataSource) 'handle powershell paths using psdrives End If connDetail.Database = DataSource If Not String.IsNullOrWhiteSpace(Password) Then connDetail.Credential = New Net.NetworkCredential(Nothing, Password) connDetail.Additional = Additional End If Engine.Logic.OpenAndAddConnection(connDetail) WriteVerbose($"{ConnectionName} (SQLiteConnection) opened.") Catch ex As Exception WriteError(New ErrorRecord(ex, "OpenSQLiteConnection.Error", ErrorCategory.OpenError, ConnectionName)) End Try End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/ProviderCmdlets/OpenSqlConnection.vb ================================================  Public Class OpenSqlConnection Inherits PSCmdlet #Region "Cmdlet Parameters" <[Alias]("cn")> Public Property ConnectionName As String = "default" Public Property CommandTimeout As Integer = 30 <[Alias]("SqlInstance", "SqlServer", "DataSource")> Public Property Server As String = "localhost" <[Alias]("SqlDatabase", "InitialCatalog")> Public Property Database As String = "master" Public Property Credential As PSCredential Public Property AzureAD As SwitchParameter Public Property AzureToken As String Public Property Additional As Hashtable Public Property ConnectionString As String #End Region Protected Overrides Sub ProcessRecord() Try If Engine.Logic.ConnectionExists(ConnectionName) Then Engine.Logic.CloseAndRemoveConnection(ConnectionName) End If Dim connDetail As New Engine.ConnectionMSSQL(ConnectionName, CommandTimeout) Select Case Me.ParameterSetName Case "credential" connDetail.SetAuthCredential(Credential, AzureAD.IsPresent) Case "token" connDetail.SetAuthToken(AzureToken) End Select If Me.ParameterSetName = "conn" Then connDetail.ConnectionString = ConnectionString If Credential IsNot Nothing Then connDetail.SetAuthCredential(Credential) Else With connDetail .Server = Server .Database = Database .Additional = Additional End With End If Engine.Logic.OpenAndAddConnection(connDetail) WriteVerbose($"{ConnectionName} (SQLConnection) opened.") Catch ex As Exception WriteError(New ErrorRecord(ex, "OpenSQLConnection.Error", ErrorCategory.OpenError, ConnectionName)) End Try End Sub End Class ================================================ FILE: source/SimplySql.Cmdlets/SimplySql.Cmdlets.vbproj ================================================ SimplySql.Cmdlets netstandard2.0 2.0.0 False latest-minimum Library 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 41999,42016,42017,42018,42019,42020,42021,42022,42032,42036 ================================================ FILE: source/SimplySql.Engine/Dry.vb ================================================ Imports System.Data Imports System.Data.Common Imports System.Runtime.CompilerServices Module Dry Sub AddHashtable(this As DbConnectionStringBuilder, ht As Hashtable) If ht IsNot Nothing Then For Each key In ht.Keys this.Add(key, ht(key)) Next End If End Sub Sub AddQueryDetails(this As Exception, query As String, ht As Hashtable) this.Data.Add("Query", query) Try this.Data.Add("Parameters", ht) Catch ex As Exception this.Data.Add("ParameterExceptionMessage", ex.Message) End Try End Sub Sub AddQueryDetails(this As Exception, query As String, sqlParams As IDataParameterCollection) this.Data.Add("Query", query) Try this.Data.Add("Parameters", sqlParams) Catch ex As Exception this.Data.Add("ParameterExceptionMessage", ex.Message) End Try End Sub End Module ================================================ FILE: source/SimplySql.Engine/ISimplySqlProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data Public Interface ISimplySqlProvider ReadOnly Property ConnectionName As String ReadOnly Property Connection As IDbConnection ReadOnly Property ProviderName As String Property CommandTimeout As Integer Function ConnectionInfo() As OrderedDictionary Sub ChangeDatabase(databaseName As String) #Region "DataAccess" Function GetScalar(query As String, cmdTimeout As Integer, parameters As Hashtable) As Object Function GetCommand(query As String, cmdTimeout As Integer, parameters As Hashtable) As IDbCommand Function GetDataSet(query As String, cmdTimeout As Integer, parameters As Hashtable, useProviderTypes As Boolean) As DataSet Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Int64)) As Int64 Function GetDataReader(query As String, parameters As Hashtable, Optional cmdTimeout As Integer = -1) As IDataReader Function Update(cmd As IDbCommand) As Int64 Function Update(query As String, cmdTimeout As Integer, parameters As Hashtable) As Int64 #End Region #Region "Messages" ReadOnly Property Messages As Queue(Of SqlMessage) ReadOnly Property HasMessages As Boolean Function GetMessage() As SqlMessage Sub ClearMessages() #End Region #Region "Transaction" Property Transaction As IDbTransaction ReadOnly Property HasTransaction As Boolean Sub BeginTransaction() Sub CommitTransaction() Sub RollbackTransaction() #End Region End Interface ================================================ FILE: source/SimplySql.Engine/Logic.vb ================================================ Imports System.Management.Automation Public Module Logic ReadOnly Property Connections As New Dictionary(Of String, ISimplySqlProvider) Function ConnectionExists(connectionName As String, Optional checkIsOpen As Boolean = True) As ValidateConnectionResult If Not Connections.Keys.Any(Function(key) key.Equals(connectionName, StringComparison.OrdinalIgnoreCase)) Then Return ValidateConnectionResult.NotFound Else If Not checkIsOpen Then Return ValidateConnectionResult.Found Else If Not GetConnection(connectionName).Connection.State = Data.ConnectionState.Open Then Return ValidateConnectionResult.NotOpen Else Return ValidateConnectionResult.Open End If End If End If End Function Function GetConnection(connectionName As String) As ISimplySqlProvider Try Return Connections.First(Function(item) item.Key.Equals(connectionName, StringComparison.OrdinalIgnoreCase)).Value Catch ioex As InvalidOperationException Throw New KeyNotFoundException($"No connection named '{connectionName}' exists.") End Try End Function Sub OpenAndAddConnection(connDetail As baseConnectionDetail) Dim provider As ISimplySqlProvider Select Case connDetail.ConnectionType Case ProviderTypes.MSSQL provider = CreateProviderMSSQL(connDetail) Case ProviderTypes.MySql provider = CreateProviderMySQL(connDetail) Case ProviderTypes.Oracle provider = CreateProviderOracle(connDetail) Case ProviderTypes.PostGre provider = CreateProviderPostGre(connDetail) Case ProviderTypes.SQLite provider = CreateProviderSQLite(connDetail) Case Else Throw New ArgumentOutOfRangeException(NameOf(connDetail), connDetail.ConnectionType, $"'{connDetail.ConnectionType}' is not a supported provider.") End Select provider.Connection.Open() Connections.Add(connDetail.ConnectionName, provider) End Sub Sub OpenAndAddConnection(newProvider As ISimplySqlProvider) ' ideally, this should take the type and the base Connection details (abstraction) and handle provider creation and returning it. newProvider.Connection.Open() Connections.Add(newProvider.ConnectionName, newProvider) End Sub Sub CloseAndRemoveConnection(connectionName As String) Try Dim conn = Connections.First(Function(item) item.Key.Equals(connectionName, StringComparison.OrdinalIgnoreCase)).Value If conn.HasTransaction Then conn.RollbackTransaction() Try conn.Connection.Close() Finally conn.Connection.Dispose() Connections.Remove(conn.ConnectionName) End Try Catch ioex As InvalidOperationException Throw New KeyNotFoundException($"No connection named '{connectionName}' exists.") End Try End Sub #Region "Provider Create Functions" Private Function CreateProviderMSSQL(connDetail As baseConnectionDetail) As ISimplySqlProvider Return MSSQLProvider.Create(connDetail) End Function Private Function CreateProviderMySql(connDetail As baseConnectionDetail) As ISimplySqlProvider Return MySqlProvider.Create(connDetail) End Function Private Function CreateProviderOracle(connDetail As baseConnectionDetail) As ISimplySqlProvider Return OracleProvider.Create(connDetail) End Function Private Function CreateProviderPostGre(connDetail As baseConnectionDetail) As ISimplySqlProvider Return PostGreProvider.Create(connDetail) End Function Private Function CreateProviderSQLite(connDetail As baseConnectionDetail) As ISimplySqlProvider Return SQLiteProvider.Create(connDetail) End Function #End Region End Module ================================================ FILE: source/SimplySql.Engine/MSSQL/ConnectionMSSQL.vb ================================================ Imports System.Net Public Class ConnectionMSSQL Inherits baseConnectionDetail Public ReadOnly Property AuthType As AuthMSSQLType = AuthMSSQLType.Credential Public ReadOnly Property Token As String Get If AuthType = AuthMSSQLType.Token Then Return Credential.Password Else Throw New InvalidOperationException($"Cannot return {NameOf(Token)} when {NameOf(AuthType)} is not 'Token'.") End If End Get End Property Public Property Server As String Public Property Database As String Sub New(connName As String, cmdTimeout As Integer) MyBase.New(connName, ProviderTypes.MSSQL, cmdTimeout) SetAuthWindows() End Sub Sub SetAuthWindows() _AuthType = AuthMSSQLType.Windows Me.UseIntegratedSecurity = True End Sub Sub SetAuthToken(tkn As String) _AuthType = AuthMSSQLType.Token If tkn.StartsWith("bearer ") Then tkn = tkn.Substring(7) Credential = New NetworkCredential(Nothing, tkn) Me.UseIntegratedSecurity = False End Sub Sub SetAuthCredential(cred As NetworkCredential, Optional isAzure As Boolean = False) _AuthType = If(isAzure, AuthMSSQLType.AzureCredential, AuthMSSQLType.Credential) Credential = cred Me.UseIntegratedSecurity = False End Sub Public Enum AuthMSSQLType Windows Credential AzureCredential Token End Enum End Class ================================================ FILE: source/SimplySql.Engine/MSSQL/MSSQLProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data Imports System.Data.Common Imports Microsoft.Data.SqlClient Public Class MSSQLProvider Inherits ProviderBase Public Overloads ReadOnly Property Connection As SqlConnection Get Return DirectCast(MyBase.Connection, SqlConnection) End Get End Property Private Sub New(connectionName As String, commandTimeout As Integer, connection As SqlConnection) MyBase.New(connectionName, ProviderTypes.MSSQL, connection, commandTimeout) AddHandler Me.Connection.InfoMessage, AddressOf HandleInfoMessage End Sub Public Overrides Function ConnectionInfo() As OrderedDictionary Dim od = MyBase.ConnectionInfo With od .Add("ServerVersion", Connection.ServerVersion) .Add("Server", Connection.DataSource) .Add("Database", Connection.Database) End With Return od End Function Public Overrides Sub ChangeDatabase(databaseName As String) Connection.ChangeDatabase(databaseName) End Sub Public Overrides Function GetDataset(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As DataSet If Not useProviderTypes Then Return MyBase.GetDataset(query, cmdTimeout, params, False) Else Using cmd As SqlCommand = GetCommand(query, cmdTimeout, params) Using da As New SqlDataAdapter(cmd) Dim ds As New Data.DataSet da.ReturnProviderSpecificTypes = True Try da.Fill(ds) Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Using End If End Function Public Overrides Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long If batchTimeout < 0 Then batchTimeout = CommandTimeout Dim bcpOption = SqlBulkCopyOptions.KeepIdentity + SqlBulkCopyOptions.CheckConstraints + SqlBulkCopyOptions.FireTriggers Using dataReader Using bcp As New SqlBulkCopy(Connection, bcpOption, Transaction) With {.BulkCopyTimeout = batchTimeout, .BatchSize = batchSize, .DestinationTableName = destinationTable, .EnableStreaming = True} GenerateSchemaMap(dataReader, columnMap).ForEach(Sub(x) bcp.ColumnMappings.Add(x.SourceName, x.DestinationName)) If notify IsNot Nothing Then bcp.NotifyAfter = batchSize AddHandler bcp.SqlRowsCopied, Sub(sender As Object, e As SqlRowsCopiedEventArgs) notify.Invoke(e.RowsCopied) End If bcp.WriteToServer(dataReader) If notify IsNot Nothing Then notify.Invoke(bcp.RowsCopied) Return bcp.RowsCopied End Using End Using End Function Private Sub HandleInfoMessage(sender As Object, e As SqlInfoMessageEventArgs) Me.Messages.Enqueue(New SqlMessage(e.Message)) End Sub #Region "Shared Functions" Public Shared Function Create(connDetail As ConnectionMSSQL) As MSSQLProvider Dim connString As String If connDetail.HasConnectionString Then connString = connDetail.ConnectionString Else Dim sb As New SqlConnectionStringBuilder With {.ApplicationName = connDetail.ApplicationName, .DataSource = connDetail.Server, .InitialCatalog = connDetail.Database} Select Case connDetail.AuthType Case ConnectionMSSQL.AuthMSSQLType.Windows sb.Encrypt = SqlConnectionEncryptOption.Optional sb.IntegratedSecurity = True Case ConnectionMSSQL.AuthMSSQLType.Credential sb.Encrypt = SqlConnectionEncryptOption.Optional Case ConnectionMSSQL.AuthMSSQLType.AzureCredential sb.Authentication = SqlAuthenticationMethod.ActiveDirectoryPassword End Select 'Process additional parameters through the hashtable sb.AddHashtable(connDetail.Additional) connString = sb.ToString End If Dim conn As New SqlConnection(connString) Select Case connDetail.AuthType Case ConnectionMSSQL.AuthMSSQLType.Token conn.AccessToken = connDetail.Token Case ConnectionMSSQL.AuthMSSQLType.AzureCredential, ConnectionMSSQL.AuthMSSQLType.Credential Dim p = connDetail.SecurePassword p.MakeReadOnly() conn.Credential = New SqlCredential(connDetail.UserName, p) End Select Return New MSSQLProvider(connDetail.ConnectionName, connDetail.CommandTimeout, conn) End Function #End Region End Class ================================================ FILE: source/SimplySql.Engine/My Project/Application.myapp ================================================ true Form1 false 0 true 0 true ================================================ FILE: source/SimplySql.Engine/MySQL/ConnectionMySql.vb ================================================ Imports System.Net Public Class ConnectionMySql Inherits baseConnectionDetail Public Property Server As String Public Property Database As String Public Property Port As Integer Public Property SslMode As String = "" Sub New(connName As String, cmdTimeout As Integer) MyBase.New(connName, ProviderTypes.MySql, cmdTimeout) Me.UseIntegratedSecurity = False End Sub Sub SetAuthCredential(cred As NetworkCredential) Me.UseIntegratedSecurity = False Me.Credential = cred End Sub End Class ================================================ FILE: source/SimplySql.Engine/MySQL/MySqlProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data Imports MySqlConnector Public Class MySqlProvider Inherits ProviderBase Public Overloads ReadOnly Property Connection As MySqlConnection Get Return DirectCast(MyBase.Connection, MySqlConnection) End Get End Property Private Sub New(connectionName As String, commandTimeout As Integer, connection As MySqlConnection) MyBase.New(connectionName, ProviderTypes.MySql, connection, commandTimeout) AddHandler connection.InfoMessage, AddressOf HandleInfoMessage End Sub Public Overrides Function ConnectionInfo() As OrderedDictionary Dim od = MyBase.ConnectionInfo With od .Add("ServerVersion", Connection.ServerVersion) .Add("Server", Connection.DataSource) .Add("Database", Connection.Database) End With Return od End Function Public Overrides Function GetDataSet(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As Data.DataSet If Not useProviderTypes Then Return MyBase.GetDataset(query, cmdTimeout, params, False) Else Using cmd As MySqlCommand = GetCommand(query, cmdTimeout, params) Using da As New MySqlDataAdapter(cmd) Dim ds As New Data.DataSet da.ReturnProviderSpecificTypes = True Try da.Fill(ds) Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Using End If End Function Public Overrides Sub ChangeDatabase(databaseName As String) Connection.ChangeDatabase(databaseName) End Sub Public Overrides Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long If batchTimeout < 0 Then batchTimeout = CommandTimeout Using dataReader Dim bcp As New MySqlBulkCopy(Connection, Transaction) With {.BulkCopyTimeout = batchTimeout, .DestinationTableName = destinationTable} GenerateSchemaMap(dataReader, columnMap).ForEach(Sub(x) bcp.ColumnMappings.Add(New MySqlBulkCopyColumnMapping(x.Ordinal, x.DestinationName))) If notify IsNot Nothing Then bcp.NotifyAfter = batchSize AddHandler bcp.MySqlRowsCopied, Sub(sender As Object, e As MySqlRowsCopiedEventArgs) notify.Invoke(e.RowsCopied) End If 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 Private Sub HandleInfoMessage(sender As Object, e As MySqlInfoMessageEventArgs) For Each m In e.Errors Messages.Enqueue(New SqlMessage(m.Message)) Next End Sub #Region "Shared Functions" Public Shared Function Create(connDetail As ConnectionMySql) As MySqlProvider Dim sb As MySqlConnectionStringBuilder If connDetail.HasConnectionString Then sb = New MySqlConnectionStringBuilder(connDetail.ConnectionString) Else sb = New MySqlConnectionStringBuilder With { .ApplicationName = connDetail.ApplicationName, .Server = connDetail.Server, .Port = connDetail.Port, .Database = connDetail.Database, .SslMode = MapSslMode(connDetail.SslMode), .AllowLoadLocalInfile = True, .UseAffectedRows = True, .AllowUserVariables = True } 'Process additional parameters through the hashtable sb.AddHashtable(connDetail.Additional) End If If connDetail.Credential IsNot Nothing Then sb.UserID = connDetail.UserName sb.Password = connDetail.Password End If Return New MySqlProvider(connDetail.ConnectionName, connDetail.CommandTimeout, New MySqlConnection(sb.ToString)) End Function Private Shared Function MapSslMode(ssl As String) As MySqlSslMode Return [Enum].Parse(GetType(MySqlSslMode), ssl) End Function #End Region End Class ================================================ FILE: source/SimplySql.Engine/Oracle/ConnectionOracle.vb ================================================ Imports System.Net Public Class ConnectionOracle Inherits baseConnectionDetail Public ReadOnly Property HasTnsName As Boolean Get Return Not String.IsNullOrWhiteSpace(TNSName) End Get End Property Public Property TnsName As String Public Property Host As String Public Property ServiceName As String Public Property Port As Integer Public Property Privilege As String = "None" Sub New(connName As String, cmdTimeout As Integer) MyBase.New(connName, ProviderTypes.Oracle, cmdTimeout) End Sub Sub SetAuthCredential(cred As NetworkCredential) Me.UseIntegratedSecurity = False Me.Credential = cred End Sub End Class ================================================ FILE: source/SimplySql.Engine/Oracle/OracleProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data Imports Oracle.ManagedDataAccess.Client Public Class OracleProvider Inherits ProviderBase Private Privilege As String Public Overloads ReadOnly Property Connection As OracleConnection Get Return DirectCast(MyBase.Connection, OracleConnection) End Get End Property Private Sub New(connName As String, timeout As Integer, conn As OracleConnection, priv As String) MyBase.New(connName, ProviderTypes.Oracle, conn, timeout) Privilege = priv AddHandler Me.Connection.InfoMessage, AddressOf HandleInfoMessage End Sub Public Overrides Function ConnectionInfo() As OrderedDictionary Dim od = MyBase.ConnectionInfo With od .Add("ServerVersion", Connection.ServerVersion) .Add("HostName", Connection.HostName) .Add("ServiceName", Connection.ServiceName) .Add("Privilege", Privilege) End With Return od End Function Public Overrides Sub ChangeDatabase(databaseName As String) Connection.ChangeDatabase(databaseName) End Sub Public Overrides Function GetDataset(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As DataSet If Not useProviderTypes Then Return MyBase.GetDataset(query, cmdTimeout, params, False) Else Using cmd As OracleCommand = GetCommand(query, cmdTimeout, params) Using da As New OracleDataAdapter(cmd) Dim ds As New Data.DataSet da.ReturnProviderSpecificTypes = True Try da.Fill(ds) Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Using End If End Function Public Overrides Function HandleParamValue(x As Object) As Object If x.GetType().IsEnum Then x = DirectCast(x, Integer) Return MyBase.HandleParamValue(x) End Function Public Overrides Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long If batchTimeout < 0 Then batchTimeout = CommandTimeout If Me.HasTransaction Then Return OracleArrayParam(dataReader, destinationTable, columnMap, batchSize, batchTimeout, notify) Else Return OracleBulkCopy(dataReader, destinationTable, columnMap, batchSize, batchTimeout, notify) End If End Function Private Function OracleBulkCopy(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long Using dataReader Using bcp As New OracleBulkCopy(Me.Connection) With {.BatchSize = batchSize, .BulkCopyTimeout = batchTimeout, .DestinationTableName = destinationTable} GenerateSchemaMap(dataReader, columnMap).ForEach(Sub(x) bcp.ColumnMappings.Add(x.SourceName, x.DestinationName)) bcp.NotifyAfter = 1 Dim rowsCopied As Long = 0 AddHandler bcp.OracleRowsCopied, Sub(sender As Object, e As OracleRowsCopiedEventArgs) rowsCopied += 1 If rowsCopied Mod batchSize = 0 AndAlso notify IsNot Nothing Then notify.Invoke(rowsCopied) End If End Sub bcp.WriteToServer(dataReader) Return rowsCopied End Using End Using End Function Private Function OracleArrayParam(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long Dim batchIteration As Long = 0 Dim schemaMap = GenerateSchemaMap(dataReader, columnMap) Dim destColNames = """" + String.Join(""", """, schemaMap.Select(Function(x) x.DestinationName)) + """" Dim paramNames = ":Param" + String.Join(", :Param", schemaMap.Select(Function(x) x.Ordinal.ToString)) Using dataReader Using bulkcmd As OracleCommand = GetCommand($"INSERT INTO {destinationTable} ({destColNames}) VALUES ({paramNames})") 'adding parameters For Each sm In schemaMap Dim p As New OracleParameter($"Param{sm.Ordinal}", MapOracleType(sm.DataType)) With {.Value = Array.CreateInstance(Type.GetType(sm.DataType), batchSize)} bulkcmd.Parameters.Add(p) Next bulkcmd.ArrayBindCount = batchSize Dim index As Integer = 0 While dataReader.Read batchIteration += 1 For Each sm In schemaMap index = (batchIteration - 1) Mod batchSize DirectCast(bulkcmd.Parameters(sm.Ordinal).Value, Array).SetValue(dataReader.GetValue(sm.Ordinal), index) Next If batchIteration Mod batchSize = 0 Then bulkcmd.ExecuteNonQuery() If notify IsNot Nothing Then notify.Invoke(batchIteration) 'schemaMap.ForEach(Sub(sm) bulkcmd.Parameters(sm.Ordinal).Value = Array.CreateInstance(Type.GetType(sm.DataType), batchSize)) schemaMap.ForEach(Sub(sm) DirectCast(bulkcmd.Parameters(sm.Ordinal).Value, Array).Initialize()) End If End While Dim remaining = batchIteration Mod batchSize If remaining > 0 Then bulkcmd.ArrayBindCount = remaining bulkcmd.ExecuteNonQuery() If notify IsNot Nothing Then notify.Invoke(batchIteration) End If Return batchIteration End Using End Using End Function Private Sub HandleInfoMessage(sender As Object, e As OracleInfoMessageEventArgs) Me.Messages.Enqueue(New SqlMessage(e.Message)) End Sub #Region "Shared" 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" Return OracleDbType.Boolean Case "system.byte" Return OracleDbType.Byte Case "system.byte[]" Return OracleDbType.Raw Case "system.datetime" Return OracleDbType.TimeStamp Case "system.datetimeoffset" Return OracleDbType.TimeStampTZ Case "system.decimal" Return OracleDbType.Decimal Case "system.double" Return OracleDbType.Double Case "system.float", "system.single" Return OracleDbType.Single Case "system.guid" Return OracleDbType.Blob Case "system.int16" Return OracleDbType.Int16 Case "system.int32" Return OracleDbType.Int32 Case "system.int64" Return OracleDbType.Int64 Case "system.timespan" Return OracleDbType.IntervalDS Case Else Return OracleDbType.Varchar2 End Select End Function Shared Sub New() OracleConfiguration.BindByName = True 'otherwise oracle commands will bind parameters by position End Sub Public Shared Function Create(connDetail As ConnectionOracle) As OracleProvider Dim sb As OracleConnectionStringBuilder Dim conn As OracleConnection If connDetail.HasConnectionString Then sb = New OracleConnectionStringBuilder(connDetail.ConnectionString) Else sb = New OracleConnectionStringBuilder() If connDetail.HasTnsName Then sb.DataSource = connDetail.TnsName Else sb.DataSource = $"(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={connDetail.Host})(PORT={connDetail.Port}))(CONNECT_DATA=(SERVICE_NAME={connDetail.ServiceName})))" End If 'Process additional parameters through the hashtable sb.AddHashtable(connDetail.Additional) End If If connDetail.Credential IsNot Nothing Then Dim sp = connDetail.SecurePassword sp.MakeReadOnly() conn = New OracleConnection(sb.ConnectionString, New OracleCredential(connDetail.UserName, sp, ConvertToOracleDBAPrivilege(connDetail.Privilege))) Else If (sb.UserID = "/" Or String.IsNullOrWhiteSpace(sb.UserID)) Then sb.UserID = "/" If Not connDetail.Privilege.Equals("None", StringComparison.OrdinalIgnoreCase) Then sb.DBAPrivilege = connDetail.Privilege End If conn = New OracleConnection(sb.ConnectionString) End If Return New OracleProvider(connDetail.ConnectionName, connDetail.CommandTimeout, conn, connDetail.Privilege) End Function Private Shared Function ConvertToOracleDBAPrivilege(priv As String) As OracleDBAPrivilege Return [Enum].Parse(GetType(OracleDBAPrivilege), priv) End Function #End Region End Class ================================================ FILE: source/SimplySql.Engine/PostGre/ConnectionPostGre.vb ================================================ Imports System.Net Public Class ConnectionPostGre Inherits baseConnectionDetail Public Property Host As String Public Property Port As Integer Public Property Database As String Public Property SslMode As String = "" Public Property MaxAutoPrepare As Integer Sub New(connName As String, cmdTimeout As Integer) MyBase.New(connName, ProviderTypes.PostGre, cmdTimeout) SetAuthIntegrated() End Sub Sub SetAuthCredential(cred As NetworkCredential) Me.UseIntegratedSecurity = False Me.Credential = cred End Sub Sub SetAuthIntegrated() Me.UseIntegratedSecurity = True End Sub End Class ================================================ FILE: source/SimplySql.Engine/PostGre/PostGreProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data Imports System.Data.Common Imports System.Runtime.CompilerServices Imports System.Security.Cryptography Imports NetTopologySuite.Geometries Imports Npgsql Public Class PostGreProvider Inherits ProviderBase Public Overloads ReadOnly Property Connection As NpgsqlConnection Get Return DirectCast(MyBase.Connection, NpgsqlConnection) End Get End Property Private Sub New(connectionName As String, commandTimeout As Integer, connection As NpgsqlConnection) MyBase.New(connectionName, ProviderTypes.PostGre, connection, commandTimeout) AddHandler Me.Connection.Notice, AddressOf HandleNoticeMessage End Sub Public Overrides Function ConnectionInfo() As OrderedDictionary Dim od = MyBase.ConnectionInfo With od .Add("ServerVersion", Connection.ServerVersion) .Add("Host", Connection.Host) .Add("Port", Connection.Port) .Add("Database", Connection.Database) .Add("User", Connection.UserName) End With Return od End Function Public Overrides Sub ChangeDatabase(databaseName As String) Connection.ChangeDatabase(databaseName) End Sub Public Overrides Function GetDataset(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As DataSet If Not useProviderTypes Then Return MyBase.GetDataset(query, cmdTimeout, params, False) Else Using cmd As NpgsqlCommand = GetCommand(query, cmdTimeout, params) Using da As New NpgsqlDataAdapter(cmd) Dim ds As New Data.DataSet da.ReturnProviderSpecificTypes = True Try da.Fill(ds) Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Using End If End Function Public Overrides Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Long)) As Long Dim iteration As Long = 0 Using dataReader Dim schemaMap = GenerateSchemaMap(dataReader, columnMap) Dim copyFromSql As String = $"COPY {destinationTable} ({String.Join(", ", schemaMap.Select(Function(x) x.DestinationName))}) FROM STDIN (FORMAT BINARY)" Using bulk = Connection.BeginBinaryImport(copyFromSql) While dataReader.Read() iteration += 1 bulk.StartRow() For Each field In schemaMap If dataReader.IsDBNull(field.Ordinal) Then bulk.WriteNull() Else bulk.Write(dataReader.GetValue(field.Ordinal)) End If Next 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 End Function Public Overrides Function HandleParamValue(x As Object) As Object If x.GetType().IsEnum Then x = DirectCast(x, Integer) Return MyBase.HandleParamValue(x) End Function Private Sub HandleNoticeMessage(sender As Object, e As NpgsqlNoticeEventArgs) Me.Messages.Enqueue(New SqlMessage(e.Notice.MessageText)) End Sub #Region "Shared Functions" Public Shared Function Create(connDetail As ConnectionPostGre) As PostGreProvider Dim sb As NpgsqlConnectionStringBuilder If connDetail.HasConnectionString Then sb = New NpgsqlConnectionStringBuilder(connDetail.ConnectionString) Else sb = New NpgsqlConnectionStringBuilder() With { .ApplicationName = connDetail.ApplicationName, .Host = connDetail.Host, .Port = connDetail.Port, .Database = connDetail.Database, .MaxAutoPrepare = connDetail.MaxAutoPrepare, .SslMode = MapSslMode(connDetail.SslMode) } 'Process additional parameters through the hashtable sb.AddHashtable(connDetail.Additional) End If If connDetail.Credential IsNot Nothing Then sb.Username = connDetail.UserName sb.Password = connDetail.Password End If Dim dsBuilder As New NpgsqlDataSourceBuilder(sb.ToString) dsBuilder.UseNetTopologySuite() Return New PostGreProvider(connDetail.ConnectionName, connDetail.CommandTimeout, dsBuilder.Build.CreateConnection()) End Function Private Shared Function MapSslMode(ssl As String) As SslMode Return [Enum].Parse(GetType(SslMode), ssl) End Function #End Region End Class ================================================ FILE: source/SimplySql.Engine/ProviderBase.vb ================================================ Imports System.Collections.Specialized Imports System.Data Imports System.Data.Common Imports System.Threading Public MustInherit Class ProviderBase Implements ISimplySqlProvider Public ReadOnly Property ConnectionName As String Implements ISimplySqlProvider.ConnectionName Private _providerType As Engine.ProviderTypes Public ReadOnly Property ProviderType As String Implements ISimplySqlProvider.ProviderName Get Return _providerType.ToString() End Get End Property Public ReadOnly Property Connection As IDbConnection Implements ISimplySqlProvider.Connection Public Property CommandTimeout As Integer = 30 Implements ISimplySqlProvider.CommandTimeout Public Sub New(connName As String, providerType As Engine.ProviderTypes, conn As IDbConnection, timeout As Integer) ConnectionName = connName _providerType = providerType Connection = conn CommandTimeout = timeout 'conn.Open() End Sub #Region "Overrides" Public Overridable Function ConnectionInfo() As OrderedDictionary Implements ISimplySqlProvider.ConnectionInfo Dim od As New OrderedDictionary With od .Add("ConnectionName", ConnectionName) .Add("ProviderType", ProviderType) .Add("ConnectionState", Connection.State) .Add("ConnectionString", Connection.ConnectionString) .Add("CommandTimeout", CommandTimeout) .Add("HasTransaction", HasTransaction) End With Return od End Function Public MustOverride Sub ChangeDatabase(databaseName As String) Implements ISimplySqlProvider.ChangeDatabase Public Overridable Function HandleParamValue(x As Object) As Object If TypeOf x Is System.Management.Automation.PSObject Then x = DirectCast(x, System.Management.Automation.PSObject).BaseObject Return If(x, DBNull.Value) End Function #End Region #Region "Concrete" Public Sub AttachCommand(cmd As IDbCommand) cmd.Connection = Me.Connection If Me.HasTransaction Then cmd.Transaction = Me.Transaction End Sub #Region "GetCommand" Public Overridable Function GetCommand(query As String, timeout As Integer, params As Hashtable) As IDbCommand Implements ISimplySqlProvider.GetCommand Dim cmd As IDbCommand = Me.Connection.CreateCommand() cmd.CommandText = query cmd.CommandTimeout = If(timeout < 0, Me.CommandTimeout, timeout) If Me.HasTransaction Then cmd.Transaction = Me.Transaction If params IsNot Nothing Then For Each de As DictionaryEntry In params Dim param As IDbDataParameter = cmd.CreateParameter() param.ParameterName = de.Key param.Value = HandleParamValue(de.Value) cmd.Parameters.Add(param) Next End If Return cmd End Function Public Function GetCommand(query As String, Optional params As Hashtable = Nothing) As IDbCommand Return Me.GetCommand(query, Me.CommandTimeout, params) End Function #End Region #Region "GetScalar" Public Overridable Function GetScalar(query As String, timeout As Integer, params As Hashtable) As Object Implements ISimplySqlProvider.GetScalar Using cmd As IDbCommand = GetCommand(query, timeout, params) Try Return cmd.ExecuteScalar() Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Function Public Function GetScalar(query As String, timeout As Integer) As Object Return Me.GetScalar(query, timeout, Nothing) End Function #End Region #Region "GetDataSet" Public Overridable Function GetDataset(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As DataSet Implements ISimplySqlProvider.GetDataSet If useProviderTypes Then Throw New NotSupportedException($"{ProviderType} does not support -UseTypesFromProvider.") Using cmd As IDbCommand = GetCommand(query, cmdTimeout, params) Try Dim ds As New DataSet Using dr As IDataReader = cmd.ExecuteReader Do Dim dt As New DataTable 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 Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Function #End Region #Region "GetReader" Public Overridable Function GetReader(query As String, params As Hashtable, Optional timeout As Integer = -1) As IDataReader Implements ISimplySqlProvider.GetDataReader Using cmd As IDbCommand = Me.GetCommand(query, timeout, params) Try Return cmd.ExecuteReader() Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Function #End Region #Region "Update" Public Overridable Function Update(cmd As IDbCommand) As Int64 Implements ISimplySqlProvider.Update If cmd.Transaction Is Nothing AndAlso HasTransaction Then cmd.Transaction = Transaction Try Return cmd.ExecuteNonQuery() Catch ex As Exception ex.AddQueryDetails(cmd.CommandText, cmd.Parameters) Throw End Try End Function Public Overridable Function Update(query As String, timeout As Integer, params As Hashtable) As Int64 Implements ISimplySqlProvider.Update Using cmd As IDbCommand = Me.GetCommand(query, timeout, params) Return Update(cmd) End Using End Function #End Region #Region "BulkLoad" Public Overridable Function BulkLoad(dataReader As IDataReader, destinationTable As String, columnMap As Dictionary(Of String, String), batchSize As Integer, batchTimeout As Integer, notify As Action(Of Int64)) As Int64 Implements ISimplySqlProvider.BulkLoad If batchTimeout < 0 Then batchTimeout = CommandTimeout Dim batchIteration As Int64 = 0 Dim ord As Integer = 0 Dim hasPrepared As Boolean = False Dim schemaMap = GenerateSchemaMap(dataReader, columnMap) Dim insertSql As String = String.Format("INSERT INTO {0} ([{1}]) VALUES (@Param{2})", destinationTable, String.Join("], [", schemaMap.Select(Function(x) x.DestinationName)), String.Join(", @Param", schemaMap.Select(Function(x) x.Ordinal)) ) Dim sw = Stopwatch.StartNew() Using bulkCmd = Me.GetCommand(insertSql) Using dataReader bulkCmd.Transaction = Me.Connection.BeginTransaction Try While dataReader.Read() If Not hasPrepared Then schemaMap.ForEach(Sub(x) Dim param = bulkCmd.CreateParameter() param.ParameterName = String.Format("Param{0}", x.Ordinal) param.Value = dataReader.GetValue(x.Ordinal) bulkCmd.Parameters.Add(param) End Sub) bulkCmd.Prepare() hasPrepared = True Else schemaMap.ForEach(Sub(x) DirectCast(bulkCmd.Parameters(x.Ordinal), IDataParameter).Value = dataReader.GetValue(x.Ordinal)) End If batchIteration += 1 bulkCmd.ExecuteNonQuery() If sw.Elapsed.TotalSeconds > batchTimeout Then Dim ex As New TimeoutException(String.Format("Batch took longer than {0} seconds to complete.", batchTimeout)) ex.AddQueryDetails(insertSql, bulkCmd.Parameters) Throw ex End If If batchIteration Mod batchSize = 0 Then bulkCmd.Transaction.Commit() bulkCmd.Transaction.Dispose() If notify IsNot Nothing Then notify.Invoke(batchIteration) bulkCmd.Transaction = Me.Connection.BeginTransaction() sw.Restart() End If End While bulkCmd.Transaction.Commit() Catch ex As Exception ex.AddQueryDetails(insertSql, bulkCmd.Parameters) Throw Finally If bulkCmd.Transaction IsNot Nothing Then bulkCmd.Transaction.Dispose() End Try End Using End Using If notify IsNot Nothing Then notify.Invoke(batchIteration) Return batchIteration End Function Friend Shared Function GenerateSchemaMap(dr As IDataReader, columnMap As Dictionary(Of String, String)) As List(Of SchemaMapItem) Dim schemaMap As New List(Of SchemaMapItem) Dim ord As Integer = 0 For Each row In dr.GetSchemaTable().Select().OrderBy(Function(x) x("ColumnOrdinal")) Dim smi = New SchemaMapItem With {.Ordinal = ord} smi.SourceName = row("ColumnName") smi.DestinationName = row("ColumnName") smi.DataType = row("DataType").ToString schemaMap.Add(smi) ord += 1 Next If columnMap Is Nothing OrElse columnMap.Count = 0 Then Return schemaMap Else Return schemaMap.Where(Function(x) columnMap.ContainsKey(x.SourceName)).Select(Function(x) New SchemaMapItem With {.Ordinal = x.Ordinal, .SourceName = x.SourceName, .DestinationName = columnMap.Item(x.SourceName)}).ToList End If End Function #End Region #Region "Messages" Public ReadOnly Property Messages As New Queue(Of SqlMessage) Implements ISimplySqlProvider.Messages Public Overridable Function GetMessage() As SqlMessage Implements ISimplySqlProvider.GetMessage Return Me.Messages.Dequeue() End Function Public Overridable Sub ClearMessages() Implements ISimplySqlProvider.ClearMessages Me.Messages.Clear() End Sub Public Overridable ReadOnly Property HasMessages() As Boolean Implements ISimplySqlProvider.HasMessages Get Return Me.Messages.Count > 0 End Get End Property #End Region #Region "Transactions" Public Property Transaction As IDbTransaction Implements ISimplySqlProvider.Transaction Public ReadOnly Property HasTransaction As Boolean Implements ISimplySqlProvider.HasTransaction Get Return Me.Transaction IsNot Nothing End Get End Property Sub BeginTransaction() Implements ISimplySqlProvider.BeginTransaction If Me.HasTransaction Then Throw New InvalidOperationException("Cannot BEGIN a transaction when one is already in progress.") Me.Transaction = Me.Connection.BeginTransaction() End Sub Sub RollbackTransaction() Implements ISimplySqlProvider.RollbackTransaction If Me.HasTransaction Then Try Me.Transaction.Rollback() Finally Me.Transaction.Dispose() Me.Transaction = Nothing End Try Else Throw New InvalidOperationException("Cannot ROLLBACK when there is no transaction in progress.") End If End Sub Sub CommitTransaction() Implements ISimplySqlProvider.CommitTransaction If Me.HasTransaction Then Try Me.Transaction.Commit() Finally Me.Transaction.Dispose() Me.Transaction = Nothing End Try Else Throw New InvalidOperationException("Cannot COMMIT when there is no transaction in progress.") End If End Sub #End Region #End Region Friend Structure SchemaMapItem Public Ordinal As Integer Public SourceName As String Public DestinationName As String Public DataType As String End Structure End Class Public Enum ProviderTypes PostGre Oracle MySql MSSQL SQLite End Enum ================================================ FILE: source/SimplySql.Engine/SQLite/ConnectionSQLite.vb ================================================ Public Class ConnectionSQLite Inherits baseConnectionDetail Public Property Database As String Sub New(connName As String, cmdTimeout As Integer) MyBase.New(connName, ProviderTypes.SQLite, cmdTimeout) Me.UseIntegratedSecurity = False End Sub End Class ================================================ FILE: source/SimplySql.Engine/SQLite/SQLiteProvider.vb ================================================ Imports System.Collections.Specialized Imports System.Data.SQLite Public Class SQLiteProvider Inherits ProviderBase Public Overloads ReadOnly Property Connection As SQLiteConnection Get Return DirectCast(MyBase.Connection, SQLiteConnection) End Get End Property Private Sub New(connectionName As String, commandTimeout As Integer, connection As SQLiteConnection) MyBase.New(connectionName, ProviderTypes.SQLite, connection, commandTimeout) End Sub Public Overrides Function ConnectionInfo() As OrderedDictionary Dim od = MyBase.ConnectionInfo od.Add("ServerVersion", Connection.ServerVersion) od.Add("DataSource", Connection.DataSource) Return od End Function Public Overrides Function GetDataSet(query As String, cmdTimeout As Integer, params As Hashtable, useProviderTypes As Boolean) As Data.DataSet If Not useProviderTypes Then Return MyBase.GetDataset(query, cmdTimeout, params, False) Else Using cmd As SQLiteCommand = GetCommand(query, cmdTimeout, params) Using da As New SQLiteDataAdapter(cmd) Dim ds As New Data.DataSet da.ReturnProviderSpecificTypes = True Try da.Fill(ds) Return ds Catch ex As Exception ex.AddQueryDetails(query, params) Throw End Try End Using End Using End If End Function #Region "Not Supported" Public Overrides Sub ChangeDatabase(databaseName As String) Throw New NotSupportedException($"{NameOf(SQLiteProvider)} does not support databases, cannot change to {databaseName}.") End Sub Public Overrides Function GetMessage() As SqlMessage Throw New NotSupportedException($"{NameOf(SQLiteProvider)} does not support SqlMessages.") End Function Public Overrides Sub ClearMessages() Throw New NotSupportedException($"{NameOf(SQLiteProvider)} does not support SqlMessages.") End Sub Public Overrides ReadOnly Property HasMessages As Boolean Get Throw New NotSupportedException($"{NameOf(SQLiteProvider)} does not support SqlMessages.") End Get End Property #End Region #Region "Shared Functions" Public Shared Function Create(connDetail As ConnectionSQLite) As SQLiteProvider Dim connString As String If connDetail.HasConnectionString Then connString = connDetail.ConnectionString Else Dim sb As New SQLiteConnectionStringBuilder If Not connDetail.Database.Equals(":memory:", StringComparison.OrdinalIgnoreCase) Then Dim filepath = New IO.FileInfo(connDetail.Database) If Not filepath.Directory.Exists Then filepath.Directory.Create() End If sb.DataSource = connDetail.Database If Not String.IsNullOrWhiteSpace(connDetail.Password) Then sb.Password = connDetail.Password 'Process additional parameters through the hashtable sb.AddHashtable(connDetail.Additional) connString = sb.ToString End If Return New SQLiteProvider(connDetail.ConnectionName, connDetail.CommandTimeout, New SQLiteConnection(connString)) End Function #End Region End Class ================================================ FILE: source/SimplySql.Engine/SimplySql.Engine.vbproj ================================================  SimplySql.Engine netstandard2.0;net47;net6.0 2.0.0 False True latest-minimum 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 False True ================================================ FILE: source/SimplySql.Engine/SqlMessage.vb ================================================ Public Class SqlMessage Public ReadOnly Property Received As DateTime Public ReadOnly Property Message As String Public Sub New(_message As String, Optional _received As DateTime? = Nothing) If _received Is Nothing Then _received = DateTime.Now Received = _received Message = _message End Sub End Class ================================================ FILE: source/SimplySql.Engine/ValidateConnectionResult.vb ================================================ Public Enum ValidateConnectionResult NotFound Found NotOpen Open End Enum ================================================ FILE: source/SimplySql.Engine/baseConnectionDetail.vb ================================================ Imports System.Net Imports System.Security Imports System.Security.Cryptography Public Class baseConnectionDetail Public ReadOnly Property ConnectionName As String Public ReadOnly Property ConnectionType As ProviderTypes Public ReadOnly Property UserName As String Get Return Credential?.UserName End Get End Property Public ReadOnly Property Password As String Get Return Credential?.Password End Get End Property Public ReadOnly Property SecurePassword As SecureString Get Return Credential?.SecurePassword End Get End Property Public ReadOnly Property HasConnectionString As Boolean Get Return Not String.IsNullOrWhiteSpace(ConnectionString) End Get End Property Public Property Credential As NetworkCredential Public Property UseIntegratedSecurity As Boolean Public Property ConnectionString As String Public ReadOnly Property CommandTimeout As Integer Public Property Additional As Hashtable Sub New(connName As String, conntype As ProviderTypes, cmdTimeout As Integer) Me.ConnectionName = connName Me.ConnectionType = conntype Me.CommandTimeout = cmdTimeout End Sub Public Function ApplicationName() As String Return $"PowerShell (SimplySql: {ConnectionName})" End Function End Class ================================================ FILE: source/source.build.ps1 ================================================ 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 = @( [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"} [PSCustomObject]@{framework="net6.0"; env="osx-arm64"; output="output\bin\PS7\osx-arm64"} ) if($DebugOnly){ $Script:envList = $Script:envList | Where-Object env -eq "win-x64" if($PSEdition -eq "core") { if($DebugOnly) { $Script:envList = $Script:envList | Where-Object framework -eq "net6.0" } else { $Script:envList = $Script:envList | Where-Object framework -eq "net47" } } } 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 = @{} $first = $list[0] Write-Host " --$($first | Split-Path -Leaf)" -NoNewline Get-ChildItem -Path $first -File | 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 "!" #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 } Write-Host "!" } #cleanup foreach($file in $safeFiles.Keys) { 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 } } } $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\*" -Recurse #-Exclude "SimplySql.*" -Recurse if($DebugOnly) { #create folders... New-Item -ItemType Directory -Name ".\output\bin\PS5\" | Out-Null New-Item -ItemType Directory -Name ".\output\bin\PS7\" | Out-Null } 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... if(-not $DebugOnly -or $PSEdition -eq "desktop") { exec { dotnet build "SimplySql.Engine" -c $configuration } | HV "SQLite Interop (PS5)" "." 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 $DebugOnly) { dedup ".\output\bin\PS5" dedup ".\output\bin\PS7" dedup ".\output\bin" } } task . Clean, Build, DeDup ================================================ FILE: source/source.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.2.32616.157 MinimumVisualStudioVersion = 10.0.40219.1 Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "SimplySql.Cmdlets", "SimplySql.Cmdlets\SimplySql.Cmdlets.vbproj", "{3B996E33-6A34-4C80-8200-355F3B039EC3}" EndProject Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "SimplySql.Engine", "SimplySql.Engine\SimplySql.Engine.vbproj", "{98B5F33B-7FC0-4F47-9218-728FF177E5E6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6FF4B42A-008C-45FE-8117-9860F7CE54E8}" ProjectSection(SolutionItems) = preProject ConstructModule.ps1 = ConstructModule.ps1 thoughts.txt = thoughts.txt wsl.ps1 = wsl.ps1 EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {3B996E33-6A34-4C80-8200-355F3B039EC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3B996E33-6A34-4C80-8200-355F3B039EC3}.Debug|Any CPU.Build.0 = Debug|Any CPU {3B996E33-6A34-4C80-8200-355F3B039EC3}.Release|Any CPU.ActiveCfg = Release|Any CPU {3B996E33-6A34-4C80-8200-355F3B039EC3}.Release|Any CPU.Build.0 = Release|Any CPU {98B5F33B-7FC0-4F47-9218-728FF177E5E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {98B5F33B-7FC0-4F47-9218-728FF177E5E6}.Debug|Any CPU.Build.0 = Debug|Any CPU {98B5F33B-7FC0-4F47-9218-728FF177E5E6}.Release|Any CPU.ActiveCfg = Release|Any CPU {98B5F33B-7FC0-4F47-9218-728FF177E5E6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {540D6EC3-FEA3-4998-B1B2-7619D33571A2} EndGlobalSection EndGlobal ================================================ FILE: source/thoughts.txt ================================================ automapper v10 (supports .net standard 2) -- use this for datareader to psobject? EnumerableToDataReader -- for getting input objects to datareader to be used by bulkCopy Tasks -Add argumentcompleter to all ConnectionName parameters Handling dataReader to PSObject: https://expressiontree-tutorial.net/knowledge-base/19841120/generic-dbdatareader-to-list-t--mapping - https://tyrrrz.me/blog/expression-trees - https://www.programmerall.com/article/6642195713/ - https://expressiontree-tutorial.net/knowledge-base/19841120/generic-dbdatareader-to-list-t--mapping ================================================ FILE: source/wsl.ps1 ================================================ Invoke-Build -SkipDedup wsl pwsh