Modules/Database/Dispatcher.vb
2022-10-17 10:38:37 +02:00

229 lines
9.6 KiB
VB.net

Imports DigitalData.Modules.Logging
Imports Oracle.ManagedDataAccess.Client
Public Class Dispatcher
Public ReadOnly Property Connections As New List(Of DispatcherConnection)
Public ReadOnly Logger As Logger
Public ReadOnly LogConfig As LogConfig
''' <summary>
''' Create a new instance of Dispatcher. This is the preferred way to create the dispatcher.
''' </summary>
''' <param name="pLogConfig">An instance of LogConfig</param>
''' <param name="pConnectionString">Initial connectionstring for connecting to DD_ECM database.</param>
''' <returns>An instance of Dispatcher with connections</returns>
Public Shared Function Create(pLogConfig As LogConfig, pConnectionString As String) As Dispatcher
Dim oDecryptedConnectionString As String = MSSQLServer.DecryptConnectionString(pConnectionString)
Dim oDatabase As MSSQLServer = New MSSQLServer(pLogConfig, oDecryptedConnectionString)
Dim oTable As DataTable = oDatabase.GetDatatable(Queries.DD_ECM.Connections.AllConnections)
Dim oConnections As New List(Of DispatcherConnection)
For Each oRow As DataRow In oTable.Rows
Dim oConnection As DispatcherConnection = CreateFromDataRow(oRow)
If oConnection IsNot Nothing Then
oConnections.Add(oConnection)
End If
Next
Return New Dispatcher(pLogConfig, oConnections)
End Function
''' <summary>
''' Create a new instance of Dispatcher. Needs a manually constructed list of connection objects.
''' </summary>
''' <param name="pLogConfig">An instance of LogConfig</param>
''' <param name="pConnections">A list of DispatcherConnection objects</param>
''' <seealso cref="Create"/>
Public Sub New(pLogConfig As LogConfig, pConnections As List(Of DispatcherConnection))
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger()
Connections = pConnections
End Sub
Public Enum ConnectionType
MSSQL
Oracle
ODBC
Firebird
End Enum
Public Class DispatcherOptions
Public Property QueryTimeout As Integer = Constants.DEFAULT_TIMEOUT
End Class
Public Class DispatcherConnection
Public Property Id As Integer
Public Property Name As String
Public Property ConnectionString As String
Public Property ConnectionType As ConnectionType
End Class
''' <summary>
''' Returns a Datatable from the database with the specified connection id
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <param name="pConnectionId">The connection id</param>
''' <returns>A datatable with the results or nothing if an error occurred</returns>
Public Function GetDatatable(pSQLCommand As String, pConnectionId As Integer) As DataTable
Dim oAdapter As IDatabase = GetAdapterClass(pConnectionId)
Return oAdapter.GetDatatable(pSQLCommand)
End Function
''' <summary>
''' Returns a Datatable from the database
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <returns>A datatable with the results or nothing if an error occurred</returns>
Public Function GetDatatable(pSQLCommand As String) As DataTable
Return GetDatatable(pSQLCommand, Constants.DEFAULT_CONNECTION_ID)
End Function
''' <summary>
''' Executes a query without return value like INSERT or UPDATE from the database with the specified connection id and
''' returns a boolean value indicating success or failure of the query
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <param name="pConnectionId">The connection id</param>
''' <returns>True if the query was successful, otherwise false</returns>
Public Function ExecuteNonQuery(pSQLCommand As String, pConnectionId As Integer) As Boolean
Dim oAdapter As IDatabase = GetAdapterClass(pConnectionId)
Return oAdapter.ExecuteNonQuery(pSQLCommand)
End Function
''' <summary>
''' Executes a query without return value like INSERT or UPDATE from the database and
''' returns a boolean value indicating success or failure of the query
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <returns>True if the query was successful, otherwise false</returns>
Public Function ExecuteNonQuery(pSQLCommand As String) As Boolean
Return ExecuteNonQuery(pSQLCommand, Constants.DEFAULT_CONNECTION_ID)
End Function
''' <summary>
''' Returns a single value from the database specified by the connection id
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <param name="pConnectionId">The connection id</param>
''' <returns>A value of type object</returns>
Public Function GetScalarValue(pSQLCommand As String, pConnectionId As Integer) As Object
Dim oAdapter As IDatabase = GetAdapterClass(pConnectionId)
Return oAdapter.GetScalarValue(pSQLCommand)
End Function
''' <summary>
''' Returns a single value from the database
''' </summary>
''' <param name="pSQLCommand">The SQL query</param>
''' <returns>A value of type object</returns>
Public Function GetScalarValue(pSQLCommand As String) As Object
Return GetScalarValue(pSQLCommand, Constants.DEFAULT_CONNECTION_ID)
End Function
Private Function GetConnection(pConnectionId As Integer) As DispatcherConnection
Dim oConnection As DispatcherConnection = Connections.
Where(Function(conn) conn.Id = pConnectionId).
FirstOrDefault()
If oConnection IsNot Nothing Then
Logger.Debug("Resolved ConnectionId [{0}] into Connection [{1}]", pConnectionId, oConnection.Name)
End If
Return oConnection
End Function
Private Function GetAdapterClass(pConnectionId As Integer) As IDatabase
Dim oConnection = GetConnection(pConnectionId)
Dim oArgs As New List(Of Object) From {LogConfig, oConnection.ConnectionString, Constants.DEFAULT_TIMEOUT}
Logger.Debug("Creating database adapter object for type [{0}]", ConnectionType.MSSQL)
' TODO: Cache Database instances to avoid constructing them for every call
Select Case oConnection.ConnectionType
Case ConnectionType.MSSQL
Dim oConnectionString = MSSQLServer.DecryptConnectionString(oConnection.ConnectionString)
Return New MSSQLServer(LogConfig, oConnectionString, Constants.DEFAULT_TIMEOUT)
Case ConnectionType.Oracle
Return New Oracle(LogConfig, oConnection.ConnectionString, Constants.DEFAULT_TIMEOUT)
Case ConnectionType.Firebird
Dim oBuilder As New FirebirdSql.Data.FirebirdClient.FbConnectionStringBuilder(oConnection.ConnectionString)
Return New Firebird(LogConfig, oBuilder.DataSource, oBuilder.Database, oBuilder.UserID, oBuilder.Password)
Case ConnectionType.ODBC
'Dim oBuilder As New Data.Odbc.OdbcConnectionStringBuilder(pConnection.ConnectionString)
'Return New ODBC(LogConfig)
Return Nothing
Case Else
Return Nothing
End Select
End Function
Private Shared Function CreateFromDataRow(pConnectionDataRow As DataRow) As DispatcherConnection
Try
Dim oGuid = pConnectionDataRow.Item("GUID")
Dim oName = pConnectionDataRow.Item("BEZEICHNUNG")
Dim oUser = pConnectionDataRow.Item("USERNAME")
Dim oPassword = pConnectionDataRow.Item("PASSWORD")
Dim oServer = pConnectionDataRow.Item("SERVER")
Dim oDatabase = pConnectionDataRow.Item("DATENBANK")
Dim oConnectionType As ConnectionType
Dim oConnectionString As String
Select Case pConnectionDataRow.Item("SQL_PROVIDER")
Case "Oracle"
' TODO: Test Oracle Connection
oConnectionType = ConnectionType.Oracle
oConnectionString = New OracleConnectionStringBuilder() With {
.UserID = oUser,
.Password = oPassword,
.DataSource = oServer
}.ToString()
Case "ODBC"
' TODO: Test ODBC Connection
oConnectionType = ConnectionType.ODBC
oConnectionString = New Data.Odbc.OdbcConnectionStringBuilder() With {
.ConnectionString = oServer
}.ToString()
Case "Firebird"
oConnectionType = ConnectionType.Firebird
oConnectionString = New FirebirdSql.Data.FirebirdClient.FbConnectionStringBuilder() With {
.UserID = oUser,
.Password = oPassword,
.DataSource = oServer,
.Database = oDatabase
}.ToString()
Case Else ' MSSQL
oConnectionType = ConnectionType.MSSQL
oConnectionString = New SqlClient.SqlConnectionStringBuilder() With {
.UserID = oUser,
.Password = oPassword,
.DataSource = oServer,
.InitialCatalog = oDatabase
}.ToString()
End Select
Return New DispatcherConnection With {
.Id = oGuid,
.Name = oName,
.ConnectionType = oConnectionType,
.ConnectionString = oConnectionString
}
Catch ex As Exception
Return Nothing
End Try
End Function
End Class