OleDbConnection.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Data / System / Data / OleDb / OleDbConnection.cs / 1 / OleDbConnection.cs

                            //------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.OleDb {
 
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data; 
    using System.Data.Common;
    using System.Data.ProviderBase; 
    using System.Diagnostics; 
    using System.Globalization;
    using System.IO; 
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Permissions;
    using System.Text; 
    using System.Threading;
    using SysTx = System.Transactions; 
 
    // wraps the OLEDB IDBInitialize interface which represents a connection
    // Notes about connection pooling 
    // 1. Connection pooling isn't supported on Win95
    // 2. Only happens if we use the IDataInitialize or IDBPromptInitialize interfaces
    //    it won't happen if you directly create the provider and set its properties
    // 3. First call on IDBInitialize must be Initialize, can't QI for any other interfaces before that 
    [DefaultEvent("InfoMessage")]
#if WINFSInternalOnly 
    internal 
#else
    public 
#endif
    sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConnection {

        static private readonly object EventInfoMessage = new object(); 

        public OleDbConnection(string connectionString) : this() { 
            ConnectionString = connectionString; 
        }
 
        private OleDbConnection(OleDbConnection connection) : this() { // Clone
            CopyFrom(connection);
        }
 
        [
        DefaultValue(""), 
        RecommendedAsConfigurable(true), 
        RefreshProperties(RefreshProperties.All),
        ResCategoryAttribute(Res.DataCategory_Data), 
        Editor("Microsoft.VSDesigner.Data.ADO.Design.OleDbConnectionStringEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
        ResDescriptionAttribute(Res.OleDbConnection_ConnectionString),
        ]
        override public string ConnectionString { 
            get {
                return ConnectionString_Get(); 
            } 
            set {
                ConnectionString_Set(value); 
            }
        }

        private OleDbConnectionString OleDbConnectionStringValue { 
            get { return (OleDbConnectionString)ConnectionOptions; }
        } 
 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        ResDescriptionAttribute(Res.OleDbConnection_ConnectionTimeout),
        ]
        override public int ConnectionTimeout {
            get { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try { 
                    object value = null;
                    if (IsOpen) { 
                        value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_TIMEOUT);
                    }
                    else {
                        OleDbConnectionString constr = this.OleDbConnectionStringValue; 
                        value = (null != constr) ? constr.ConnectTimeout : ADP.DefaultConnectionTimeout;
                    } 
                    if (null != value) { 
                        return Convert.ToInt32(value, CultureInfo.InvariantCulture);
                    } 
                    else {
                        return ADP.DefaultConnectionTimeout;
                    }
                } 
                finally {
                    Bid.ScopeLeave(ref hscp); 
                } 
            }
        } 

        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ResDescriptionAttribute(Res.OleDbConnection_Database), 
        ]
        override public string Database { 
            get { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try {
                    OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions;
                    object value = (null != constr) ? constr.InitialCatalog : ADP.StrEmpty;
                    if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) { 
                        OleDbConnectionInternal connection = GetOpenConnection();
                        if (null != connection) { 
                            if (connection.HasSession) { 
                                value = GetDataSourceValue(OleDbPropertySetGuid.DataSource, ODB.DBPROP_CURRENTCATALOG);
                            } 
                            else {
                                value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_CATALOG);
                            }
                        } 
                        else {
                            constr = this.OleDbConnectionStringValue; 
                            value = (null != constr) ? constr.InitialCatalog : ADP.StrEmpty; 
                        }
                    } 
                    return Convert.ToString(value, CultureInfo.InvariantCulture);
                }
                finally {
                    Bid.ScopeLeave(ref hscp); 
                }
            } 
        } 

        [ 
        Browsable(true),
        ResDescriptionAttribute(Res.OleDbConnection_DataSource),
        ]
        override public string DataSource { 
            get {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try {
                    OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions; 
                    object value = (null != constr) ? constr.DataSource : ADP.StrEmpty;
                    if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) {
                        if (IsOpen) {
                            value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_DATASOURCE); 
                            if ((null == value) || ((value is string) && (0 == (value as string).Length))) {
                                value = GetDataSourceValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DATASOURCENAME); // MDAC 76248 
                            } 
                        }
                        else { 
                            constr = this.OleDbConnectionStringValue;
                            value = (null != constr) ? constr.DataSource : ADP.StrEmpty;
                        }
                    } 
                    return Convert.ToString(value, CultureInfo.InvariantCulture);
                } 
                finally { 
                    Bid.ScopeLeave(ref hscp);
                } 
            }
        }

        internal bool IsOpen { 
            get { return (null != GetOpenConnection()); }
        } 
 
        internal OleDbTransaction LocalTransaction {
            set { 
                OleDbConnectionInternal openConnection = GetOpenConnection();

                if (null != openConnection) {
                    openConnection.LocalTransaction = value; 
                }
            } 
        } 

        [ 
        Browsable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
       ResCategoryAttribute(Res.DataCategory_Data),
        ResDescriptionAttribute(Res.OleDbConnection_Provider), 
        ]
        public String Provider { 
            get { 
                Bid.Trace(" %d#\n", ObjectID);
                OleDbConnectionString constr = this.OleDbConnectionStringValue; 
                string value = ((null != constr) ? constr.ConvertValueToString(ODB.Provider, null) : null);
                return ((null != value) ? value : ADP.StrEmpty);
            }
        } 

        internal OleDbConnectionPoolGroupProviderInfo ProviderInfo { 
            get { 
                return (OleDbConnectionPoolGroupProviderInfo)PoolGroup.ProviderInfo;
            } 
        }

        [
        ResDescriptionAttribute(Res.OleDbConnection_ServerVersion), 
        ]
        override public string ServerVersion { // MDAC 55481 
            get { 
                return InnerConnection.ServerVersion;
            } 
        }

        [
        EditorBrowsableAttribute(EditorBrowsableState.Advanced), 
        ]
        public void ResetState() { // MDAC 58606 
            IntPtr hscp; 
            Bid.ScopeEnter(out hscp, " %d#\n", ObjectID);
            try { 
                if (IsOpen) {
                    object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_CONNECTIONSTATUS);
                    if (value is Int32) {
                        int connectionStatus = (int) value; 
                        switch (connectionStatus) {
                        case ODB.DBPROPVAL_CS_UNINITIALIZED: // provider closed on us 
                        case ODB.DBPROPVAL_CS_COMMUNICATIONFAILURE: // broken connection 
                            GetOpenConnection().DoomThisConnection();
                            NotifyWeakReference(OleDbReferenceCollection.Canceling); // MDAC 71435 
                            Close();
                            break;

                        case ODB.DBPROPVAL_CS_INITIALIZED: // everything is okay 
                            break;
 
                        default: // have to assume everything is okay 
                            Debug.Assert(false, "Unknown 'Connection Status' value " + connectionStatus.ToString("G", CultureInfo.InvariantCulture));
                            break; 
                        }
                    }
                }
            } 
            finally {
                Bid.ScopeLeave(ref hscp); 
            } 
        }
 
        [
        ResCategoryAttribute(Res.DataCategory_InfoMessage),
        ResDescriptionAttribute(Res.DbConnection_InfoMessage),
        ] 
        public event OleDbInfoMessageEventHandler InfoMessage {
            add { 
                Events.AddHandler(EventInfoMessage, value); 
            }
            remove { 
                Events.RemoveHandler(EventInfoMessage, value);
            }
        }
 
        internal UnsafeNativeMethods.ICommandText ICommandText() {
            Debug.Assert(null != GetOpenConnection(), "ICommandText closed"); 
            return GetOpenConnection().ICommandText(); 
        }
 
        private IDBPropertiesWrapper IDBProperties() {
            Debug.Assert(null != GetOpenConnection(), "IDBProperties closed");
            return GetOpenConnection().IDBProperties();
        } 

        internal IOpenRowsetWrapper IOpenRowset() { 
            Debug.Assert(null != GetOpenConnection(), "IOpenRowset closed"); 
            return GetOpenConnection().IOpenRowset();
        } 

        internal int SqlSupport() {
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SqlSupport");
            return this.OleDbConnectionStringValue.GetSqlSupport(this); 
        }
 
        internal bool SupportMultipleResults() { 
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SupportMultipleResults");
            return this.OleDbConnectionStringValue.GetSupportMultipleResults(this); 
        }

        internal bool SupportIRow(OleDbCommand cmd) { // MDAC 72902
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SupportIRow"); 
            return this.OleDbConnectionStringValue.GetSupportIRow(this, cmd);
        } 
 
        internal int QuotedIdentifierCase() { // MDAC 67385
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString QuotedIdentifierCase"); 

            int quotedIdentifierCase;
            object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_QUOTEDIDENTIFIERCASE);
            if (value is Int32) {// not OleDbPropertyStatus 
                quotedIdentifierCase =  (int) value;
            } 
            else { 
                quotedIdentifierCase = -1;
            } 
            return quotedIdentifierCase;
        }

        new public OleDbTransaction BeginTransaction() { 
            return BeginTransaction(IsolationLevel.Unspecified);
        } 
 
        new public OleDbTransaction BeginTransaction(IsolationLevel isolationLevel) {
            return (OleDbTransaction)InnerConnection.BeginTransaction(isolationLevel); 
        }

        override public void ChangeDatabase(string value) {
            OleDbConnection.ExecutePermission.Demand(); 

            IntPtr hscp; 
            Bid.ScopeEnter(out hscp, " %d#, value='%ls'\n", ObjectID, value); 
            try {
                CheckStateOpen(ADP.ChangeDatabase); 
                if ((null == value) || (0 == value.Trim().Length)) { // MDAC 62679
                    throw ADP.EmptyDatabaseName();
                }
                SetDataSourcePropertyValue(OleDbPropertySetGuid.DataSource, ODB.DBPROP_CURRENTCATALOG, ODB.Current_Catalog, true, value); 
            }
            finally { 
                Bid.ScopeLeave(ref hscp); 
            }
        } 

        internal void CheckStateOpen(string method) {
            ConnectionState state = State;
            if (ConnectionState.Open != state) { 
                throw ADP.OpenConnectionRequired(method, state);
            } 
        } 

        object ICloneable.Clone() { 
            OleDbConnection clone = new OleDbConnection(this);
            Bid.Trace(" %d#, clone=%d#\n", ObjectID, clone.ObjectID);
            return clone;
        } 

        override public void Close() { 
            InnerConnection.CloseConnection(this, ConnectionFactory); 
            // does not require GC.KeepAlive(this) because of OnStateChange
        } 

        new public OleDbCommand CreateCommand() {
            return new OleDbCommand("", this);
        } 

        private void DisposeMe(bool disposing) { // MDAC 65459 
            if (disposing) { // release mananged objects 
                if (DesignMode) {
                    // release the object pool in design-mode so that 
                    // native MDAC can be properly released during shutdown
                    OleDbConnection.ReleaseObjectPool();
                }
            } 
        }
 
        public void EnlistDistributedTransaction(System.EnterpriseServices.ITransaction transaction) { 
            EnlistDistributedTransactionHelper(transaction);
        } 

        internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) {
            OleDbConnectionInternal connection = GetOpenConnection();
            return connection.GetDataSourcePropertyValue(propertySet, propertyID); 
        }
 
        internal object GetDataSourceValue(Guid propertySet, int propertyID) { 
            object value = GetDataSourcePropertyValue(propertySet, propertyID);
            if ((value is OleDbPropertyStatus) || Convert.IsDBNull(value)) { 
                value = null;
            }
            return value;
        } 

        private OleDbConnectionInternal GetOpenConnection() { 
            DbConnectionInternal innerConnection = InnerConnection; 
            return (innerConnection as OleDbConnectionInternal);
        } 

        internal void GetLiteralQuotes(string method, out string quotePrefix, out string quoteSuffix) {
            CheckStateOpen(method);
            OleDbConnectionPoolGroupProviderInfo info = ProviderInfo; 
            if (info.HasQuoteFix) {
                quotePrefix = info.QuotePrefix; 
                quoteSuffix = info.QuoteSuffix; 
            }
            else { 
                OleDbConnectionInternal connection = GetOpenConnection();
                quotePrefix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_PREFIX);
                quoteSuffix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_SUFFIX);
                if (null == quotePrefix) { 
                    quotePrefix = "";
                } 
                if (null == quoteSuffix) { 
                    quoteSuffix = quotePrefix;
                } 
                info.SetQuoteFix(quotePrefix, quoteSuffix);
            }
        }
 
        public DataTable GetOleDbSchemaTable(Guid schema, object[] restrictions) { // MDAC 61846
            OleDbConnection.ExecutePermission.Demand(); 
 
            IntPtr hscp;
            Bid.ScopeEnter(out hscp, " %d#, schema=%p{GUID}, restrictions\n", ObjectID, schema); 
            try {
                CheckStateOpen(ADP.GetOleDbSchemaTable);
                OleDbConnectionInternal connection = GetOpenConnection();
 
                if (OleDbSchemaGuid.DbInfoLiterals == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) { 
                        return connection.BuildInfoLiterals(); 
                    }
                    throw ODB.InvalidRestrictionsDbInfoLiteral("restrictions"); 
                }
                else if (OleDbSchemaGuid.SchemaGuids == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) {
                        return connection.BuildSchemaGuids(); 
                    }
                    throw ODB.InvalidRestrictionsSchemaGuids("restrictions"); 
                } 
                else if (OleDbSchemaGuid.DbInfoKeywords == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) { 
                        return connection.BuildInfoKeywords();
                    }
                    throw ODB.InvalidRestrictionsDbInfoKeywords("restrictions");
                } 

                if (connection.SupportSchemaRowset(schema)) { 
                    return connection.GetSchemaRowset(schema, restrictions); 
                }
                else { 
                    using(IDBSchemaRowsetWrapper wrapper = connection.IDBSchemaRowset()) {
                        if (null == wrapper.Value) {
                            throw ODB.SchemaRowsetsNotSupported(Provider); // MDAC 72689
                        } 
                    }
                    throw ODB.NotSupportedSchemaTable(schema, this); // MDAC 63279 
                } 
            }
            finally { 
                Bid.ScopeLeave(ref hscp);
            }
        }
 
        internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) {
            Debug.Assert(null != GetOpenConnection(), "GetSchemaRowset closed"); 
            return GetOpenConnection().GetSchemaRowset(schema, restrictions); 
        }
 
        internal bool HasLiveReader(OleDbCommand cmd)  {
            bool result = false;
            OleDbConnectionInternal openConnection = GetOpenConnection();
 
            if (null != openConnection) {
                result = openConnection.HasLiveReader(cmd); 
            } 
            return result;
        } 

        internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) {
            OleDbInfoMessageEventHandler handler = (OleDbInfoMessageEventHandler) Events[EventInfoMessage];
            if (null != handler) { 
                try {
                    OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); 
                    OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); 
                    if (Bid.TraceOn) {
                        Bid.Trace(" %d#, Message='%ls'\n", ObjectID, e.Message); 
                    }
                    handler(this, e);
                }
                catch (Exception e) { // eat the exception 
                    //
                    if (!ADP.IsCatchableOrSecurityExceptionType(e)) { 
                        throw; 
                    }
 
                    ADP.TraceExceptionWithoutRethrow(e);
                }
            }
#if DEBUG 
            else {
                OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); 
                Bid.Trace(" %d#, Message='%ls'\n", ObjectID, exception.Message); 
            }
#endif 
        }

        override public void Open() {
            InnerConnection.OpenConnection(this, ConnectionFactory); 

            // SQLBUDT #276132 - need to manually enlist in some cases, because 
            // native OLE DB doesn't know about SysTx transactions. 
            if ((0!=(ODB.DBPROPVAL_OS_TXNENLISTMENT & ((OleDbConnectionString)(this.ConnectionOptions)).OleDbServices))
                        && ADP.NeedManualEnlistment()) { 
                GetOpenConnection().EnlistTransactionInternal(SysTx.Transaction.Current, true);
            }
        }
 
        internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, string description, bool required, object value) {
            CheckStateOpen(ADP.SetProperties); 
            OleDbHResult hr; 
            using(IDBPropertiesWrapper idbProperties = IDBProperties()) {
                using(DBPropSet propSet = DBPropSet.CreateProperty(propertySet, propertyID, required, value)) { 

                    Bid.Trace(" %d#\n", ObjectID);
                    hr = idbProperties.Value.SetProperties(propSet.PropertySetCount, propSet);
                    Bid.Trace(" %08X{HRESULT}\n", hr); 

                    if (hr < 0) { 
                        Exception e = OleDbConnection.ProcessResults(hr, null, this); 
                        if (OleDbHResult.DB_E_ERRORSOCCURRED == hr) {
 
                            StringBuilder builder = new StringBuilder();
                            Debug.Assert(1 == propSet.PropertySetCount, "too many PropertySets");

                            tagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet); 
                            Debug.Assert(1 == dbprops.Length, "too many Properties");
 
                            ODB.PropsetSetFailure(builder, description, dbprops[0].dwStatus); 

                            e = ODB.PropsetSetFailure(builder.ToString(), e); 
                        }
                        if (null != e) {
                            throw e;
                        } 
                    }
                    else { 
                        SafeNativeMethods.Wrapper.ClearErrorInfo(); 
                    }
                } 
            }
        }

        internal bool SupportSchemaRowset(Guid schema) { 
            return GetOpenConnection().SupportSchemaRowset(schema);
        } 
 
        internal OleDbTransaction ValidateTransaction(OleDbTransaction transaction, string method) {
            return GetOpenConnection().ValidateTransaction(transaction, method); 
        }

        static internal Exception ProcessResults(OleDbHResult hresult, OleDbConnection connection, object src) {
            if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) { 
                SafeNativeMethods.Wrapper.ClearErrorInfo();
                return null; 
            } 

            // ErrorInfo object is to be checked regardless the hresult returned by the function called 
            Exception e = null;
            UnsafeNativeMethods.IErrorInfo errorInfo = null;
            OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo);  // 0 - IErrorInfo exists, 1 - no IErrorInfo
            if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) { 
                if (hresult < 0) {
                    // 
 

 


                    e = OleDbException.CreateException(errorInfo, hresult, null);
                    //} 

                    if (OleDbHResult.DB_E_OBJECTOPEN == hresult) { 
                        e = ADP.OpenReaderExists(e); 
                    }
 
                    ResetState(connection);
                }
                else if (null != connection) {
                    connection.OnInfoMessage(errorInfo, hresult); 
                }
                else { 
                    Bid.Trace(" ErrorInfo available, but not connection %08X{HRESULT}\n", hresult); 
                }
                Marshal.ReleaseComObject(errorInfo); 
            }
            else if (0 < hresult) {
                // @devnote: OnInfoMessage with no ErrorInfo
                Bid.Trace(" ErrorInfo not available %08X{HRESULT}\n", hresult); 
            }
            else if ((int)hresult < 0) { 
                e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException 

                ResetState(connection); 
            }
            if (null != e) {
                ADP.TraceExceptionAsReturnValue(e);
            } 
            return e;
        } 
 
        // @devnote: should be multithread safe
        static public void ReleaseObjectPool() { 
            (new OleDbPermission(PermissionState.Unrestricted)).Demand();

            IntPtr hscp;
            Bid.ScopeEnter(out hscp, "\n"); 
            try {
                OleDbConnectionString.ReleaseObjectPool(); 
                OleDbConnectionInternal.ReleaseObjectPool(); 
                OleDbConnectionFactory.SingletonInstance.ClearAllPools();
            } 
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        } 

        static private void ResetState(OleDbConnection connection) { 
            if (null != connection) { 
                connection.ResetState();
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// [....] 
// [....]
//----------------------------------------------------------------------------- 
 
namespace System.Data.OleDb {
 
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data; 
    using System.Data.Common;
    using System.Data.ProviderBase; 
    using System.Diagnostics; 
    using System.Globalization;
    using System.IO; 
    using System.Runtime.InteropServices;
    using System.Security;
    using System.Security.Permissions;
    using System.Text; 
    using System.Threading;
    using SysTx = System.Transactions; 
 
    // wraps the OLEDB IDBInitialize interface which represents a connection
    // Notes about connection pooling 
    // 1. Connection pooling isn't supported on Win95
    // 2. Only happens if we use the IDataInitialize or IDBPromptInitialize interfaces
    //    it won't happen if you directly create the provider and set its properties
    // 3. First call on IDBInitialize must be Initialize, can't QI for any other interfaces before that 
    [DefaultEvent("InfoMessage")]
#if WINFSInternalOnly 
    internal 
#else
    public 
#endif
    sealed partial class OleDbConnection : DbConnection, ICloneable, IDbConnection {

        static private readonly object EventInfoMessage = new object(); 

        public OleDbConnection(string connectionString) : this() { 
            ConnectionString = connectionString; 
        }
 
        private OleDbConnection(OleDbConnection connection) : this() { // Clone
            CopyFrom(connection);
        }
 
        [
        DefaultValue(""), 
        RecommendedAsConfigurable(true), 
        RefreshProperties(RefreshProperties.All),
        ResCategoryAttribute(Res.DataCategory_Data), 
        Editor("Microsoft.VSDesigner.Data.ADO.Design.OleDbConnectionStringEditor, " + AssemblyRef.MicrosoftVSDesigner, "System.Drawing.Design.UITypeEditor, " + AssemblyRef.SystemDrawing),
        ResDescriptionAttribute(Res.OleDbConnection_ConnectionString),
        ]
        override public string ConnectionString { 
            get {
                return ConnectionString_Get(); 
            } 
            set {
                ConnectionString_Set(value); 
            }
        }

        private OleDbConnectionString OleDbConnectionStringValue { 
            get { return (OleDbConnectionString)ConnectionOptions; }
        } 
 
        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), 
        ResDescriptionAttribute(Res.OleDbConnection_ConnectionTimeout),
        ]
        override public int ConnectionTimeout {
            get { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try { 
                    object value = null;
                    if (IsOpen) { 
                        value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_TIMEOUT);
                    }
                    else {
                        OleDbConnectionString constr = this.OleDbConnectionStringValue; 
                        value = (null != constr) ? constr.ConnectTimeout : ADP.DefaultConnectionTimeout;
                    } 
                    if (null != value) { 
                        return Convert.ToInt32(value, CultureInfo.InvariantCulture);
                    } 
                    else {
                        return ADP.DefaultConnectionTimeout;
                    }
                } 
                finally {
                    Bid.ScopeLeave(ref hscp); 
                } 
            }
        } 

        [
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        ResDescriptionAttribute(Res.OleDbConnection_Database), 
        ]
        override public string Database { 
            get { 
                IntPtr hscp;
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try {
                    OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions;
                    object value = (null != constr) ? constr.InitialCatalog : ADP.StrEmpty;
                    if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) { 
                        OleDbConnectionInternal connection = GetOpenConnection();
                        if (null != connection) { 
                            if (connection.HasSession) { 
                                value = GetDataSourceValue(OleDbPropertySetGuid.DataSource, ODB.DBPROP_CURRENTCATALOG);
                            } 
                            else {
                                value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_CATALOG);
                            }
                        } 
                        else {
                            constr = this.OleDbConnectionStringValue; 
                            value = (null != constr) ? constr.InitialCatalog : ADP.StrEmpty; 
                        }
                    } 
                    return Convert.ToString(value, CultureInfo.InvariantCulture);
                }
                finally {
                    Bid.ScopeLeave(ref hscp); 
                }
            } 
        } 

        [ 
        Browsable(true),
        ResDescriptionAttribute(Res.OleDbConnection_DataSource),
        ]
        override public string DataSource { 
            get {
                IntPtr hscp; 
                Bid.ScopeEnter(out hscp, " %d#\n", ObjectID); 
                try {
                    OleDbConnectionString constr = (OleDbConnectionString)UserConnectionOptions; 
                    object value = (null != constr) ? constr.DataSource : ADP.StrEmpty;
                    if ((null != value) && !((string)value).StartsWith(DbConnectionOptions.DataDirectory, StringComparison.OrdinalIgnoreCase)) {
                        if (IsOpen) {
                            value = GetDataSourceValue(OleDbPropertySetGuid.DBInit, ODB.DBPROP_INIT_DATASOURCE); 
                            if ((null == value) || ((value is string) && (0 == (value as string).Length))) {
                                value = GetDataSourceValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_DATASOURCENAME); // MDAC 76248 
                            } 
                        }
                        else { 
                            constr = this.OleDbConnectionStringValue;
                            value = (null != constr) ? constr.DataSource : ADP.StrEmpty;
                        }
                    } 
                    return Convert.ToString(value, CultureInfo.InvariantCulture);
                } 
                finally { 
                    Bid.ScopeLeave(ref hscp);
                } 
            }
        }

        internal bool IsOpen { 
            get { return (null != GetOpenConnection()); }
        } 
 
        internal OleDbTransaction LocalTransaction {
            set { 
                OleDbConnectionInternal openConnection = GetOpenConnection();

                if (null != openConnection) {
                    openConnection.LocalTransaction = value; 
                }
            } 
        } 

        [ 
        Browsable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
       ResCategoryAttribute(Res.DataCategory_Data),
        ResDescriptionAttribute(Res.OleDbConnection_Provider), 
        ]
        public String Provider { 
            get { 
                Bid.Trace(" %d#\n", ObjectID);
                OleDbConnectionString constr = this.OleDbConnectionStringValue; 
                string value = ((null != constr) ? constr.ConvertValueToString(ODB.Provider, null) : null);
                return ((null != value) ? value : ADP.StrEmpty);
            }
        } 

        internal OleDbConnectionPoolGroupProviderInfo ProviderInfo { 
            get { 
                return (OleDbConnectionPoolGroupProviderInfo)PoolGroup.ProviderInfo;
            } 
        }

        [
        ResDescriptionAttribute(Res.OleDbConnection_ServerVersion), 
        ]
        override public string ServerVersion { // MDAC 55481 
            get { 
                return InnerConnection.ServerVersion;
            } 
        }

        [
        EditorBrowsableAttribute(EditorBrowsableState.Advanced), 
        ]
        public void ResetState() { // MDAC 58606 
            IntPtr hscp; 
            Bid.ScopeEnter(out hscp, " %d#\n", ObjectID);
            try { 
                if (IsOpen) {
                    object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_CONNECTIONSTATUS);
                    if (value is Int32) {
                        int connectionStatus = (int) value; 
                        switch (connectionStatus) {
                        case ODB.DBPROPVAL_CS_UNINITIALIZED: // provider closed on us 
                        case ODB.DBPROPVAL_CS_COMMUNICATIONFAILURE: // broken connection 
                            GetOpenConnection().DoomThisConnection();
                            NotifyWeakReference(OleDbReferenceCollection.Canceling); // MDAC 71435 
                            Close();
                            break;

                        case ODB.DBPROPVAL_CS_INITIALIZED: // everything is okay 
                            break;
 
                        default: // have to assume everything is okay 
                            Debug.Assert(false, "Unknown 'Connection Status' value " + connectionStatus.ToString("G", CultureInfo.InvariantCulture));
                            break; 
                        }
                    }
                }
            } 
            finally {
                Bid.ScopeLeave(ref hscp); 
            } 
        }
 
        [
        ResCategoryAttribute(Res.DataCategory_InfoMessage),
        ResDescriptionAttribute(Res.DbConnection_InfoMessage),
        ] 
        public event OleDbInfoMessageEventHandler InfoMessage {
            add { 
                Events.AddHandler(EventInfoMessage, value); 
            }
            remove { 
                Events.RemoveHandler(EventInfoMessage, value);
            }
        }
 
        internal UnsafeNativeMethods.ICommandText ICommandText() {
            Debug.Assert(null != GetOpenConnection(), "ICommandText closed"); 
            return GetOpenConnection().ICommandText(); 
        }
 
        private IDBPropertiesWrapper IDBProperties() {
            Debug.Assert(null != GetOpenConnection(), "IDBProperties closed");
            return GetOpenConnection().IDBProperties();
        } 

        internal IOpenRowsetWrapper IOpenRowset() { 
            Debug.Assert(null != GetOpenConnection(), "IOpenRowset closed"); 
            return GetOpenConnection().IOpenRowset();
        } 

        internal int SqlSupport() {
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SqlSupport");
            return this.OleDbConnectionStringValue.GetSqlSupport(this); 
        }
 
        internal bool SupportMultipleResults() { 
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SupportMultipleResults");
            return this.OleDbConnectionStringValue.GetSupportMultipleResults(this); 
        }

        internal bool SupportIRow(OleDbCommand cmd) { // MDAC 72902
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString SupportIRow"); 
            return this.OleDbConnectionStringValue.GetSupportIRow(this, cmd);
        } 
 
        internal int QuotedIdentifierCase() { // MDAC 67385
            Debug.Assert(null != this.OleDbConnectionStringValue, "no OleDbConnectionString QuotedIdentifierCase"); 

            int quotedIdentifierCase;
            object value = GetDataSourcePropertyValue(OleDbPropertySetGuid.DataSourceInfo, ODB.DBPROP_QUOTEDIDENTIFIERCASE);
            if (value is Int32) {// not OleDbPropertyStatus 
                quotedIdentifierCase =  (int) value;
            } 
            else { 
                quotedIdentifierCase = -1;
            } 
            return quotedIdentifierCase;
        }

        new public OleDbTransaction BeginTransaction() { 
            return BeginTransaction(IsolationLevel.Unspecified);
        } 
 
        new public OleDbTransaction BeginTransaction(IsolationLevel isolationLevel) {
            return (OleDbTransaction)InnerConnection.BeginTransaction(isolationLevel); 
        }

        override public void ChangeDatabase(string value) {
            OleDbConnection.ExecutePermission.Demand(); 

            IntPtr hscp; 
            Bid.ScopeEnter(out hscp, " %d#, value='%ls'\n", ObjectID, value); 
            try {
                CheckStateOpen(ADP.ChangeDatabase); 
                if ((null == value) || (0 == value.Trim().Length)) { // MDAC 62679
                    throw ADP.EmptyDatabaseName();
                }
                SetDataSourcePropertyValue(OleDbPropertySetGuid.DataSource, ODB.DBPROP_CURRENTCATALOG, ODB.Current_Catalog, true, value); 
            }
            finally { 
                Bid.ScopeLeave(ref hscp); 
            }
        } 

        internal void CheckStateOpen(string method) {
            ConnectionState state = State;
            if (ConnectionState.Open != state) { 
                throw ADP.OpenConnectionRequired(method, state);
            } 
        } 

        object ICloneable.Clone() { 
            OleDbConnection clone = new OleDbConnection(this);
            Bid.Trace(" %d#, clone=%d#\n", ObjectID, clone.ObjectID);
            return clone;
        } 

        override public void Close() { 
            InnerConnection.CloseConnection(this, ConnectionFactory); 
            // does not require GC.KeepAlive(this) because of OnStateChange
        } 

        new public OleDbCommand CreateCommand() {
            return new OleDbCommand("", this);
        } 

        private void DisposeMe(bool disposing) { // MDAC 65459 
            if (disposing) { // release mananged objects 
                if (DesignMode) {
                    // release the object pool in design-mode so that 
                    // native MDAC can be properly released during shutdown
                    OleDbConnection.ReleaseObjectPool();
                }
            } 
        }
 
        public void EnlistDistributedTransaction(System.EnterpriseServices.ITransaction transaction) { 
            EnlistDistributedTransactionHelper(transaction);
        } 

        internal object GetDataSourcePropertyValue(Guid propertySet, int propertyID) {
            OleDbConnectionInternal connection = GetOpenConnection();
            return connection.GetDataSourcePropertyValue(propertySet, propertyID); 
        }
 
        internal object GetDataSourceValue(Guid propertySet, int propertyID) { 
            object value = GetDataSourcePropertyValue(propertySet, propertyID);
            if ((value is OleDbPropertyStatus) || Convert.IsDBNull(value)) { 
                value = null;
            }
            return value;
        } 

        private OleDbConnectionInternal GetOpenConnection() { 
            DbConnectionInternal innerConnection = InnerConnection; 
            return (innerConnection as OleDbConnectionInternal);
        } 

        internal void GetLiteralQuotes(string method, out string quotePrefix, out string quoteSuffix) {
            CheckStateOpen(method);
            OleDbConnectionPoolGroupProviderInfo info = ProviderInfo; 
            if (info.HasQuoteFix) {
                quotePrefix = info.QuotePrefix; 
                quoteSuffix = info.QuoteSuffix; 
            }
            else { 
                OleDbConnectionInternal connection = GetOpenConnection();
                quotePrefix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_PREFIX);
                quoteSuffix = connection.GetLiteralInfo(ODB.DBLITERAL_QUOTE_SUFFIX);
                if (null == quotePrefix) { 
                    quotePrefix = "";
                } 
                if (null == quoteSuffix) { 
                    quoteSuffix = quotePrefix;
                } 
                info.SetQuoteFix(quotePrefix, quoteSuffix);
            }
        }
 
        public DataTable GetOleDbSchemaTable(Guid schema, object[] restrictions) { // MDAC 61846
            OleDbConnection.ExecutePermission.Demand(); 
 
            IntPtr hscp;
            Bid.ScopeEnter(out hscp, " %d#, schema=%p{GUID}, restrictions\n", ObjectID, schema); 
            try {
                CheckStateOpen(ADP.GetOleDbSchemaTable);
                OleDbConnectionInternal connection = GetOpenConnection();
 
                if (OleDbSchemaGuid.DbInfoLiterals == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) { 
                        return connection.BuildInfoLiterals(); 
                    }
                    throw ODB.InvalidRestrictionsDbInfoLiteral("restrictions"); 
                }
                else if (OleDbSchemaGuid.SchemaGuids == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) {
                        return connection.BuildSchemaGuids(); 
                    }
                    throw ODB.InvalidRestrictionsSchemaGuids("restrictions"); 
                } 
                else if (OleDbSchemaGuid.DbInfoKeywords == schema) {
                    if ((null == restrictions) || (0 == restrictions.Length)) { 
                        return connection.BuildInfoKeywords();
                    }
                    throw ODB.InvalidRestrictionsDbInfoKeywords("restrictions");
                } 

                if (connection.SupportSchemaRowset(schema)) { 
                    return connection.GetSchemaRowset(schema, restrictions); 
                }
                else { 
                    using(IDBSchemaRowsetWrapper wrapper = connection.IDBSchemaRowset()) {
                        if (null == wrapper.Value) {
                            throw ODB.SchemaRowsetsNotSupported(Provider); // MDAC 72689
                        } 
                    }
                    throw ODB.NotSupportedSchemaTable(schema, this); // MDAC 63279 
                } 
            }
            finally { 
                Bid.ScopeLeave(ref hscp);
            }
        }
 
        internal DataTable GetSchemaRowset(Guid schema, object[] restrictions) {
            Debug.Assert(null != GetOpenConnection(), "GetSchemaRowset closed"); 
            return GetOpenConnection().GetSchemaRowset(schema, restrictions); 
        }
 
        internal bool HasLiveReader(OleDbCommand cmd)  {
            bool result = false;
            OleDbConnectionInternal openConnection = GetOpenConnection();
 
            if (null != openConnection) {
                result = openConnection.HasLiveReader(cmd); 
            } 
            return result;
        } 

        internal void OnInfoMessage(UnsafeNativeMethods.IErrorInfo errorInfo, OleDbHResult errorCode) {
            OleDbInfoMessageEventHandler handler = (OleDbInfoMessageEventHandler) Events[EventInfoMessage];
            if (null != handler) { 
                try {
                    OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); 
                    OleDbInfoMessageEventArgs e = new OleDbInfoMessageEventArgs(exception); 
                    if (Bid.TraceOn) {
                        Bid.Trace(" %d#, Message='%ls'\n", ObjectID, e.Message); 
                    }
                    handler(this, e);
                }
                catch (Exception e) { // eat the exception 
                    //
                    if (!ADP.IsCatchableOrSecurityExceptionType(e)) { 
                        throw; 
                    }
 
                    ADP.TraceExceptionWithoutRethrow(e);
                }
            }
#if DEBUG 
            else {
                OleDbException exception = OleDbException.CreateException(errorInfo, errorCode, null); 
                Bid.Trace(" %d#, Message='%ls'\n", ObjectID, exception.Message); 
            }
#endif 
        }

        override public void Open() {
            InnerConnection.OpenConnection(this, ConnectionFactory); 

            // SQLBUDT #276132 - need to manually enlist in some cases, because 
            // native OLE DB doesn't know about SysTx transactions. 
            if ((0!=(ODB.DBPROPVAL_OS_TXNENLISTMENT & ((OleDbConnectionString)(this.ConnectionOptions)).OleDbServices))
                        && ADP.NeedManualEnlistment()) { 
                GetOpenConnection().EnlistTransactionInternal(SysTx.Transaction.Current, true);
            }
        }
 
        internal void SetDataSourcePropertyValue(Guid propertySet, int propertyID, string description, bool required, object value) {
            CheckStateOpen(ADP.SetProperties); 
            OleDbHResult hr; 
            using(IDBPropertiesWrapper idbProperties = IDBProperties()) {
                using(DBPropSet propSet = DBPropSet.CreateProperty(propertySet, propertyID, required, value)) { 

                    Bid.Trace(" %d#\n", ObjectID);
                    hr = idbProperties.Value.SetProperties(propSet.PropertySetCount, propSet);
                    Bid.Trace(" %08X{HRESULT}\n", hr); 

                    if (hr < 0) { 
                        Exception e = OleDbConnection.ProcessResults(hr, null, this); 
                        if (OleDbHResult.DB_E_ERRORSOCCURRED == hr) {
 
                            StringBuilder builder = new StringBuilder();
                            Debug.Assert(1 == propSet.PropertySetCount, "too many PropertySets");

                            tagDBPROP[] dbprops = propSet.GetPropertySet(0, out propertySet); 
                            Debug.Assert(1 == dbprops.Length, "too many Properties");
 
                            ODB.PropsetSetFailure(builder, description, dbprops[0].dwStatus); 

                            e = ODB.PropsetSetFailure(builder.ToString(), e); 
                        }
                        if (null != e) {
                            throw e;
                        } 
                    }
                    else { 
                        SafeNativeMethods.Wrapper.ClearErrorInfo(); 
                    }
                } 
            }
        }

        internal bool SupportSchemaRowset(Guid schema) { 
            return GetOpenConnection().SupportSchemaRowset(schema);
        } 
 
        internal OleDbTransaction ValidateTransaction(OleDbTransaction transaction, string method) {
            return GetOpenConnection().ValidateTransaction(transaction, method); 
        }

        static internal Exception ProcessResults(OleDbHResult hresult, OleDbConnection connection, object src) {
            if ((0 <= (int)hresult) && ((null == connection) || (null == connection.Events[EventInfoMessage]))) { 
                SafeNativeMethods.Wrapper.ClearErrorInfo();
                return null; 
            } 

            // ErrorInfo object is to be checked regardless the hresult returned by the function called 
            Exception e = null;
            UnsafeNativeMethods.IErrorInfo errorInfo = null;
            OleDbHResult hr = UnsafeNativeMethods.GetErrorInfo(0, out errorInfo);  // 0 - IErrorInfo exists, 1 - no IErrorInfo
            if ((OleDbHResult.S_OK == hr) && (null != errorInfo)) { 
                if (hresult < 0) {
                    // 
 

 


                    e = OleDbException.CreateException(errorInfo, hresult, null);
                    //} 

                    if (OleDbHResult.DB_E_OBJECTOPEN == hresult) { 
                        e = ADP.OpenReaderExists(e); 
                    }
 
                    ResetState(connection);
                }
                else if (null != connection) {
                    connection.OnInfoMessage(errorInfo, hresult); 
                }
                else { 
                    Bid.Trace(" ErrorInfo available, but not connection %08X{HRESULT}\n", hresult); 
                }
                Marshal.ReleaseComObject(errorInfo); 
            }
            else if (0 < hresult) {
                // @devnote: OnInfoMessage with no ErrorInfo
                Bid.Trace(" ErrorInfo not available %08X{HRESULT}\n", hresult); 
            }
            else if ((int)hresult < 0) { 
                e = ODB.NoErrorInformation((null != connection) ? connection.Provider : null, hresult, null); // OleDbException 

                ResetState(connection); 
            }
            if (null != e) {
                ADP.TraceExceptionAsReturnValue(e);
            } 
            return e;
        } 
 
        // @devnote: should be multithread safe
        static public void ReleaseObjectPool() { 
            (new OleDbPermission(PermissionState.Unrestricted)).Demand();

            IntPtr hscp;
            Bid.ScopeEnter(out hscp, "\n"); 
            try {
                OleDbConnectionString.ReleaseObjectPool(); 
                OleDbConnectionInternal.ReleaseObjectPool(); 
                OleDbConnectionFactory.SingletonInstance.ClearAllPools();
            } 
            finally {
                Bid.ScopeLeave(ref hscp);
            }
        } 

        static private void ResetState(OleDbConnection connection) { 
            if (null != connection) { 
                connection.ResetState();
            } 
        }
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.

                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK