Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports DigitalData.Modules.Filesystem Imports DigitalData.Modules.language Imports DigitalData.Modules Imports System.IO Imports System.ServiceModel Imports System.Data.SqlClient Imports DigitalData.Services.EDMIService.Results Public Class EDMIService Implements IEDMIService Public Shared LogConfig As LogConfig Public Shared MSSQL_ECM As MSSQLServer Public Shared MSSQL_IDB As MSSQLServer Public Shared Firebird As Firebird Public Shared AppConfig As Config Public Shared Filesystem As Filesystem.File Public Shared EDMIArchive As EDMI.File.Archive Public Shared GlobalState As GlobalState Public Shared Scheduler As Scheduler Private ReadOnly _logger As Logger Private ReadOnly _debug As Boolean = False Private ReadOnly _username As String Public Sub New() Dim oOperationContext As OperationContext = OperationContext.Current Dim oInstanceContext As InstanceContext = oOperationContext.InstanceContext Dim oUsername = StripDomainFromUsername(oOperationContext.ServiceSecurityContext.WindowsIdentity.Name) _username = oUsername _logger = LogConfig.GetLogger() _logger.Debug("New Request by User [{0}]", _username) End Sub Public Function StripDomainFromUsername(UserName As String) If UserName.Contains("\") Then Return UserName.Split("\")(1) ElseIf UserName.Contains("@") Then Return UserName.Split("@")(0) Else Return UserName End If End Function #Region "=== Authorization ===" 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 Return True Catch ex As Exception _logger.Error(ex) Return False End Try End Function #End Region #Region "=== Heartbeat ===" Public Function Heartbeat() As Boolean Implements IEDMIService.Heartbeat Return True End Function #End Region #Region "Database" Public Function ReturnDatatableFromCache(Name As String, FilterExpression As String, SortByColumn As String) As TableResult Implements IEDMIService.ReturnDatatableFromCache Try _logger.Info($"ReturnDatatableFromCache, Datatable: {Name}") Dim oDataset As DataSet = Scheduler.DataSet Dim oDataTable As DataTable = Nothing _logger.Debug("DataSet contains [{0}] datatables", oDataset.Tables.Count) If oDataset.Tables.Contains(Name) Then oDataTable = oDataset.Tables.Item(Name).Copy() ' Apply filter and sorting to data Dim oFilterExpression As String = Utils.NotNull(FilterExpression, String.Empty) Dim oSortByColumn As String = Utils.NotNull(SortByColumn, String.Empty) Dim oFilteredRows = oDataTable.Select(oFilterExpression, oSortByColumn) Dim oFilteredTable As DataTable = Nothing If oFilteredRows.Count > 0 Then oFilteredTable = oFilteredRows.CopyToDataTable() oFilteredTable.TableName = Name Else ' Produce empty table oFilteredTable = oDataTable.Clone() oFilteredTable.TableName = Name End If _logger.Debug("Datatable Stats for [{0}]:", Name) _logger.Debug("Unfiltered: [{0}] rows", oDataTable.Rows.Count) _logger.Debug("Filtered: [{0}] rows", oFilteredTable.Rows.Count) Return New TableResult(oFilteredTable) Else Throw New ApplicationException($"DataTable {Name} does not exist") End If Catch ex As Exception _logger.Error(ex) Return New TableResult(ex.Message) End Try End Function #End Region #Region "=== Database (MSSQL IDB) ===" Public Function ReturnDatatable_MSSQL_IDB(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_IDB Try _logger.Info($"ReturnDatatable_MSSQL_IDB, SQL: {SQL}") Dim oResult As DataTable = MSSQL_IDB.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception _logger.Error(ex) Return New TableResult(ex.Message) End Try End Function Public Function ReturnScalar_MSSQL_IDB(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_MSSQL_IDB Try _logger.Info($"ReturnScalar_MSSQL_IDB, SQL: {SQL}") Dim oResult As Object = MSSQL_IDB.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception _logger.Error(ex) Return New ScalarResult(ex.Message) End Try End Function Public Function ExecuteNonQuery_MSSQL_IDB(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_MSSQL_IDB Try _logger.Info($"ExecuteNonQuery_MSSQL_IDB, SQL: {SQL}") Dim oResult As Boolean = MSSQL_IDB.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception _logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function #End Region #Region "=== Database (MSSQL ECM) ===" Public Function ReturnDatatable_MSSQL_ECM(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_MSSQL_ECM Try _logger.Info($"ReturnDatatable_MSSQL_ECM, SQL: {SQL}") Dim oResult As DataTable = MSSQL_ECM.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception _logger.Error(ex) Return New TableResult(ex.Message) End Try End Function Public Function ReturnScalar_MSSQL_ECM(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_MSSQL_ECM Try _logger.Info($"ReturnScalar_MSSQL_ECM, SQL: {SQL}") Dim oResult As Object = MSSQL_ECM.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception _logger.Error(ex) Return New ScalarResult(ex.Message) End Try End Function Public Function ExecuteNonQuery_MSSQL_ECM(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_MSSQL_ECM Try _logger.Info($"ExecuteNonQuery_MSSQL_ECM, SQL: {SQL}") Dim oResult As Boolean = MSSQL_ECM.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception _logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function #End Region #Region "=== Database (Firebird) ===" Public Function ReturnDatatable_Firebird(SQL As String) As TableResult Implements IEDMIService.ReturnDatatable_Firebird Try _logger.Info($"ReturnDatatable, SQL: {SQL}") Dim oResult As DataTable = Firebird.GetDatatable(SQL) Return New TableResult(oResult) Catch ex As Exception _logger.Error(ex) Return New TableResult(ex.Message) End Try End Function Public Function ReturnScalar_Firebird(SQL As String) As ScalarResult Implements IEDMIService.ReturnScalar_Firebird Try _logger.Info($"ReturnScalar, SQL: {SQL}") Dim oResult As Object = Firebird.GetScalarValue(SQL) Return New ScalarResult(oResult) Catch ex As Exception _logger.Error(ex) Return New ScalarResult(ex.Message) End Try End Function Public Function ExecuteNonQuery_Firebird(SQL As String) As NonQueryResult Implements IEDMIService.ExecuteNonQuery_Firebird Try _logger.Info($"ExecuteNonQuery, SQL: {SQL}") Dim oResult As Boolean = Firebird.ExecuteNonQuery(SQL) Return New NonQueryResult() Catch ex As Exception _logger.Error(ex) Return New NonQueryResult(ex.Message) End Try End Function #End Region #Region "=== Document ===" ''' ''' Imports a file according to ObjectStoreId ''' ''' Public Function ImportFile(Data As Messages.DocumentImportRequest) As Messages.DocumentImportResponse Implements IEDMIService.ImportFile Dim oObjectStore = GlobalState.ObjectStores. Where(Function(s) s.Id = Data.ObjectStoreId). FirstOrDefault() If oObjectStore Is Nothing Then Throw New FaultException($"Object Store with Id [{Data.ObjectStoreId}] does not exist!") End If Dim EDMIPath = New EDMI.File.Path(LogConfig, oObjectStore.Path) ' TODO: ' - Get Object Store -> Object Catalog -> Catalog Path ' - If IS_ARCHIVE = True And RetentionDays <> Nothing: ' DoArchive! ' - Refactor EDMIPath to get ObjectStore at service start up ' and return ObjectStore Path from ObjectStoreId + RelativePath ' VWIDB_OBJECTSTORE Dim oRelativePath As String = EDMIPath.GetRelativePath(Data.DocumentType, Data.FileName) Dim oAbsolutePath As String = EDMIPath.GetFullPath(Data.DocumentType, Data.FileName) Dim oDirectoryPath = EDMIPath.GetFullPath(Data.DocumentType) Try Directory.CreateDirectory(oDirectoryPath) Catch ex As Exception _logger.Error(ex) Throw New FaultException(ex.Message) End Try Try Dim oVersionedFileName As String = Filesystem.GetVersionedFilename(oAbsolutePath) _logger.Info("ImportFile: Saving file [{0}] to path [{1}]", Data.FileName, oVersionedFileName) Using oStream = New FileStream(oVersionedFileName, FileMode.CreateNew) oStream.Write(Data.Contents, 0, Data.Contents.Length) oStream.Flush(True) oStream.Close() End Using ' insert into db Dim oCommand As New SqlCommand("PRIDB_NEW_DOCUMENT") oCommand.Parameters.AddWithValue("@OBJ_ST_ID", 1) oCommand.Parameters.AddWithValue("@REL_PATH", oRelativePath) oCommand.Parameters.AddWithValue("@WHO", _username) oCommand.Parameters.AddWithValue("@REF_DOCID", 0) oCommand.Parameters.Add(New SqlParameter("@IDB_OBJ_ID", SqlDbType.BigInt)) Dim oObjectId = MSSQL_IDB.GetScalarValue(oCommand, "@IDB_OBJ_ID") Return New Messages.DocumentImportResponse() With {.ObjectId = oObjectId} Catch ex As Exception _logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function Public Function GetFileByObjectId(Data As Messages.DocumentStreamRequest) As Messages.DocumentStreamResponse Implements IEDMIService.GetFileByObjectId Try Dim oSQL As String = $"SELECT ObjectStoreId FROM VWIDB_DOC_DATA WHERE IDB_OBJ_ID = {Data.ObjectId}" Dim oObjectStoreId = MSSQL_IDB.GetScalarValue(oSQL) Dim oObjectStore = GlobalState.ObjectStores. Where(Function(s) s.Id = oObjectStoreId). FirstOrDefault() Dim oSQL2 As String = $"SELECT DocRelativePath FROM VWIDB_DOC_DATA WHERE IDB_OBJ_ID = {Data.ObjectId}" Dim oPath As String = MSSQL_IDB.GetScalarValue(oSQL2) If IsNothing(oPath) Then Throw New FaultException($"Object [{Data.ObjectId}] does not exist in database!") End If Dim EDMIPath As New EDMI.File.Path(LogConfig, oObjectStore.Path) Dim oFullPath = EDMIPath.GetFullPathFromRelativePath(oPath) _logger.Debug("GetFileByObjectId: Loading file [{0}]", oFullPath) Dim oFileInfo As New FileInfo(oFullPath) If Not oFileInfo.Exists Then Throw New FaultException($"Object [{Data.ObjectId}] does not exist on filesystem!") End If Dim oDestination As New MemoryStream() Using oSource As FileStream = IO.File.OpenRead(oFullPath) oSource.CopyTo(oDestination) End Using oDestination.Seek(0, SeekOrigin.Begin) Dim oMessage As New Messages.DocumentStreamResponse() With { .FileName = oFileInfo.Name, .FileContents = oDestination } Return oMessage Catch ex As IOException _logger.Error(ex) Throw New FaultException($"Object [{Data.ObjectId}] could not be streamed!") Catch ex As Exception _logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function Public Function ListFilesForUser() As Messages.DocumentListResponse Implements IEDMIService.ListFilesForUser Try Dim oSQL = $"SELECT * FROM VWIDB_DOC_DATA" Dim oDatatable As DataTable = MSSQL_IDB.GetDatatable(oSQL) oDatatable.TableName = "DocumentList" Return New Messages.DocumentListResponse() With { .Datatable = oDatatable } Catch ex As Exception _logger.Error(ex) Throw New FaultException(ex.Message) End Try End Function #End Region End Class