| File: src\runtime\src\libraries\Common\src\System\Data\ProviderBase\DbConnectionClosed.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.Diagnostics; using System.Threading.Tasks; namespace System.Data.ProviderBase { internal abstract partial class DbConnectionClosed : DbConnectionInternal { // Construct an "empty" connection protected DbConnectionClosed(ConnectionState state, bool hidePassword, bool allowSetConnectionString) : base(state, hidePassword, allowSetConnectionString) { } public override string ServerVersion => throw ADP.ClosedConnectionError(); public override DbTransaction BeginTransaction(IsolationLevel il) => throw ADP.ClosedConnectionError(); public override void ChangeDatabase(string database) => throw ADP.ClosedConnectionError(); internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) { // not much to do here... } protected override void Deactivate() => ADP.ClosedConnectionError(); protected internal override DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string?[]? restrictions) => throw ADP.ClosedConnectionError(); protected override DbReferenceCollection CreateReferenceCollection() => throw ADP.ClosedConnectionError(); internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal>? retry, DbConnectionOptions? userOptions) => base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions); } internal abstract class DbConnectionBusy : DbConnectionClosed { protected DbConnectionBusy(ConnectionState state) : base(state, true, false) { } internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal>? retry, DbConnectionOptions? userOptions) => throw ADP.ConnectionAlreadyOpen(State); } internal sealed class DbConnectionClosedBusy : DbConnectionBusy { // Closed Connection, Currently Busy - changing connection string internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedBusy(); // singleton object private DbConnectionClosedBusy() : base(ConnectionState.Closed) { } } internal sealed class DbConnectionOpenBusy : DbConnectionBusy { // Open Connection, Currently Busy - closing connection internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionOpenBusy(); // singleton object private DbConnectionOpenBusy() : base(ConnectionState.Open) { } } internal sealed class DbConnectionClosedConnecting : DbConnectionBusy { // Closed Connection, Currently Connecting internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedConnecting(); // singleton object private DbConnectionClosedConnecting() : base(ConnectionState.Connecting) { } internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) { connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance); } internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal>? retry, DbConnectionOptions? userOptions) => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions); internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal>? retry, DbConnectionOptions? userOptions) { if (retry == null || !retry.Task.IsCompleted) { // retry is null if this is a synchronous call // if someone calls Open or OpenAsync while in this state, // then the retry task will not be completed throw ADP.ConnectionAlreadyOpen(State); } // we are completing an asynchronous open Debug.Assert(retry.Task.Status == TaskStatus.RanToCompletion, "retry task must be completed successfully"); DbConnectionInternal openConnection = retry.Task.Result; if (null == openConnection) { connectionFactory.SetInnerConnectionTo(outerConnection, this); throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull); } connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection); return true; } } internal sealed class DbConnectionClosedNeverOpened : DbConnectionClosed { // Closed Connection, Has Never Been Opened internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedNeverOpened(); // singleton object private DbConnectionClosedNeverOpened() : base(ConnectionState.Closed, false, true) { } } internal sealed class DbConnectionClosedPreviouslyOpened : DbConnectionClosed { // Closed Connection, Has Previously Been Opened internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedPreviouslyOpened(); // singleton object private DbConnectionClosedPreviouslyOpened() : base(ConnectionState.Closed, true, true) { } internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal>? retry, DbConnectionOptions? userOptions) => TryOpenConnection(outerConnection, connectionFactory, retry, userOptions); } }