OracleConnection类源代码

Imports System
Imports System.ComponentModel
Imports System.Data
Imports System.Data.Common
Imports System.Data.ProviderBase
Imports System.Diagnostics
Imports System.EnterpriseServices
Imports System.Globalization
Imports System.Runtime.ConstrainedExecution
Imports System.Security
Imports System.Security.Permissions
Imports System.Threading
Imports System.Transactions

Namespace System.Data.OracleClient
    <DefaultEvent("InfoMessage")> _
    Public NotInheritable Class OracleConnection
        Inherits DbConnection
        Implements ICloneable
        ' Events
        <ResCategory("OracleCategory_InfoMessage"), ResDescription("OracleConnection_InfoMessage")> _
        Public Event InfoMessage As OracleInfoMessageEventHandler
            AddHandler(ByVal value As OracleInfoMessageEventHandler)
                MyBase.Events.AddHandler(OracleConnection.EventInfoMessage, value)
            End AddHandler
            RemoveHandler(ByVal value As OracleInfoMessageEventHandler)
                MyBase.Events.RemoveHandler(OracleConnection.EventInfoMessage, value)
            End RemoveHandler
        End Event

        ' Methods
        Public Sub New()
            Me.ObjectID = Interlocked.Increment((OracleConnection._objectTypeCount))
            GC.SuppressFinalize(Me)
            Me._innerConnection = DbConnectionClosedNeverOpened.SingletonInstance
        End Sub

        Friend Sub New(ByVal connection As OracleConnection)
            Me.New()
            Me.CopyFrom(connection)
        End Sub

        Public Sub New(ByVal connectionString As String)
            Me.New()
            Me.ConnectionString = connectionString
        End Sub

        <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)> _
        Friend Sub Abort(ByVal e As Exception)
            Dim comparand As DbConnectionInternal = Me._innerConnection
            If (ConnectionState.Open = comparand.State) Then
                Interlocked.CompareExchange(Of DbConnectionInternal)((Me._innerConnection), DbConnectionClosedPreviouslyOpened.SingletonInstance, comparand)
                comparand.DoomThisConnection
            End If
            If TypeOf e Is OutOfMemoryException Then
                Bid.Trace("<prov.DbConnectionHelper.Abort|RES|INFO|CPOOL> %d#, Aborting operation due to asynchronous exception: %ls" & ChrW(10), Me.ObjectID, "OutOfMemory")
            Else
                Bid.Trace("<prov.DbConnectionHelper.Abort|RES|INFO|CPOOL> %d#, Aborting operation due to asynchronous exception: %ls" & ChrW(10), Me.ObjectID, e.ToString)
            End If
        End Sub

        Friend Sub AddWeakReference(ByVal value As Object, ByVal tag As Integer)
            Me.InnerConnection.AddWeakReference(value, tag)
        End Sub

        Protected Overrides Function BeginDbTransaction(ByVal isolationLevel As IsolationLevel) As DbTransaction
            Dim transaction As DbTransaction
            Dim ptr As IntPtr
            Bid.ScopeEnter(ptr, "<prov.DbConnectionHelper.BeginDbTransaction|API> %d#, isolationLevel=%d{ds.IsolationLevel}", Me.ObjectID, CInt(isolationLevel))
            Try
                transaction = Me.InnerConnection.BeginTransaction(isolationLevel)
            Finally
                Bid.ScopeLeave((ptr))
            End Try
            Return transaction
        End Function

        Public Function BeginTransaction() As OracleTransaction
            Return Me.BeginTransaction(IsolationLevel.Unspecified)
        End Function

        Public Function BeginTransaction(ByVal il As IsolationLevel) As OracleTransaction
            Return DirectCast(MyBase.BeginTransaction(il), OracleTransaction)
        End Function

        Public Overrides Sub ChangeDatabase(ByVal value As String)
            Dim ptr As IntPtr
            Bid.ScopeEnter(ptr, "<ora.OracleConnection.ChangeDatabase|API> %d#, value='%ls'" & ChrW(10), Me.ObjectID, value)
            Try
                Throw ADP.ChangeDatabaseNotSupported
            Finally
                Bid.ScopeLeave((ptr))
            End Try
        End Sub

        Friend Sub CheckError(ByVal errorHandle As OciErrorHandle, ByVal rc As Integer)
            Select Case DirectCast(rc, RETURNCODE)
                Case RETURNCODE.OCI_INVALID_HANDLE
                    Throw ADP.InvalidOperation(Res.GetString("ADP_InternalError", New Object() { rc }))
                Case RETURNCODE.OCI_ERROR, RETURNCODE.OCI_NO_DATA
                    Dim exception2 As Exception = ADP.OracleError(errorHandle, rc)
                    If ((Not errorHandle Is Nothing) AndAlso errorHandle.ConnectionIsBroken) Then
                        Dim openInternalConnection As OracleInternalConnection = Me.GetOpenInternalConnection
                        If (Not openInternalConnection Is Nothing) Then
                            openInternalConnection.ConnectionIsBroken
                        End If
                    End If
                    Throw exception2
                Case RETURNCODE.OCI_SUCCESS_WITH_INFO
                    Dim infoMessageEvent As New OracleInfoMessageEventArgs(OracleException.CreateException(errorHandle, rc))
                    Me.OnInfoMessage(infoMessageEvent)
                    Return
            End Select
            If ((rc < 0) OrElse (rc = &H63)) Then
                Throw ADP.Simple(Res.GetString("ADP_UnexpectedReturnCode", New Object() { rc.ToString(CultureInfo.CurrentCulture) }))
            End If
        End Sub

        Public Shared Sub ClearAllPools()
            New OraclePermission(PermissionState.Unrestricted).Demand
            OracleConnectionFactory.SingletonInstance.ClearAllPools
        End Sub

        Public Shared Sub ClearPool(ByVal connection As OracleConnection)
            ADP.CheckArgumentNull(connection, "connection")
            Dim userConnectionOptions As DbConnectionOptions = connection.UserConnectionOptions
            If (Not userConnectionOptions Is Nothing) Then
                userConnectionOptions.DemandPermission
                OracleConnectionFactory.SingletonInstance.ClearPool(connection)
            End If
        End Sub

        Public Overrides Sub Close()
            Me.InnerConnection.CloseConnection(Me, Me.ConnectionFactory)
        End Sub

        Friend Sub Commit()
            Me.GetOpenInternalConnection.Commit
        End Sub

        Private Function ConnectionString_Get() As String
            Bid.Trace("<prov.DbConnectionHelper.ConnectionString_Get|API> %d#" & ChrW(10), Me.ObjectID)
            Dim shouldHidePassword As Boolean = Me.InnerConnection.ShouldHidePassword
            Dim userConnectionOptions As DbConnectionOptions = Me.UserConnectionOptions
            If (userConnectionOptions Is Nothing) Then
                Return ""
            End If
            Return userConnectionOptions.UsersConnectionString(shouldHidePassword)
        End Function

        Private Sub ConnectionString_Set(ByVal value As String)
            Dim userConnectionOptions As DbConnectionOptions = Nothing
            Dim group As DbConnectionPoolGroup = Me.ConnectionFactory.GetConnectionPoolGroup(value, Nothing, (userConnectionOptions))
            Dim innerConnection As DbConnectionInternal = Me.InnerConnection
            Dim allowSetConnectionString As Boolean = innerConnection.AllowSetConnectionString
            If allowSetConnectionString Then
                allowSetConnectionString = Me.SetInnerConnectionFrom(DbConnectionClosedBusy.SingletonInstance, innerConnection)
                If allowSetConnectionString Then
                    Me._userConnectionOptions = userConnectionOptions
                    Me._poolGroup = group
                    Me._innerConnection = DbConnectionClosedNeverOpened.SingletonInstance
                End If
            End If
            If Not allowSetConnectionString Then
                Throw ADP.OpenConnectionPropertySet("ConnectionString", innerConnection.State)
            End If
            If Bid.TraceOn Then
                Dim str As String = IIf((Not userConnectionOptions Is Nothing), userConnectionOptions.UsersConnectionStringForTrace, "")
                Bid.Trace("<prov.DbConnectionHelper.ConnectionString_Set|API> %d#, '%ls'" & ChrW(10), Me.ObjectID, str)
            End If
        End Sub

        Private Sub CopyFrom(ByVal connection As OracleConnection)
            ADP.CheckArgumentNull(connection, "connection")
            Me._userConnectionOptions = connection.UserConnectionOptions
            Me._poolGroup = connection.PoolGroup
            Me._innerConnection = DbConnectionClosedNeverOpened.SingletonInstance
        End Sub

        Public Function CreateCommand() As OracleCommand
            Dim command As New OracleCommand
            command.Connection = Me
            Return command
        End Function

        Protected Overrides Function CreateDbCommand() As DbCommand
            Dim command As DbCommand = Nothing
            Dim ptr As IntPtr
            Bid.ScopeEnter(ptr, "<prov.DbConnectionHelper.CreateDbCommand|API> %d#" & ChrW(10), Me.ObjectID)
            Try
                command = Me.ConnectionFactory.ProviderFactory.CreateCommand
                command.Connection = Me
            Finally
                Bid.ScopeLeave((ptr))
            End Try
            Return command
        End Function

        Private Shared Function CreateExecutePermission() As CodeAccessPermission
            Dim permission As New OraclePermission(PermissionState.None)
            permission.Add(String.Empty, String.Empty, KeyRestrictionBehavior.AllowOnly)
            Return permission
        End Function

        Protected Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                Me._userConnectionOptions = Nothing
                Me._poolGroup = Nothing
                Me.Close
            End If
            Me.DisposeMe(disposing)
            MyBase.Dispose(disposing)
        End Sub

        Private Sub DisposeMe(ByVal disposing As Boolean)
        End Sub

        Public Sub EnlistDistributedTransaction(ByVal distributedTransaction As ITransaction)
            Me.EnlistDistributedTransactionHelper(distributedTransaction)
        End Sub

        Private Sub EnlistDistributedTransactionHelper(ByVal transaction As ITransaction)
            Dim set As New PermissionSet(PermissionState.None)
            [set].AddPermission(OracleConnection.ExecutePermission)
            [set].AddPermission(New SecurityPermission(SecurityPermissionFlag.UnmanagedCode))
            [set].Demand
            Bid.Trace("<prov.DbConnectionHelper.EnlistDistributedTransactionHelper|RES|TRAN> %d#, Connection enlisting in a transaction." & ChrW(10), Me.ObjectID)
            Dim transactionFromDtcTransaction As Transaction = Nothing
            If (Not transaction Is Nothing) Then
                transactionFromDtcTransaction = TransactionInterop.GetTransactionFromDtcTransaction(DirectCast(transaction, IDtcTransaction))
            End If
            Me.InnerConnection.EnlistTransaction(transactionFromDtcTransaction)
            GC.KeepAlive(Me)
        End Sub

        Public Overrides Sub EnlistTransaction(ByVal transaction As Transaction)
            OracleConnection.ExecutePermission.Demand
            Bid.Trace("<prov.DbConnectionHelper.EnlistTransaction|RES|TRAN> %d#, Connection enlisting in a transaction." & ChrW(10), Me.ObjectID)
            Dim innerConnection As DbConnectionInternal = Me.InnerConnection
            If innerConnection.HasEnlistedTransaction Then
                Throw ADP.TransactionPresent
            End If
            innerConnection.EnlistTransaction(transaction)
            GC.KeepAlive(Me)
        End Sub

        Friend Function GetBytes(ByVal value As String, ByVal useNationalCharacterSet As Boolean) As Byte()
            Return Me.GetOpenInternalConnection.GetBytes(value, useNationalCharacterSet)
        End Function

        Private Function GetMetaDataFactory(ByVal internalConnection As DbConnectionInternal) As DbMetaDataFactory
            Return Me.ConnectionFactory.GetMetaDataFactory(Me._poolGroup, internalConnection)
        End Function

        Friend Function GetMetaDataFactoryInternal(ByVal internalConnection As DbConnectionInternal) As DbMetaDataFactory
            Return Me.GetMetaDataFactory(internalConnection)
        End Function

        Friend Function GetOpenInternalConnection() As OracleInternalConnection
            Dim innerConnection As DbConnectionInternal = Me.InnerConnection
            If Not TypeOf innerConnection Is OracleInternalConnection Then
                Throw ADP.ClosedConnectionError
            End If
            Return TryCast(innerConnection,OracleInternalConnection)
        End Function

        Public Overrides Function GetSchema() As DataTable
            Return Me.GetSchema(DbMetaDataCollectionNames.MetaDataCollections, Nothing)
        End Function

        Public Overrides Function GetSchema(ByVal collectionName As String) As DataTable
            Return Me.GetSchema(collectionName, Nothing)
        End Function

        Public Overrides Function GetSchema(ByVal collectionName As String, ByVal restrictionValues As String()) As DataTable
            OracleConnection.ExecutePermission.Demand
            Return Me.InnerConnection.GetSchema(Me.ConnectionFactory, Me.PoolGroup, Me, collectionName, restrictionValues)
        End Function

        Friend Function GetScratchBuffer(ByVal minSize As Integer) As NativeBuffer
            Return Me.GetOpenInternalConnection.GetScratchBuffer(minSize)
        End Function

        Friend Function GetString(ByVal bytearray As Byte()) As String
            Return Me.GetOpenInternalConnection.GetString(bytearray)
        End Function

        Friend Function GetString(ByVal bytearray As Byte(), ByVal useNationalCharacterSet As Boolean) As String
            Return Me.GetOpenInternalConnection.GetString(bytearray, useNationalCharacterSet)
        End Function

        Friend Sub NotifyWeakReference(ByVal message As Integer)
            Me.InnerConnection.NotifyWeakReference(message)
        End Sub

        Friend Sub OnInfoMessage(ByVal infoMessageEvent As OracleInfoMessageEventArgs)
            Dim handler As OracleInfoMessageEventHandler = DirectCast(MyBase.Events.Item(OracleConnection.EventInfoMessage), OracleInfoMessageEventHandler)
            If (Not handler Is Nothing) Then
                handler.Invoke(Me, infoMessageEvent)
            End If
        End Sub

        Public Overrides Sub Open()
            Me.InnerConnection.OpenConnection(Me, Me.ConnectionFactory)
            Dim innerConnection As OracleInternalConnection = TryCast(Me.InnerConnection,OracleInternalConnection)
            If (Not innerConnection Is Nothing) Then
                innerConnection.FireDeferredInfoMessageEvents(Me)
            End If
        End Sub

        Friend Sub PermissionDemand()
            Dim poolGroup As DbConnectionPoolGroup = Me.PoolGroup
            Dim options As DbConnectionOptions = IIf((Not poolGroup Is Nothing), poolGroup.ConnectionOptions, Nothing)
            If ((options Is Nothing) OrElse options.IsEmpty) Then
                Throw ADP.NoConnectionString
            End If
            Me.UserConnectionOptions.DemandPermission
        End Sub

        Friend Sub RemoveWeakReference(ByVal value As Object)
            Me.InnerConnection.RemoveWeakReference(value)
        End Sub

        Friend Sub Rollback()
            Dim innerConnection As OracleInternalConnection = TryCast(Me.InnerConnection,OracleInternalConnection)
            If (Not innerConnection Is Nothing) Then
                innerConnection.Rollback
            End If
        End Sub

        Friend Sub RollbackDeadTransaction()
            Me.GetOpenInternalConnection.RollbackDeadTransaction
        End Sub

        Friend Sub SetInnerConnectionEvent(ByVal [to] As DbConnectionInternal)
            Dim originalState As ConnectionState = (Me._innerConnection.State And ConnectionState.Open)
            Dim currentState As ConnectionState = ([to].State And ConnectionState.Open)
            If ((originalState <> currentState) AndAlso (currentState = ConnectionState.Closed)) Then
                Me._closeCount += 1
            End If
            Me._innerConnection = [to]
            If ((originalState = ConnectionState.Closed) AndAlso (ConnectionState.Open = currentState)) Then
                Me.OnStateChange(DbConnectionInternal.StateChangeOpen)
            ElseIf ((ConnectionState.Open = originalState) AndAlso (currentState = ConnectionState.Closed)) Then
                Me.OnStateChange(DbConnectionInternal.StateChangeClosed)
            ElseIf (originalState <> currentState) Then
                Me.OnStateChange(New StateChangeEventArgs(originalState, currentState))
            End If
        End Sub

        Friend Function SetInnerConnectionFrom(ByVal [to] As DbConnectionInternal, ByVal from As DbConnectionInternal) As Boolean
            Return (from Is Interlocked.CompareExchange(Of DbConnectionInternal)((Me._innerConnection), [to], from))
        End Function

        Friend Sub SetInnerConnectionTo(ByVal [to] As DbConnectionInternal)
            Me._innerConnection = [to]
        End Sub

        Private Function System.ICloneable.Clone() As Object Implements ICloneable.Clone
            Dim connection As New OracleConnection(Me)
            Bid.Trace("<ora.OracleConnection.Clone|API> %d#, clone=%d#" & ChrW(10), Me.ObjectID, connection.ObjectID)
            Return connection
        End Function

        <Conditional("DEBUG")> _
        Friend Shared Sub VerifyExecutePermission()
            Try
                OracleConnection.ExecutePermission.Demand
            Catch exception1 As SecurityException
                Throw
            End Try
        End Sub


        ' Properties
        Friend ReadOnly Property CloseCount As Integer
            Get
                Return Me._closeCount
            End Get
        End Property

        Friend ReadOnly Property ConnectionFactory As DbConnectionFactory
            Get
                Return OracleConnection._connectionFactory
            End Get
        End Property

        Friend ReadOnly Property ConnectionOptions As DbConnectionOptions
            Get
                Dim poolGroup As DbConnectionPoolGroup = Me.PoolGroup
                If (poolGroup Is Nothing) Then
                    Return Nothing
                End If
                Return poolGroup.ConnectionOptions
            End Get
        End Property

        <ResDescription("OracleConnection_ConnectionString"), Editor("Microsoft.VSDesigner.Data.Oracle.Design.OracleConnectionStringEditor, Microsoft.VSDesigner, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.Drawing.Design.UITypeEditor, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"), DefaultValue(""), ResCategory("OracleCategory_Data"), RefreshProperties(RefreshProperties.All), RecommendedAsConfigurable(True)> _
        Public Overrides Property ConnectionString As String
            Get
                Return Me.ConnectionString_Get
            End Get
            Set(ByVal value As String)
                Me.ConnectionString_Set(value)
            End Set
        End Property

        <EditorBrowsable(EditorBrowsableState.Never), Browsable(False)> _
        Public Overrides ReadOnly Property ConnectionTimeout As Integer
            Get
                Return 0
            End Get
        End Property

        <EditorBrowsable(EditorBrowsableState.Never), Browsable(False)> _
        Public Overrides ReadOnly Property Database As String
            Get
                Return String.Empty
            End Get
        End Property

        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), ResDescription("OracleConnection_DataSource"), Browsable(False)> _
        Public Overrides ReadOnly Property DataSource As String
            Get
                Dim connectionOptions As OracleConnectionString = DirectCast(Me.ConnectionOptions, OracleConnectionString)
                Dim dataSource As String = String.Empty
                If (Not connectionOptions Is Nothing) Then
                    dataSource = connectionOptions.DataSource
                End If
                Return dataSource
            End Get
        End Property

        Friend ReadOnly Property EnvironmentHandle As OciEnvironmentHandle
            Get
                Return Me.GetOpenInternalConnection.EnvironmentHandle
            End Get
        End Property

        Friend ReadOnly Property ErrorHandle As OciErrorHandle
            Get
                Return Me.GetOpenInternalConnection.ErrorHandle
            End Get
        End Property

        Friend ReadOnly Property HasTransaction As Boolean
            Get
                Return Me.GetOpenInternalConnection.HasTransaction
            End Get
        End Property

        Friend ReadOnly Property InnerConnection As DbConnectionInternal
            Get
                Return Me._innerConnection
            End Get
        End Property

        Friend Property PoolGroup As DbConnectionPoolGroup
            Get
                Return Me._poolGroup
            End Get
            Set(ByVal value As DbConnectionPoolGroup)
                Me._poolGroup = value
            End Set
        End Property

        Friend ReadOnly Property ServerTimeZoneAdjustmentToUTC As TimeSpan
            Get
                Return Me.GetOpenInternalConnection.GetServerTimeZoneAdjustmentToUTC(Me)
            End Get
        End Property

        <Browsable(False), ResDescription("OracleConnection_ServerVersion"), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Overrides ReadOnly Property ServerVersion As String
            Get
                Return Me.GetOpenInternalConnection.ServerVersion
            End Get
        End Property

        Friend ReadOnly Property ServerVersionAtLeastOracle8 As Boolean
            Get
                Return Me.GetOpenInternalConnection.ServerVersionAtLeastOracle8
            End Get
        End Property

        Friend ReadOnly Property ServerVersionAtLeastOracle9i As Boolean
            Get
                Return Me.GetOpenInternalConnection.ServerVersionAtLeastOracle9i
            End Get
        End Property

        Friend ReadOnly Property ServiceContextHandle As OciServiceContextHandle
            Get
                Return Me.GetOpenInternalConnection.ServiceContextHandle
            End Get
        End Property

        <ResDescription("DbConnection_State"), Browsable(False), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Overrides ReadOnly Property State As ConnectionState
            Get
                Return Me.InnerConnection.State
            End Get
        End Property

        Friend ReadOnly Property Transaction As OracleTransaction
            Get
                Return Me.GetOpenInternalConnection.Transaction
            End Get
        End Property

        Friend Property TransactionState As TransactionState
            Get
                Return Me.GetOpenInternalConnection.TransactionState
            End Get
            Set(ByVal value As TransactionState)
                Me.GetOpenInternalConnection.TransactionState = value
            End Set
        End Property

        Friend ReadOnly Property UnicodeEnabled As Boolean
            Get
                Return Me.GetOpenInternalConnection.UnicodeEnabled
            End Get
        End Property

        Friend ReadOnly Property UserConnectionOptions As DbConnectionOptions
            Get
                Return Me._userConnectionOptions
            End Get
        End Property


        ' Fields
        Private _closeCount As Integer
        Private Shared ReadOnly _connectionFactory As DbConnectionFactory = OracleConnectionFactory.SingletonInstance
        Private _innerConnection As DbConnectionInternal
        Private Shared _objectTypeCount As Integer
        Private _poolGroup As DbConnectionPoolGroup
        Private _userConnectionOptions As DbConnectionOptions
        Private Shared ReadOnly EventInfoMessage As Object = New Object
        Friend Shared ReadOnly ExecutePermission As CodeAccessPermission = OracleConnection.CreateExecutePermission
        Friend ReadOnly ObjectID As Integer
    End Class
End Namespace

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值