Imports System.Data
Imports System.Data.SqlClient
Imports AppCommon

''' <summary>
''' ストアド プロシージャを管理します。
''' </summary>
''' <remarks></remarks>
Public Class StoredProcedureManager
    Implements IDisposable

    'メンバ変数
    Private _disposed As Boolean = False
    Private _con As SqlConnection
    Private _cmd As SqlCommand
    Private _trn As SqlTransaction  '2018.9.6 ADD /Liu

    'プロパティ
    Private _ds As DataSet
    Public ReadOnly Property ds() As DataSet
        Get
            Return _ds
        End Get
    End Property

    ''' <summary>
    ''' コンストラクタ
    ''' </summary>
    ''' <param name="cmdText">StoredProcedure名</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal cmdText As String)
        _con = New SqlConnection(GetConStr)
        _con.Open()

        _cmd = New SqlCommand(cmdText, _con)
        _cmd.CommandType = CommandType.StoredProcedure
    End Sub

    ''' <summary>
    ''' デストラクタ
    ''' </summary>
    ''' <remarks></remarks>
    Protected Overrides Sub Finalize()
        Dispose(False)
        MyBase.Finalize()
    End Sub

    ''' <summary>
    ''' Dispose
    ''' </summary>
    ''' <param name="disposing"></param>
    ''' <remarks></remarks>
    Protected Overridable Sub Dispose(ByVal disposing As Boolean)
        If Not _disposed Then
            If disposing Then
                '明示的に呼び出されたときにマネージ リソースを解放します。
                '2018.9.6 ADD START /Liu
                If _trn IsNot Nothing Then
                    _trn.Rollback()
                    _trn.Dispose()
                    _trn = Nothing
                End If
                '2018.9.6 ADD END /Liu
                _con.Close()
                _con.Dispose()

                _cmd.Dispose()
            End If

            '共有のアンマネージ リソースを解放します。
        End If
        _disposed = True
    End Sub

    ''' <summary>
    ''' Dispose
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

    Public Sub Reset(ByVal cmdText As String)
        _cmd.CommandText = cmdText
        _cmd.Parameters.Clear()
    End Sub

    ''' <summary>
    ''' INパラメータを追加します。
    ''' </summary>
    ''' <param name="prmNm"></param>
    ''' <param name="type"></param>
    ''' <param name="value"></param>
    ''' <remarks></remarks>
    Public Sub AddPrmIn(ByVal prmNm As String, ByVal type As Data.SqlDbType, ByVal value As Object)
        _cmd.Parameters.Add(prmNm, type).Value = BlankToNull(value)
    End Sub

    ''' <summary>
    ''' INパラメータを追加します。
    ''' </summary>
    ''' <param name="prmNm"></param>
    ''' <param name="type"></param>
    ''' <param name="size"></param>
    ''' <param name="value"></param>
    ''' <remarks></remarks>
    Public Sub AddPrmIn(ByVal prmNm As String, ByVal type As Data.SqlDbType, ByVal size As Integer, ByVal value As Object)
        _cmd.Parameters.Add(prmNm, type, size).Value = BlankToNull(value)
    End Sub

    ''' <summary>
    ''' OUTパラメータを追加します。
    ''' </summary>
    ''' <param name="prmNm"></param>
    ''' <param name="type"></param>
    ''' <remarks></remarks>
    Public Sub AddPrmOut(ByVal prmNm As String, ByVal type As Data.SqlDbType)
        _cmd.Parameters.Add(prmNm, type).Direction = ParameterDirection.Output
    End Sub

    ''' <summary>
    ''' OUTパラメータを追加します。
    ''' </summary>
    ''' <param name="prmNm"></param>
    ''' <param name="type"></param>
    ''' <param name="size"></param>
    ''' <remarks></remarks>
    Public Sub AddPrmOut(ByVal prmNm As String, ByVal type As Data.SqlDbType, ByVal size As Integer)
        Dim sp As SqlParameter = _cmd.Parameters.Add(prmNm, type, size)
        _cmd.Parameters(prmNm).Direction = ParameterDirection.Output
    End Sub

    ''' <summary>
    ''' ストアド プロシージャを実行します。
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub Exec()
        _cmd.ExecuteNonQuery()
    End Sub

    ''' <summary>
    ''' ストアド プロシージャを実行し、レコードをデータ セット(メンバ変数)に格納します。
    ''' </summary>
    ''' <param name="srcTbl">テーブル マップに使用するソース テーブル名(任意)</param>
    ''' <remarks></remarks>
    Public Sub Fill(Optional ByVal srcTbl As String = Nothing)
        Dim sda = New SqlDataAdapter
        If IsNothing(_ds) Then
            _ds = New DataSet()
        End If

        sda.SelectCommand = _cmd
        _cmd.ExecuteNonQuery()
        If IsNothing(srcTbl) Then
            sda.Fill(_ds)
        Else
            sda.Fill(_ds, srcTbl)
        End If

        sda.Dispose()
    End Sub

    ''' <summary>
    ''' ストアド プロシージャを実行し、レコードをデータ セット(引数)に格納します。
    ''' </summary>
    ''' <param name="ds">レコードを格納する為のデータ セット</param>
    ''' <param name="srcTbl">テーブル マップに使用するソース テーブル名(任意)</param>
    ''' <remarks></remarks>
    Public Sub Fill(ByRef ds As DataSet, Optional ByVal srcTbl As String = Nothing)
        Dim sda = New SqlDataAdapter

        sda.SelectCommand = _cmd
        _cmd.ExecuteNonQuery()
        If IsNothing(srcTbl) Then
            sda.Fill(ds)
        Else
            sda.Fill(ds, srcTbl)
        End If

        sda.Dispose()
    End Sub

    ''' <summary>
    ''' OUTパラメータの値を取得します。
    ''' </summary>
    ''' <param name="prmNm">パラメータ名</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function GetValue(ByVal prmNm As String) As Object
        Return _cmd.Parameters(prmNm).Value()
    End Function

	'2018.9.6 ADD START /Liu
    ''' <summary>
    ''' Transactionを開始する
    ''' </summary>
    Public Sub BeginTransaction()
        _trn = _con.BeginTransaction
        _cmd.Transaction = _trn
    End Sub

    ''' <summary>
    ''' ロールバックする
    ''' </summary>
    Public Sub Rollback()
        If _trn Is Nothing Then
            Return
        End If
        _trn.Rollback()
        _trn.Dispose()
        _trn = Nothing
    End Sub

    ''' <summary>
    ''' コミットする
    ''' </summary>
    Public Sub Commit()
        If _trn Is Nothing Then
            Return
        End If
        _trn.Commit()
        _trn.Dispose()
        _trn = Nothing
    End Sub
    '2018.9.6 ADD END /Liu
End Class
