diff --git a/Modules.EDMIAPI/Client.vb b/Modules.EDMIAPI/Client.vb index 3560ee7e..e05bdac4 100644 --- a/Modules.EDMIAPI/Client.vb +++ b/Modules.EDMIAPI/Client.vb @@ -18,43 +18,12 @@ Public Class Client Private _dummy_table_attributes As DataTable Private _channel As IEDMIServiceChannel - 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 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(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 + ''' + ''' Parse a IPAddress:Port String into its parts + ''' + ''' + ''' Public Shared Function ParseServiceAddress(AddressWithOptionalPort As String) As Tuple(Of String, Integer) Dim oSplit() As String = AddressWithOptionalPort.Split(":"c) Dim oAppServerAddress As String = oSplit(0) @@ -131,10 +100,6 @@ Public Class Client End Try End Function - Private Function PreloadAttributes() - - End Function - ''' ''' TODO: Creates a new object ''' @@ -143,23 +108,7 @@ Public Class Client Throw New NotImplementedException() End Function - ''' - ''' Import options for NewFileAsync. - ''' - Public Class NewFileOptions - ''' - ''' Option to keep the original extension when importing. Defaults to false. - ''' - Public KeepExtension As Boolean = False - ''' - ''' Windows username of the user responsible for the import. Defaults to the currently logged in user. - ''' - Public Username As String = Environment.UserName - ''' - ''' Date when the file was imported. Can be in the past. Defaults to now. - ''' - Public DateImported As Date = Date.Now - End Class + ''' ''' Imports a file from a filepath, creating a IDB ObjectId and Filesystem Object @@ -236,30 +185,27 @@ Public Class Client End Try End Function - Public Class SetVariableValueOptions - Public CheckDeleted As Boolean = False - Public Username As String = String.Empty - Public Language As String = String.Empty - End Class - ''' ''' Sets a value to an attribute ''' ''' IDB ObjectId ''' Name of the attribute - ''' The type of Attribute ''' ''' ''' - Public Function SetVariableValue(pObjectId As Long, pAttributeName As String, pAttributeType As AttributeType, pValue As Object, Optional pOptions As SetVariableValueOptions = Nothing) As Boolean + Public Function SetVariableValue(pObjectId As Long, pAttributeName As String, pValue As Object, Optional pOptions As SetVariableValueOptions = Nothing) As Boolean Try ' Set default options If pOptions Is Nothing Then pOptions = New SetVariableValueOptions() End If - Dim oLanguage = NotNull(pOptions.Language, GetUserLanguage()) - Dim oUsername = NotNull(pOptions.Username, Environment.UserName) + Dim oLanguage = GetUserLanguage(pOptions.UserLanguage) + Dim oUsername = GetUserName(pOptions.UserName) + Dim oOptions As New GetVariableValueOptions With { + .UserLanguage = oLanguage, + .UserName = oUsername + } Try Dim oResponse = _channel.TestObjectIdExists(New TestObjectIdExistsRequest With {.ObjectId = pObjectId}) @@ -272,96 +218,85 @@ Public Class Client Return False End Try - ' TODO: Check if Attribute exists - Dim oType = pValue.GetType.Name If oType = GetType(DataTable).Name Then Dim oValueTable As DataTable = pValue Dim oCurrentValue As VariableValue - If pOptions.CheckDeleted = True Then - Dim oOptions As New GetVariableValueOptions With { - .Language = oLanguage, - .Username = oUsername - } + ' Get current value + oCurrentValue = GetVariableValue(pObjectId, pAttributeName, oOptions) - ' Get current value - oCurrentValue = GetVariableValue(pObjectId, pAttributeName, pAttributeType, oOptions) + ' If current value is datatable + If oCurrentValue.Type = GetType(DataTable) Then - ' If current value is datatable - If oCurrentValue.Type = GetType(DataTable) Then + ' Convert value to Datatable + Dim oTable As DataTable = oCurrentValue.Value - ' Convert value to Datatable - Dim oTable As DataTable = oCurrentValue.Value + If oTable.Rows.Count > 1 Then - 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 - Dim oInfo = $"Checking oldValue[{oRow.Item(0)}] 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 + 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 = oCurrentValue.ToString.ToUpper Then + 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 [{oCurrentValue}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") - DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) + _logger.Debug($"Value [{oRow.Item(0)}] no longer existing in Vector-Attribute [{pAttributeName}] - will be deleted!") + DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oRow.Item(0)) End If - Else - _logger.Debug($"Value [{oCurrentValue}] of Attribute [{pAttributeName}] obviously was updated during runtime - will be deleted!") - DeleteTermObjectFromMetadata(pObjectId, pAttributeName, oCurrentValue.Value) + 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 oSuccess As Boolean = False - Dim oSQL = $"DECLARE @NEW_OBJ_MD_ID BIGINT - EXEC PRIDB_NEW_OBJ_DATA({pObjectId}, '{pAttributeName}', '{oUsername}', '{oNewValueRow.Item(1)}', '{oLanguage}', 0, @OMD_ID = @NEW_OBJ_MD_ID OUTPUT)" + Dim oResult As Boolean = NewObjectData(pObjectId, pAttributeName, pValue, New NewObjectOptions With { + .UserLanguage = oLanguage, + .UserName = oUsername + }) - Dim oResult = _channel.ExecuteNonQuery_MSSQL_IDB(oSQL) - - If Not oResult.OK Then + If oResult = False Then Return False End If Next Return True Else - 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) - - Return oResult.OK + Return NewObjectData(pObjectId, pAttributeName, pValue, New NewObjectOptions With { + .UserLanguage = oLanguage, + .UserName = oUsername + }) End If Catch ex As Exception @@ -370,112 +305,60 @@ Public Class Client End Try End Function - Public Class GetVariableValueOptions - Public Username As String = String.Empty - Public Language As String = String.Empty - End Class - - Public Function GetVariableValue(pObjectId As Long, pAttributeName As String, pAttributeType As AttributeType, Optional pOptions As GetVariableValueOptions = Nothing) As VariableValue + ''' + ''' + ''' + ''' + ''' + ''' + ''' + Public Function GetVariableValue(pObjectId As Long, pAttributeName As String, Optional pOptions As GetVariableValueOptions = Nothing) As VariableValue If pOptions Is Nothing Then pOptions = New GetVariableValueOptions() End If - pOptions.Language = NotNull(pOptions.Language, GetUserLanguage()) - pOptions.Username = NotNull(pOptions.Username, Environment.UserName) + pOptions.UserLanguage = GetUserLanguage(pOptions.UserLanguage) + pOptions.UserName = GetUserName(pOptions.UserName) ' Check if ObjectId exists Try Dim oResponse = _channel.TestObjectIdExists(New TestObjectIdExistsRequest With {.ObjectId = pObjectId}) If oResponse.Exists = False Then - Return Nothing + Return New VariableValue() + End If Catch ex As Exception _logger.Error(ex) - Return Nothing + Return New VariableValue() + End Try - ' Get Attributes and Values from Database - Dim oAttributes As DataTable = GetAttributesForObject(pObjectId, pOptions.Language) - - ' TODO: Check if Attribute exists & REfactor Try - Dim oVectorAttribute As Boolean = False - Select Case pAttributeType - Case AttributeType.VectorInteger - oVectorAttribute = True - Case AttributeType.VectorString - oVectorAttribute = True - Case Else - oVectorAttribute = False - End Select - - Dim oValues As New List(Of Object) - Dim oRows As List(Of DataRow) = oAttributes.AsEnumerable(). - Where(Function(pRow As DataRow) pRow.Item("AttributeTitle") = pAttributeName). + ' Get Attributes and Values from Database + Dim oAttributes As List(Of ObjectAttribute) = GetAttributesForObject(pObjectId, pOptions.UserLanguage) + Dim oValues = oAttributes.AsEnumerable(). + Where(Function(pAttr) + Return pAttr.Title.ToUpper = pAttributeName.ToUpper + End Function). + Select(Function(pAttr) pAttr.Value). ToList() - 'If Not IsNothing(oAttributes) Then - ' If oVectorAttribute = True And _dummy_table_attributes.Rows.Count = 1 And pOptions.FromIDB = False Then - ' Try - ' If pAttributeName = "IDBCreatedWhen" Then - ' pAttributeName = "ADDED_WHEN" - ' ElseIf pAttributeName = "IDBCreatedWho" Then - ' pAttributeName = "ADDED_WHO" - ' ElseIf pAttributeName = "IDBChangedWhen" Then - ' pAttributeName = "CHANGED_WHEN" - ' ElseIf pAttributeName = "IDBChangedWho" Then - ' pAttributeName = "CHANGED_WHO" - ' End If - - ' oAttributeValue = _dummy_table_attributes.Rows(0).Item(pAttributeName) - ' Catch ex As Exception - ' _logger.Debug($"Error getting Attribute from IDB_DT_DOC_DATA: {ex.Message}") - ' End Try - - ' End If - 'Else - ' Throw New ApplicationException($"Could not get Attributes for ObjectId [{pObjectId}]") - 'End If - - 'TODO: BRAUCHEN SIE DAS ÜBERHAUPT??????11111?!!1!1 - 'If Not IsNothing(oAttributeValue) Then - ' Return oAttributeValue - 'Else - ' _logger.Debug($"oAttributeValue for Attribute [{pAttributeName}] is so far nothing..Now trying FNIDB_PM_GET_VARIABLE_VALUE ") - 'End If - 'Dim oFNSQL = $"SELECT * FROM [dbo].[FNIDB_PM_GET_VARIABLE_VALUE] ({pObjectId},'{pAttributeName}','{pOptions.Language}',CONVERT(BIT,'0'))" - 'Dim oDatatable As TableResult = _channel.ReturnDatatable_MSSQL_IDB(oFNSQL) - - 'If oDatatable.OK = False Then - ' Throw New ApplicationException(oDatatable.ErrorMessage) - 'End If - - 'If oDatatable.Table.Rows.Count = 1 Then - ' oAttributeValue = oDatatable.Table.Rows.Item(0).Item(0) - 'End If - - If oVectorAttribute = False Then - Dim oRow As DataRow = oRows.FirstOrDefault() - Dim oType As String = oRow.Item("AttributeType") - - Dim oValue = GetValueByType(oRow, oType) - 'oValues.Add(oValue) - - Return New VariableValue(oValue) - Else - For Each oRow As DataRow In oRows - Dim oType As String = oRow.Item("AttributeType") - - Dim oValue = GetValueByType(oRow, oType) - oValues.Add(oValue) - Next - + ' Either return a list or a single value or nothing, always wrapped in VariableValue + If oValues.Count > 1 Then Return New VariableValue(oValues) + + ElseIf oValues.Count = 1 Then + Return New VariableValue(oValues.First()) + + Else + Return New VariableValue() + End If + Catch ex As Exception _logger.Error(ex) - Return Nothing + Return New VariableValue() End Try End Function @@ -525,11 +408,62 @@ Public Class Client End Try End Function - Private Function GetAttributesForObject(pObjectId As Long, pLanguage As String) As DataTable - Dim oTable As DataTable + Private 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 + + 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}')") + 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) @@ -539,24 +473,61 @@ Public Class Client Return Nothing End If - oTable = oResult.Table + 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 = NotNull(oRow.Item("ValueBigInt"), Nothing), + .ValueDate = NotNull(oRow.Item("ValueDate"), Nothing), + .ValueDecimal = NotNull(oRow.Item("ValueDecimal"), Nothing), + .ValueText = NotNull(oRow.Item("ValueText"), Nothing) + } - Return oTable + 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 NewObjectOptions) + If pOptions Is Nothing Then + pOptions = New NewObjectOptions() + End If + + Dim oLanguage = GetUserLanguage(pOptions.UserLanguage) + 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 = NotNull(pLanguage, GetUserLanguage()) - Dim oUsername = NotNull(pUsername, Environment.UserName) + 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) @@ -574,7 +545,6 @@ Public Class Client End Try End Function - Public Async Function GetDatatableFromIDBAsync(SQL As String) As Task(Of TableResult) Try Dim oResponse = Await _channel.ReturnDatatable_MSSQL_IDBAsync(SQL) @@ -699,8 +669,93 @@ Public Class Client End Try End Function - Private Function GetUserLanguage() As String - Return Threading.Thread.CurrentThread.CurrentUICulture.Name + Private Function GetUserLanguage(pOverrideLanguage As String) As String + Return NotNull(pOverrideLanguage, Threading.Thread.CurrentThread.CurrentUICulture.Name) End Function + Private Function GetUserName(pOverrideName) As String + Return NotNull(pOverrideName, Environment.UserName) + End Function + + +#Region "Option & Parameter Classes" + ''' + ''' Import options for NewFileAsync. + ''' + Public Class NewFileOptions + ''' + ''' Option to keep the original extension when importing. Defaults to false. + ''' + Public KeepExtension As Boolean = False + ''' + ''' Windows username of the user responsible for the import. Defaults to the currently logged in user. + ''' + Public Username As String = Environment.UserName + ''' + ''' Date when the file was imported. Can be in the past. Defaults to now. + ''' + Public DateImported As Date = Date.Now + End Class + + Public Class NewObjectOptions + Public UserName As String + Public UserLanguage As String + End Class + + Public Class VariableValueOptions + Public UserName As String + Public UserLanguage As String + End Class + + Public Class GetVariableValueOptions + Inherits VariableValueOptions + End Class + + Public Class SetVariableValueOptions + Inherits VariableValueOptions + End Class +#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 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 End Class