Add license and copyright to all source files in System.Data
[mono.git] / mcs / class / System.Data / System.Data.Odbc / OdbcCommand.cs
1 //\r
2 // System.Data.Odbc.OdbcCommand\r
3 //\r
4 // Authors:\r
5 //   Brian Ritchie (brianlritchie@hotmail.com)\r
6 //\r
7 // Copyright (C) Brian Ritchie, 2002\r
8 //\r
9
10 //
11 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32 \r
33 using System.ComponentModel;\r
34 using System.Data;\r
35 using System.Data.Common;\r
36 using System.Collections;\r
37 using System.Runtime.InteropServices;\r
38 \r
39 namespace System.Data.Odbc\r
40 {\r
41         /// <summary>\r
42         /// Represents an SQL statement or stored procedure to execute against a data source.\r
43         /// </summary>\r
44         [DesignerAttribute ("Microsoft.VSDesigner.Data.VS.OdbcCommandDesigner, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.ComponentModel.Design.IDesigner")]\r
45         [ToolboxItemAttribute ("System.Drawing.Design.ToolboxItem, "+ Consts.AssemblySystem_Drawing)]\r
46         public sealed class OdbcCommand : Component, ICloneable, IDbCommand\r
47         {\r
48                 #region Fields\r
49 \r
50                 string commandText;\r
51                 int timeout;\r
52                 CommandType commandType;\r
53                 OdbcConnection connection;\r
54                 OdbcParameterCollection parameters;\r
55                 OdbcTransaction transaction;\r
56                 bool designTimeVisible;\r
57                 bool prepared=false;\r
58                 OdbcDataReader dataReader;\r
59                 IntPtr hstmt;\r
60                 \r
61                 #endregion // Fields\r
62 \r
63                 #region Constructors\r
64 \r
65                 public OdbcCommand ()\r
66                 {\r
67                         commandText = String.Empty;\r
68                         timeout = 30; // default timeout \r
69                         commandType = CommandType.Text;\r
70                         connection = null;\r
71                         parameters = new OdbcParameterCollection ();\r
72                         transaction = null;\r
73                         designTimeVisible = false;\r
74                         dataReader = null;\r
75                 }\r
76 \r
77                 public OdbcCommand (string cmdText) : this ()\r
78                 {\r
79                         CommandText = cmdText;\r
80                 }\r
81 \r
82                 public OdbcCommand (string cmdText, OdbcConnection connection)\r
83                         : this (cmdText)\r
84                 {\r
85                         Connection = connection;\r
86                 }\r
87 \r
88                 public OdbcCommand (string cmdText,\r
89                                      OdbcConnection connection,\r
90                                      OdbcTransaction transaction) : this (cmdText, connection)\r
91                 {\r
92                         this.transaction = transaction;\r
93                 }\r
94 \r
95                 #endregion // Constructors\r
96 \r
97                 #region Properties\r
98 \r
99                 internal IntPtr hStmt\r
100                 {\r
101                         get { return hstmt; }\r
102                 }\r
103                 \r
104 \r
105                 [OdbcCategory ("Data")]\r
106                 [DefaultValue ("")]\r
107                 [OdbcDescriptionAttribute ("Command text to execute")]\r
108                 [EditorAttribute ("Microsoft.VSDesigner.Data.Odbc.Design.OdbcCommandTextEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]\r
109                 [RefreshPropertiesAttribute (RefreshProperties.All)]\r
110                 public string CommandText \r
111                 {\r
112                         get {\r
113                                 return commandText;\r
114                         }\r
115                         set { \r
116                                 prepared=false;\r
117                                 commandText = value;\r
118                         }\r
119                 }\r
120 \r
121 \r
122                 [OdbcDescriptionAttribute ("Time to wait for command to execute")]\r
123                 [DefaultValue (30)]\r
124                 public int CommandTimeout {\r
125                         get {\r
126                                 return timeout;\r
127                         }\r
128                         set {\r
129                                 timeout = value;\r
130                         }\r
131                 }\r
132 \r
133                 [OdbcCategory ("Data")]\r
134                 [DefaultValue ("Text")]\r
135                 [OdbcDescriptionAttribute ("How to interpret the CommandText")]\r
136                 [RefreshPropertiesAttribute (RefreshProperties.All)]\r
137                 public CommandType CommandType { \r
138                         get {\r
139                                 return commandType;\r
140                         }\r
141                         set {\r
142                                 commandType = value;\r
143                         }\r
144                 }\r
145 \r
146                 [OdbcCategory ("Behavior")]\r
147                 [OdbcDescriptionAttribute ("Connection used by the command")]\r
148                 [DefaultValue (null)]\r
149                 [EditorAttribute ("Microsoft.VSDesigner.Data.Design.DbConnectionEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]\r
150                 public OdbcConnection Connection { \r
151                         get {\r
152                                 return connection;\r
153                         }\r
154                         set {\r
155                                 connection = value;\r
156                         }\r
157                 }\r
158 \r
159                 [BrowsableAttribute (false)]\r
160                 [DesignOnlyAttribute (true)]\r
161                 [DefaultValue (true)]\r
162                 public bool DesignTimeVisible { \r
163                         get {\r
164                                 return designTimeVisible;\r
165                         }\r
166                         set {\r
167                                 designTimeVisible = value;\r
168                         }\r
169                 }\r
170 \r
171                 [OdbcCategory ("Data")]\r
172                 [OdbcDescriptionAttribute ("The parameters collection")]\r
173                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Content)]\r
174                 public OdbcParameterCollection Parameters {\r
175                         get {\r
176                                 return parameters;\r
177                         }\r
178                 }\r
179                 \r
180                 [BrowsableAttribute (false)]\r
181                 [OdbcDescriptionAttribute ("The transaction used by the command")]\r
182                 [DesignerSerializationVisibilityAttribute (DesignerSerializationVisibility.Hidden)]\r
183                 public OdbcTransaction Transaction {\r
184                         get {\r
185                                 return transaction;\r
186                         }\r
187                         set {\r
188                                 transaction = value;\r
189                         }\r
190                 }\r
191                 \r
192                 [OdbcCategory ("Behavior")]\r
193                 [DefaultValue (UpdateRowSource.Both)]\r
194                 [OdbcDescriptionAttribute ("When used by a DataAdapter.Update, how command results are applied to the current DataRow")]\r
195                 public UpdateRowSource UpdatedRowSource { \r
196                         [MonoTODO]\r
197                         get {\r
198                                 throw new NotImplementedException ();\r
199                         }\r
200                         [MonoTODO]\r
201                         set {\r
202                                 throw new NotImplementedException ();\r
203                         }\r
204                 }\r
205 \r
206                 IDbConnection IDbCommand.Connection {\r
207                         get {\r
208                                 return Connection;\r
209                         }\r
210                         set {\r
211                                 Connection = (OdbcConnection) value;\r
212                         }\r
213                 }\r
214 \r
215                 IDataParameterCollection IDbCommand.Parameters  {\r
216                         get {\r
217                                 return Parameters;\r
218                         }\r
219                 }\r
220 \r
221                 IDbTransaction IDbCommand.Transaction  {\r
222                         get {\r
223                                 return (IDbTransaction) Transaction;\r
224                         }\r
225                         set {\r
226                                 throw new NotImplementedException ();\r
227                         }\r
228                 }\r
229 \r
230                 #endregion // Properties\r
231 \r
232                 #region Methods\r
233 \r
234                 public void Cancel () \r
235                 {\r
236                         if (hstmt!=IntPtr.Zero)\r
237                         {\r
238                                 OdbcReturn Ret=libodbc.SQLCancel(hstmt);\r
239                                 if ((Ret!=OdbcReturn.Success) && (Ret!=OdbcReturn.SuccessWithInfo)) \r
240                                         throw new OdbcException(new OdbcError("SQLCancel",OdbcHandleType.Stmt,hstmt));\r
241                         }\r
242                         else\r
243                                 throw new InvalidOperationException();\r
244                 }\r
245 \r
246                 public OdbcParameter CreateParameter ()\r
247                 {\r
248                         return new OdbcParameter ();\r
249                 }\r
250 \r
251                 IDbDataParameter IDbCommand.CreateParameter ()\r
252                 {\r
253                         return CreateParameter ();\r
254                 }\r
255                 \r
256                 [MonoTODO]\r
257                 protected override void Dispose (bool disposing)\r
258                 {\r
259                 }\r
260                 \r
261                 private void ExecSQL(string sql)\r
262                 {\r
263                         OdbcReturn ret;\r
264 \r
265                         if ((parameters.Count>0) && !prepared)\r
266                                 Prepare();\r
267         \r
268                         if (prepared)\r
269                         {\r
270                                 ret=libodbc.SQLExecute(hstmt);\r
271                                 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) \r
272                                         throw new OdbcException(new OdbcError("SQLExecute",OdbcHandleType.Stmt,hstmt));\r
273                         }\r
274                         else\r
275                         {\r
276                                 ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);\r
277                                 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) \r
278                                         throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));\r
279 \r
280                                 ret=libodbc.SQLExecDirect(hstmt, sql, sql.Length);\r
281                                 if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) \r
282                                         throw new OdbcException(new OdbcError("SQLExecDirect",OdbcHandleType.Stmt,hstmt));\r
283                         }\r
284                 }\r
285 \r
286                 public int ExecuteNonQuery ()\r
287                 {\r
288                         if (connection == null)\r
289                                 throw new InvalidOperationException ();\r
290                         if (connection.State == ConnectionState.Closed)\r
291                                 throw new InvalidOperationException ();\r
292                         // FIXME: a third check is mentioned in .NET docs\r
293 \r
294                         ExecSQL(CommandText);\r
295 \r
296 //                      if (!prepared)\r
297 //                              libodbc.SQLFreeHandle( (ushort) OdbcHandleType.Stmt, hstmt);\r
298                         return 0;\r
299                 }\r
300 \r
301                 public void Prepare()\r
302                 {\r
303                         OdbcReturn ret=libodbc.SQLAllocHandle(OdbcHandleType.Stmt, Connection.hDbc, ref hstmt);\r
304                         if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) \r
305                                 throw new OdbcException(new OdbcError("SQLAllocHandle",OdbcHandleType.Dbc,Connection.hDbc));\r
306 \r
307                         ret=libodbc.SQLPrepare(hstmt, CommandText, CommandText.Length);\r
308                         if ((ret!=OdbcReturn.Success) && (ret!=OdbcReturn.SuccessWithInfo)) \r
309                                 throw new OdbcException(new OdbcError("SQLPrepare",OdbcHandleType.Stmt,hstmt));\r
310 \r
311                         int i=1;\r
312                         foreach (OdbcParameter p in parameters)\r
313                         {\r
314                                 p.Bind(hstmt, i);\r
315                                 i++;\r
316                         }\r
317 \r
318                         prepared=true;\r
319                 }\r
320 \r
321                 public OdbcDataReader ExecuteReader ()\r
322                 {\r
323                         return ExecuteReader (CommandBehavior.Default);\r
324                 }\r
325 \r
326                 IDataReader IDbCommand.ExecuteReader ()\r
327                 {\r
328                         return ExecuteReader ();\r
329                 }\r
330 \r
331                 public OdbcDataReader ExecuteReader (CommandBehavior behavior)\r
332                 {\r
333                         ExecuteNonQuery();\r
334                         dataReader=new OdbcDataReader(this,behavior);\r
335                         return dataReader;\r
336                 }\r
337 \r
338                 IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)\r
339                 {\r
340                         return ExecuteReader (behavior);\r
341                 }\r
342                 \r
343                 public object ExecuteScalar ()\r
344                 {\r
345                         object val;\r
346                         OdbcDataReader reader=ExecuteReader();\r
347                         try\r
348                         {\r
349                                 val=reader[0];\r
350                         }\r
351                         finally\r
352                         {\r
353                                 reader.Close();\r
354                         }\r
355                         return val;\r
356                 }\r
357 \r
358                 [MonoTODO]\r
359                 object ICloneable.Clone ()\r
360                 {\r
361                         throw new NotImplementedException ();   \r
362                 }\r
363 \r
364                 public void ResetCommandTimeout ()\r
365                 {\r
366                         timeout = 30;\r
367                 }\r
368 \r
369                 #endregion\r
370         }\r
371 }\r