Imports System.IO Imports System.ServiceModel Imports DigitalData.Modules.Base Imports DigitalData.Modules.EDMI.API.Constants Imports DigitalData.Modules.EDMI.API.EDMIServiceReference Imports DigitalData.Modules.EDMI.API.Rights Imports DigitalData.Modules.Logging Public Class Client ' Constants Private Const UPDATE_INTERVAL_IN_MINUTES As Integer = 1 Private Const KIND_TYPE_DOC = "DOC" ' Helper Classes Private ReadOnly LogConfig As LogConfig Private ReadOnly Logger As Logger Private ReadOnly ChannelManager As Channel ' Runtime Variables Private _ServerAddress As ServerAddressStruct Private _ClientConfig As GlobalStateClientConfiguration Private _CachedTables As New List(Of String) Private _IsOnline As Boolean Private _Channel As IEDMIServiceChannel ' Update Timer Private WithEvents UpdateTimer As New Timers.Timer ' Public Variables Public ReadOnly Property CachedTables Get Return _CachedTables End Get End Property Public ReadOnly Property ClientConfig As GlobalStateClientConfiguration Get If _ClientConfig Is Nothing Then Throw New ApplicationException("ClientConfig is empty! Please connect to the service before accessing this property") End If Return _ClientConfig End Get End Property Public ReadOnly Property IsOnline As Boolean Get Return _IsOnline End Get End Property Public ReadOnly Property ServerAddress As String Get Return $"{_ServerAddress.Host}:{_ServerAddress.Port}" End Get End Property ''' ''' Parse a IPAddress:Port String into its parts ''' ''' A Server Address, for example: 192.168.1.50, 192.168.1.50:9000, 192.168.1.50;9000 Public Shared Function ParseServiceAddress(AddressWithOptionalPort As String) As Tuple(Of String, Integer) Dim oConnection As New Connection() Dim oAddress As ServerAddressStruct = oConnection.ParseServiceAddress(AddressWithOptionalPort) Return New Tuple(Of String, Integer)(oAddress.Host, oAddress.Port) End Function ''' ''' Creates a new EDMI Client object ''' ''' LogConfig object ''' The IP address/hostname and port, separated by semicolon or colon, ex. 1.2.3.4:9000 Public Sub New(pLogConfig As LogConfig, pServiceAdress As String) LogConfig = pLogConfig Logger = pLogConfig.GetLogger() UpdateTimer.Interval = 60 * 1000 * UPDATE_INTERVAL_IN_MINUTES UpdateTimer.Start() Try Dim oConnection = New Connection() _ServerAddress = oConnection.ParseServiceAddress(pServiceAdress) ChannelManager = New Channel(pLogConfig, _ServerAddress) AddHandler ChannelManager.Reconnect, AddressOf Reconnect Logger.Debug("Ready for connection to Service at: [{0}:{1}]", _ServerAddress.Host, _ServerAddress.Port) Catch ex As Exception Logger.Error(ex) End Try End Sub ''' ''' Creates a new EDMI Client object ''' ''' LogConfig object ''' The IP address to connect to ''' The Port number to use for the connection Public Sub New(pLogConfig As LogConfig, pIPAddress As String, pPortNumber As Integer) LogConfig = pLogConfig Logger = pLogConfig.GetLogger() UpdateTimer.Interval = 60 * 1000 * UPDATE_INTERVAL_IN_MINUTES UpdateTimer.Start() Try Dim oConnection = New Connection() _ServerAddress = oConnection.ParseServiceAddress(pIPAddress, pPortNumber) ChannelManager = New Channel(pLogConfig, _ServerAddress) AddHandler ChannelManager.Reconnect, AddressOf Reconnect Logger.Debug("Ready for connection to Service at: [{0}:{1}]", _ServerAddress.Host, _ServerAddress.Port) Catch ex As Exception Logger.Error(ex) End Try End Sub ''' ''' Connect to the service ''' ''' True if connection was successful, false otherwise Public Function Connect() As Boolean Try _Channel = ChannelManager.GetChannel() Logger.Debug("Opening channel..") _Channel.Open() Dim oResponse = _Channel.GetClientConfig() If oResponse.OK Then _ClientConfig = oResponse.ClientConfig Else Logger.Warn("Client Configuration could not be loaded: [{0}]", oResponse.ErrorMessage) End If Logger.Info($"Connection to AppService [{ServerAddress}] successfully established!") _IsOnline = True Return True Catch ex As Exception _IsOnline = False Logger.Error(ex) Return False End Try End Function ''' ''' Aborts the channel and creates a new connection ''' Public Sub Reconnect() Logger.Warn("Connection faulted. Trying to reconnect..") Try _Channel.Abort() _Channel = ChannelManager.GetChannel() _Channel.Open() _IsOnline = True Catch ex As Exception Logger.Error(ex) End Try End Sub Private Async Function UpdateTimer_Elapsed(sender As Object, e As Timers.ElapsedEventArgs) As Task Handles UpdateTimer.Elapsed Try Dim oTables As String() = Await _Channel.GetCachedTablesAsync() _CachedTables = oTables. Select(Function(table) table.ToUpper). ToList() Catch ex As Exception Logger.Warn("Update of CachedTable was not successful!") Logger.Error(ex) _CachedTables = New List(Of String) End Try End Function ''' ''' Imports a file from a filepath, creating a IDB ObjectId and Filesystem Object ''' ''' Type of ObjectStore. Can be WORK or ARCHIVE. ''' Business entity that the new file object should belong to. ''' Other file import options ''' When local filepath was not found ''' When there was a error in the Service ''' The ObjectId of the newly generated filesystem object Public Async Function NewFileAsync(pFilePath As String, pObjectStoreName As String, pObjectKind As String, pIDBDoctypeId As Long, Optional pImportOptions As Options.NewFileOptions = Nothing) As Task(Of Long) Try Dim oNewFile As New Modules.IDB.NewFile(LogConfig, _Channel) Return Await oNewFile.RunAsync(pFilePath, pObjectStoreName, pObjectKind, pIDBDoctypeId, pImportOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function UpdateFileAsync(pObjectId As Long, pFilePath As String, Optional pImportOptions As Options.UpdateFileOptions = Nothing) As Task(Of Long) Try Dim oUpdateFile As New Modules.IDB.UpdateFile(LogConfig, _Channel) Return Await oUpdateFile.RunAsync(pFilePath, pObjectId, pImportOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function SetObjectStateAsync(pObjectId As Long, pState As String, Optional pOptions As Options.SetObjectStateOptions = Nothing) As Task(Of Boolean) Try Dim oSetObjectState As New Modules.IDB.SetObjectState(LogConfig, _Channel) Return Await oSetObjectState.RunAsync(pObjectId, pState, pOptions) Catch ex As Exception Logger.Error(ex) Return False End Try End Function Public Async Function SetAttributeValueAsync(pObjectId As Long, pName As String, pValue As Object, Optional pOptions As Options.SetAttributeValueOptions = Nothing) As Task(Of Boolean) Try Dim oSetAttributeValue As New Modules.IDB.SetAttributeValue(LogConfig, _Channel) Return Await oSetAttributeValue.RunAsync(pObjectId, pName, pValue, pOptions) Catch ex As Exception Logger.Error(ex) Return False End Try End Function Public Async Function CheckOutFile(pObjectId As Long, pComment As String, Optional pOptions As Options.CheckOutInOptions = Nothing) As Task(Of Long) Try Dim oCheckOutFile As New Modules.IDB.CheckOutFile(LogConfig, _Channel) Return Await oCheckOutFile.RunAsync(pObjectId, pComment, pOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function CheckOutFile(pObjectId As Long, Optional pOptions As Options.CheckOutInOptions = Nothing) As Task(Of Long) Try Dim oCheckOutFile As New Modules.IDB.CheckOutFile(LogConfig, _Channel) Return Await oCheckOutFile.RunAsync(pObjectId, String.Empty, pOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function CheckInFile(pObjectId As Long, Optional pOptions As Options.CheckOutInOptions = Nothing) As Task(Of Long) Try Dim oCheckInFile As New Modules.IDB.CheckInFile(LogConfig, _Channel) Return Await oCheckInFile.RunAsync(pObjectId, pOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function ImportFileAsync( pFilePath As String, pAttributeValues As List(Of UserAttributeValue), pObjectStoreName As String, pObjectKind As String, pIDBDoctypeId As String, Optional pImportOptions As Options.ImportFileOptions = Nothing) As Task(Of ImportFileResponse) Try Dim oImportFile As New Modules.IDB.ImportFile(LogConfig, _Channel) Return Await oImportFile.RunAsync(pFilePath, pAttributeValues, pObjectStoreName, pObjectKind, pIDBDoctypeId, pImportOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function Globix_ImportFileAsync( pFilePath As String, pProfileId As Integer, pAttributeValues As List(Of UserAttributeValue), pObjectStoreName As String, pObjectKind As String, pIDBDoctypeId As String, Optional pImportOptions As Options.ImportFileOptions = Nothing) As Task(Of Globix_ImportFileResponse) Try Dim oImportFile As New Modules.Globix.ImportFile(LogConfig, _Channel) Return Await oImportFile.RunAsync(pFilePath, pProfileId, pAttributeValues, pObjectStoreName, pObjectKind, pIDBDoctypeId, pImportOptions) Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Function Zooflow_GetFileObject(pObjectId As Long, pLoadFileContents As Boolean) As FileObject Try Dim oGetFileObject As New Modules.Zooflow.GetFileObject(LogConfig, _Channel) Dim oFileObject = oGetFileObject.Run(pObjectId, pLoadFileContents) Return oFileObject Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Public Async Function ZooFlow_GetFileObjectAsync(pObjectId As Long, pLoadFileContents As Boolean) As Task(Of FileObject) Try Dim oGetFileObject As New Modules.Zooflow.GetFileObject(LogConfig, Me) Dim oFileObject = Await oGetFileObject.RunAsync(pObjectId, pLoadFileContents) Return oFileObject Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function ''' ''' Sets a value to an attribute ''' ''' IDB ObjectId ''' Name of the attribute ''' ''' ''' 'Public Function SetVariableValue(pObjectId As Long, pAttributeName As String, pValue As Object, Optional pOptions As Options.SetVariableValueOptions = Nothing) As Boolean ' Try ' ' Set default options ' If pOptions Is Nothing Then ' pOptions = New Options.SetVariableValueOptions() ' End If ' Dim oOptions As New Options.GetVariableValueOptions With { ' .Language = pOptions.Language, ' .Username = pOptions.Username ' } ' Try ' Dim oResponse = Channel.TestObjectIdExists(New TestObjectIdExistsRequest With {.ObjectId = pObjectId}) ' If oResponse.Exists = False Then ' Return False ' End If ' Catch ex As Exception ' Logger.Error(ex) ' Return False ' End Try ' Dim oType = pValue.GetType.Name ' If oType = GetType(DataTable).Name Then ' Dim oValueTable As DataTable = pValue ' Dim oCurrentValue As VariableValue ' ' Get current value ' oCurrentValue = GetVariableValue(pObjectId, pAttributeName, oOptions) ' ' If current value is datatable ' If oCurrentValue.Type = GetType(DataTable) Then ' ' Convert value to Datatable ' Dim oTable As DataTable = oCurrentValue.Value ' If oTable.Rows.Count > 1 Then ' 'now Checking whether the old row still remains in Vector? If not it will be deleted as it cannot be replaced in multivalues ' For Each oRow As DataRow In oTable.Rows ' Dim oExists As Boolean = False ' For Each oNewValueRow As DataRow In oValueTable.Rows ' Logger.Debug($"Checking oldValue[{oCurrentValue}] vs NewValue [{oNewValueRow.Item(1)}]") ' If oNewValueRow.Item(1).ToString.ToUpper = oRow.Item(0).ToString.ToUpper Then ' oExists = True ' Exit For ' End If ' Next ' If oExists = False Then ' Logger.Debug($"Value [{oRow.Item(0)}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") ' DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oRow.Item(0)) ' End If ' Next ' End If ' Else ' If oValueTable.Rows.Count > 1 Then ' 'now Checking whether the old row still remains in Vector? If not it will be deleted as it cannot be replaced in multivalues ' Dim oExists As Boolean = False ' For Each oNewValueRow As DataRow In oValueTable.Rows ' Logger.Debug($"Checking oldValue[{oCurrentValue}] vs NewValue [{oNewValueRow.Item(1)}]") ' If oNewValueRow.Item(1).ToString.ToUpper = oCurrentValue.ToString.ToUpper Then ' oExists = True ' Exit For ' End If ' Next ' If oExists = False Then ' Logger.Debug($"Value [{oCurrentValue}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") ' DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) ' End If ' Else ' Logger.Debug($"Value [{oCurrentValue}] of Attribute [{pAttributeName}] obviously was updated during runtime - will be deleted!") ' DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) ' End If ' End If ' For Each oNewValueRow As DataRow In oValueTable.Rows ' Dim oResult As Boolean = NewObjectData(pObjectId, pAttributeName, pValue, New Options.NewObjectOptions With { ' .Language = pOptions.Language, ' .Username = pOptions.Username ' }) ' If oResult = False Then ' Return False ' End If ' Next ' Return True ' Else ' Return NewObjectData(pObjectId, pAttributeName, pValue, New Options.NewObjectOptions With { ' .Language = pOptions.Language, ' .Username = pOptions.Username ' }) ' End If ' Catch ex As Exception ' Logger.Error(ex) ' Return False ' End Try 'End Function ''' ''' ''' ''' ''' ''' ''' Public Function GetVariableValue(pObjectId As Long, pAttributeName As String, Optional pOptions As Options.GetVariableValueOptions = Nothing) As VariableValue If pOptions Is Nothing Then pOptions = New Options.GetVariableValueOptions() End If Try Dim oArgs = New GetAttributeValueRequest With { .ObjectId = pObjectId, .AttributeName = pAttributeName, .User = New UserState() With { .UserName = pOptions.Username, .Language = pOptions.Language } } Dim oResponse = _Channel.GetAttributeValue(oArgs) If oResponse.OK = False Then Return New VariableValue() End If Return New VariableValue(oResponse.Value) Catch ex As Exception Logger.Error(ex) Return New VariableValue() End Try End Function Private Function GetValueByType(pRow As DataRow, pTypeString As String) As Object Try Dim oAttributeValue As Object Select Case pTypeString Case Constants.AttributeTypeName.BIT oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.BIG_INTEGER oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.DATE oAttributeValue = pRow.Item("ValueDate") Case Constants.AttributeTypeName.DATETIME oAttributeValue = pRow.Item("ValueDate") Case Constants.AttributeTypeName.DECIMAL oAttributeValue = pRow.Item("ValueDecimal") Case Constants.AttributeTypeName.FLOAT oAttributeValue = pRow.Item("ValueDecimal") Case Constants.AttributeTypeName.VARCHAR oAttributeValue = pRow.Item("ValueText") Case Constants.AttributeTypeName.VECTOR_INTEGER oAttributeValue = pRow.Item("ValueBigInt") Case Constants.AttributeTypeName.VECTOR_STRING oAttributeValue = pRow.Item("ValueText") Case Else oAttributeValue = Nothing End Select Return oAttributeValue Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Private Function GetAttributesForObject(pObjectId As Long, pLanguage As String) As List(Of ObjectAttribute) Dim oAttributes As New List(Of ObjectAttribute) Try Dim oResult As TableResult = _Channel.ReturnDatatable_MSSQL_IDB($"EXEC [PRIDB_GET_VALUE_DT] {pObjectId}, '{pLanguage}'") If oResult.OK = False Then Throw New ApplicationException(oResult.ErrorMessage) End If If oResult.Table Is Nothing OrElse oResult.Table.Rows.Count = 0 Then Return Nothing End If For Each oRow As DataRow In oResult.Table.Rows Dim oAttribute As New ObjectAttribute With { .Id = oRow.Item("AttributeId"), .Title = oRow.Item("AttributeTitle"), .Type = oRow.Item("AttributeType"), .ValueBigInt = oRow.ItemEx(Of Object)("ValueBigInt", Nothing), .ValueDate = oRow.ItemEx(Of Object)("ValueDate", Nothing), .ValueDecimal = oRow.ItemEx(Of Object)("ValueDecimal", Nothing), .ValueText = oRow.ItemEx(Of Object)("ValueText", Nothing) } oAttributes.Add(oAttribute) Next Return oAttributes Catch ex As Exception Logger.Error(ex) Return Nothing End Try End Function Private Function NewObjectData(pObjectId As Long, pAttributeName As String, pValue As Object, pOptions As Options.NewObjectOptions) If pOptions Is Nothing Then pOptions = New Options.NewObjectOptions() End If Dim oLanguage = GetUserLanguage(pOptions.Language) Dim oUsername = GetUserName(pOptions.Username) Dim oSql = $"DECLARE @NEW_OBJ_MD_ID BIGINT EXEC PRIDB_NEW_OBJ_DATA({pObjectId}, '{pAttributeName}', '{oUsername}', '{pValue}', '{oLanguage}', 0, @OMD_ID = @NEW_OBJ_MD_ID OUTPUT)" Dim oResult = _Channel.ExecuteNonQuery_MSSQL_IDB(oSql) If oResult.OK = False Then Logger.Warn("Error while deleting Term object") Logger.Error(oResult.ErrorMessage) End If Return oResult.OK End Function Private Function DeleteTermObjectFromMetadata(pObjectId As Long, pAttributeName As String, pTerm2Delete As String, Optional pUsername As String = "", Optional pLanguage As String = "") As Boolean Try Dim oLanguage = GetUserLanguage(pLanguage) Dim oUsername = GetUserName(pUsername) Dim oIdIsForeign As Integer = 1 Dim oDELSQL = $"EXEC PRIDB_DELETE_TERM_OBJECT_METADATA {pObjectId},'{pAttributeName}','{pTerm2Delete}','{oUsername}','{oLanguage}',{oIdIsForeign}" Dim oResult = _Channel.ExecuteNonQuery_MSSQL_IDB(oDELSQL) If oResult.OK = False Then Logger.Warn("Error while deleting Term object") Logger.Error(oResult.ErrorMessage) End If Return oResult.OK Catch ex As Exception Logger.Error(ex) Return False End Try End Function #Region "GetDatatable" Public Function GetDatatableFromIDB(pSQL As String) As GetDatatableResponse Try Dim oResponse = _Channel.ReturnDatatable(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetDatatableFromECM(pSQL As String) As GetDatatableResponse Try Dim oResponse = _Channel.ReturnDatatable(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetDatatableFromConnection(pSQL As String, pConnectionId As Integer) As GetDatatableResponse Try Dim oResponse = _Channel.ReturnDatatable(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableFromIDBAsync(pSQL As String) As Task(Of GetDatatableResponse) Try Dim oResponse = Await _Channel.ReturnDatatableAsync(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableFromECMAsync(pSQL As String) As Task(Of GetDatatableResponse) Try Dim oResponse = Await _Channel.ReturnDatatableAsync(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableFromConnectionAsync(pSQL As String, Optional pConnectionId As Integer = 0) As Task(Of GetDatatableResponse) Try Dim oResponse = Await _Channel.ReturnDatatableAsync(New GetDatatableRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function #End Region #Region "GetScalarValue" Public Function GetScalarValueFromIDB(pSQL As String) As GetScalarValueResponse Try Dim oResponse = _Channel.ReturnScalarValue(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetScalarValueFromECM(pSQL As String) As GetScalarValueResponse Try Dim oResponse = _Channel.ReturnScalarValue(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function GetScalarValueFromConnection(pSQL As String, pConnectionId As Integer) As GetScalarValueResponse Try Dim oResponse = _Channel.ReturnScalarValue(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetScalarValueFromIDBAsync(pSQL As String) As Task(Of GetScalarValueResponse) Try Dim oResponse = Await _Channel.ReturnScalarValueAsync(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetScalarValueFromECMAsync(pSQL As String) As Task(Of GetScalarValueResponse) Try Dim oResponse = Await _Channel.ReturnScalarValueAsync(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetScalarValueFromConnectionAsync(pSQL As String, pConnectionId As Integer) As Task(Of GetScalarValueResponse) Try Dim oResponse = Await _Channel.ReturnScalarValueAsync(New GetScalarValueRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function #End Region #Region "ExecuteNonQuery" Public Function ExecuteNonQueryFromIDB(pSQL As String) As ExecuteNonQueryResponse Try Dim oResponse = _Channel.ExecuteNonQuery(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function ExecuteNonQueryFromECM(pSQL As String) As ExecuteNonQueryResponse Try Dim oResponse = _Channel.ExecuteNonQuery(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Function ExecuteNonQueryFromConnection(pSQL As String, pConnectionId As Integer) As ExecuteNonQueryResponse Try Dim oResponse = _Channel.ExecuteNonQuery(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function ExecuteNonQueryFromIDBAsync(pSQL As String) As Task(Of ExecuteNonQueryResponse) Try Dim oResponse = Await _Channel.ExecuteNonQueryAsync(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.IDB }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function ExecuteNonQueryFromECMAsync(pSQL As String) As Task(Of ExecuteNonQueryResponse) Try Dim oResponse = Await _Channel.ExecuteNonQueryAsync(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.ECM }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function ExecuteNonQueryFromConnectionAsync(pSQL As String, pConnectionId As Integer) As Task(Of ExecuteNonQueryResponse) Try Dim oResponse = Await _Channel.ExecuteNonQueryAsync(New ExecuteNonQueryRequest() With { .SqlCommand = pSQL, .NamedDatabase = DatabaseName.None, .ConnectionId = pConnectionId }) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function #End Region Public Function GetDatatableByName(DatatableName As String, Optional FilterExpression As String = "", Optional SortByColumn As String = "") As TableResult Try Dim oResponse = _Channel.ReturnDatatableFromCache(DatatableName, FilterExpression, SortByColumn) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDatatableByNameAsync(DatatableName As String, Optional FilterExpression As String = "", Optional SortByColumn As String = "") As Task(Of TableResult) Try Dim oResponse = Await _Channel.ReturnDatatableFromCacheAsync(DatatableName, FilterExpression, SortByColumn) Return oResponse Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function ''' ''' Return infos about a file object ''' ''' ''' ''' Public Function GetDocumentInfo(UserId As Long, ObjectId As Long) As DocumentInfo Try Dim oResponse As DocumentInfoResponse = _Channel.GetFileInfoByObjectId(New DocumentInfoRequest With { .ObjectId = ObjectId, .UserId = UserId }) Return New DocumentInfo With { .AccessRight = oResponse.FileRight, .FullPath = oResponse.FullPath } Catch ex As FaultException(Of ObjectDoesNotExistFault) Logger.Error(ex) Throw ex Catch ex As FaultException Logger.Error(ex) Throw ex Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function Public Async Function GetDocumentInfoAsync(UserId As Long, ObjectId As Long) As Task(Of DocumentInfo) Try Dim oParams = New DocumentInfoRequest With { .ObjectId = ObjectId, .UserId = UserId } Dim oResponse As DocumentInfoResponse = Await _Channel.GetFileInfoByObjectIdAsync(oParams) Return New DocumentInfo With { .AccessRight = oResponse.FileRight, .FullPath = oResponse.FullPath } Catch ex As Exception Logger.Error(ex) Throw ex End Try End Function #Region "Private Functions" Private Function GetUserLanguage(pOverrideLanguage As String) As String Return ObjectEx.NotNull(pOverrideLanguage, Threading.Thread.CurrentThread.CurrentUICulture.Name) End Function Private Function GetUserName(pOverrideName) As String Return ObjectEx.NotNull(pOverrideName, Environment.UserName) End Function #End Region #Region "Response Classes" Public Class StreamedFile Public Stream As MemoryStream Public FileName As String End Class Public Class FileList Public Datatable As DataTable End Class Public Class DocumentInfo Public Id As Long Public FullPath As String Public AccessRight As AccessRight End Class Public Class VariableValue Public ReadOnly Property IsVector As Boolean = False Public Property Value As Object Public Property Type As Type Public Sub New() MyClass.New(Nothing) End Sub Public Sub New(pValue As Object) ' Check if value is a collection If TypeOf pValue Is IEnumerable Then IsVector = True End If ' Try to determine the type If IsNothing(pValue) Then Type = Nothing Else Type = pValue.GetType End If Value = pValue End Sub End Class #End Region Public Class ObjectAttribute Public Property Id As Long Public Property Title As String Public Property Type As String Public Property ValueBigInt As Long Public Property ValueText As String Public Property ValueDecimal As Decimal Public Property ValueDate As DateTime Public ReadOnly Property Value As Object Get Return GetValue() End Get End Property Private Function GetValue() As Object Select Case Type Case AttributeTypeName.VECTOR_INTEGER Return ValueBigInt Case AttributeTypeName.BIG_INTEGER Return ValueBigInt Case AttributeTypeName.VECTOR_STRING Return ValueText Case AttributeTypeName.VARCHAR Return ValueText Case AttributeTypeName.BIT Return IIf(ValueBigInt = 1, True, False) Case AttributeTypeName.DATE Return ValueDate Case AttributeTypeName.DATETIME Return ValueDate Case AttributeTypeName.DECIMAL Return ValueDecimal Case AttributeTypeName.FLOAT Return ValueDecimal Case Else Return Nothing End Select End Function End Class End Class