Imports System.Text.RegularExpressions
Imports Oracle.ManagedDataAccess.Client

Public Class frmSQLEditor
    Dim CurrentPosition As Integer = 0
    Dim CurrentPlaceholders As New Placeholders()
    Dim CurrentTableType As String

    Dim AtPlaceholderPattern As String = "@[A-Za-z_]+"

    Public Class Placeholders
        Public Property RecordId As Integer
        Public Property ParentRecordId As Integer
        Public Property FormId As Integer
    End Class

    Public Property Value() As String
        Get
            Return txtValue.Text
        End Get
        Set(value As String)
            txtValue.Text = value
        End Set
    End Property

    Private Sub frmSQLEditor_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Load_Connections()

        cmbPlaceholder.SelectedIndex = 0


    End Sub

    Private Sub Load_Connections()
        Try
            'TODO: Diese Codezeile lädt Daten in die Tabelle "DD_DMSDataSet.TBDD_CONNECTION". Sie können sie bei Bedarf verschieben oder entfernen.
            Me.TBDD_CONNECTIONTableAdapter.Connection.ConnectionString = MyConnectionString
            Me.TBDD_CONNECTIONTableAdapter.Fill(Me.DD_DMSDataSet.TBDD_CONNECTION)
        Catch ex As Exception
            ClassLogger.Add(" - Unexpected Error in Load Connections - errpor: " & vbNewLine & ex.Message)
            MsgBox("Unexpected Error in Load Connections: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
       
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim frm As New frmConnections()
        frm.Show()
    End Sub

    Private Sub txtValue_TextChanged(sender As Object, e As EventArgs) Handles txtValue.TextChanged, txtValue.Click
        CurrentPosition = txtValue.SelectionStart

        If txtValue.Text.Trim().Count = 0 Then
            dgvPlaceholders.Enabled = False
        Else
            dgvPlaceholders.Enabled = True
        End If

        CheckForPlaceholders()
    End Sub

    Private Sub CheckForPlaceholders()
        Dim count As Integer = 0
        Dim text As String = Me.Value
        Dim atPlaceholderRegex = New Regex(AtPlaceholderPattern, RegexOptions.IgnoreCase)
        Dim matches As MatchCollection = atPlaceholderRegex.Matches(text)

        dgvPlaceholders.Rows.Clear()

        For Each match As Match In matches
            dgvPlaceholders.Rows.Add({match.Value, ""})
        Next
    End Sub

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles btnAddPlaceholder.Click
        If Not cmbPlaceholder.Text = String.Empty Then
            Dim placeholder As String = cmbPlaceholder.Text
            txtValue.Text = txtValue.Text.Insert(CurrentPosition, placeholder)
        End If
    End Sub

    Private Sub btnRefreshConnections_Click(sender As Object, e As EventArgs) Handles btnRefreshConnections.Click
        Load_Connections()
    End Sub

    Private Sub btnTestSQL_Click(sender As Object, e As EventArgs) Handles btnTestSQL.Click
        Dim query As String = txtValue.Text

        For Each row As DataGridViewRow In dgvPlaceholders.Rows
            Dim placeholder As String = row.Cells(0).Value
            Dim replacement As String = row.Cells(1).Value

            ' Wenn Ersetzung ausgefüllt wurde, Platzhalter damit ersetzen
            If Not String.IsNullOrEmpty(replacement) Then
                query = query.Replace(placeholder, replacement)
            Else
                MsgBox("Bitte geben Sie für den Platzhalter " & placeholder & " einen Wert an!", MsgBoxStyle.Exclamation, "Fehlende Platzhalter Ersetzung")
                Exit Sub
            End If
        Next

        Dim ds As DataSet = ExecuteWithConnection(cmbConnection.SelectedValue, query)

        If ds IsNot Nothing Then
            dgvResult.DataSource = ds.Tables(0)
        End If


    End Sub

    Private Function ExecuteWithConnection(connectionId As Integer, sql As String) As DataSet
        Try

            Dim connectionString As String

            connectionString = ClassDatabase.GetConnectionString(connectionId)

            If connectionString <> "" Then

                If connectionString.StartsWith("Server=") And connectionString.Contains("Database=") Then
                    Dim sqlConnection As SqlClient.SqlConnection
                    Dim sqlCommand As SqlClient.SqlCommand
                    Dim sqlAdapter As New SqlClient.SqlDataAdapter
                    Dim dataset As New DataSet

                    sqlConnection = New SqlClient.SqlConnection(connectionString)
                    sqlConnection.Open()

                    sqlCommand = New SqlClient.SqlCommand(sql, sqlConnection)

                    sqlAdapter.SelectCommand = sqlCommand
                    sqlAdapter.Fill(dataset)

                    Return dataset
                ElseIf connectionString.Contains("dsn=") Then 'ODBC-Connection
                    Dim sqlConnection As Odbc.OdbcConnection
                    Dim sqlCommand As Odbc.OdbcCommand
                    Dim sqlAdapter As New Odbc.OdbcDataAdapter
                    Dim dataset As New DataSet

                    sqlConnection = New Odbc.OdbcConnection(connectionString)
                    sqlConnection.Open()

                    sqlCommand = New Odbc.OdbcCommand(sql, sqlConnection)

                    sqlAdapter.SelectCommand = sqlCommand
                    sqlAdapter.Fill(dataset)

                    Return dataset
                Else

                    If LogErrorsOnly = True Then ClassLogger.Add(" >> It's an Oracle-Connection (ExecuteWithConnection)", False)
                    Dim sqlConnection As OracleConnection
                    Dim sqlCommand As OracleCommand
                    Dim sqlAdapter As New OracleDataAdapter
                    Dim dataset As New DataSet

                    sqlConnection = New OracleConnection(connectionString)
                    sqlConnection.Open()

                    sqlCommand = New OracleCommand(sql, sqlConnection)

                    sqlAdapter.SelectCommand = sqlCommand
                    sqlAdapter.Fill(dataset)

                    Return dataset
                End If
            Else
                MsgBox("Keine gültige ConnectionID", MsgBoxStyle.Exclamation)
            End If

        Catch ex As Exception
            ClassLogger.Add(" - Unvorhergesehener Fehler bei TestSQL - Fehler: " & vbNewLine & ex.Message)
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Fehler bei TestSQL:")
            Return Nothing
        End Try
    End Function
  

    Private Sub EnableColumns(Optional enabled = True)
        cmbSelectColumns.Enabled = enabled
        cmbWhereColumns.Enabled = enabled
    End Sub

    Private Sub EnableTables()
        cmbFromTables.Enabled = True
    End Sub

    Private Sub radioTable_CheckedChanged(sender As Object, e As EventArgs) Handles radioTable.CheckedChanged
        CurrentTableType = "TABLE"
        EnableTables()
    End Sub

    Private Sub radioView_CheckedChanged(sender As Object, e As EventArgs) Handles radioView.CheckedChanged
        CurrentTableType = "VIEW"
        EnableTables()
    End Sub

    Private Sub GetColumns(tableName As String, ByRef combobox As ComboBox)
        Try
            Dim CS As String
            CS = ClassDatabase.GetConnectionString(cmbConnection.SelectedValue)
            Dim typeCS As String = ClassDatabase.Execute_Scalar("SELECT SQL_PROVIDER FROM TBDD_CONNECTION WHERE GUID = " & cmbConnection.SelectedValue, True)
            Dim SQL As String
            Dim DT As DataTable
            If typeCS.ToUpper = "Oracle".ToUpper Then
                SQL = "select COLUMN_NAME from USER_TAB_COLS where TABLE_NAME='" & tableName & "' order by COLUMN_NAME"
                DT = ClassDatabase.Oracle_Return_Datatable(SQL, CS, True)
            Else
                SQL = "SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('" & tableName & "') ORDER BY name"
                DT = ClassDatabase.Return_Datatable_CS(SQL, CS, True)
            End If

            If DT IsNot Nothing Then
                combobox.Items.Clear()
                For Each row As DataRow In DT.Rows
                    combobox.Items.Add(row.Item(0))
                Next
            End If
        Catch ex As Exception
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Error in GetColumns:")
        End Try
    End Sub

    Private Sub GetColumns(tableName As String, ByRef combobox As DevExpress.XtraEditors.CheckedComboBoxEdit)
        Dim SQL As String = "SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('" & tableName & "') ORDER BY name"
        Dim ds As DataSet = ExecuteWithConnection(cmbConnection.SelectedValue, SQL)

        If ds IsNot Nothing Then
            combobox.Properties.Items.Clear()

            For Each row As DataRow In ds.Tables(0).Rows
                combobox.Properties.Items.Add(row.Item(0))
            Next
        End If
    End Sub


    Private Sub cmbTables_DropDown(sender As Object, e As EventArgs) Handles cmbFromTables.DropDown
        Dim type As String

        If CurrentTableType = "TABLE" Then
            type = "'BASE TABLE'"
        ElseIf CurrentTableType = "VIEW" Then
            type = "'VIEW'"
        End If

        Dim SQL As String = "SELECT TABLE_NAME from information_schema.tables where TABLE_TYPE = " & type & " ORDER BY TABLE_NAME"
        Dim ds As DataSet = ExecuteWithConnection(cmbConnection.SelectedValue, SQL)

        If ds IsNot Nothing Then
            cmbFromTables.Items.Clear()

            For Each row As DataRow In ds.Tables(0).Rows
                cmbFromTables.Items.Add(row.Item(0))
            Next
        End If
    End Sub

    Private Sub cmbColumns_DropDown(sender As Object, e As EventArgs) Handles cmbSelectColumns.DropDown
        Dim table = cmbFromTables.Text
        GetColumns(table, cmbSelectColumns)
    End Sub

    Private Sub cmbWhereColumns_DropDown(sender As Object, e As EventArgs) Handles cmbWhereColumns.DropDown
        Dim table = cmbFromTables.Text
        GetColumns(table, cmbWhereColumns)
    End Sub

    Private Sub cmbFromTables_SelectedIndexChanged() Handles cmbFromTables.SelectedIndexChanged
        If cmbFromTables.Text <> "" Then
            EnableColumns()
        Else
            EnableColumns(False)
        End If
    End Sub

    Private Sub queryBuilder_Changed(sender As Object, e As EventArgs) Handles cmbSelectColumns.SelectedIndexChanged, cmbFromTables.SelectedIndexChanged, cmbWhereColumns.SelectedIndexChanged, cmbWhereOperator.SelectedIndexChanged, txtCondition.TextChanged
        Dim sql = ""
        Dim column, table, column2, op, condition As String
        Dim isNumberRegex = New Regex("^\d+$")

        column = cmbSelectColumns.Text
        table = cmbFromTables.Text
        column2 = cmbWhereColumns.Text
        op = cmbWhereOperator.Text
        condition = txtCondition.Text


        If column <> "" And table <> "" Then

            sql = String.Format("SELECT [{0}] FROM [{1}]", column, table)

            If column2 <> "" And op <> "" And condition <> "" Then

                If isNumberRegex.Match(condition).Success = False Then
                    condition = String.Format("'{0}'", condition)
                End If

                sql &= String.Format(" WHERE [{0}] {1} {2}", column2, op, condition)

            End If

        End If

        txtValue.Text = sql

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Try
            Dim sql_comamnd As String = txtValue.Text
            If txtValue.Text.Contains("'") Then
                sql_comamnd = txtValue.Text.Replace("'", "''")
            End If
            Dim upd As String = "UPDATE TBPMO_CONTROL SET SQL_COMMAND_1 = '" & sql_comamnd & "', CONNECTION_ID_1 = " & cmbConnection.SelectedValue & ", CHANGED_WHO = '" & Environment.UserName & "' WHERE GUID = " & CURRENT_CONTROL_ID
            If ClassDatabase.Execute_non_Query(upd, True) Then
                MsgBox("SQL-Befehl erfolgreich gespeichert!", MsgBoxStyle.Exclamation)
            End If
        Catch ex As Exception
            ClassLogger.Add(" - Unexpected Error in Save SQL-Command for control - error: " & vbNewLine & ex.Message)
            MsgBox("Unexpected Error in Save SQL-Command for control - error: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub

    Private Sub frmSQLEditor_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        Try
            Dim connsql = "SELECT BEZEICHNUNG FROM TBDD_CONNECTION WHERE GUID = (SELECT CONNECTION_ID_1 FROM TBPMO_CONTROL WHERE GUID = " & CURRENT_CONTROL_ID & ")"
            Dim con_name = ClassDatabase.Execute_Scalar(connsql, True)

            If IsDBNull(con_name) Then
                If Me.DD_DMSDataSet.TBDD_CONNECTION.Rows.Count > 0 Then
                    cmbConnection.SelectedIndex = 0
                End If
            Else
                If IsNothing(con_name) Then
                    If Me.DD_DMSDataSet.TBDD_CONNECTION.Rows.Count > 0 Then
                        cmbConnection.SelectedIndex = 0
                    End If
                Else
                    cmbConnection.SelectedIndex = cmbConnection.FindStringExact(con_name)
                End If

            End If
        Catch ex As Exception
            ClassLogger.Add(" - Unexpected Error in Get Connection for Control - error: " & vbNewLine & ex.Message)
            MsgBox("Unexpected Error in Get Connection for Control - error: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
End Class