Imports Renci.SshNet
Imports MySql.Data.MySqlClient
Imports System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel
Imports System.Data.SqlTypes
Imports Renci.SshNet.Common

Module SSHModule
    '' SSH 접속 정보
    Private sshHost As String = "139.150.76.217"
    Private sshUserName As String = "5phbgsdualsonic"
    Private sshUserPw As String = "vl4p9iz5"
    Private sshPort As Byte = 22

    ''MySQL 접속 정보
    Private sqlHost As String = "10.9.218.4"
    Private sqlPort As Short = 3306
    Private sqlDB As String = "dualsonic"
    Private sqlUserName As String = "dualsonic"
    Private sqlUserPw As String = "1703741406dualsonic"

    Private localPort As Short = 3308

    ''Private Conn As String = "Server=" + sqlHost + ";Port=" + Str(sqlPort) + ";DataBase=" + sqlDB + ";user=" + sqlUserName + ";password=" + sqlUserPw + ";"
    Private Conn As String = "Server=127.0.0.1;Port=" + Str(localPort) + ";DataBase=" + sqlDB + ";user=" + sqlUserName + ";password=" + sqlUserPw + ";"
    Private sqlCon As New MySqlConnection(Conn)
    Private sqlCmd As New MySqlCommand()

    Public sshDataQuery() As Object


    Private sshClient As New SshClient(sshHost, sshPort, sshUserName, sshUserPw)
    Private portForwarded = New ForwardedPortLocal("127.0.0.1", localPort, sqlHost, sqlPort)

    Public Function DataBaseOn() As Boolean
        Try
            sshClient.Connect()
            sshClient.AddForwardedPort(portForwarded)

            If Not sshClient.IsConnected Then
                MsgBox("SSH 연결 안됨")
            End If

            portForwarded.Start()

            If Not portForwarded.IsStarted Then
                MsgBox("포트 포워딩 안됨")
            End If

            DBOpen()

        Catch ex As Exception
            MsgBox("ssh on 오류 발생 : " & vbCrLf & ex.Message, vbCritical)

            If sshClient.IsConnected Then
                sshClient.Disconnect()
            End If

            Return False
        End Try

        Return True

    End Function

    Public Function DataBaseOFF() As Boolean

        Try
            DBClose()
            portForwarded.Stop()
            sshClient.Disconnect()
        Catch ex As Exception
            MsgBox("ssh off 오류 발생 : " & vbCrLf & ex.Message, vbCritical)
            Return False
        Finally
            If sshClient.IsConnected Then
                sshClient.Disconnect()
            End If
        End Try

        Return True

    End Function

    Private Function DBOpen() As Boolean
        Try
            If sqlCon.State <> ConnectionState.Open Then       '' sqlCon.State 의 상태를 나타냄
                sqlCon.Open()
            End If
            Return True
        Catch ex As Exception
            MsgBox("MySQL Command Error:" + vbCrLf + Err.Description, vbCritical)
            Return False
        End Try
    End Function

    Private Function DBClose() As Boolean
        Try
            If sqlCon.State = ConnectionState.Open Then
                sqlCon.Close()
            End If
            Return True

        Catch ex As Exception
            MsgBox("MySQL Command Error:" + vbCrLf + Err.Description, vbCritical)
            Return False
        End Try
    End Function

    Public Function SSHCommand(cmdStr As String) As Boolean
        Try
            Database_Use() '' 연결에 대한 sql문 실행, 명령을 수행하고 영향을 받은 행의 수를 반환하는 메서드, 행 추가나 변경, 삭제 등의 명령을 수행할 때는 명령으로 영향받은 행의 수만 알면 되기 때문에 ExecuteNonQuery 메서드를 사용합니다. 리턴값은 INT32 형
            sqlCmd.CommandText = cmdStr
            sqlCmd.Connection = sqlCon

            Dim affectedRows As Integer = sqlCmd.ExecuteNonQuery()
            MsgBox("영향받은 행 수: " & affectedRows)

            DataBaseOFF()
            Return True

        Catch ex As Exception
            MsgBox("MySQL Command Error:" & vbCrLf & ex.Message, vbCritical)
            DBClose()
            Return False
        End Try
        End
    End Function

    Private Function Database_Use() As Boolean
        Try
            DataBaseOn()

            sqlCmd.CommandText = "USE " & sqlDB & ";"
            sqlCmd.Connection = sqlCon
            sqlCmd.ExecuteNonQuery()

            Return True
        Catch ex As Exception
            MsgBox("MySQL Command Error:" + vbCrLf + Err.Description, vbCritical)
            Return False
        End Try
    End Function

    Public Function SSHQueryReader(cmdStr As String) As Integer
        Dim FieldCount As Integer
        Dim initRun As Boolean = True
        Dim DataTypeName As String
        Dim TmpData As Object
        Dim QueryCount As ULong

        Try
            Database_Use()

            sqlCmd.CommandText = cmdStr
            sqlCmd.Connection = sqlCon
            Dim sqlData = sqlCmd.ExecuteReader       '' 어떤 쿼리에서도 적용이 가능하다. SELECT 쿼리를 이용할 경우 해당하는 값들이 DataReader 타입으로 온다. 값을 가져온 후에는 SqlDataReader객체의 read메서드를 통해 값을 읽어올 수 있고 , 사용 후에는 close메서드를 이용하여 실행을 끝내주어야 한다.
            FieldCount = sqlData.FieldCount      '' 현재 행의 열 수를 가져옵니다.

            Dim readCount As Integer
            While (sqlData.Read())
                readCount += 1
                If initRun Then
                    ReDim sshDataQuery(FieldCount - 1)     '' 배열을 모든 필드를 담을 수 있는 양으로 맞추는 기능
                    initRun = False

                Else
                    ReDim Preserve sshDataQuery(UBound(sshDataQuery) + FieldCount)     '' 배열에 저장된 값을 보존하면서 배열의 길이만 재선언
                End If

                For cnt = 0 To FieldCount - 1
                    DataTypeName = sqlData.GetDataTypeName(cnt)               '' 지정된 열의 데이터 형식을 나타내는 문자열을 가져옵니다.

                    If DataTypeName = "DATE" Then
                        TmpData = sqlData.GetDateTime(cnt)
                    Else
                        TmpData = sqlData.GetValue(cnt)
                    End If

                    If DBNull.Value.Equals(TmpData) Or TmpData.Equals(String.Empty) Then
                        sshDataQuery(QueryCount) = String.Empty
                    Else
                        sshDataQuery(QueryCount) = TmpData
                    End If

                    QueryCount += 1
                Next
            End While

            DataBaseOFF()
            MsgBox("조회 데이터 수: " & readCount)
            Return QueryCount

        Catch ex As Exception
            MsgBox("예외 발생!" & vbCrLf & ex.Message, vbCritical)
            DataBaseOFF()
            Return 0
        End Try

    End Function
End Module
