Verbesserung DocSearchLoad, Mapping Sharedrive Refactoring Zusatzsuchen, Dokumentenhandling & Cleanup Umfangreiches Refactoring der Zusatzsuchen-Logik (Validator/ValidatorSearch): Vereinheitlichung und Typprüfung der DataTables, zentrale Filterung, robustere Tab-Steuerung und thread-sicheres Nachladen. Netzlaufwerk-Mapping und Dokumentenpfad-Handling wurden entfernt bzw. auf neue Handler ausgelagert. Profilsuchen-Handling vereinheitlicht, Parametrierung (Working Mode) klarer strukturiert. Diverse Bugfixes, verbessertes Logging, Cleanup von Ressourcen und Projektdateien, veraltete Komponenten entfernt. Update auf DocumentViewer 2.6.0.0. Die Anwendung ist robuster, wartbarer und für Erweiterungen vorbereitet.
350 lines
16 KiB
VB.net
350 lines
16 KiB
VB.net
Public Class ClassIDBData
|
||
Public DTVWIDB_BE_ATTRIBUTE As DataTable
|
||
Public IDBSystemIndices As List(Of String)
|
||
''' <summary>
|
||
''' Wenn True, werden SQL-Statements nicht sofort ausgeführt,
|
||
''' sondern in <see cref="_sqlBatch"/> gesammelt.
|
||
''' </summary>
|
||
Public Property BatchMode As Boolean = False
|
||
Private _sqlBatch As New List(Of String)
|
||
|
||
''' <summary>
|
||
''' Startet den Batch-Sammelmodus.
|
||
''' </summary>
|
||
Public Sub BeginBatch()
|
||
_sqlBatch.Clear()
|
||
BatchMode = True
|
||
End Sub
|
||
''' <summary>
|
||
''' Führt alle gesammelten SQL-Statements als einen einzigen String
|
||
''' an ExecuteNonQueryIDB weiter. Jeder Block wird in BEGIN...END
|
||
''' gekapselt, damit DECLARE-Variablen nicht kollidieren.
|
||
''' </summary>
|
||
''' <returns>True wenn erfolgreich</returns>
|
||
Public Function CommitBatch() As Boolean
|
||
BatchMode = False
|
||
If _sqlBatch.Count = 0 Then Return True
|
||
Try
|
||
Dim oStatements = _sqlBatch.
|
||
Where(Function(s) Not String.IsNullOrWhiteSpace(s)).
|
||
ToList()
|
||
|
||
' @NEW_OBJ_MD_ID pro Statement eindeutig umbenennen → kein Namenskonflikt im Batch
|
||
Dim oNumberedStatements As New List(Of String)
|
||
Dim oIndex As Integer = 0
|
||
For Each oStatement As String In oStatements
|
||
Dim oNumbered = oStatement.Replace("@NEW_OBJ_MD_ID", $"@NEW_OBJ_MD_ID_{oIndex}")
|
||
oNumberedStatements.Add(oNumbered)
|
||
oIndex += 1
|
||
Next
|
||
|
||
Dim oBatchSQL = String.Join(vbNewLine, oNumberedStatements)
|
||
LOGGER.Debug($"⚡ CommitBatch - Executing {oStatements.Count} statements as one batch:{vbNewLine}{oBatchSQL}")
|
||
Dim oResult = DatabaseFallback.ExecuteNonQueryIDB(oBatchSQL)
|
||
_sqlBatch.Clear()
|
||
Return oResult
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
_sqlBatch.Clear()
|
||
Return False
|
||
End Try
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' Verwirft alle gesammelten Statements ohne Ausführung.
|
||
''' </summary>
|
||
Public Sub RollbackBatch()
|
||
_sqlBatch.Clear()
|
||
BatchMode = False
|
||
End Sub
|
||
|
||
''' <summary>
|
||
''' Führt ein SQL-Statement aus – sofort oder gesammelt je nach BatchMode.
|
||
''' </summary>
|
||
Private Function ExecuteOrQueue(oSQL As String) As Boolean
|
||
If BatchMode Then
|
||
_sqlBatch.Add(oSQL)
|
||
LOGGER.Debug($"BatchMode - Queued statement: {oSQL}")
|
||
Return True
|
||
Else
|
||
Return DatabaseFallback.ExecuteNonQueryIDB(oSQL)
|
||
End If
|
||
End Function
|
||
''' <summary>
|
||
''' Gets all indices by BusinessEntity.
|
||
''' </summary>
|
||
''' <param name="BusinessEntity">Title of Business Entity</param>
|
||
''' <returns>Array with all Indices</returns>
|
||
''' <remarks></remarks>
|
||
'''
|
||
Public Function Init() As Boolean
|
||
Dim oSQL = $"SELECT DISTINCT ATTR_TITLE, TYP_ID, TYP_ID as [TYPE_ID] FROM VWIDB_BE_ATTRIBUTE WHERE SYS_ATTRIBUTE = 0 ORDER BY ATTR_TITLE"
|
||
DTVWIDB_BE_ATTRIBUTE = DatabaseFallback.GetDatatableIDB(oSQL)
|
||
If IsNothing(DTVWIDB_BE_ATTRIBUTE) Then
|
||
oSQL = $"SELECT DISTINCT ATTR_TITLE, TYP_ID, TYP_ID as [TYPE_ID] FROM VWIDB_BE_ATTRIBUTE ORDER BY ATTR_TITLE "
|
||
DTVWIDB_BE_ATTRIBUTE = DatabaseFallback.GetDatatableIDB(oSQL)
|
||
End If
|
||
Return True
|
||
End Function
|
||
|
||
Public Function GetIndicesByBE(ByVal BusinessEntity As String) As String()
|
||
Try
|
||
Dim aNames(4) As String
|
||
aNames(0) = "ObjectID"
|
||
aNames(1) = "IDBCreatedWhen"
|
||
aNames(2) = "IDBCreatedWho"
|
||
aNames(3) = "IDBChangedWhen"
|
||
aNames(4) = "IDBChangedWho"
|
||
IDBSystemIndices = aNames.ToList
|
||
' Array für Indizes vorbereiten
|
||
Dim aIndexNames(DTVWIDB_BE_ATTRIBUTE.Rows.Count + 4) As String
|
||
Dim oCount As Integer = 0
|
||
aIndexNames(oCount) = "ObjectID"
|
||
oCount += 1
|
||
aIndexNames(oCount) = "IDBCreatedWhen"
|
||
oCount += 1
|
||
aIndexNames(oCount) = "IDBCreatedWho"
|
||
oCount += 1
|
||
aIndexNames(oCount) = "IDBChangedWhen"
|
||
oCount += 1
|
||
aIndexNames(oCount) = "IDBChangedWho"
|
||
For Each oRow As DataRow In DTVWIDB_BE_ATTRIBUTE.Rows
|
||
oCount += 1
|
||
aIndexNames(oCount) = oRow.Item("ATTR_TITLE")
|
||
|
||
Next
|
||
|
||
|
||
' Indexarray sortiert zurückgeben
|
||
Array.Sort(aIndexNames)
|
||
' Indexarray zurückgeben
|
||
Return aIndexNames
|
||
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
MsgBox(ex.Message, MsgBoxStyle.Critical, "Error getting the IDB Indicies")
|
||
Return Nothing
|
||
End Try
|
||
End Function
|
||
Public Function GetTypeOfIndex(ByVal indexname As String) As Integer
|
||
Try
|
||
For Each oRow As DataRow In DTVWIDB_BE_ATTRIBUTE.Rows
|
||
If oRow.Item("ATTR_TITLE") = indexname Then
|
||
Try
|
||
Dim oType = oRow.Item("TYP_ID")
|
||
Return oType
|
||
Catch ex As Exception
|
||
Try
|
||
Dim oType = oRow.Item("TYP_ID")
|
||
Return oType
|
||
Catch ex1 As Exception
|
||
LOGGER.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
|
||
End Try
|
||
|
||
End If
|
||
Next
|
||
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
|
||
End Function
|
||
Public Function GetVariableValue(oAttributeName As String, Optional oIDBTyp As Integer = 0, Optional FromIDB As Boolean = False) As Object
|
||
Try
|
||
' Bestimme, ob es sich um ein Single-Value-Attribut handelt (nicht Typ 8 oder 9)
|
||
Dim oIsSingleAttribute As Boolean = (oIDBTyp <> 8 AndAlso oIDBTyp <> 9)
|
||
|
||
LOGGER.Debug($"IDBData - GetVariableValue - Attribute: [{oAttributeName}] - IsSingleAttribute: [{oIsSingleAttribute}] - FromIDB: [{FromIDB}]")
|
||
|
||
' Schnellpfad: Direkt aus gecachter DataTable holen
|
||
If oIsSingleAttribute AndAlso IDB_DT_DOC_DATA.Rows.Count = 1 AndAlso Not FromIDB Then
|
||
Try
|
||
Dim oMappedName As String = MapSystemAttributeName(oAttributeName)
|
||
Dim oValue As Object = IDB_DT_DOC_DATA.Rows(0).Item(oMappedName)
|
||
LOGGER.Debug($"IDBData - GetVariableValue - Retrieved from cache: Attribute=[{oAttributeName}] MappedName=[{oMappedName}] Value=[{oValue}]")
|
||
Return oValue
|
||
Catch ex As Exception
|
||
LOGGER.Debug($"Error getting Attribute from IDB_DT_DOC_DATA: {ex.Message}")
|
||
' Fallthrough zum Datenbank-Fallback
|
||
End Try
|
||
End If
|
||
|
||
' Fallback: Wert aus Datenbank über Funktion holen
|
||
LOGGER.Debug($"Retrieving value for attribute [{oAttributeName}] via FNIDB_PM_GET_VARIABLE_VALUE")
|
||
|
||
Dim oSQL As String = $"SELECT * FROM [dbo].[FNIDB_PM_GET_VARIABLE_VALUE] ({CURRENT_DOC_ID},'{oAttributeName}','{USER_LANGUAGE}',CONVERT(BIT,'{IDB_USES_WMFILESTORE}'))"
|
||
LOGGER.Debug($"SQL: {oSQL}")
|
||
|
||
Dim oResultTable As DataTable = DatabaseFallback.GetDatatableIDB(oSQL)
|
||
|
||
If oResultTable IsNot Nothing AndAlso oResultTable.Rows.Count = 1 Then
|
||
Dim oValue As Object = oResultTable.Rows(0).Item(0)
|
||
LOGGER.Debug($"IDBData - GetVariableValue - Retrieved from DB: [{oValue}]")
|
||
Return oValue
|
||
Else
|
||
LOGGER.Info($"IDBData - GetVariableValue - No value found in DB for attribute [{oAttributeName}] - SQL [{oSQL}]")
|
||
End If
|
||
|
||
Return oResultTable
|
||
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
End Function
|
||
|
||
''' <summary>
|
||
''' Mappt System-Attributnamen auf interne Spaltennamen.
|
||
''' </summary>
|
||
Private Function MapSystemAttributeName(attributeName As String) As String
|
||
Select Case attributeName
|
||
Case "IDBCreatedWhen"
|
||
Return "ADDED_WHEN"
|
||
Case "IDBCreatedWho"
|
||
Return "ADDED_WHO"
|
||
Case "IDBChangedWhen"
|
||
Return "CHANGED_WHEN"
|
||
Case "IDBChangedWho"
|
||
Return "CHANGED_WHO"
|
||
Case Else
|
||
Return attributeName
|
||
End Select
|
||
End Function
|
||
Public Function Delete_Term_Object_From_Metadata(oAttributeName As String, oTerm2Delete As String) As Object
|
||
Try
|
||
Dim oID_IS_FOREIGN As Integer
|
||
oID_IS_FOREIGN = 0
|
||
If IDB_USES_WMFILESTORE Then
|
||
oID_IS_FOREIGN = 1
|
||
End If
|
||
oTerm2Delete = oTerm2Delete.Replace("'", "''")
|
||
Dim oDELSQL = $"EXEC PRIDB_DELETE_TERM_OBJECT_METADATA {CURRENT_DOC_ID},'{oAttributeName}','{oTerm2Delete}','{USER_USERNAME}','{USER_LANGUAGE}',{oID_IS_FOREIGN};"
|
||
LOGGER.Debug($"Delete_Term_Object_From_Metadata: {oDELSQL}")
|
||
'DatabaseFallback.ExecuteNonQueryIDB(oDELSQL)
|
||
Return ExecuteOrQueue(oDELSQL)
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
|
||
End Function
|
||
Public Function Delete_AttributeData(pIDB_OBJID As Int64, pAttributeName As String) As Object
|
||
Try
|
||
Dim oDELSQL = $"EXEC PRIDB_DELETE_ATTRIBUTE_DATA {pIDB_OBJID},'{pAttributeName}','{USER_USERNAME}';"
|
||
LOGGER.Debug($"Delete_Attribute_Data: {oDELSQL}")
|
||
' DatabaseFallback.ExecuteNonQueryIDB(oDELSQL)
|
||
Return ExecuteOrQueue(oDELSQL)
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
Return Nothing
|
||
End Try
|
||
|
||
End Function
|
||
|
||
Public Function SetVariableValue(oAttributeName As String, oNewValue As Object, Optional CheckDeleted As Boolean = False, Optional oIDBTyp As Integer = 0)
|
||
Try
|
||
Dim omsg = $"IDBData - SetVariableValue - Attribute: [{oAttributeName}] - NewValue: [{oNewValue}] - CheckDeleted: [{CheckDeleted.ToString}] - oIDBTyp: [{oIDBTyp}]"
|
||
LOGGER.Debug(omsg)
|
||
Dim omytype = oNewValue.GetType.ToString
|
||
If omytype = "System.Data.DataTable" Then
|
||
Dim oDTMyNewValues As DataTable = oNewValue
|
||
Dim oAttributeResultFromDB
|
||
Dim oTypeOldResult
|
||
' Für DataTable (Mehrfachauswahl/Vektor) IMMER auf gelöschte Werte prüfen,
|
||
' unabhängig vom übergebenen CheckDeleted-Parameter.
|
||
Dim oEffectiveCheckDeleted As Boolean = True
|
||
|
||
If oEffectiveCheckDeleted = True Then
|
||
oAttributeResultFromDB = GetVariableValue(oAttributeName, oIDBTyp)
|
||
oTypeOldResult = oAttributeResultFromDB.GetType.ToString
|
||
If TypeOf oAttributeResultFromDB Is DataTable Then
|
||
Dim myOldValues As DataTable = oAttributeResultFromDB
|
||
If myOldValues.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 oOldValueRow As DataRow In myOldValues.Rows
|
||
Dim oExists As Boolean = False
|
||
For Each oNewValueRow As DataRow In oDTMyNewValues.Rows
|
||
Dim oInfo1 = $"Checking oldValue[{oOldValueRow.Item(0)}] vs NewValue [{oNewValueRow.Item(1)}]"
|
||
If oNewValueRow.Item(1).ToString.ToUpper = oOldValueRow.Item(0).ToString.ToUpper Then
|
||
oExists = True
|
||
Exit For
|
||
End If
|
||
Next
|
||
|
||
If oExists = False Then
|
||
Dim oInfo = $"Value [{oOldValueRow.Item(0)}] no longer existing in Vector-Attribute [{oAttributeName}] - will be deleted!"
|
||
LOGGER.Debug(oInfo)
|
||
'SetVariableValue(CURRENT_PROFILE_LOG_INDEX, oInfo)
|
||
Delete_Term_Object_From_Metadata(oAttributeName, oOldValueRow.Item(0))
|
||
End If
|
||
|
||
Next
|
||
End If
|
||
Else
|
||
'### Old Value is a single value ###
|
||
If oDTMyNewValues.Rows.Count > 1 Then
|
||
'### there is more than one new value ###
|
||
Dim oExists As Boolean = False
|
||
For Each oNewValueRow As DataRow In oDTMyNewValues.Rows
|
||
LOGGER.Debug($"Checking oldValue[{oAttributeResultFromDB}] vs NewValue [{oNewValueRow.Item(1)}]")
|
||
If oNewValueRow.Item(1).ToString.ToUpper = oAttributeResultFromDB.ToString.ToUpper Then
|
||
oExists = True
|
||
Exit For ' ← sobald gefunden, abbrechen
|
||
End If
|
||
Next
|
||
If oExists = False Then
|
||
LOGGER.Debug($"Value [{oAttributeResultFromDB}] no longer existing in Attribute [{oAttributeName}] - will be deleted!")
|
||
'SetVariableValue(CURRENT_PROFILE_LOG_INDEX, oInfo2)
|
||
Delete_Term_Object_From_Metadata(oAttributeName, oAttributeResultFromDB)
|
||
End If
|
||
Else
|
||
'### there is only ONE new value ###
|
||
If oDTMyNewValues.Rows(0).Item(1) <> oAttributeResultFromDB Then
|
||
Dim oInfo = $"Value [{oAttributeResultFromDB}] of Attribute [{oAttributeName}] obviously was updated during runtime - will be deleted!"
|
||
LOGGER.Debug(oInfo)
|
||
SetVariableValue(CURRENT_PROFILE_LOG_INDEX, oInfo)
|
||
Delete_Term_Object_From_Metadata(oAttributeName, oAttributeResultFromDB)
|
||
Else
|
||
LOGGER.Debug($"Attributvalue of [{oAttributeName}] did not change!")
|
||
End If
|
||
|
||
End If
|
||
|
||
End If
|
||
|
||
End If
|
||
|
||
For Each oNewValueRow As DataRow In oDTMyNewValues.Rows
|
||
'Dim oSuccess As Boolean = False
|
||
Dim oVALUE = oNewValueRow.Item(1).ToString
|
||
oVALUE = oVALUE.Replace("'", "''")
|
||
Dim oPRSQL = $"DECLARE @NEW_OBJ_MD_ID BIGINT " & vbNewLine & $"EXEC PRIDB_NEW_OBJ_DATA {CURRENT_DOC_ID},'{oAttributeName}','{USER_USERNAME}','{oVALUE}','{USER_LANGUAGE}',0,@OMD_ID = @NEW_OBJ_MD_ID OUTPUT;"
|
||
LOGGER.Debug(oPRSQL)
|
||
'oSuccess = DatabaseFallback.ExecuteNonQueryIDB(oPRSQL)
|
||
If Not ExecuteOrQueue(oPRSQL) Then Return False
|
||
'If oSuccess = False Then
|
||
' Return False
|
||
'End If
|
||
Next
|
||
Return True
|
||
Else
|
||
'oNewValue = oNewValue.Replace("'", "' + NCHAR(39) + '")
|
||
oNewValue = oNewValue.Replace("'", "''")
|
||
Dim oPRIDB_NEW_OBJ_DATA = $"DECLARE @NEW_OBJ_MD_ID BIGINT " & vbNewLine & $"EXEC PRIDB_NEW_OBJ_DATA {CURRENT_DOC_ID},'{oAttributeName}','{USER_USERNAME}','{oNewValue}','{USER_LANGUAGE}',0,@OMD_ID = @NEW_OBJ_MD_ID OUTPUT;"
|
||
LOGGER.Debug(oPRIDB_NEW_OBJ_DATA)
|
||
' Return DatabaseFallback.ExecuteNonQueryIDB(oPRIDB_NEW_OBJ_DATA)
|
||
Return ExecuteOrQueue(oPRIDB_NEW_OBJ_DATA)
|
||
End If
|
||
|
||
Catch ex As Exception
|
||
LOGGER.Error(ex)
|
||
Return False
|
||
End Try
|
||
End Function
|
||
End Class
|