DbConnectionClosed.cs 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //------------------------------------------------------------------------------
  2. // <copyright file="DbConnectionClosed.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. namespace System.Data.ProviderBase {
  9. using System;
  10. using System.ComponentModel;
  11. using System.Data;
  12. using System.Data.Common;
  13. using System.Diagnostics;
  14. using System.Globalization;
  15. using System.Threading;
  16. using System.Threading.Tasks;
  17. using SysTx = System.Transactions;
  18. abstract internal class DbConnectionClosed : DbConnectionInternal {
  19. // Construct an "empty" connection
  20. protected DbConnectionClosed(ConnectionState state, bool hidePassword, bool allowSetConnectionString) : base(state, hidePassword, allowSetConnectionString) {
  21. }
  22. override public string ServerVersion {
  23. get {
  24. throw ADP.ClosedConnectionError();
  25. }
  26. }
  27. override protected void Activate(SysTx.Transaction transaction) {
  28. throw ADP.ClosedConnectionError();
  29. }
  30. override public DbTransaction BeginTransaction(IsolationLevel il) {
  31. throw ADP.ClosedConnectionError();
  32. }
  33. override public void ChangeDatabase(string database) {
  34. throw ADP.ClosedConnectionError();
  35. }
  36. internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory) {
  37. // not much to do here...
  38. }
  39. override protected void Deactivate() {
  40. throw ADP.ClosedConnectionError();
  41. }
  42. override public void EnlistTransaction(SysTx.Transaction transaction) {
  43. throw ADP.ClosedConnectionError();
  44. }
  45. override protected internal DataTable GetSchema(DbConnectionFactory factory, DbConnectionPoolGroup poolGroup, DbConnection outerConnection, string collectionName, string[] restrictions) {
  46. throw ADP.ClosedConnectionError();
  47. }
  48. protected override DbReferenceCollection CreateReferenceCollection() {
  49. throw ADP.ClosedConnectionError();
  50. }
  51. internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
  52. return base.TryOpenConnectionInternal(outerConnection, connectionFactory, retry, userOptions);
  53. }
  54. }
  55. abstract internal class DbConnectionBusy : DbConnectionClosed {
  56. protected DbConnectionBusy(ConnectionState state) : base(state, true, false) {
  57. }
  58. internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
  59. throw ADP.ConnectionAlreadyOpen(State);
  60. }
  61. }
  62. sealed internal class DbConnectionClosedBusy : DbConnectionBusy {
  63. // Closed Connection, Currently Busy - changing connection string
  64. internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedBusy(); // singleton object
  65. private DbConnectionClosedBusy() : base(ConnectionState.Closed) {
  66. }
  67. }
  68. sealed internal class DbConnectionOpenBusy : DbConnectionBusy {
  69. // Open Connection, Currently Busy - closing connection
  70. internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionOpenBusy(); // singleton object
  71. private DbConnectionOpenBusy() : base(ConnectionState.Open) {
  72. }
  73. }
  74. sealed internal class DbConnectionClosedConnecting : DbConnectionBusy {
  75. // Closed Connection, Currently Connecting
  76. internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedConnecting(); // singleton object
  77. private DbConnectionClosedConnecting() : base(ConnectionState.Connecting) {
  78. }
  79. internal override void CloseConnection(DbConnection owningObject, DbConnectionFactory connectionFactory)
  80. {
  81. connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
  82. }
  83. internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
  84. return TryOpenConnection(outerConnection, connectionFactory, retry, userOptions);
  85. }
  86. internal override bool TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
  87. if (retry == null || !retry.Task.IsCompleted) {
  88. // retry is null if this is a synchronous call
  89. // if someone calls Open or OpenAsync while in this state,
  90. // then the retry task will not be completed
  91. throw ADP.ConnectionAlreadyOpen(State);
  92. }
  93. // we are completing an asynchronous open
  94. Debug.Assert(retry.Task.Status == TaskStatus.RanToCompletion, "retry task must be completed successfully");
  95. DbConnectionInternal openConnection = retry.Task.Result;
  96. if (null == openConnection) {
  97. connectionFactory.SetInnerConnectionTo(outerConnection, this);
  98. throw ADP.InternalConnectionError(ADP.ConnectionError.GetConnectionReturnsNull);
  99. }
  100. connectionFactory.SetInnerConnectionEvent(outerConnection, openConnection);
  101. return true;
  102. }
  103. }
  104. sealed internal class DbConnectionClosedNeverOpened : DbConnectionClosed {
  105. // Closed Connection, Has Never Been Opened
  106. internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedNeverOpened(); // singleton object
  107. private DbConnectionClosedNeverOpened() : base(ConnectionState.Closed, false, true) {
  108. }
  109. }
  110. sealed internal class DbConnectionClosedPreviouslyOpened : DbConnectionClosed {
  111. // Closed Connection, Has Previously Been Opened
  112. internal static readonly DbConnectionInternal SingletonInstance = new DbConnectionClosedPreviouslyOpened(); // singleton object
  113. private DbConnectionClosedPreviouslyOpened() : base(ConnectionState.Closed, true, true) {
  114. }
  115. internal override bool TryReplaceConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource<DbConnectionInternal> retry, DbConnectionOptions userOptions) {
  116. return TryOpenConnection(outerConnection, connectionFactory, retry, userOptions);
  117. }
  118. }
  119. }