Developer02 Digital Data a80486dad2 add DataResultList
2019-10-14 15:18:45 +02:00

310 lines
11 KiB
VB.net

Imports System.ServiceModel
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Logging
Imports System.IO
Imports DigitalData.Modules.Filesystem
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.PerSession)>
Public Class IDBService
Implements IIDBService
Public Shared LogConfig As LogConfig
Public Shared Database As Firebird
Public Shared AppConfig As AppConfig
Private ReadOnly _logger As Logger
Private _request As Request = Nothing
Private _debug As Boolean = False
Private _username As String
Public Sub New()
Dim oOperationContext As OperationContext = OperationContext.Current
Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext
Dim oUsername = oOperationContext.ServiceSecurityContext.WindowsIdentity.Name
_username = oUsername
_logger = LogConfig.GetLogger()
End Sub
#Region "Auth"
Private Function TestUserAuth() As Boolean
Try
Dim oSQL As String = $"SELECT FNIDB_AUTH_USER('{_username}') FROM RDB$DATABASE;"
Dim oResult As Boolean = Database.GetScalarValue(oSQL)
Return oResult
Catch ex As Exception
_logger.Error(ex)
Return False
End Try
End Function
#End Region
#Region "Heartbeat"
Public Function Heartbeat() As Boolean Implements IIDBService.Heartbeat
Return True
End Function
#End Region
#Region "Request"
Public Sub CreateRequest(Name As String, Optional Debug As Boolean = False)
_request = New Request(Name, _username, Database, Debug)
_debug = Debug
_logger.Info("Creating request {0}/{1}", _request.Name, _request.RequestId)
End Sub
Public Function CreateDatabaseRequest(Name As String, Optional Debug As Boolean = False) As String Implements IIDBService.CreateDatabaseRequest
CreateRequest(Name, Debug)
Return _request.Name
End Function
Public Sub CloseDatabaseRequest() Implements IIDBService.CloseDatabaseRequest
If IsNothing(_request) Then
Exit Sub
End If
_logger.Info("Closing request {0}", _request.ToString)
_request.Connection.Close()
_request = Nothing
End Sub
#End Region
#Region "Database"
Private Sub TestRequestCreated()
If IsNothing(_request) Then
Throw New Exceptions.NoRequestException()
End If
End Sub
Public Function ReturnDatatable(SQL As String) As TableResult Implements IIDBService.ReturnDatatable
Try
TestRequestCreated()
_logger.Info($"ReturnDatatable, SQL: {SQL}")
_request.LogDebug($"ReturnDatatable, SQL: {SQL}")
Dim oResult As DataTable = Database.GetDatatableWithConnection(SQL, _request.Connection)
Return New TableResult(oResult)
Catch ex As Exception
_logger.Error(ex)
_request.LogError(ex.Message)
Return New TableResult(ex.Message)
End Try
End Function
Public Function ReturnScalar(SQL As String) As ScalarResult Implements IIDBService.ReturnScalar
Try
TestRequestCreated()
_logger.Info($"ReturnScalar, SQL: {SQL}")
_request.LogDebug($"ReturnScalar, SQL: {SQL}")
Dim oResult As Object = Database.GetScalarValueWithConnection(SQL, _request.Connection)
Return New ScalarResult(oResult)
Catch ex As Exception
_logger.Error(ex)
_request.LogError(ex.Message)
Return New ScalarResult(ex.Message)
End Try
End Function
Public Function ExecuteNonQuery(SQL As String) As NonQueryResult Implements IIDBService.ExecuteNonQuery
Try
TestRequestCreated()
_logger.Info($"ExecuteNonQuery, SQL: {SQL}")
_request.LogDebug($"ExecuteNonQuery, SQL: {SQL}")
Dim oResult As Boolean = Database.ExecuteNonQueryWithConnection(SQL, _request.Connection)
Return New NonQueryResult()
Catch ex As Exception
_logger.Error(ex)
_request.LogError(ex.Message)
Return New NonQueryResult(ex.Message)
End Try
End Function
#End Region
#Region "Document"
Public Function NewFile(FileName As String, Contents() As Byte) As DocumentResult Implements IIDBService.NewFile
Try
Dim oContainer As FileContainer
Dim oContainerId As String
If Not TestUserAuth() Then
Throw New Exception($"User {_username} not authorized.")
End If
oContainer = FileContainer.Create(LogConfig, AppConfig.ContainerPassword)
oContainerId = oContainer.ContainerId
_logger.Debug("Container created with id {0}", oContainerId)
Dim oExtension As String = Path.GetExtension(FileName).Substring(1)
_logger.Debug("File extension of file {0} is {1}", FileName, oExtension)
Dim oSQL = $"SELECT FNICM_NEW_DOC('010', '{oContainerId}', '{GetContainerName(oContainerId)}', '{FileName}', '{oExtension}', '{_username}') FROM RDB$DATABASE;"
Dim oDocId As Int64 = Database.GetScalarValue(oSQL)
If oDocId = -1 Then
_logger.Warn("Database returned -1 while creating Document Entry. File was not saved!")
Return Nothing
End If
_logger.Debug("Database Entry created with DocId {0}", oDocId)
oContainer.SetFile(Contents, FileName)
oContainer.SaveAs(GetContainerPath(oContainerId))
_logger.Debug("File saved in Container!", FileName)
Dim oDocument = New DocumentObject(oContainerId, oDocId, FileName)
Return New DocumentResult(oDocument)
Catch ex As Exception
_logger.Error(ex)
Return New DocumentResult(ex.Message)
End Try
End Function
Public Function UpdateFile(DocObject As Modules.EDMIAPI.IDBServiceReference.DocumentObject, Contents() As Byte) As DocumentResult Implements IIDBService.UpdateFile
Try
TestFileExists(DocObject.ContainerId)
' TODO: update db
Dim oFilePath = GetContainerPath(DocObject.ContainerId)
Dim oFileContainer As FileContainer = FileContainer.Load(LogConfig, AppConfig.ContainerPassword, oFilePath)
oFileContainer.SetFile(Contents, oFileContainer.GetFile.FileName)
oFileContainer.Save()
Return New DocumentResult(DocObject)
Catch ex As Exception
_logger.Error(ex)
Return Nothing
End Try
End Function
Public Function GetFile(DocObject As DocumentObject) As DocumentResult Implements IIDBService.GetFile
Try
TestFileExists(DocObject.ContainerId)
Dim oContainerPath = GetContainerPath(DocObject.ContainerId)
Dim oContainer As FileContainer = FileContainer.Load(LogConfig, AppConfig.ContainerPassword, oContainerPath)
Dim oContents As Byte() = oContainer.GetFile().Contents
Return New DocumentResult(DocObject, oContents)
Catch ex As Exception
_logger.Error(ex)
Return New DocumentResult(ex.Message)
End Try
End Function
Public Function DeleteFile(DocObject As DocumentObject) As Boolean Implements IIDBService.DeleteFile
Try
TestFileExists(DocObject.ContainerId)
Dim oFilePath = GetContainerPath(DocObject.ContainerId)
IO.File.Delete(oFilePath)
'TODO: Delete doc from db
Return True
Catch ex As Exception
_logger.Error(ex)
Return False
End Try
End Function
Private Function GetContainerPath(ContainerId As String) As String
Return Path.Combine(AppConfig.ContainerPath, GetContainerName(ContainerId))
End Function
Private Function GetContainerName(ContainerId As String) As String
Return ContainerId & ".enc"
End Function
Private Sub TestFileExists(ContainerId)
Dim oContainerPath = GetContainerPath(ContainerId)
If Not IO.File.Exists(oContainerPath) Then
Throw New FileNotFoundException("Container existiert nicht", oContainerPath)
End If
End Sub
#End Region
#Region "Utils"
Public Function GetDocumentByDocumentId(DocumentId As Long) As DocumentResult Implements IIDBService.GetDocumentByDocumentId
Try
Dim oSQL = $"SELECT GUID, CONTAINER_ID, ORIGINAL_FILENAME FROM TBIDB_DOCUMENT WHERE GUID = {DocumentId}"
Dim oTable = Database.GetDatatable(oSQL)
If oTable.Rows.Count = 0 Then
Return New DocumentResult("Document not found")
End If
Dim oRow As DataRow = oTable.Rows.Item(0)
Dim oDocument As New DocumentObject(
oRow.Item("CONTAINER_ID"),
oRow.Item("GUID"),
oRow.Item("ORIGINAL_FILENAME")
)
TestFileExists(oDocument.ContainerId)
Dim oContainerPath = GetContainerPath(oDocument.ContainerId)
Dim oContainer As FileContainer = FileContainer.Load(LogConfig, AppConfig.ContainerPassword, oContainerPath)
Dim oContents As Byte() = oContainer.GetFile().Contents
Return New DocumentResult(oDocument, oContents)
Catch ex As Exception
Return New DocumentResult(ex.Message)
End Try
End Function
Public Function GetDocumentByContainerId(ContainerId As String) As DocumentResult Implements IIDBService.GetDocumentByContainerId
Try
Dim oSQL = $"SELECT GUID, CONTAINER_ID, ORIGINAL_FILENAME FROM TBIDB_DOCUMENT WHERE CONTAINER_ID = '{ContainerId}'"
Dim oTable = Database.GetDatatable(oSQL)
If oTable.Rows.Count = 0 Then
Return New DocumentResult("Document not found")
End If
Dim oRow As DataRow = oTable.Rows.Item(0)
Dim oDocument As New DocumentObject(
oRow.Item("CONTAINER_ID"),
oRow.Item("GUID"),
oRow.Item("ORIGINAL_FILENAME")
)
TestFileExists(oDocument.ContainerId)
Dim oContainerPath = GetContainerPath(oDocument.ContainerId)
Dim oContainer As FileContainer = FileContainer.Load(LogConfig, AppConfig.ContainerPassword, oContainerPath)
Dim oContents As Byte() = oContainer.GetFile().Contents
Return New DocumentResult(oDocument, oContents)
Catch ex As Exception
Return New DocumentResult(ex.Message)
End Try
End Function
#End Region
#Region "Index"
Public Function NewFileIndex(DocObject As DocumentObject, Syskey As String, LanguageCode As String, Value As String) As IndexResult Implements IIDBService.NewFileIndex
Try
Dim oSQL = $"SELECT FNIDB_NEW_DOC_VALUE({DocObject.DocumentId},'{Syskey}','{LanguageCode}','{Value}','{_username}') FROM RDB$DATABASE;"
Dim oIndexId As Int64 = Database.GetScalarValue(oSQL)
Return New IndexResult(oIndexId)
Catch ex As Exception
_logger.Error(ex)
Return New IndexResult(ex.Message)
End Try
End Function
#End Region
End Class