1 //------------------------------------------------------------------------------
2 // <copyright file="DbCommand.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 //------------------------------------------------------------------------------
8 
9 namespace System.Data.Common {
10 
11     using System;
12     using System.ComponentModel;
13     using System.Data;
14     using System.Threading.Tasks;
15     using System.Threading;
16 
17     public abstract class DbCommand : Component, IDbCommand { // V1.2.3300
DbCommand()18         protected DbCommand() : base() {
19         }
20 
21         [
22         DefaultValue(""),
23         RefreshProperties(RefreshProperties.All),
24         ResCategoryAttribute(Res.DataCategory_Data),
25         ResDescriptionAttribute(Res.DbCommand_CommandText),
26         ]
27         abstract public string CommandText {
28             get;
29             set;
30         }
31 
32         [
33         ResCategoryAttribute(Res.DataCategory_Data),
34         ResDescriptionAttribute(Res.DbCommand_CommandTimeout),
35         ]
36         abstract public int CommandTimeout {
37             get;
38             set;
39         }
40 
41         [
42         DefaultValue(System.Data.CommandType.Text),
43         RefreshProperties(RefreshProperties.All),
44         ResCategoryAttribute(Res.DataCategory_Data),
45         ResDescriptionAttribute(Res.DbCommand_CommandType),
46         ]
47         abstract public CommandType CommandType {
48             get;
49             set;
50         }
51 
52         [
53         Browsable(false),
54         DefaultValue(null),
55         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
56         ResCategoryAttribute(Res.DataCategory_Data),
57         ResDescriptionAttribute(Res.DbCommand_Connection),
58         ]
59         public DbConnection Connection {
60             get {
61                 return DbConnection;
62             }
63             set {
64                 DbConnection = value;
65             }
66         }
67 
68         IDbConnection IDbCommand.Connection {
69             get {
70                 return DbConnection;
71             }
72             set {
73                 DbConnection = (DbConnection)value;
74             }
75         }
76 
77         abstract protected DbConnection DbConnection { // V1.2.3300
78             get;
79             set;
80         }
81 
82         abstract protected DbParameterCollection DbParameterCollection { // V1.2.3300
83             get;
84         }
85 
86         abstract protected DbTransaction DbTransaction { // V1.2.3300
87             get;
88             set;
89         }
90 
91         // @devnote: By default, the cmd object is visible on the design surface (i.e. VS7 Server Tray)
92         // to limit the number of components that clutter the design surface,
93         // when the DataAdapter design wizard generates the insert/update/delete commands it will
94         // set the DesignTimeVisible property to false so that cmds won't appear as individual objects
95         [
96         DefaultValue(true),
97         DesignOnly(true),
98         Browsable(false),
99         EditorBrowsableAttribute(EditorBrowsableState.Never),
100         ]
101         public abstract bool DesignTimeVisible {
102             get;
103             set;
104         }
105 
106         [
107         Browsable(false),
108         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
109         ResCategoryAttribute(Res.DataCategory_Data),
110         ResDescriptionAttribute(Res.DbCommand_Parameters),
111         ]
112         public DbParameterCollection Parameters {
113             get {
114                 return DbParameterCollection;
115             }
116         }
117 
118         IDataParameterCollection IDbCommand.Parameters {
119             get {
120                 return (DbParameterCollection)DbParameterCollection;
121             }
122         }
123 
124         [
125         Browsable(false),
126         DefaultValue(null),
127         DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
128         ResDescriptionAttribute(Res.DbCommand_Transaction),
129         ]
130         public DbTransaction Transaction {
131             get {
132                 return DbTransaction;
133             }
134             set {
135                 DbTransaction = value;
136             }
137         }
138 
139         IDbTransaction IDbCommand.Transaction {
140             get {
141                 return DbTransaction;
142             }
143             set {
144                 DbTransaction = (DbTransaction)value;
145             }
146         }
147 
148         [
149         DefaultValue(System.Data.UpdateRowSource.Both),
150         ResCategoryAttribute(Res.DataCategory_Update),
151         ResDescriptionAttribute(Res.DbCommand_UpdatedRowSource),
152         ]
153         abstract public UpdateRowSource UpdatedRowSource {
154             get;
155             set;
156         }
157 
CancelIgnoreFailure()158         internal void CancelIgnoreFailure() {
159             // This method is used to route CancellationTokens to the Cancel method.
160             // Cancellation is a suggestion, and exceptions should be ignored
161             // rather than allowed to be unhandled, as there is no way to route
162             // them to the caller.  It would be expected that the error will be
163             // observed anyway from the regular method.  An example is cancelling
164             // an operation on a closed connection.
165             try
166             {
167                 Cancel();
168             } catch(Exception) {
169             }
170         }
171 
Cancel()172         abstract public void Cancel();
173 
CreateParameter()174         public DbParameter CreateParameter(){ // V1.2.3300
175             return CreateDbParameter();
176         }
177 
IDbCommand.CreateParameter()178         IDbDataParameter IDbCommand.CreateParameter() { // V1.2.3300
179             return CreateDbParameter();
180         }
181 
CreateDbParameter()182         abstract protected DbParameter CreateDbParameter();
183 
ExecuteDbDataReader(CommandBehavior behavior)184         abstract protected DbDataReader ExecuteDbDataReader(CommandBehavior behavior);
185 
ExecuteNonQuery()186         abstract public int ExecuteNonQuery();
187 
ExecuteReader()188         public DbDataReader ExecuteReader() {
189             return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default);
190         }
191 
IDbCommand.ExecuteReader()192         IDataReader IDbCommand.ExecuteReader() {
193             return (DbDataReader)ExecuteDbDataReader(CommandBehavior.Default);
194         }
195 
ExecuteReader(CommandBehavior behavior)196         public DbDataReader ExecuteReader(CommandBehavior behavior){
197             return (DbDataReader)ExecuteDbDataReader(behavior);
198         }
199 
IDbCommand.ExecuteReader(CommandBehavior behavior)200         IDataReader IDbCommand.ExecuteReader(CommandBehavior behavior) {
201             return (DbDataReader)ExecuteDbDataReader(behavior);
202         }
203 
ExecuteNonQueryAsync()204         public Task<int> ExecuteNonQueryAsync() {
205             return ExecuteNonQueryAsync(CancellationToken.None);
206         }
207 
ExecuteNonQueryAsync(CancellationToken cancellationToken)208         public virtual Task<int> ExecuteNonQueryAsync(CancellationToken cancellationToken) {
209             if (cancellationToken.IsCancellationRequested) {
210                 return ADP.CreatedTaskWithCancellation<int>();
211             }
212             else {
213                 CancellationTokenRegistration registration = new CancellationTokenRegistration();
214                 if (cancellationToken.CanBeCanceled) {
215                     registration = cancellationToken.Register(CancelIgnoreFailure);
216                 }
217 
218                 try {
219                     return Task.FromResult<int>(ExecuteNonQuery());
220                 }
221                 catch (Exception e) {
222                     registration.Dispose();
223                     return ADP.CreatedTaskWithException<int>(e);
224                 }
225             }
226         }
227 
ExecuteReaderAsync()228         public Task<DbDataReader> ExecuteReaderAsync() {
229             return ExecuteReaderAsync(CommandBehavior.Default, CancellationToken.None);
230         }
231 
ExecuteReaderAsync(CancellationToken cancellationToken)232         public Task<DbDataReader> ExecuteReaderAsync(CancellationToken cancellationToken) {
233             return ExecuteReaderAsync(CommandBehavior.Default, cancellationToken);
234         }
235 
ExecuteReaderAsync(CommandBehavior behavior)236         public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior) {
237             return ExecuteReaderAsync(behavior, CancellationToken.None);
238         }
239 
ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)240         public Task<DbDataReader> ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) {
241             return ExecuteDbDataReaderAsync(behavior, cancellationToken);
242         }
243 
ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)244         protected virtual Task<DbDataReader> ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken) {
245             if (cancellationToken.IsCancellationRequested) {
246                 return ADP.CreatedTaskWithCancellation<DbDataReader>();
247             }
248             else {
249                 CancellationTokenRegistration registration = new CancellationTokenRegistration();
250                 if (cancellationToken.CanBeCanceled) {
251                     registration = cancellationToken.Register(CancelIgnoreFailure);
252                 }
253 
254                 try {
255                     return Task.FromResult<DbDataReader>(ExecuteReader(behavior));
256                 }
257                 catch (Exception e) {
258                     registration.Dispose();
259                     return ADP.CreatedTaskWithException<DbDataReader>(e);
260                 }
261             }
262         }
263 
ExecuteScalarAsync()264         public Task<object> ExecuteScalarAsync() {
265             return ExecuteScalarAsync(CancellationToken.None);
266         }
267 
ExecuteScalarAsync(CancellationToken cancellationToken)268         public virtual Task<object> ExecuteScalarAsync(CancellationToken cancellationToken) {
269             if (cancellationToken.IsCancellationRequested) {
270                 return ADP.CreatedTaskWithCancellation<object>();
271             }
272             else {
273                 CancellationTokenRegistration registration = new CancellationTokenRegistration();
274                 if (cancellationToken.CanBeCanceled) {
275                     registration = cancellationToken.Register(CancelIgnoreFailure);
276                 }
277 
278                 try {
279                     return Task.FromResult<object>(ExecuteScalar());
280                 }
281                 catch (Exception e) {
282                     registration.Dispose();
283                     return ADP.CreatedTaskWithException<object>(e);
284                 }
285             }
286         }
287 
ExecuteScalar()288         abstract public object ExecuteScalar();
289 
Prepare()290         abstract public void Prepare();
291     }
292 }
293