Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Imports System
Imports System.Data
Imports System.Globalization
Namespace DotNetDataProviderTemplate
Public Class TemplateDataReader
Implements IDataReader
Implements IDataRecord
' The DataReader should always be open when returned to the user.
Private m_fOpen As Boolean = True
' Keep track of the results and position
' within that resultset (starts prior to first record).
Private m_resultset As SampleDb.SampleDbResultSet
Private Shared m_STARTPOS As Integer = -1
Private m_nPos As Integer = m_STARTPOS
'*
'* Keep track of the connection to implement the
'* CommandBehavior.CloseConnection flag. Nothing (a null reference) means
'* normal behavior (do not automatically close).
'*
Private m_connection As TemplateConnection = Nothing
'*
'* Because the user should not be able to directly create a
'* DataReader object, the constructor is
'* marked as internal.
'*
Friend Sub New(ByRef resultset As SampleDb.SampleDbResultSet)
MyBase.New
m_resultset = resultset
End Sub
Friend Sub New(ByRef resultset As SampleDb.SampleDbResultSet, ByRef connection As TemplateConnection)
MyBase.New
m_resultset = resultset
m_connection = connection
End Sub
'****
'* METHODS / PROPERTIES FROM IDataReader.
'****
Public ReadOnly Property Depth As Integer Implements IDataReader.Depth
'*
'* Always return a value of zero if nesting is not supported.
'*
Get
Return 0
End Get
End Property
Public ReadOnly Property IsClosed As Boolean Implements IDataReader.IsClosed
'*
'* Keep track of the reader state - some methods should be
'* disallowed if the reader is closed.
'*
Get
Return Not m_fOpen
End Get
End Property
Public ReadOnly Property RecordsAffected As Integer Implements IDataReader.RecordsAffected
'*
'* RecordsAffected is only applicable to batch statements
'* that include inserts/updates/deletes. The sample always
'* returns -1.
'*
Get
Return -1
End Get
End Property
Public Sub Close() Implements IDataReader.Close
'*
'* Close the reader. The sample only changes the state,
'* but an actual implementation would also clean up any
'* resources used by the operation. For example,
'* cleaning up any resources waiting for data to be
'* returned by the server.
'*
m_fOpen = false
End Sub
Public Function NextResult() As Boolean Implements IDataReader.NextResult
' The sample only returns a single resultset. However,
' DbDataAdapter expects NextResult to return a value.
Return False
End Function
Public Function Read() As Boolean Implements IDataReader.Read
' Return True if it is possible to advance and if you are still positioned
' on a valid row. Because the data array in the resultset
' is two-dimensional, you must divide by the number of columns.
m_nPos = m_nPos + 1
If m_nPos + 1 >= (m_resultset.data.Length / m_resultset.metaData.Length) Then
Return False
Else
Return True
End If
End Function
Public Function GetSchemaTable() As DataTable Implements IDataReader.GetSchemaTable
'$
Throw New NotSupportedException()
End Function
'****
'* METHODS / PROPERTIES FROM IDataRecord.
'****
Public Overloads ReadOnly Default Property Item(ByVal i As Integer) As Object Implements IDataRecord.Item
Get
Return GetValue(i)
End Get
End Property
Public Overloads ReadOnly Default Property Item(ByVal name As String) As Object Implements IDataRecord.Item
Get
' Look up the ordinal and return the value at that position.
Return Me.GetOrdinal(name)
End Get
End Property
Public ReadOnly Property FieldCount As Integer Implements IDataRecord.FieldCount
' Return a count of the number of columns, which in
' this case is the size of the column metadata array.
Get
Return m_resultset.metaData.Length - 1
End Get
End Property
Public Function GetName(ByVal i As Integer) As String Implements IDataRecord.GetName
Return m_resultset.metaData(i).name
End Function
Public Function GetDataTypeName(ByVal i As Integer) As String Implements IDataRecord.GetDataTypeName
'*
'* Usually this would return the name of the type
'* as used on the back end, for example 'smallint' or 'varchar'.
'* In this case use the simple name of the .NET Framework type.
'*
Return m_resultset.metaData(i).type.Name
End Function
Public Function GetFieldType(ByVal i As Integer) As Type Implements IDataRecord.GetFieldType
' Return the actual Type class for the data type.
Return m_resultset.metaData(i).type
End Function
Public Function GetValue(ByVal i As Integer) As Object Implements IDataRecord.GetValue
Return m_resultset.data(m_nPos, i)
End Function
Public Function GetValues(values() As Object) As Integer Implements IDataRecord.GetValues
Dim i As Integer = 0
Dim j As Integer = 0
Do While i < values.Length AND j < m_resultset.metaData.Length
values(i) = m_resultset.data(m_nPos, j)
i += 1
j += 1
Loop
Return i
End Function
Return i
End Function
Public Function GetOrdinal(ByVal name As String) As Integer Implements IDataRecord.GetOrdinal
' Look for the ordinal of the column with the same name and return it.
Dim i As Integer
For i = 0 To m_resultset.metaData.Length - 1
If 0 = _cultureAwareCompare(name, m_resultset.metaData(i).name) Then Return i
Next
' Throw an exception if the ordinal cannot be found.
Throw New IndexOutOfRangeException("Could not find the specified column in the results")
End Function
Public Function GetBoolean(ByVal i As Integer) As Boolean Implements IDataRecord.GetBoolean
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Boolean)
End Function
Public Function GetByte(ByVal i As Integer) As Byte Implements IDataRecord.GetByte
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Byte)
End Function
Public Function GetBytes(ByVal i As Integer, ByVal fieldOffset As Long, buffer() As byte, ByVal bufferOffSet As Integer, ByVal length As Integer) As Long Implements IDataRecord.GetBytes
' The sample does not support this method.
Throw New NotSupportedException("GetBytes not supported.")
End Function
Public Function GetChar(ByVal i As Integer) As Char Implements IDataRecord.GetChar
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Char)
End Function
Public Function GetChars(ByVal i As Integer, ByVal fieldOffSet As Long, buffer() As Char, ByVal bufferOffSet As Integer, ByVal length As Integer) As Long Implements IDataRecord.GetChars
' The sample code does not support this method.
Throw New NotSupportedException("GetChars not supported.")
End Function
Public Function GetGuid(ByVal i As Integer) As Guid Implements IDataRecord.GetGuid
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Guid)
End Function
Public Function GetInt16(ByVal i As Integer) As Int16 Implements IDataRecord.GetInt16
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Int16)
End Function
Public Function GetInt32(ByVal i As Integer) As Int32 Implements IDataRecord.GetInt32
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Int32)
End Function
Public Function GetInt64(ByVal i As Integer) As Int64 Implements IDataRecord.GetInt64
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Int64)
End Function
Public Function GetFloat(ByVal i As Integer) As Single Implements IDataRecord.GetFloat
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Single)
End Function
Public Function GetDouble(ByVal i As Integer) As Double Implements IDataRecord.GetDouble
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Double)
End Function
Public Function GetString(ByVal i As Integer) As String Implements IDataRecord.GetString
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), String)
End Function
Public Function GetDecimal(ByVal i As Integer) As Decimal Implements IDataRecord.GetDecimal
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), Decimal)
End Function
Public Function GetDateTime(ByVal i As Integer) As DateTime Implements IDataRecord.GetDateTime
'*
'* Force the cast to return the type. InvalidCastException
'* should be thrown if the data is not already of the correct type.
'*
Return CType(m_resultset.data(m_nPos, i), DateTime)
End Function
Public Function GetData(ByVal i As Integer) As IDataReader Implements IDataRecord.GetData
'*
'* The sample code does not support this method. Normally,
'* this would be used to expose nested tables and
'* other hierarchical data.
'*
Throw New NotSupportedException("GetData not supported.")
End Function
Public Function IsDBNull(ByVal i As Integer) As Boolean Implements IDataRecord.IsDBNull
Return m_resultset.data(m_nPos, i) Is DBNull.Value
End Function
'*
'* Implementation specific methods.
'*
Private Function _cultureAwareCompare(strA As String, strB As String) As Integer
Return CultureInfo.CurrentCulture.CompareInfo.Compare(strA, strB, CompareOptions.IgnoreKanaType Or CompareOptions.IgnoreWidth Or CompareOptions.IgnoreCase)
End Function
Public Sub Dispose() Implements IDisposable.Dispose
Me.Dispose(True)
System.GC.SuppressFinalize(Me)
End Sub
Public Sub Dispose(disposing As Boolean)
If disposing Then
Try
Me.Close()
Catch e As Exception
Throw New SystemException("An exception of type " & e.GetType().ToString() & _
" was encountered while closing the TemplateDataReader.")
End Try
End If
End Sub
End Class
End Namespace