Option Explicit On

Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Language.Utils
Imports DigitalData.Modules.Logging

Imports Quartz

Public Class DatatableJob
    Implements IJob

    Private Const COMMAND_SQL_TIMEOUT = 240

    Private _MSSQL As MSSQLServer

    Public Function Execute(context As IJobExecutionContext) As Task Implements IJob.Execute
        Dim oJobData = context.MergedJobDataMap
        Dim oLogConfig As LogConfig = oJobData.Item("LogConfig")
        Dim oCronJobId As Integer = oJobData.Item("CronJobId")
        Dim oCronJobTitle As String = oJobData.Item("CronJobTitle")
        Dim oLogger As Logger = oLogConfig.GetLogger()

        Dim oStopWatch As New Stopwatch()
        Dim oResult As New JobResult()

        oLogger.Info("Running Datatable Job [{0}]/[{1}]", context.JobDetail.Key, oCronJobTitle)

        Try
            Dim oMSSQL As MSSQLServer = oJobData.Item("MSSQL")
            Dim oCronSQL As String = $"SELECT * FROM TBAPPSERV_CRON_DETAIL WHERE CRON_ID = {oCronJobId}"
            Dim oCronDetails As DataTable = oMSSQL.GetDatatable(oCronSQL)

            For Each oRow As DataRow In oCronDetails.Rows
                Dim oDatatableName As String = NotNull(oRow.Item("DT_NAME"), String.Empty)
                Dim oParentColumn As String = NotNull(oRow.Item("DT_COLUMN"), String.Empty)
                Dim oChildColumn As String = NotNull(oRow.Item("CHILD_DT_COLUMN"), String.Empty)
                Dim oConnectionId As Integer = NotNull(oRow.Item("CON_ID"), String.Empty)
                Dim oTitle As String = NotNull(oRow.Item("TITLE"), String.Empty)
                Dim oSQL As String = NotNull(oRow.Item("COMMAND"), String.Empty)
                Dim oIndexColumns As String = NotNull(oRow.Item("INDEX_COLUMNS"), String.Empty)

                Try
                    oLogger.Debug("Running Command-Job [{0}]", oTitle)
                    oLogger.Debug("Datatable Name: {0}", oDatatableName)
                    oLogger.Debug("Connection Id: {0}", oConnectionId)

                    oStopWatch.Start()

                    Dim oConnectionString = oMSSQL.Get_ConnectionStringforID(oConnectionId)
                    Dim oDecryptedConnectionString = MSSQLServer.DecryptConnectionString(oConnectionString)

                    Dim oTable = oMSSQL.GetDatatableWithConnection(oSQL, oDecryptedConnectionString, COMMAND_SQL_TIMEOUT)
                    oTable.TableName = oDatatableName

                    oStopWatch.Stop()
                    oLogger.Debug("[Time] Getting Data From DB: {0}ms", oStopWatch.ElapsedMilliseconds)
                    oStopWatch.Restart()

                    Dim oView As DataView = Nothing

                    ' This creates an Index for the columns specified in INDEX_COLUMNS to speed up calls to 'Table.Select'!
                    If oIndexColumns <> String.Empty Then
                        oLogger.Debug("Adding indexes for Table: [{0}]", oIndexColumns)
                        oView = New DataView(oTable) With {
                            .Sort = oIndexColumns
                        }
                    End If

                    oStopWatch.Stop()
                    oLogger.Debug("[Time] Creating Indexes: {0}ms", oStopWatch.ElapsedMilliseconds)
                    oStopWatch.Restart()

                    oLogger.Debug("Result Datatable [{0}] contains [{1}] rows", oTable.TableName, oTable.Rows.Count)

                    Dim oResultTable = New JobResult.ResultTable() With {
                        .Table = oTable,
                        .View = oView,
                        .DetailRow = oRow
                    }

                    Dim oChildTableNAme As String = NotNull(oRow.Item("CHILD_DT_NAME"), String.Empty)

                    If oChildTableNAme <> String.Empty Then
                        oLogger.Debug("Child Datatable [{0}] defined, Relation: Parent [{1}] -> Child [{2}]", oChildTableNAme, oParentColumn, oChildColumn)

                        Dim oChildTable As DataTable = oMSSQL.GetDatatableWithConnection($"SELECT * FROM {oChildTableNAme}", oConnectionString)
                        oChildTable.TableName = oChildTableNAme
                        oLogger.Debug("Child Datatable [{0}] contains [{1}] rows", oChildTable.TableName, oChildTable.Rows.Count)

                        oResultTable.ChildTable = oChildTable
                        oResultTable.ChildRelationColumn = oChildColumn
                        oResultTable.TableRelationColumn = oParentColumn
                    End If

                    oStopWatch.Stop()
                    oLogger.Debug("[Time] Adding Relations: {0}ms", oStopWatch.ElapsedMilliseconds)

                    oLogger.Info("Fetched Datatable [{0}]", oDatatableName)
                    oResult.Tables.Add(oResultTable)
                Catch ex As Exception
                    oLogger.Warn("Execute: Error while saving Table: [{0}]", oDatatableName)
                    oLogger.Error(ex)
                End Try
            Next

            oLogger.Info("Fetched [{0}] Datatables", oResult.Tables.Count)

            '  Das Ergebnis speichern
            context.Result = oResult

        Catch ex As Exception
            oLogger.Error(ex)
            oLogger.Warn("Execute: Unhandled exception while executing SQL for Datatable {0}", oCronJobTitle)
        End Try

        Return Task.FromResult(True)
    End Function
End Class
