[runtime] Overwrite stacktrace for exception on re-throw. Fixes #1856.
[mono.git] / mcs / class / System.Data / System.Data.OleDb / OleDbCommand.cs
1 //
2 // System.Data.OleDb.OleDbCommand
3 //
4 // Authors:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Tim Coleman (tim@timcoleman.com)
7 //
8 // Copyright (C) Rodrigo Moya, 2002
9 // Copyright (C) Tim Coleman, 2002
10 //
11
12 //
13 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34
35 using System.ComponentModel;
36 using System.Data;
37 using System.Data.Common;
38 using System.Collections;
39 using System.Runtime.InteropServices;
40
41 namespace System.Data.OleDb
42 {
43         /// <summary>
44         /// Represents an SQL statement or stored procedure to execute against a data source.
45         /// </summary>
46         [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.OleDbCommandDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]
47         [ToolboxItemAttribute ("System.Drawing.Design.ToolboxItem, "+ Consts.AssemblySystem_Drawing)]
48         [DefaultEvent( "RecordsAffected")]
49         public sealed class OleDbCommand : 
50         DbCommand
51         , ICloneable, IDbCommand
52         {
53                 #region Fields
54
55                 const int DEFAULT_COMMAND_TIMEOUT = 30;
56
57                 string commandText;
58                 int timeout;
59                 CommandType commandType;
60                 OleDbConnection connection;
61                 OleDbParameterCollection parameters;
62                 OleDbTransaction transaction;
63                 bool designTimeVisible;
64                 OleDbDataReader dataReader;
65                 CommandBehavior behavior;
66                 IntPtr gdaCommand;
67                 UpdateRowSource updatedRowSource;
68
69                 bool disposed;
70                 
71                 #endregion // Fields
72
73                 #region Constructors
74
75                 public OleDbCommand ()
76                 {
77                         timeout = DEFAULT_COMMAND_TIMEOUT;
78                         commandType = CommandType.Text;
79                         parameters = new OleDbParameterCollection ();
80                         behavior = CommandBehavior.Default;
81                         gdaCommand = IntPtr.Zero;
82                         designTimeVisible = true;
83                         this.updatedRowSource = UpdateRowSource.Both;
84                 }
85
86                 public OleDbCommand (string cmdText) : this ()
87                 {
88                         CommandText = cmdText;
89                 }
90
91                 public OleDbCommand (string cmdText, OleDbConnection connection)
92                         : this (cmdText)
93                 {
94                         Connection = connection;
95                 }
96
97                 public OleDbCommand (string cmdText, OleDbConnection connection,
98                         OleDbTransaction transaction) : this (cmdText, connection)
99                 {
100                         this.transaction = transaction;
101                 }
102
103                 #endregion // Constructors
104
105                 #region Properties
106         
107                 [DataCategory ("Data")]
108                 [DefaultValue ("")]
109                 [EditorAttribute ("Microsoft.VSDesigner.Data.ADO.Design.OleDbCommandTextEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing)]
110                 [RefreshPropertiesAttribute (RefreshProperties.All)]
111                 public 
112                 override
113                 string CommandText {
114                         get {
115                                 if (commandText == null)
116                                         return string.Empty;
117                                 return commandText;
118                         }
119                         set {
120                                 commandText = value;
121                         }
122                 }
123
124                 public
125                 override
126                 int CommandTimeout {
127                         get {
128                                 return timeout;
129                         }
130                         set {
131                                 timeout = value;
132                         }
133                 }
134
135                 [DataCategory ("Data")]
136                 [DefaultValue ("Text")]
137                 [RefreshPropertiesAttribute (RefreshProperties.All)]
138                 public
139                 override
140                 CommandType CommandType {
141                         get {
142                                 return commandType;
143                         }
144                         set {
145                                 commandType = value;
146                         }
147                 }
148
149                 [DataCategory ("Behavior")]
150                 [DefaultValue (null)]
151                 [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
152                 public new OleDbConnection Connection {
153                         get {
154                                 return connection;
155                         }
156                         set {
157                                 connection = value;
158                         }
159                 }
160                 
161                 [BrowsableAttribute (false)]
162                 [DesignOnlyAttribute (true)]
163                 [DefaultValue (true)]
164                 [EditorBrowsable(EditorBrowsableState.Never)]
165                 public
166                 override
167                 bool DesignTimeVisible {
168                         get {
169                                 return designTimeVisible;
170                         }
171                         set {
172                                 designTimeVisible = value;
173                         }
174                 }
175
176                 [DataCategory ("Data")]
177                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]
178                 public new OleDbParameterCollection Parameters {
179                         get { return parameters; }
180                         internal set { parameters = value; }
181                 }
182
183                 [BrowsableAttribute (false)]
184                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]
185                 public new OleDbTransaction Transaction {
186                         get {
187                                 return transaction;
188                         }
189                         set {
190                                 transaction = value;
191                         }
192                 }
193
194                 [DataCategory ("Behavior")]
195                 [DefaultValue (UpdateRowSource.Both)]
196                 [MonoTODO]
197                 public
198                 override
199                 UpdateRowSource UpdatedRowSource {
200                         get { return updatedRowSource; }
201                         set {
202                                 ExceptionHelper.CheckEnumValue (typeof (UpdateRowSource), value);
203                                 updatedRowSource = value;
204                         }
205                 }
206
207                 IDbConnection IDbCommand.Connection {
208                         get {
209                                 return Connection;
210                         }
211                         set {
212                                 Connection = (OleDbConnection) value;
213                         }
214                 }
215
216                 IDataParameterCollection IDbCommand.Parameters {
217                         get {
218                                 return Parameters;
219                         }
220                 }
221
222                 IDbTransaction IDbCommand.Transaction {
223                         get {
224                                 return Transaction;
225                         }
226                         set {
227                                 Transaction = (OleDbTransaction) value;
228                         }
229                 }
230
231                 #endregion // Properties
232
233                 #region Methods
234
235                 [MonoTODO]
236                 public 
237                 override 
238                 void Cancel () 
239                 {
240                         throw new NotImplementedException ();
241                 }
242
243                 public new OleDbParameter CreateParameter ()
244                 {
245                         return new OleDbParameter ();
246                 }
247
248                 
249                 protected override void Dispose (bool disposing)
250                 {
251                         if (disposed)
252                                 return;
253                         
254                         Connection = null;
255                         Transaction = null;
256                         disposed = true;
257                 }
258
259                 private void SetupGdaCommand ()
260                 {
261                         GdaCommandType type;
262                         
263                         switch (commandType) {
264                         case CommandType.TableDirect :
265                                 type = GdaCommandType.Table;
266                                 break;
267                         case CommandType.StoredProcedure :
268                                 type = GdaCommandType.Procedure;
269                                 break;
270                         case CommandType.Text :
271                         default :
272                                 type = GdaCommandType.Sql;
273                                 break;
274                         }
275                         
276                         if (gdaCommand != IntPtr.Zero) {
277                                 libgda.gda_command_set_text (gdaCommand, CommandText);
278                                 libgda.gda_command_set_command_type (gdaCommand, type);
279                         } else {
280                                 gdaCommand = libgda.gda_command_new (CommandText, type, 0);
281                         }
282
283                         //libgda.gda_command_set_transaction 
284                 }
285
286                 public 
287                 override
288                 int ExecuteNonQuery ()
289                 {
290                         if (connection == null)
291                                 throw new InvalidOperationException ("connection == null");
292                         if (connection.State == ConnectionState.Closed)
293                                 throw new InvalidOperationException ("State == Closed");
294                         // FIXME: a third check is mentioned in .NET docs
295
296                         IntPtr gdaConnection = connection.GdaConnection;
297                         IntPtr gdaParameterList = parameters.GdaParameterList;
298
299                         SetupGdaCommand ();
300                         return libgda.gda_connection_execute_non_query (gdaConnection,
301                                                                         (IntPtr) gdaCommand,
302                                                                         gdaParameterList);
303                 }
304
305                 public new OleDbDataReader ExecuteReader ()
306                 {
307                         return ExecuteReader (behavior);
308                 }
309
310                 IDataReader IDbCommand.ExecuteReader ()
311                 {
312                         return ExecuteReader ();
313                 }
314
315                 public new OleDbDataReader ExecuteReader (CommandBehavior behavior)
316                 {
317                         ArrayList results = new ArrayList ();
318                         IntPtr rs_list;
319                         GdaList glist_node;
320
321                         if (connection.State != ConnectionState.Open)
322                                 throw new InvalidOperationException ("State != Open");
323
324                         this.behavior = behavior;
325
326                         IntPtr gdaConnection = connection.GdaConnection;
327                         IntPtr gdaParameterList = parameters.GdaParameterList;
328
329                         /* execute the command */
330                         SetupGdaCommand ();
331                         rs_list = libgda.gda_connection_execute_command (
332                                 gdaConnection,
333                                 gdaCommand,
334                                 gdaParameterList);
335                         if (rs_list != IntPtr.Zero) {
336                                 glist_node = (GdaList) Marshal.PtrToStructure (rs_list, typeof (GdaList));
337
338                                 while (glist_node != null) {
339                                         results.Add (glist_node.data);
340                                         if (glist_node.next == IntPtr.Zero)
341                                                 break;
342
343                                         glist_node = (GdaList) Marshal.PtrToStructure (glist_node.next,
344                                                 typeof (GdaList));
345                                 }
346                                 dataReader = new OleDbDataReader (this, results);
347                                 dataReader.NextResult ();
348                         }
349
350                         return dataReader;
351                 }
352
353                 IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
354                 {
355                         return ExecuteReader (behavior);
356                 }
357                 
358                 public
359                 override
360                 object ExecuteScalar ()
361                 {
362                         SetupGdaCommand ();
363                         OleDbDataReader reader = ExecuteReader ();
364                         if (reader == null) {
365                                 return null;
366                         }
367                         if (!reader.Read ()) {
368                                 reader.Close ();
369                                 return null;
370                         }
371                         object o = reader.GetValue (0);
372                         reader.Close ();
373                         return o;
374                 }
375
376                 public
377                 OleDbCommand Clone ()
378                 {
379                         OleDbCommand command = new OleDbCommand ();
380                         command.CommandText = this.CommandText;
381                         command.CommandTimeout = this.CommandTimeout;
382                         command.CommandType = this.CommandType;
383                         command.Connection = this.Connection;
384                         command.DesignTimeVisible = this.DesignTimeVisible;
385                         command.Parameters = this.Parameters;
386                         command.Transaction = this.Transaction;
387                         return command;
388                 }
389
390                 object ICloneable.Clone ()
391                 {
392                         return Clone ();
393                 }
394
395                 [MonoTODO]
396                 public 
397                 override
398                 void Prepare ()
399                 {
400                         throw new NotImplementedException ();
401                 }
402
403                 public void ResetCommandTimeout ()
404                 {
405                         timeout = DEFAULT_COMMAND_TIMEOUT;
406                 }
407                 
408                 protected override DbParameter CreateDbParameter ()
409                 {
410                         return (DbParameter) CreateParameter ();
411                 }
412                 
413                 protected override DbDataReader ExecuteDbDataReader (CommandBehavior behavior)
414                 {
415                         return (DbDataReader) ExecuteReader (behavior);
416                 }
417                 
418                 protected override DbConnection DbConnection {
419                         get { return Connection; }
420                         set { Connection = (OleDbConnection) value; }
421                 }
422                 
423                 protected override DbParameterCollection DbParameterCollection {
424                         get { return Parameters; }
425                 }
426                 
427                 protected override DbTransaction DbTransaction {
428                         get { return Transaction; }
429                         set { Transaction = (OleDbTransaction) value; }
430                 }
431
432                 #endregion
433         }
434 }