| File: System\Data\Odbc\OdbcConnectionHelper.cs | Web Access |
| Project: src\runtime\src\libraries\System.Data.Odbc\src\System.Data.Odbc.csproj (System.Data.Odbc) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Data.Common; using System.Data.ProviderBase; using System.Diagnostics; using System.Threading; namespace System.Data.Odbc { public sealed partial class OdbcConnection : DbConnection { private static readonly DbConnectionFactory s_connectionFactory = OdbcConnectionFactory.SingletonInstance; private DbConnectionOptions? _userConnectionOptions; private DbConnectionPoolGroup? _poolGroup; private DbConnectionInternal _innerConnection; private int _closeCount; public OdbcConnection() : base() { GC.SuppressFinalize(this); _innerConnection = DbConnectionClosedNeverOpened.SingletonInstance; } // Copy Constructor private void CopyFrom(OdbcConnection connection) { // V1.2.3300 ADP.CheckArgumentNull(connection, nameof(connection)); _userConnectionOptions = connection.UserConnectionOptions; _poolGroup = connection.PoolGroup; // SQLBU 432115 // Match the original connection's behavior for whether the connection was never opened, // but ensure Clone is in the closed state. if (DbConnectionClosedNeverOpened.SingletonInstance == connection._innerConnection) { _innerConnection = DbConnectionClosedNeverOpened.SingletonInstance; } else { _innerConnection = DbConnectionClosedPreviouslyOpened.SingletonInstance; } } internal int CloseCount { get { return _closeCount; } } internal static DbConnectionFactory ConnectionFactory { get { return s_connectionFactory; } } internal DbConnectionOptions? ConnectionOptions { get { System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; return poolGroup?.ConnectionOptions; } } private string ConnectionString_Get() { bool hidePassword = InnerConnection.ShouldHidePassword; DbConnectionOptions? connectionOptions = UserConnectionOptions; return ((null != connectionOptions) ? connectionOptions.UsersConnectionString(hidePassword) : ""); } private void ConnectionString_Set(string? value) { DbConnectionPoolKey key = new DbConnectionPoolKey(value); ConnectionString_Set(key); } private void ConnectionString_Set(DbConnectionPoolKey key) { DbConnectionOptions? connectionOptions = null; System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = ConnectionFactory.GetConnectionPoolGroup(key, null, ref connectionOptions); DbConnectionInternal connectionInternal = InnerConnection; bool flag = connectionInternal.AllowSetConnectionString; if (flag) { flag = SetInnerConnectionFrom(DbConnectionClosedBusy.SingletonInstance, connectionInternal); if (flag) { _userConnectionOptions = connectionOptions; _poolGroup = poolGroup; _innerConnection = DbConnectionClosedNeverOpened.SingletonInstance; } } if (!flag) { throw ADP.OpenConnectionPropertySet(nameof(ConnectionString), connectionInternal.State); } } internal DbConnectionInternal InnerConnection { get { return _innerConnection; } } internal System.Data.ProviderBase.DbConnectionPoolGroup? PoolGroup { get { return _poolGroup; } set { Debug.Assert(null != value, "null poolGroup"); _poolGroup = value; } } internal DbConnectionOptions? UserConnectionOptions { get { return _userConnectionOptions; } } internal void Abort() { DbConnectionInternal innerConnection = _innerConnection; if (ConnectionState.Open == innerConnection.State) { Interlocked.CompareExchange(ref _innerConnection, DbConnectionClosedPreviouslyOpened.SingletonInstance, innerConnection); innerConnection.DoomThisConnection(); } } internal void AddWeakReference(object value, int tag) { InnerConnection.AddWeakReference(value, tag); } protected override DbCommand CreateDbCommand() { DbProviderFactory providerFactory = ConnectionFactory.ProviderFactory; DbCommand command = providerFactory.CreateCommand()!; command.Connection = this; return command; } protected override void Dispose(bool disposing) { if (disposing) { _userConnectionOptions = null; _poolGroup = null; Close(); } base.Dispose(disposing); } partial void RepairInnerConnection(); public override DataTable GetSchema() { return this.GetSchema(DbMetaDataCollectionNames.MetaDataCollections, null); } public override DataTable GetSchema(string collectionName) { return this.GetSchema(collectionName, null); } public override DataTable GetSchema(string collectionName, string?[]? restrictionValues) { // NOTE: This is virtual because not all providers may choose to support // returning schema data return InnerConnection.GetSchema(ConnectionFactory, PoolGroup!, this, collectionName, restrictionValues); } internal void NotifyWeakReference(int message) { InnerConnection.NotifyWeakReference(message); } internal void PermissionDemand() { Debug.Assert(DbConnectionClosedConnecting.SingletonInstance == _innerConnection, "not connecting"); System.Data.ProviderBase.DbConnectionPoolGroup? poolGroup = PoolGroup; DbConnectionOptions? connectionOptions = poolGroup?.ConnectionOptions; if ((null == connectionOptions) || connectionOptions.IsEmpty) { throw ADP.NoConnectionString(); } DbConnectionOptions? userConnectionOptions = UserConnectionOptions; Debug.Assert(null != userConnectionOptions, "null UserConnectionOptions"); } internal void RemoveWeakReference(object value) { InnerConnection.RemoveWeakReference(value); } internal void SetInnerConnectionEvent(DbConnectionInternal to) { Debug.Assert(null != _innerConnection, "null InnerConnection"); Debug.Assert(null != to, "to null InnerConnection"); ConnectionState originalState = _innerConnection.State & ConnectionState.Open; ConnectionState currentState = to.State & ConnectionState.Open; if ((originalState != currentState) && (ConnectionState.Closed == currentState)) { unchecked { _closeCount++; } } _innerConnection = to; if (ConnectionState.Closed == originalState && ConnectionState.Open == currentState) { OnStateChange(DbConnectionInternal.StateChangeOpen); } else if (ConnectionState.Open == originalState && ConnectionState.Closed == currentState) { OnStateChange(DbConnectionInternal.StateChangeClosed); } else { Debug.Fail("unexpected state switch"); if (originalState != currentState) { OnStateChange(new StateChangeEventArgs(originalState, currentState)); } } } internal bool SetInnerConnectionFrom(DbConnectionInternal to, DbConnectionInternal from) { Debug.Assert(null != _innerConnection, "null InnerConnection"); Debug.Assert(null != from, "from null InnerConnection"); Debug.Assert(null != to, "to null InnerConnection"); bool result = (from == Interlocked.CompareExchange<DbConnectionInternal>(ref _innerConnection, to, from)); return result; } internal void SetInnerConnectionTo(DbConnectionInternal to) { Debug.Assert(null != _innerConnection, "null InnerConnection"); Debug.Assert(null != to, "to null InnerConnection"); _innerConnection = to; } } }