1 //------------------------------------------------------------------------------
2 // <copyright file="DbConnection.cs" company="Microsoft">
3 //      Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 // <owner current="true" primary="true">Microsoft</owner>
6 // <owner current="true" primary="false">Microsoft</owner>
7 // <owner current="true" primary="false">Microsoft</owner>
8 //------------------------------------------------------------------------------
9 
10 namespace System.Data.Common {
11 
12     using System;
13     using System.ComponentModel;
14     using System.Data;
15     using System.Threading;
16     using System.Threading.Tasks;
17 
18     public abstract class DbConnection : Component, IDbConnection { // V1.2.3300
19 
20         private StateChangeEventHandler _stateChangeEventHandler;
21 
DbConnection()22         protected DbConnection() : base() {
23         }
24 
25         [
26         DefaultValue(""),
27 #pragma warning disable 618 // ignore obsolete warning about RecommendedAsConfigurable to use SettingsBindableAttribute
28         RecommendedAsConfigurable(true),
29 #pragma warning restore 618
30         SettingsBindableAttribute(true),
31         RefreshProperties(RefreshProperties.All),
32         ResCategoryAttribute(Res.DataCategory_Data),
33         ]
34         abstract public string ConnectionString {
35             get;
36             set;
37         }
38 
39         [
40         ResCategoryAttribute(Res.DataCategory_Data),
41         ]
42         virtual public int ConnectionTimeout {
43             get {
44                 return ADP.DefaultConnectionTimeout;
45             }
46         }
47 
48         [
49         ResCategoryAttribute(Res.DataCategory_Data),
50         ]
51         abstract public string Database {
52             get;
53         }
54 
55         [
56         ResCategoryAttribute(Res.DataCategory_Data),
57         ]
58         abstract public string DataSource {
59             // NOTE: if you plan on allowing the data source to be changed, you
60             //       should implement a ChangeDataSource method, in keeping with
61             //       the ChangeDatabase method paradigm.
62             get;
63         }
64 
65         /// <summary>
66         /// The associated provider factory for derived class.
67         /// </summary>
68         virtual protected DbProviderFactory DbProviderFactory {
69             get {
70                 return null;
71             }
72         }
73 
74         internal DbProviderFactory ProviderFactory {
75             get {
76                 return DbProviderFactory;
77             }
78         }
79 
80         [
81         Browsable(false),
82         ]
83         abstract public string ServerVersion {
84             get;
85         }
86 
87         [
88         Browsable(false),
89         ResDescriptionAttribute(Res.DbConnection_State),
90         ]
91         abstract public ConnectionState State {
92             get;
93         }
94 
95         [
96         ResCategoryAttribute(Res.DataCategory_StateChange),
97         ResDescriptionAttribute(Res.DbConnection_StateChange),
98         ]
99         virtual public event StateChangeEventHandler StateChange {
100             add {
101                 _stateChangeEventHandler += value;
102             }
103             remove {
104                 _stateChangeEventHandler -= value;
105             }
106         }
107 
BeginDbTransaction(IsolationLevel isolationLevel)108         abstract protected DbTransaction BeginDbTransaction(IsolationLevel isolationLevel);
109 
BeginTransaction()110         public DbTransaction BeginTransaction() {
111             return BeginDbTransaction(IsolationLevel.Unspecified);
112         }
113 
BeginTransaction(IsolationLevel isolationLevel)114         public DbTransaction BeginTransaction(IsolationLevel isolationLevel) {
115             return BeginDbTransaction(isolationLevel);
116         }
117 
IDbConnection.BeginTransaction()118         IDbTransaction IDbConnection.BeginTransaction() {
119             return BeginDbTransaction(IsolationLevel.Unspecified);
120         }
121 
IDbConnection.BeginTransaction(IsolationLevel isolationLevel)122         IDbTransaction IDbConnection.BeginTransaction(IsolationLevel isolationLevel) {
123             return BeginDbTransaction(isolationLevel);
124         }
125 
Close()126         abstract public void Close();
127 
ChangeDatabase(string databaseName)128         abstract public void ChangeDatabase(string databaseName);
129 
CreateCommand()130         public DbCommand CreateCommand() {
131             return CreateDbCommand();
132         }
133 
IDbConnection.CreateCommand()134         IDbCommand IDbConnection.CreateCommand() {
135             return CreateDbCommand();
136         }
137 
CreateDbCommand()138         abstract protected DbCommand CreateDbCommand();
139 
EnlistTransaction(System.Transactions.Transaction transaction)140         virtual public void EnlistTransaction(System.Transactions.Transaction transaction) {
141             // NOTE: This is virtual because not all providers may choose to support
142             //       distributed transactions.
143             throw ADP.NotSupported();
144         }
145 
146         // these need to be here so that GetSchema is visible when programming to a dbConnection object.
147         // they are overridden by the real implementations in DbConnectionBase
GetSchema()148         virtual public  DataTable GetSchema() {
149             throw ADP.NotSupported();
150         }
151 
GetSchema(string collectionName)152         virtual public DataTable GetSchema(string collectionName) {
153             throw ADP.NotSupported();
154         }
155 
GetSchema(string collectionName, string[] restrictionValues )156         virtual public DataTable GetSchema(string collectionName, string[] restrictionValues   ) {
157             throw ADP.NotSupported();
158         }
159 
160         internal bool _supressStateChangeForReconnection = false; // Do not use for anything else ! Value will be overwritten by CR process
161 
OnStateChange(StateChangeEventArgs stateChange)162         protected virtual void OnStateChange(StateChangeEventArgs stateChange) {
163             if (_supressStateChangeForReconnection) {
164                 return;
165             }
166             StateChangeEventHandler handler = _stateChangeEventHandler;
167             if (null != handler) {
168                 handler(this, stateChange);
169             }
170         }
171 
172         internal bool ForceNewConnection {
173             get;
174             set;
175         }
176 
177 
Open()178         abstract public void Open();
179 
OpenAsync()180         public Task OpenAsync() {
181             return OpenAsync(CancellationToken.None);
182         }
183 
OpenAsync(CancellationToken cancellationToken)184         public virtual Task OpenAsync(CancellationToken cancellationToken) {
185             TaskCompletionSource<object> taskCompletionSource = new TaskCompletionSource<object>();
186 
187             if (cancellationToken.IsCancellationRequested) {
188                 taskCompletionSource.SetCanceled();
189             }
190             else {
191                 try {
192                     Open();
193                     taskCompletionSource.SetResult(null);
194                 }
195                 catch (Exception e) {
196                     taskCompletionSource.SetException(e);
197                 }
198             }
199 
200             return taskCompletionSource.Task;
201         }
202     }
203 }
204