-
Notifications
You must be signed in to change notification settings - Fork 332
Expand file tree
/
Copy pathDbConnectionClosed.cs
More file actions
184 lines (150 loc) · 7.2 KB
/
Copy pathDbConnectionClosed.cs
File metadata and controls
184 lines (150 loc) · 7.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Data;
using System.Data.Common;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Data.Common;
using Microsoft.Data.SqlClient;
using Microsoft.Data.SqlClient.ConnectionPool;
namespace Microsoft.Data.ProviderBase
{
internal abstract 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();
protected override void Activate(System.Transactions.Transaction transaction) => 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, SqlConnectionFactory connectionFactory)
{
// not much to do here...
}
/// <inheritdoc/>
protected override void Deactivate() => ADP.ClosedConnectionError();
public override void EnlistTransaction(System.Transactions.Transaction transaction) => throw ADP.ClosedConnectionError();
protected internal override DataTable GetSchema(
SqlConnectionFactory factory,
DbConnectionPoolGroup poolGroup,
DbConnection outerConnection,
string collectionName,
string[] restrictions)
{
throw ADP.ClosedConnectionError();
}
protected internal override Task<DataTable> GetSchemaAsync(
SqlConnectionFactory factory,
DbConnectionPoolGroup poolGroup,
DbConnection outerConnection,
string collectionName,
string[] restrictions,
CancellationToken cancellationToken)
=> throw ADP.ClosedConnectionError();
protected override DbReferenceCollection CreateReferenceCollection() => throw ADP.ClosedConnectionError();
internal override bool TryOpenConnection(
DbConnection outerConnection,
SqlConnectionFactory connectionFactory,
TaskCompletionSource<DbConnectionInternal> retry,
TimeoutTimer timeout) =>
TryOpenConnectionInternal(outerConnection, connectionFactory, retry, timeout);
/// <inheritdoc/>
internal override void ResetConnection() => throw ADP.ClosedConnectionError();
}
internal abstract class DbConnectionBusy : DbConnectionClosed
{
protected DbConnectionBusy(ConnectionState state) : base(state, true, false)
{
}
internal override bool TryOpenConnection(
DbConnection outerConnection,
SqlConnectionFactory connectionFactory,
TaskCompletionSource<DbConnectionInternal> retry,
TimeoutTimer timeout)
=> 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, SqlConnectionFactory connectionFactory)
{
connectionFactory.SetInnerConnectionTo(owningObject, DbConnectionClosedPreviouslyOpened.SingletonInstance);
}
internal override bool TryReplaceConnection(
DbConnection outerConnection,
SqlConnectionFactory connectionFactory,
TaskCompletionSource<DbConnectionInternal> retry,
TimeoutTimer timeout) =>
TryOpenConnection(outerConnection, connectionFactory, retry, timeout);
internal override bool TryOpenConnection(
DbConnection outerConnection,
SqlConnectionFactory connectionFactory,
TaskCompletionSource<DbConnectionInternal> retry,
TimeoutTimer timeout)
{
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 (openConnection == null)
{
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,
SqlConnectionFactory connectionFactory,
TaskCompletionSource<DbConnectionInternal> retry,
TimeoutTimer timeout) =>
TryOpenConnection(outerConnection, connectionFactory, retry, timeout);
}
}