Imports System.ServiceModel Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Filesystem Imports System.IO Public Class EDMService Implements IEDMService 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 FNICM_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 IEDMService.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 IEDMService.CreateDatabaseRequest CreateRequest(Name, Debug) Return _request.Name End Function Public Sub CloseDatabaseRequest() Implements IEDMService.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 IEDMService.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(True, oResult, Nothing) Catch ex As Exception _logger.Error(ex) _request.LogError(ex.Message) Return New TableResult(False, Nothing, ex.Message) End Try End Function Public Function ReturnScalar(SQL As String) As ScalarResult Implements IEDMService.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(True, oResult, Nothing) Catch ex As Exception _logger.Error(ex) _request.LogError(ex.Message) Return New ScalarResult(False, Nothing, ex.Message) End Try End Function Public Function ExecuteNonQuery(SQL As String) As NonQueryResult Implements IEDMService.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(True, Nothing) Catch ex As Exception _logger.Error(ex) _request.LogError(ex.Message) Return New NonQueryResult(False, ex.Message) End Try End Function #End Region #Region "Document" Public Function CreateFile(FileName As String, Contents() As Byte) As DocumentResult Implements IEDMService.CreateFile Try Dim oContainer As FileContainer Dim oContainerId As String If Not TestUserAuth() Then Throw New Exception("User 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('{FileName}','{oExtension}','{oContainerId}','{GetContainerName(oContainerId)}','{_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) Return New DocumentResult() With { .Document = New DocumentObject(oContainerId, oDocId, FileName) } Catch ex As Exception _logger.Error(ex) Return New DocumentResult(ex.Message) End Try End Function Public Function UpdateFile(DocObject As DocumentObject, Contents() As Byte) As DocumentResult Implements IEDMService.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() With { .Document = DocObject } Catch ex As Exception _logger.Error(ex) Return Nothing End Try End Function Public Function GetFile(DocObject As DocumentObject) As DocumentResult Implements IEDMService.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 With { .Document = DocObject, .Contents = 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 IEDMService.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 "Index" Public Function SetFileIndex(DocObject As DocumentObject, Syskey As String, Value As String) As Object Implements IEDMService.SetFileIndex Throw New NotImplementedException() End Function #End Region End Class