(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Mono.Data.SybaseClient / Mono.Data.SybaseClient / SybaseCommand.cs
blob850bce04e98b32d7116cc0425d321c12bc68b9da
1 //
2 // Mono.Data.SybaseClient.SybaseCommand.cs
3 //
4 // Author:
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Daniel Morgan (danmorg@sc.rr.com)
7 // Tim Coleman (tim@timcoleman.com)
8 //
9 // (C) Ximian, Inc 2002 http://www.ximian.com/
10 // (C) Daniel Morgan, 2002
11 // Copyright (C) Tim Coleman, 2002
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.
35 using Mono.Data.Tds;
36 using Mono.Data.Tds.Protocol;
37 using System;
38 using System.Collections;
39 using System.Collections.Specialized;
40 using System.ComponentModel;
41 using System.Data;
42 using System.Data.Common;
43 using System.Runtime.InteropServices;
44 using System.Text;
46 namespace Mono.Data.SybaseClient {
47 public sealed class SybaseCommand : Component, IDbCommand, ICloneable
49 #region Fields
51 bool disposed = false;
52 int commandTimeout;
53 bool designTimeVisible;
54 string commandText;
55 CommandType commandType;
56 SybaseConnection connection;
57 SybaseTransaction transaction;
58 UpdateRowSource updatedRowSource;
59 CommandBehavior behavior = CommandBehavior.Default;
60 SybaseParameterCollection parameters;
61 string preparedStatement = null;
63 #endregion // Fields
65 #region Constructors
67 public SybaseCommand()
68 : this (String.Empty, null, null)
72 public SybaseCommand (string commandText)
73 : this (commandText, null, null)
75 commandText = commandText;
78 public SybaseCommand (string commandText, SybaseConnection connection)
79 : this (commandText, connection, null)
81 Connection = connection;
84 public SybaseCommand (string commandText, SybaseConnection connection, SybaseTransaction transaction)
86 this.commandText = commandText;
87 this.connection = connection;
88 this.transaction = transaction;
89 this.commandType = CommandType.Text;
90 this.updatedRowSource = UpdateRowSource.Both;
92 this.designTimeVisible = false;
93 this.commandTimeout = 30;
94 parameters = new SybaseParameterCollection (this);
97 #endregion // Constructors
99 #region Properties
101 internal CommandBehavior CommandBehavior {
102 get { return behavior; }
105 public string CommandText {
106 get { return commandText; }
107 set {
108 if (value != commandText && preparedStatement != null)
109 Unprepare ();
110 commandText = value;
114 public int CommandTimeout {
115 get { return commandTimeout; }
116 set {
117 if (commandTimeout < 0)
118 throw new ArgumentException ("The property value assigned is less than 0.");
119 commandTimeout = value;
123 public CommandType CommandType {
124 get { return commandType; }
125 set {
126 if (value == CommandType.TableDirect)
127 throw new ArgumentException ("CommandType.TableDirect is not supported by the Mono SybaseClient Data Provider.");
128 commandType = value;
132 public SybaseConnection Connection {
133 get { return connection; }
134 set {
135 if (transaction != null && connection.Transaction != null && connection.Transaction.IsOpen)
136 throw new InvalidOperationException ("The Connection property was changed while a transaction was in progress.");
137 transaction = null;
138 connection = value;
142 public bool DesignTimeVisible {
143 get { return designTimeVisible; }
144 set { designTimeVisible = value; }
147 public SybaseParameterCollection Parameters {
148 get { return parameters; }
151 internal ITds Tds {
152 get { return Connection.Tds; }
155 IDbConnection IDbCommand.Connection {
156 get { return Connection; }
157 set {
158 if (!(value is SybaseConnection))
159 throw new InvalidCastException ("The value was not a valid SybaseConnection.");
160 Connection = (SybaseConnection) value;
164 IDataParameterCollection IDbCommand.Parameters {
165 get { return Parameters; }
168 IDbTransaction IDbCommand.Transaction {
169 get { return Transaction; }
170 set {
171 if (!(value is SybaseTransaction))
172 throw new ArgumentException ();
173 Transaction = (SybaseTransaction) value;
177 public SybaseTransaction Transaction {
178 get { return transaction; }
179 set { transaction = value; }
182 public UpdateRowSource UpdatedRowSource {
183 get { return updatedRowSource; }
184 set { updatedRowSource = value; }
187 #endregion // Fields
189 #region Methods
191 public void Cancel ()
193 if (Connection == null || Connection.Tds == null)
194 return;
195 Connection.Tds.Cancel ();
198 internal void CloseDataReader (bool moreResults)
200 GetOutputParameters ();
201 Connection.DataReader = null;
203 if ((behavior & CommandBehavior.CloseConnection) != 0)
204 Connection.Close ();
207 public SybaseParameter CreateParameter ()
209 return new SybaseParameter ();
212 internal void DeriveParameters ()
214 if (commandType != CommandType.StoredProcedure)
215 throw new InvalidOperationException (String.Format ("SybaseCommand DeriveParameters only supports CommandType.StoredProcedure, not CommandType.{0}", commandType));
216 ValidateCommand ("DeriveParameters");
218 SybaseParameterCollection localParameters = new SybaseParameterCollection (this);
219 localParameters.Add ("@P1", SybaseType.NVarChar, commandText.Length).Value = commandText;
221 string sql = "sp_procedure_params_rowset";
223 Connection.Tds.ExecProc (sql, localParameters.MetaParameters, 0, true);
225 SybaseDataReader reader = new SybaseDataReader (this);
226 parameters.Clear ();
227 object[] dbValues = new object[reader.FieldCount];
229 while (reader.Read ()) {
230 reader.GetValues (dbValues);
231 parameters.Add (new SybaseParameter (dbValues));
233 reader.Close ();
236 private void Execute (CommandBehavior behavior, bool wantResults)
238 TdsMetaParameterCollection parms = Parameters.MetaParameters;
239 if (preparedStatement == null) {
240 bool schemaOnly = ((CommandBehavior & CommandBehavior.SchemaOnly) > 0);
241 bool keyInfo = ((CommandBehavior & CommandBehavior.SchemaOnly) > 0);
243 StringBuilder sql1 = new StringBuilder ();
244 StringBuilder sql2 = new StringBuilder ();
246 if (schemaOnly || keyInfo)
247 sql1.Append ("SET FMTONLY OFF;");
248 if (keyInfo) {
249 sql1.Append ("SET NO_BROWSETABLE ON;");
250 sql2.Append ("SET NO_BROWSETABLE OFF;");
252 if (schemaOnly) {
253 sql1.Append ("SET FMTONLY ON;");
254 sql2.Append ("SET FMTONLY OFF;");
257 switch (CommandType) {
258 case CommandType.StoredProcedure:
259 if (keyInfo || schemaOnly)
260 Connection.Tds.Execute (sql1.ToString ());
261 Connection.Tds.ExecProc (CommandText, parms, CommandTimeout, wantResults);
262 if (keyInfo || schemaOnly)
263 Connection.Tds.Execute (sql2.ToString ());
264 break;
265 case CommandType.Text:
266 string sql = String.Format ("{0}{1}{2}", sql1.ToString (), CommandText, sql2.ToString ());
267 Connection.Tds.Execute (sql, parms, CommandTimeout, wantResults);
268 break;
271 else
272 Connection.Tds.ExecPrepared (preparedStatement, parms, CommandTimeout, wantResults);
275 public int ExecuteNonQuery ()
277 ValidateCommand ("ExecuteNonQuery");
278 int result = 0;
280 try {
281 Execute (CommandBehavior.Default, false);
283 catch (TdsTimeoutException e) {
284 throw SybaseException.FromTdsInternalException ((TdsInternalException) e);
287 GetOutputParameters ();
288 return result;
291 public SybaseDataReader ExecuteReader ()
293 return ExecuteReader (CommandBehavior.Default);
296 public SybaseDataReader ExecuteReader (CommandBehavior behavior)
298 ValidateCommand ("ExecuteReader");
299 try {
300 Execute (behavior, true);
302 catch (TdsTimeoutException e) {
303 throw SybaseException.FromTdsInternalException ((TdsInternalException) e);
305 Connection.DataReader = new SybaseDataReader (this);
306 return Connection.DataReader;
309 public object ExecuteScalar ()
311 ValidateCommand ("ExecuteScalar");
312 try {
313 Execute (CommandBehavior.Default, true);
315 catch (TdsTimeoutException e) {
316 throw SybaseException.FromTdsInternalException ((TdsInternalException) e);
319 if (!Connection.Tds.NextResult () || !Connection.Tds.NextRow ())
320 return null;
322 object result = Connection.Tds.ColumnValues [0];
323 CloseDataReader (true);
324 return result;
327 private void GetOutputParameters ()
329 Connection.Tds.SkipToEnd ();
331 IList list = Connection.Tds.ColumnValues;
333 if (list != null && list.Count > 0) {
334 int index = 0;
335 foreach (SybaseParameter parameter in parameters) {
336 if (parameter.Direction != ParameterDirection.Input) {
337 parameter.Value = list [index];
338 index += 1;
340 if (index >= list.Count)
341 break;
346 object ICloneable.Clone ()
348 return new SybaseCommand (commandText, Connection);
351 IDbDataParameter IDbCommand.CreateParameter ()
353 return CreateParameter ();
356 IDataReader IDbCommand.ExecuteReader ()
358 return ExecuteReader ();
361 IDataReader IDbCommand.ExecuteReader (CommandBehavior behavior)
363 return ExecuteReader (behavior);
366 public void Prepare ()
368 ValidateCommand ("Prepare");
369 if (CommandType == CommandType.Text)
370 preparedStatement = Connection.Tds.Prepare (CommandText, Parameters.MetaParameters);
373 public void ResetCommandTimeout ()
375 commandTimeout = 30;
378 private void Unprepare ()
380 Connection.Tds.Unprepare (preparedStatement);
381 preparedStatement = null;
384 private void ValidateCommand (string method)
386 if (Connection == null)
387 throw new InvalidOperationException (String.Format ("{0} requires a Connection object to continue.", method));
388 if (Connection.Transaction != null && transaction != Connection.Transaction)
389 throw new InvalidOperationException ("The Connection object does not have the same transaction as the command object.");
390 if (Connection.State != ConnectionState.Open)
391 throw new InvalidOperationException (String.Format ("ExecuteNonQuery requires an open Connection object to continue. This connection is closed.", method));
392 if (commandText == String.Empty || commandText == null)
393 throw new InvalidOperationException ("The command text for this Command has not been set.");
394 if (Connection.DataReader != null)
395 throw new InvalidOperationException ("There is already an open DataReader associated with this Connection which must be closed first.");
398 #endregion // Methods