Use UNIX line endings consistently
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / SqlDataSourceView.cs
1 //
2 // System.Web.UI.WebControls.SqlDataSourceView
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Sanjay Gupta (gsanjay@novell.com)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) Novell, Inc. (http://www.novell.com)
10 //
11
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
33 #if NET_2_0
34 using System.Collections;
35 using System.Collections.Specialized;
36 using System.Text;
37 using System.Data;
38 using System.ComponentModel;
39 using System.Data.Common;
40
41 namespace System.Web.UI.WebControls {
42         public class SqlDataSourceView : DataSourceView, IStateManager {
43
44                 HttpContext context;
45                 DbProviderFactory factory;
46                 DbConnection connection;
47
48                 public SqlDataSourceView (SqlDataSource owner, string name, HttpContext context)
49                         : base (owner, name)
50                 {
51                         this.owner = owner;
52                         this.name = name;
53                         this.context = context;
54                 }
55
56                 void InitConnection ()
57                 {
58                         if (factory == null) factory = owner.GetDbProviderFactoryInternal ();
59                         if (connection == null) {
60                                 connection = factory.CreateConnection ();
61                                 connection.ConnectionString = owner.ConnectionString;
62                         }
63                 }
64
65                 public int Delete (IDictionary keys, IDictionary oldValues)
66                 {
67                         return ExecuteDelete (keys, oldValues);
68                 }
69                 
70                 protected override int ExecuteDelete (IDictionary keys, IDictionary oldValues)
71                 {
72                         if (!CanDelete)
73                                 throw new NotSupportedException("Delete operation is not supported");
74                         if (oldValues == null && ConflictDetection == ConflictOptions.CompareAllValues)
75                                 throw new InvalidOperationException ("oldValues parameters should be specified when ConflictOptions is set to CompareAllValues");
76
77                         InitConnection ();
78
79                         DbCommand command = factory.CreateCommand ();
80                         command.CommandText = DeleteCommand;
81                         command.Connection = connection;
82                         if (DeleteCommandType == SqlDataSourceCommandType.Text)
83                                 command.CommandType = CommandType.Text;
84                         else
85                                 command.CommandType = CommandType.StoredProcedure;
86
87                         IDictionary oldDataValues;
88                         if (ConflictDetection == ConflictOptions.CompareAllValues) {
89                                 oldDataValues = new Hashtable ();
90                                 if (keys != null) {
91                                         foreach (DictionaryEntry de in keys)
92                                                 oldDataValues [de.Key] = de.Value;
93                                 }
94                                 if (oldValues != null) {
95                                         foreach (DictionaryEntry de in oldValues)
96                                                 oldDataValues [de.Key] = de.Value;
97                                 }
98                         }
99                         else
100                                 oldDataValues = keys;
101                         
102                         InitializeParameters (command, DeleteParameters, null, oldDataValues, true);
103
104                         SqlDataSourceCommandEventArgs args = new SqlDataSourceCommandEventArgs (command);
105                         OnDeleting (args);
106                         if (args.Cancel)
107                                 return -1; 
108
109                         bool closed = connection.State == ConnectionState.Closed;
110
111                         if (closed)
112                                 connection.Open();
113                         Exception exception = null; 
114                         int result = -1;;
115                         try {
116                                 result = command.ExecuteNonQuery();
117                         } catch (Exception e) {
118                                 exception = e;
119                         }
120
121                         if (closed)
122                                 connection.Close ();
123
124                         OnDataSourceViewChanged (EventArgs.Empty);
125
126                         SqlDataSourceStatusEventArgs deletedArgs =
127                                 new SqlDataSourceStatusEventArgs (command, result, exception);
128                         OnDeleted (deletedArgs);
129
130                         if (exception != null && !deletedArgs.ExceptionHandled)
131                                 throw exception;
132
133                         return result;
134                 }
135                 
136                 public int Insert (IDictionary values)
137                 {
138                         return ExecuteInsert (values);
139                 }
140
141                 protected override int ExecuteInsert (IDictionary values)
142                 {
143                         if (!CanInsert)
144                                 throw new NotSupportedException ("Insert operation is not supported");
145
146                         InitConnection ();
147
148                         DbCommand command = factory.CreateCommand ();
149                         command.CommandText = InsertCommand;
150                         command.Connection = connection;
151                         if (InsertCommandType == SqlDataSourceCommandType.Text)
152                                 command.CommandType = CommandType.Text;
153                         else
154                                 command.CommandType = CommandType.StoredProcedure;
155
156                         InitializeParameters (command, InsertParameters, values, null, false);
157
158                         SqlDataSourceCommandEventArgs args = new SqlDataSourceCommandEventArgs (command);
159                         OnInserting (args);
160                         if (args.Cancel)
161                                 return -1;
162
163                         bool closed = connection.State == ConnectionState.Closed;
164                         if (closed)
165                                 connection.Open ();
166                         Exception exception = null;
167                         int result = -1;
168                         try {
169                                 result = command.ExecuteNonQuery ();
170                         }
171                         catch (Exception e) {
172                                 exception = e;
173                         }
174
175                         if (closed)
176                                 connection.Close ();
177
178                         OnDataSourceViewChanged (EventArgs.Empty);
179
180                         OnInserted (new SqlDataSourceStatusEventArgs (command, result, exception));
181
182                         if (exception != null)
183                                 throw exception;
184                         return result;
185                 }
186                                 
187                 public IEnumerable Select (DataSourceSelectArguments arguments)
188                 {
189                         return ExecuteSelect (arguments);
190                 }
191
192                 protected internal override IEnumerable ExecuteSelect (DataSourceSelectArguments arguments)
193                 {
194                         if (SortParameterName.Length > 0 && SelectCommandType == SqlDataSourceCommandType.Text)
195                                 throw new NotSupportedException ("The SortParameterName property is only supported with stored procedure commands in SqlDataSource");
196
197                         if (arguments.SortExpression.Length > 0 && owner.DataSourceMode == SqlDataSourceMode.DataReader)
198                                 throw new NotSupportedException ("SqlDataSource cannot sort. Set DataSourceMode to DataSet to enable sorting.");
199
200                         if (arguments.StartRowIndex > 0 || arguments.MaximumRows > 0)
201                                 throw new NotSupportedException ("SqlDataSource does not have paging enabled. Set the DataSourceMode to DataSet to enable paging.");
202
203                         if (FilterExpression.Length > 0 && owner.DataSourceMode == SqlDataSourceMode.DataReader)
204                                 throw new NotSupportedException ("SqlDataSource only supports filtering when the data source's DataSourceMode is set to DataSet.");
205
206                         InitConnection ();
207
208                         DbCommand command = factory.CreateCommand ();
209                         command.CommandText = SelectCommand;
210                         command.Connection = connection;
211                         if (SelectCommandType == SqlDataSourceCommandType.Text)
212                                 command.CommandType = CommandType.Text;
213                         else {
214                                 command.CommandType = CommandType.StoredProcedure;
215                                 if (SortParameterName.Length > 0 && arguments.SortExpression.Length > 0)
216                                         command.Parameters.Add (CreateDbParameter (SortParameterName, arguments.SortExpression));
217                         }
218
219                         if (SelectParameters.Count > 0)
220                                 InitializeParameters (command, SelectParameters, null, null, false);
221
222                         Exception exception = null;
223                         if (owner.DataSourceMode == SqlDataSourceMode.DataSet) {
224                                 DataView dataView = null;
225
226                                 if (owner.EnableCaching)
227                                         dataView = (DataView) owner.Cache.GetCachedObject (SelectCommand, SelectParameters);
228
229                                 if (dataView == null) {
230                                         SqlDataSourceSelectingEventArgs selectingArgs = new SqlDataSourceSelectingEventArgs (command, arguments);
231                                         OnSelecting (selectingArgs);
232                                         if (selectingArgs.Cancel || !PrepareNullParameters (command, CancelSelectOnNullParameter)) {
233                                                 return null;
234                                         }
235                                         try {
236                                                 DbDataAdapter adapter = factory.CreateDataAdapter ();
237                                                 DataSet dataset = new DataSet ();
238
239                                                 adapter.SelectCommand = command;
240                                                 adapter.Fill (dataset, name);
241
242                                                 dataView = dataset.Tables [0].DefaultView;
243                                                 if (dataView == null)
244                                                         throw new InvalidOperationException ();
245                                         }
246                                         catch (Exception e) {
247                                                 exception = e;
248                                         }
249                                         int rowsAffected = (dataView == null) ? 0 : dataView.Count;
250                                         SqlDataSourceStatusEventArgs selectedArgs = new SqlDataSourceStatusEventArgs (command, rowsAffected, exception);
251                                         OnSelected (selectedArgs);
252
253                                         if (exception != null && !selectedArgs.ExceptionHandled)
254                                                 throw exception;
255
256                                         if (owner.EnableCaching)
257                                                 owner.Cache.SetCachedObject (SelectCommand, selectParameters, dataView);
258                                 }
259
260                                 if (SortParameterName.Length == 0 || SelectCommandType == SqlDataSourceCommandType.Text)
261                                         dataView.Sort = arguments.SortExpression;
262
263                                 if (FilterExpression.Length > 0) {
264                                         IOrderedDictionary fparams = FilterParameters.GetValues (context, owner);
265                                         SqlDataSourceFilteringEventArgs fargs = new SqlDataSourceFilteringEventArgs (fparams);
266                                         OnFiltering (fargs);
267                                         if (!fargs.Cancel) {
268                                                 object [] formatValues = new object [fparams.Count];
269                                                 for (int n = 0; n < formatValues.Length; n++) {
270                                                         formatValues [n] = fparams [n];
271                                                         if (formatValues [n] == null) return dataView;
272                                                 }
273                                                 dataView.RowFilter = string.Format (FilterExpression, formatValues);
274                                         }
275                                 }
276
277                                 return dataView;
278                         }
279                         else {
280                                 SqlDataSourceSelectingEventArgs selectingArgs = new SqlDataSourceSelectingEventArgs (command, arguments);
281                                 OnSelecting (selectingArgs);
282                                 if (selectingArgs.Cancel || !PrepareNullParameters (command, CancelSelectOnNullParameter)) {
283                                         return null;
284                                 }
285
286                                 DbDataReader reader = null;
287                                 bool closed = connection.State == ConnectionState.Closed;
288
289                                 if (closed)
290                                         connection.Open ();
291                                 try {
292                                         reader = command.ExecuteReader (closed ? CommandBehavior.CloseConnection : CommandBehavior.Default);
293                                 }
294                                 catch (Exception e) {
295                                         exception = e;
296                                 }
297                                 SqlDataSourceStatusEventArgs selectedArgs =
298                                         new SqlDataSourceStatusEventArgs (command, reader.RecordsAffected, exception);
299                                 OnSelected (selectedArgs);
300                                 if (exception != null && !selectedArgs.ExceptionHandled)
301                                         throw exception;
302
303                                 return reader;
304                         }
305                 }
306
307                 static bool PrepareNullParameters (DbCommand command, bool cancelIfHas)
308                 {
309                         for (int i = 0; i < command.Parameters.Count; i++) {
310                                 DbParameter param = command.Parameters [i];
311                                 if (param.Value == null && ((param.Direction & ParameterDirection.Input) != 0)) {
312                                         if (cancelIfHas)
313                                                 return false;
314                                         else
315                                                 param.Value = DBNull.Value;
316                                 }
317                         }
318                         return true;
319                 }
320
321                 public int Update (IDictionary keys, IDictionary values, IDictionary oldValues)
322                 {
323                         return ExecuteUpdate (keys, values, oldValues);
324                 }
325
326                 protected override int ExecuteUpdate (IDictionary keys, IDictionary values, IDictionary oldValues)
327                 {
328                         if (!CanUpdate)
329                                 throw new NotSupportedException ("Update operation is not supported");
330                         if (oldValues == null && ConflictDetection == ConflictOptions.CompareAllValues)
331                                 throw new InvalidOperationException ("oldValues parameters should be specified when ConflictOptions is set to CompareAllValues");
332
333                         InitConnection ();
334
335                         DbCommand command = factory.CreateCommand ();
336                         command.CommandText = UpdateCommand;
337                         command.Connection = connection;
338                         if (UpdateCommandType == SqlDataSourceCommandType.Text)
339                                 command.CommandType = CommandType.Text;
340                         else
341                                 command.CommandType = CommandType.StoredProcedure;
342
343                         IDictionary oldDataValues;
344                         if (ConflictDetection == ConflictOptions.CompareAllValues) {
345                                 oldDataValues = new OrderedDictionary ();
346                                 if (keys != null) {
347                                         foreach (DictionaryEntry de in keys)
348                                                 oldDataValues [de.Key] = de.Value;
349                                 }
350                                 if (oldValues != null) {
351                                         foreach (DictionaryEntry de in oldValues)
352                                                 oldDataValues [de.Key] = de.Value;
353                                 }
354                         }
355                         else {
356                                 oldDataValues = keys;
357                         }
358
359                         IDictionary dataValues = values;
360
361                         InitializeParameters (command, UpdateParameters, dataValues, oldDataValues, ConflictDetection == ConflictOptions.OverwriteChanges);
362
363                         SqlDataSourceCommandEventArgs args = new SqlDataSourceCommandEventArgs (command);
364                         OnUpdating (args);
365                         if (args.Cancel)
366                                 return -1;
367
368                         bool closed = connection.State == ConnectionState.Closed;
369                         if (closed)
370                                 connection.Open ();
371                         Exception exception = null;
372                         int result = -1;
373                         try {
374                                 result = command.ExecuteNonQuery ();
375                         }
376                         catch (Exception e) {
377                                 exception = e;
378                         }
379
380                         if (closed)
381                                 connection.Close ();
382
383                         OnDataSourceViewChanged (EventArgs.Empty);
384
385                         SqlDataSourceStatusEventArgs updatedArgs =
386                                 new SqlDataSourceStatusEventArgs (command, result, exception);
387                         OnUpdated (updatedArgs);
388
389                         if (exception != null && !updatedArgs.ExceptionHandled)
390                                 throw exception;
391
392                         return result;
393                 }
394
395                 string FormatOldParameter (string name)
396                 {
397                         string f = OldValuesParameterFormatString;
398                         if (f.Length > 0)
399                                 return String.Format (f, name);
400                         else
401                                 return name;
402                 }
403
404                 object FindValueByName (string parameterName, IDictionary values, bool format)
405                 {
406                         if (values == null)
407                                 return null;
408
409                         foreach (DictionaryEntry de in values) {
410                                 string valueName = format == true ? FormatOldParameter (de.Key.ToString ()) : de.Key.ToString ();
411                                 if (String.Compare(parameterName, valueName, StringComparison.InvariantCultureIgnoreCase) == 0)
412                                         return values [de.Key];
413                         }
414                         return null;
415                 }
416
417                 void InitializeParameters (DbCommand command, ParameterCollection parameters, IDictionary values, IDictionary oldValues, bool parametersMayMatchOldValues)
418                 {
419                         IOrderedDictionary parameterValues = parameters.GetValues (context, owner);
420
421                         foreach (string parameterName in parameterValues.Keys) {
422                                 Parameter p = parameters [parameterName];
423                                 object value = FindValueByName (parameterName, values, false);
424                                 string valueName = parameterName;
425                                 if (value == null)
426                                         value = FindValueByName (parameterName, oldValues, true);
427
428                                 if (value == null && parametersMayMatchOldValues) {
429                                         value = FindValueByName (parameterName, oldValues, false);
430                                         valueName = FormatOldParameter (parameterName);
431                                 }
432
433                                 if (value != null) {
434                                         object dbValue = p.ConvertValue (value);
435                                         DbParameter newParameter = CreateDbParameter (valueName, dbValue, p.Direction, p.Size);
436                                         if (!command.Parameters.Contains (newParameter.ParameterName)) {
437                                                 command.Parameters.Add (newParameter);
438                                         }
439                                 }
440                                 else {
441                                         command.Parameters.Add (CreateDbParameter (p.Name, parameterValues [parameterName], p.Direction, p.Size));
442                                 }
443                         }
444
445                         if (values != null) {
446                                 foreach (DictionaryEntry de in values)
447                                         if (!command.Parameters.Contains (ParameterPrefix + (string) de.Key))
448                                                 command.Parameters.Add (CreateDbParameter ((string) de.Key, de.Value));
449                         }
450
451                         if (oldValues != null) {
452                                 foreach (DictionaryEntry de in oldValues)
453                                         if (!command.Parameters.Contains (ParameterPrefix + FormatOldParameter ((string) de.Key)))
454                                                 command.Parameters.Add (CreateDbParameter (FormatOldParameter ((string) de.Key), de.Value));
455                         }
456                 }
457
458                 private DbParameter CreateDbParameter (string name, object value)
459                 {
460                         return CreateDbParameter (name, value, ParameterDirection.Input, -1);
461                 }
462                 
463                 private DbParameter CreateDbParameter (string name, object value, ParameterDirection dir, int size)
464                 {
465                         DbParameter dbp = factory.CreateParameter ();
466                         dbp.ParameterName = ParameterPrefix + name;
467                         dbp.Value = value;
468                         dbp.Direction = dir;
469                         if (size != -1)
470                                 dbp.Size = size;
471
472                         return dbp;
473                 }
474
475                 void IStateManager.LoadViewState (object savedState)
476                 {
477                         LoadViewState (savedState);
478                 }
479                 
480                 object IStateManager.SaveViewState ()
481                 {
482                         return SaveViewState ();
483                 }
484                 
485                 void IStateManager.TrackViewState ()
486                 {
487                         TrackViewState ();
488                 }
489                 
490                 protected virtual void LoadViewState (object savedState)
491                 {
492                         object [] vs = savedState as object [];
493                         if (vs == null)
494                                 return;
495                         
496                         if (vs [0] != null) ((IStateManager) deleteParameters).LoadViewState (vs [0]);
497                         if (vs [1] != null) ((IStateManager) filterParameters).LoadViewState (vs [1]);
498                         if (vs [2] != null) ((IStateManager) insertParameters).LoadViewState (vs [2]);
499                         if (vs [3] != null) ((IStateManager) selectParameters).LoadViewState (vs [3]);
500                         if (vs [4] != null) ((IStateManager) updateParameters).LoadViewState (vs [4]);
501                 }
502
503                 protected virtual object SaveViewState ()
504                 {
505                         object [] vs = new object [5];
506                         
507                         if (deleteParameters != null) vs [0] = ((IStateManager) deleteParameters).SaveViewState ();
508                         if (filterParameters != null) vs [1] = ((IStateManager) filterParameters).SaveViewState ();
509                         if (insertParameters != null) vs [2] = ((IStateManager) insertParameters).SaveViewState ();
510                         if (selectParameters != null) vs [3] = ((IStateManager) selectParameters).SaveViewState ();
511                         if (updateParameters != null) vs [4] = ((IStateManager) updateParameters).SaveViewState ();
512                                 
513                         foreach (object o in vs)
514                                 if (o != null) return vs;
515                         return null;
516                 }
517                 
518                 protected virtual void TrackViewState ()
519                 {
520                         tracking = true;
521                         
522                         if (filterParameters != null) ((IStateManager) filterParameters).TrackViewState ();
523                         if (selectParameters != null) ((IStateManager) selectParameters).TrackViewState ();
524                 }
525                 
526                 bool IStateManager.IsTrackingViewState {
527                         get { return IsTrackingViewState; }
528                 }
529
530                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
531                 private bool cancelSelectOnNullParameter = true;
532                 public bool CancelSelectOnNullParameter {
533                         get { return cancelSelectOnNullParameter; }
534                         set {
535                                 if (CancelSelectOnNullParameter == value)
536                                         return;
537                                 cancelSelectOnNullParameter = value;
538                                 OnDataSourceViewChanged (EventArgs.Empty);
539                         }
540                 }
541
542                 public override bool CanDelete {
543                         get { return DeleteCommand != null && DeleteCommand != ""; }
544                 }
545
546                 public override bool CanInsert {
547                         get { return InsertCommand != null && InsertCommand != ""; }
548                 }
549                 
550                 public override bool CanPage {
551                         /* according to MS, this is false in all cases */
552                         get { return false; }
553                 }
554
555                 public override bool CanRetrieveTotalRowCount {
556                         /* according to MS, this is false in all cases */
557                         get { return false; }
558                 }
559
560                 public override bool CanSort {
561                         get {
562                                 /* we can sort if we're a DataSet, regardless of sort parameter name.
563                                    we can sort if we're a DataReader, if the sort parameter name is not null/"".
564                                 */
565                                 return (owner.DataSourceMode == SqlDataSourceMode.DataSet
566                                         || (SortParameterName != null && SortParameterName != ""));
567                         }
568                 }
569                 
570                 public override bool CanUpdate {
571                         get { return UpdateCommand != null && UpdateCommand != ""; }
572                 }
573
574                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
575                 private ConflictOptions conflictDetection = ConflictOptions.OverwriteChanges;
576                 public ConflictOptions ConflictDetection {
577                         get { return conflictDetection; }
578                         set {
579                                 if (ConflictDetection == value)
580                                         return;
581                                 conflictDetection = value;
582                                 OnDataSourceViewChanged (EventArgs.Empty);
583                         }
584                 }
585
586                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
587                 private string deleteCommand = "";
588                 public string DeleteCommand {
589                         get { return deleteCommand; }
590                         set { deleteCommand = value; }
591                 }
592
593                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
594                 private SqlDataSourceCommandType deleteCommandType = SqlDataSourceCommandType.Text;
595                 public SqlDataSourceCommandType DeleteCommandType {
596                         get { return deleteCommandType; }
597                         set { deleteCommandType = value; }
598                 }
599
600                 [DefaultValueAttribute (null)]
601                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
602                 [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
603                 public ParameterCollection DeleteParameters {
604                         get { return GetParameterCollection (ref deleteParameters, false, false); }
605                 }
606
607                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
608                 private string filterExpression;
609                 public string FilterExpression {
610                         get { return filterExpression ?? string.Empty; }
611                         set {
612                                 if (FilterExpression == value)
613                                         return;
614                                 filterExpression = value;
615                                 OnDataSourceViewChanged (EventArgs.Empty);
616                         }
617                 }
618
619                 [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
620                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
621                 [DefaultValueAttribute (null)]
622                 public ParameterCollection FilterParameters {
623                         get { return GetParameterCollection (ref filterParameters, true, true); }
624                 }
625
626                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
627                 private string insertCommand = "";
628                 public string InsertCommand {
629                         get { return insertCommand; }
630                         set { insertCommand = value; }
631                 }
632
633                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
634                 private SqlDataSourceCommandType insertCommandType = SqlDataSourceCommandType.Text;
635                 public SqlDataSourceCommandType InsertCommandType {
636                         get { return insertCommandType; }
637                         set { insertCommandType = value; }
638                 }
639
640                 [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
641                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
642                 [DefaultValueAttribute (null)]
643                 public ParameterCollection InsertParameters {
644                         get { return GetParameterCollection (ref insertParameters, false, false); }
645                 }
646
647                 protected bool IsTrackingViewState {
648                         get { return tracking; }
649                 }
650
651                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
652                 private string oldValuesParameterFormatString = "{0}";
653                 [DefaultValue ("{0}")]
654                 public string OldValuesParameterFormatString {
655                         get { return oldValuesParameterFormatString; }
656                         set {
657                                 if (OldValuesParameterFormatString == value)
658                                         return;
659                                 oldValuesParameterFormatString = value;
660                                 OnDataSourceViewChanged (EventArgs.Empty);
661                         }
662                 }
663
664                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
665                 private string selectCommand;
666                 public string SelectCommand {
667                         get { return selectCommand != null ? selectCommand : string.Empty; }
668                         set {
669                                 if (SelectCommand == value)
670                                         return;
671                                 selectCommand = value;
672                                 OnDataSourceViewChanged (EventArgs.Empty);
673                         }
674                 }
675
676                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
677                 private SqlDataSourceCommandType selectCommandType = SqlDataSourceCommandType.Text;
678                 public SqlDataSourceCommandType SelectCommandType {
679                         get { return selectCommandType; }
680                         set { selectCommandType = value; }
681                 }
682                 
683                 public ParameterCollection SelectParameters {
684                         get { return GetParameterCollection (ref selectParameters, true, true); }
685                 }
686
687                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
688                 private string sortParameterName = "";
689                 public string SortParameterName {
690                         get { return sortParameterName; }
691                         set {
692                                 if (SortParameterName == value)
693                                         return;
694                                 sortParameterName = value;
695                                 OnDataSourceViewChanged (EventArgs.Empty);
696                         }
697                 }
698
699                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
700                 private string updateCommand = "";
701                 public string UpdateCommand {
702                         get { return updateCommand; }
703                         set { updateCommand = value; }
704                 }
705
706                 // LAME SPEC: MSDN says value should be saved in ViewState but tests show otherwise.
707                 private SqlDataSourceCommandType updateCommandType = SqlDataSourceCommandType.Text;
708                 public SqlDataSourceCommandType UpdateCommandType {
709                         get { return updateCommandType; }
710                         set { updateCommandType = value; }
711                 }
712
713                 [EditorAttribute ("System.Web.UI.Design.WebControls.ParameterCollectionEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
714                 [PersistenceModeAttribute (PersistenceMode.InnerProperty)]
715                 [DefaultValueAttribute (null)]
716                 public ParameterCollection UpdateParameters {
717                         get { return GetParameterCollection (ref updateParameters, false, false); }
718                 }
719                 
720                 void ParametersChanged (object source, EventArgs args)
721                 {
722                         OnDataSourceViewChanged (EventArgs.Empty);
723                 }
724                 
725                 ParameterCollection GetParameterCollection (ref ParameterCollection output, bool propagateTrackViewState, bool subscribeChanged)
726                 {
727                         if (output != null)
728                                 return output;
729                         
730                         output = new ParameterCollection ();
731                         if(subscribeChanged)
732                                 output.ParametersChanged += new EventHandler (ParametersChanged);
733                         
734                         if (IsTrackingViewState && propagateTrackViewState)
735                                 ((IStateManager) output).TrackViewState ();
736                         
737                         return output;
738                 }
739                 
740                 protected virtual string ParameterPrefix {
741                         get {
742                                 switch (owner.ProviderName) {
743                                         case "":
744                                         case "System.Data.SqlClient": return "@";
745                                         case "System.Data.OracleClient": return ":";
746                                 }
747                                 return "";
748                         }
749                 }
750
751                 ParameterCollection deleteParameters;
752                 ParameterCollection filterParameters;
753                 ParameterCollection insertParameters;
754                 ParameterCollection selectParameters;
755                 ParameterCollection updateParameters;
756
757                 bool tracking;
758         
759                 string name;
760                 SqlDataSource owner;
761
762                 #region OnDelete
763                 static readonly object EventDeleted = new object ();
764                 protected virtual void OnDeleted (SqlDataSourceStatusEventArgs e)
765                 {
766                         if (!HasEvents ()) return;
767                         SqlDataSourceStatusEventHandler h = Events [EventDeleted] as SqlDataSourceStatusEventHandler;
768                         if (h != null)
769                                 h (this, e);
770                 }
771                 
772                 public event SqlDataSourceStatusEventHandler Deleted {
773                         add { Events.AddHandler (EventDeleted, value); }
774                         remove { Events.RemoveHandler (EventDeleted, value); }
775                 }
776                 
777                 static readonly object EventDeleting = new object ();
778                 protected virtual void OnDeleting (SqlDataSourceCommandEventArgs e)
779                 {
780                         if (!HasEvents ()) return;
781                         SqlDataSourceCommandEventHandler h = Events [EventDeleting] as SqlDataSourceCommandEventHandler;
782                         if (h != null)
783                                 h (this, e);
784                 }
785                 public event SqlDataSourceCommandEventHandler Deleting {
786                         add { Events.AddHandler (EventDeleting, value); }
787                         remove { Events.RemoveHandler (EventDeleting, value); }
788                 }
789                 #endregion
790
791                 #region OnFiltering
792                 static readonly object EventFiltering = new object ();
793                 protected virtual void OnFiltering (SqlDataSourceFilteringEventArgs e)
794                 {
795                         if (!HasEvents ()) return;
796                         SqlDataSourceFilteringEventHandler h = Events [EventFiltering] as SqlDataSourceFilteringEventHandler;
797                         if (h != null)
798                                 h (this, e);
799                 }
800                 public event SqlDataSourceFilteringEventHandler Filtering {
801                         add { Events.AddHandler (EventFiltering, value); }
802                         remove { Events.RemoveHandler (EventFiltering, value); }
803                 }
804                 #endregion
805                 
806                 #region OnInsert
807                 static readonly object EventInserted = new object ();
808                 protected virtual void OnInserted (SqlDataSourceStatusEventArgs e)
809                 {
810                         if (!HasEvents ()) return;
811                         SqlDataSourceStatusEventHandler h = Events [EventInserted] as SqlDataSourceStatusEventHandler;
812                         if (h != null)
813                                 h (this, e);
814                 }
815                 
816                 public event SqlDataSourceStatusEventHandler Inserted {
817                         add { Events.AddHandler (EventInserted, value); }
818                         remove { Events.RemoveHandler (EventInserted, value); }
819                 }
820                 
821                 static readonly object EventInserting = new object ();
822                 protected virtual void OnInserting (SqlDataSourceCommandEventArgs e)
823                 {
824                         if (!HasEvents ()) return;
825                         SqlDataSourceCommandEventHandler h = Events [EventInserting] as SqlDataSourceCommandEventHandler;
826                         if (h != null)
827                                 h (this, e);
828                 }
829                 public event SqlDataSourceCommandEventHandler Inserting {
830                         add { Events.AddHandler (EventInserting, value); }
831                         remove { Events.RemoveHandler (EventInserting, value); }
832                 }
833                 #endregion
834                 
835                 #region OnSelect
836                 static readonly object EventSelected = new object ();
837                 protected virtual void OnSelected (SqlDataSourceStatusEventArgs e)
838                 {
839                         if (!HasEvents ()) return;
840                         SqlDataSourceStatusEventHandler h = Events [EventSelected] as SqlDataSourceStatusEventHandler;
841                         if (h != null)
842                                 h (this, e);
843                 }
844                 
845                 public event SqlDataSourceStatusEventHandler Selected {
846                         add { Events.AddHandler (EventSelected, value); }
847                         remove { Events.RemoveHandler (EventSelected, value); }
848                 }
849                 
850                 static readonly object EventSelecting = new object ();
851                 protected virtual void OnSelecting (SqlDataSourceSelectingEventArgs e)
852                 {
853                         if (!HasEvents ()) return;
854                         SqlDataSourceSelectingEventHandler h = Events [EventSelecting] as SqlDataSourceSelectingEventHandler;
855                         if (h != null)
856                                 h (this, e);
857                 }
858                 public event SqlDataSourceSelectingEventHandler Selecting {
859                         add { Events.AddHandler (EventSelecting, value); }
860                         remove { Events.RemoveHandler (EventSelecting, value); }
861                 }
862                 #endregion
863                 
864                 #region OnUpdate
865                 static readonly object EventUpdated = new object ();
866                 protected virtual void OnUpdated (SqlDataSourceStatusEventArgs e)
867                 {
868                         if (owner.EnableCaching)
869                                 owner.Cache.Expire ();
870
871                         if (!HasEvents ()) return;
872                         SqlDataSourceStatusEventHandler h = Events [EventUpdated] as SqlDataSourceStatusEventHandler;
873                         if (h != null)
874                                 h (this, e);
875                 }
876                 
877                 public event SqlDataSourceStatusEventHandler Updated {
878                         add { Events.AddHandler (EventUpdated, value); }
879                         remove { Events.RemoveHandler (EventUpdated, value); }
880                 }
881                 
882                 static readonly object EventUpdating = new object ();
883                 protected virtual void OnUpdating (SqlDataSourceCommandEventArgs e)
884                 {
885                         if (!HasEvents ()) return;
886                         SqlDataSourceCommandEventHandler h = Events [EventUpdating] as SqlDataSourceCommandEventHandler;
887                         if (h != null)
888                                 h (this, e);
889                 }
890                 public event SqlDataSourceCommandEventHandler Updating {
891                         add { Events.AddHandler (EventUpdating, value); }
892                         remove { Events.RemoveHandler (EventUpdating, value); }
893                 }
894                 #endregion
895                                 
896         }
897         
898 }
899 #endif
900
901