Fix problems with overlong directory names: phase #1
[mono.git] / mcs / class / System.Data / System.Data.SqlClient / SqlConnection.cs
1 //
2 // System.Data.SqlClient.SqlConnection.cs
3 //
4 // Authors:
5 //   Rodrigo Moya (rodrigo@ximian.com)
6 //   Daniel Morgan (danmorg@sc.rr.com)
7 //   Tim Coleman (tim@timcoleman.com)
8 //   Phillip Jerkins (Phillip.Jerkins@morgankeegan.com)
9 //   Diego Caravana (diego@toth.it)
10 //
11 // Copyright (C) Ximian, Inc 2002
12 // Copyright (C) Daniel Morgan 2002, 2003
13 // Copyright (C) Tim Coleman, 2002, 2003
14 // Copyright (C) Phillip Jerkins, 2003
15 //
16
17 //
18 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
19 //
20 // Permission is hereby granted, free of charge, to any person obtaining
21 // a copy of this software and associated documentation files (the
22 // "Software"), to deal in the Software without restriction, including
23 // without limitation the rights to use, copy, modify, merge, publish,
24 // distribute, sublicense, and/or sell copies of the Software, and to
25 // permit persons to whom the Software is furnished to do so, subject to
26 // the following conditions:
27 // 
28 // The above copyright notice and this permission notice shall be
29 // included in all copies or substantial portions of the Software.
30 // 
31 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 //
39
40 using Mono.Data.Tds;
41 using Mono.Data.Tds.Protocol;
42 using System;
43 using System.Collections;
44 using System.Collections.Specialized;
45 using System.ComponentModel;
46 using System.Data;
47 using System.Data.Common;
48 using System.EnterpriseServices;
49 using System.Globalization;
50 using System.Net;
51 using System.Net.Sockets;
52 using System.Text;
53 using System.Xml;
54
55 namespace System.Data.SqlClient {
56         [DefaultEvent ("InfoMessage")]
57 #if NET_2_0
58         public sealed class SqlConnection : DbConnection, IDbConnection, ICloneable     
59 #else
60         public sealed class SqlConnection : Component, IDbConnection, ICloneable                        
61 #endif // NET_2_0
62         {
63                 #region Fields
64                 bool disposed = false;
65
66                 // The set of SQL connection pools
67                 static TdsConnectionPoolManager sqlConnectionPools = new TdsConnectionPoolManager (TdsVersion.tds70);
68
69                 // The current connection pool
70                 TdsConnectionPool pool;
71
72                 // The connection string that identifies this connection
73                 string connectionString = null;
74
75                 // The transaction object for the current transaction
76                 SqlTransaction transaction = null;
77
78                 // Connection parameters
79                 
80                 TdsConnectionParameters parms = new TdsConnectionParameters ();
81                 NameValueCollection connStringParameters = null;
82                 bool connectionReset;
83                 bool pooling;
84                 string dataSource;
85                 int connectionTimeout;
86                 int minPoolSize;
87                 int maxPoolSize;
88                 int packetSize;
89                 int port = 1433;
90
91                 // The current state
92                 ConnectionState state = ConnectionState.Closed;
93
94                 SqlDataReader dataReader = null;
95                 XmlReader xmlReader = null;
96
97                 // The TDS object
98                 ITds tds;
99
100                 #endregion // Fields
101
102                 #region Constructors
103
104                 public SqlConnection () 
105                         : this (String.Empty)
106                 {
107                 }
108         
109                 public SqlConnection (string connectionString)
110                 {
111                         Init (connectionString);
112                 }
113
114                 private void Init (string connectionString)
115                 {
116                         connectionTimeout       = 15; // default timeout
117                         dataSource              = ""; // default datasource
118                         packetSize              = 8192; // default packetsize
119                         ConnectionString        = connectionString;
120                 }
121                 
122
123                 #endregion // Constructors
124
125                 #region Properties
126
127                 [DataCategory ("Data")]
128 #if !NET_2_0
129                 [DataSysDescription ("Information used to connect to a DataSource, such as 'Data Source=x;Initial Catalog=x;Integrated Security=SSPI'.")]
130 #endif
131                 [DefaultValue ("")]
132                 [EditorAttribute ("Microsoft.VSDesigner.Data.SQL.Design.SqlConnectionStringEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
133                 [RecommendedAsConfigurable (true)]      
134                 [RefreshProperties (RefreshProperties.All)]
135                 [MonoTODO("persist security info, encrypt, enlist and , attachdbfilename keyword not implemented")]
136                 public 
137 #if NET_2_0
138                 override
139 #endif // NET_2_0
140                 string ConnectionString {
141                         get { return connectionString; }
142                         set {
143                                 if (state == ConnectionState.Open)
144                                         throw new InvalidOperationException ("Not Allowed to change ConnectionString property while Connection state is OPEN");
145                                 SetConnectionString (value); 
146                         }
147                 }
148         
149 #if !NET_2_0
150                 [DataSysDescription ("Current connection timeout value, 'Connect Timeout=X' in the ConnectionString.")] 
151 #endif
152                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
153                 public 
154 #if NET_2_0
155                 override
156 #endif // NET_2_0
157                 
158                 int ConnectionTimeout {
159                         get { return connectionTimeout; }
160                 }
161
162 #if !NET_2_0
163                 [DataSysDescription ("Current SQL Server database, 'Initial Catalog=X' in the connection string.")]
164 #endif
165                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
166                 public 
167 #if NET_2_0
168                 override
169 #endif // NET_2_0
170                 string Database {
171                         get { 
172                                 if (State == ConnectionState.Open)
173                                         return tds.Database; 
174                                 return parms.Database ;
175                         }
176                 }
177                 
178                 internal SqlDataReader DataReader {
179                         get { return dataReader; }
180                         set { dataReader = value; }
181                 }
182
183 #if !NET_2_0
184                 [DataSysDescription ("Current SqlServer that the connection is opened to, 'Data Source=X' in the connection string. ")]
185 #endif
186                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
187                 public 
188 #if NET_2_0
189                 override
190 #endif // NET_2_0
191                 string DataSource {
192                         get { return dataSource; }
193                 }
194
195 #if !NET_2_0
196                 [DataSysDescription ("Network packet size, 'Packet Size=x' in the connection string.")]
197 #endif
198                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
199                 public int PacketSize {
200                         get {   
201                                 if (State == ConnectionState.Open) 
202                                         return ((Tds)tds).PacketSize ;
203                                 return packetSize; 
204                         }
205                 }
206
207                 [Browsable (false)]
208 #if !NET_2_0
209                 [DataSysDescription ("Version of the SQL Server accessed by the SqlConnection.")]
210 #endif
211                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
212                 public 
213 #if NET_2_0
214                 override
215 #endif // NET_2_0
216                 string ServerVersion {
217                         get { 
218                                 if (state == ConnectionState.Closed)
219                                         throw new InvalidOperationException ("Invalid Operation.The Connection is Closed");
220                                 else
221                                         return tds.ServerVersion; 
222                         }
223                 }
224
225                 [Browsable (false)]
226 #if !NET_2_0
227                 [DataSysDescription ("The ConnectionState indicating whether the connection is open or closed.")]
228 #endif
229                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
230                 public 
231 #if NET_2_0
232                 override
233 #endif // NET_2_0
234                 ConnectionState State {
235                         get { return state; }
236                 }
237
238                 internal ITds Tds {
239                         get { return tds; }
240                 }
241
242                 internal SqlTransaction Transaction {
243                         get { return transaction; }
244                         set { transaction = value; }
245                 }
246
247 #if !NET_2_0
248                 [DataSysDescription ("Workstation Id, 'Workstation ID=x' in the connection string.")]
249 #endif
250                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
251                 public string WorkstationId {
252                         get { return parms.Hostname; }
253                 }
254
255                 internal XmlReader XmlReader {
256                         get { return xmlReader; }
257                         set { xmlReader = value; }
258                 }
259
260                 #endregion // Properties
261
262                 #region Events
263
264                 [DataCategory ("InfoMessage")]
265 #if !NET_2_0
266                 [DataSysDescription ("Event triggered when messages arrive from the DataSource.")]
267 #endif
268                 public event SqlInfoMessageEventHandler InfoMessage;
269
270                 [DataCategory ("StateChange")]
271 #if !NET_2_0
272                 [DataSysDescription ("Event triggered when the connection changes state.")]
273 #endif
274                 public 
275 #if NET_2_0
276                 override
277 #endif // NET_2_0
278                 event StateChangeEventHandler StateChange;
279                 
280                 #endregion // Events
281
282                 #region Delegates
283
284                 private void ErrorHandler (object sender, TdsInternalErrorMessageEventArgs e)
285                 {
286                         throw new SqlException (e.Class, e.LineNumber, e.Message, e.Number, e.Procedure, e.Server, "Mono SqlClient Data Provider", e.State);
287                 }
288
289                 private void MessageHandler (object sender, TdsInternalInfoMessageEventArgs e)
290                 {
291                         OnSqlInfoMessage (CreateSqlInfoMessageEvent (e.Errors));
292                 }
293
294                 #endregion // Delegates
295
296                 #region Methods
297                 
298                 internal string GetConnStringKeyValue (params string [] keys)
299                 {
300                         if (connStringParameters == null || connStringParameters.Count == 0)
301                                 return "";
302                         foreach (string key in keys) {
303                                 string value = connStringParameters [key];
304                                 if (value != null)
305                                         return value;
306                         }
307                         
308                         return "";
309                 }
310                 
311
312                 public new SqlTransaction BeginTransaction ()
313                 {
314                         return BeginTransaction (IsolationLevel.ReadCommitted, String.Empty);
315                 }
316
317                 public new SqlTransaction BeginTransaction (IsolationLevel iso)
318                 {
319                         return BeginTransaction (iso, String.Empty);
320                 }
321
322                 public SqlTransaction BeginTransaction (string transactionName)
323                 {
324                         return BeginTransaction (IsolationLevel.ReadCommitted, transactionName);
325                 }
326
327                 public SqlTransaction BeginTransaction (IsolationLevel iso, string transactionName)
328                 {
329                         if (state == ConnectionState.Closed)
330                                 throw new InvalidOperationException ("The connection is not open.");
331                         if (transaction != null)
332                                 throw new InvalidOperationException ("SqlConnection does not support parallel transactions.");
333
334                         if (iso == IsolationLevel.Chaos)
335                                 throw new ArgumentException ("Invalid IsolationLevel parameter: must be ReadCommitted, ReadUncommitted, RepeatableRead, or Serializable.");
336
337                         string isolevel = String.Empty;
338                         switch (iso) {
339                         case IsolationLevel.ReadCommitted:
340                                 isolevel = "READ COMMITTED";
341                                 break;
342                         case IsolationLevel.ReadUncommitted:
343                                 isolevel = "READ UNCOMMITTED";
344                                 break;
345                         case IsolationLevel.RepeatableRead:
346                                 isolevel = "REPEATABLE READ";
347                                 break;
348                         case IsolationLevel.Serializable:
349                                 isolevel = "SERIALIZABLE";
350                                 break;
351                         }
352
353                         tds.Execute (String.Format ("SET TRANSACTION ISOLATION LEVEL {0};BEGIN TRANSACTION {1}", isolevel, transactionName));
354                         
355                         transaction = new SqlTransaction (this, iso);
356                         return transaction;
357                 }
358
359                 public 
360 #if NET_2_0
361                 override
362 #endif // NET_2_0
363          void ChangeDatabase (string database) 
364                 {
365                         if (!IsValidDatabaseName (database))
366                                 throw new ArgumentException (String.Format ("The database name {0} is not valid.", database));
367                         if (state != ConnectionState.Open)
368                                 throw new InvalidOperationException ("The connection is not open.");
369                         tds.Execute (String.Format ("use [{0}]", database));
370                 }
371
372                 private void ChangeState (ConnectionState currentState)
373                 {
374                         ConnectionState originalState = state;
375                         state = currentState;
376                         OnStateChange (CreateStateChangeEvent (originalState, currentState));
377                 }
378
379                 public 
380 #if NET_2_0
381                 override
382 #endif // NET_2_0
383                 void Close () 
384                 {
385                         if (transaction != null && transaction.IsOpen)
386                                 transaction.Rollback ();
387
388                         if (dataReader != null || xmlReader != null) {
389                                 if(tds != null) tds.SkipToEnd ();
390                                 dataReader = null;
391                                 xmlReader = null;
392                         }
393
394                         if (pooling) {
395                                 if(pool != null) pool.ReleaseConnection (tds);
396                         }else
397                                 if(tds != null) tds.Disconnect ();
398
399                         if(tds != null) {
400                                 tds.TdsErrorMessage -= new TdsInternalErrorMessageEventHandler (ErrorHandler);
401                                 tds.TdsInfoMessage -= new TdsInternalInfoMessageEventHandler (MessageHandler);
402                         }
403
404                         ChangeState (ConnectionState.Closed);
405                 }
406
407                 public new SqlCommand CreateCommand () 
408                 {
409                         SqlCommand command = new SqlCommand ();
410                         command.Connection = this;
411                         return command;
412                 }
413                 
414                 private SqlInfoMessageEventArgs CreateSqlInfoMessageEvent (TdsInternalErrorCollection errors)
415                 {
416                         return new SqlInfoMessageEventArgs (errors);
417                 }
418
419                 private StateChangeEventArgs CreateStateChangeEvent (ConnectionState originalState, ConnectionState currentState)
420                 {
421                         return new StateChangeEventArgs (originalState, currentState);
422                 }
423
424                 protected override void Dispose (bool disposing) 
425                 {
426                         if (disposed)
427                                 return;
428
429                         try {
430                                 if (disposing) {
431                                         if (State == ConnectionState.Open) 
432                                                 Close ();
433                                         ConnectionString = "";
434                                         SetDefaultConnectionParameters (this.connStringParameters); 
435                                 }
436                         } finally {
437                                 disposed = true;
438                                 base.Dispose (disposing);
439                         }
440                 }
441
442                 [MonoTODO ("Not sure what this means at present.")]
443                 public 
444                 void EnlistDistributedTransaction (ITransaction transaction)
445                 {
446                         throw new NotImplementedException ();
447                 }
448
449                 object ICloneable.Clone ()
450                 {
451                         return new SqlConnection (ConnectionString);
452                 }
453
454                 IDbTransaction IDbConnection.BeginTransaction ()
455                 {
456                         return BeginTransaction ();
457                 }
458
459                 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel iso)
460                 {
461                         return BeginTransaction (iso);
462                 }
463 #if NET_2_0
464                 protected override DbTransaction BeginDbTransaction (IsolationLevel level)
465                 {
466                         return (DbTransaction)BeginTransaction (level);
467                 }
468
469                 protected override DbCommand CreateDbCommand ()
470                 {
471                         return CreateCommand ();
472                 }
473 #endif
474
475                 IDbCommand IDbConnection.CreateCommand ()
476                 {
477                         return CreateCommand ();
478                 }
479
480                 void IDisposable.Dispose ()
481                 {
482                         Dispose (true);
483                         GC.SuppressFinalize (this);
484                 }
485
486                 public 
487 #if NET_2_0
488                 override
489 #endif // NET_2_0
490                 void Open () 
491                 {
492                         string serverName = "";
493                         if (state == ConnectionState.Open)
494                                 throw new InvalidOperationException ("The Connection is already Open (State=Open)");
495
496                         if (connectionString == null || connectionString.Trim().Length == 0)
497                                 throw new InvalidOperationException ("Connection string has not been initialized.");
498
499                         try {
500                                 if (!pooling) {
501                                         if(!ParseDataSource (dataSource, out port, out serverName))
502                                                 throw new SqlException(20, 0, "SQL Server does not exist or access denied.",  17, "ConnectionOpen (Connect()).", dataSource, parms.ApplicationName, 0);
503                                         tds = new Tds70 (serverName, port, PacketSize, ConnectionTimeout);
504                                 }
505                                 else {
506                                         if(!ParseDataSource (dataSource, out port, out serverName))
507                                                 throw new SqlException(20, 0, "SQL Server does not exist or access denied.",  17, "ConnectionOpen (Connect()).", dataSource, parms.ApplicationName, 0);
508                                         
509                                         TdsConnectionInfo info = new TdsConnectionInfo (serverName, port, packetSize, ConnectionTimeout, minPoolSize, maxPoolSize);
510                                         pool = sqlConnectionPools.GetConnectionPool (connectionString, info);
511                                         tds = pool.GetConnection ();
512                                 }
513                         } catch (TdsTimeoutException e) {
514                                 throw SqlException.FromTdsInternalException ((TdsInternalException) e);
515                         }catch (TdsInternalException e) {
516                                 throw SqlException.FromTdsInternalException (e);
517                         }
518
519                         tds.TdsErrorMessage += new TdsInternalErrorMessageEventHandler (ErrorHandler);
520                         tds.TdsInfoMessage += new TdsInternalInfoMessageEventHandler (MessageHandler);
521
522                         if (!tds.IsConnected) {
523                                 try {
524                                         tds.Connect (parms);
525                                 }
526                                 catch {
527                                         if (pooling)
528                                                 pool.ReleaseConnection (tds);
529                                         throw;
530                                 }
531                         } else if (connectionReset) {
532                                 tds.Reset ();
533                         }
534
535                         disposed = false; // reset this, so using () would call Close ().
536                         ChangeState (ConnectionState.Open);
537                 }
538
539                 private bool ParseDataSource (string theDataSource, out int thePort, out string theServerName) 
540                 {
541                         theServerName = "";
542                         string theInstanceName = "";
543         
544                         if (theDataSource == null)
545                                 throw new ArgumentException("Format of initialization string does not conform to specifications");
546
547                         thePort = 1433; // default TCP port for SQL Server
548                         bool success = true;
549
550                         int idx = 0;
551                         if ((idx = theDataSource.IndexOf (",")) > -1) {
552                                 theServerName = theDataSource.Substring (0, idx);
553                                 string p = theDataSource.Substring (idx + 1);
554                                 thePort = Int32.Parse (p);
555                         }
556                         else if ((idx = theDataSource.IndexOf ("\\")) > -1) {
557                                 theServerName = theDataSource.Substring (0, idx);
558                                 theInstanceName = theDataSource.Substring (idx + 1);
559                                 // do port discovery via UDP port 1434
560                                 port = DiscoverTcpPortViaSqlMonitor (theServerName, theInstanceName);
561                                 if (port == -1)
562                                         success = false;
563                         }
564                         else if (theDataSource == "" || theDataSource == "(local)")
565                                 theServerName = "localhost";
566                         else
567                                 theServerName = theDataSource;
568
569                         return success;
570                 }
571
572                 private bool ConvertIntegratedSecurity (string value)
573                 {
574                         if (value.ToUpper() == "SSPI") 
575                         {
576                                 return true;
577                         }
578
579                         return ConvertToBoolean("integrated security", value);
580                 }
581
582                 private bool ConvertToBoolean(string key, string value)
583                 {
584                         string upperValue = value.ToUpper();
585
586                         if (upperValue == "TRUE" ||upperValue == "YES")
587                         {
588                                 return true;
589                         } 
590                         else if (upperValue == "FALSE" || upperValue == "NO")
591                         {
592                                 return false;
593                         }
594
595                         throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
596                                 "Invalid value \"{0}\" for key '{1}'.", value, key));
597                 }
598
599                 private int ConvertToInt32(string key, string value)
600                 {
601                         try
602                         {
603                                 return int.Parse(value);
604                         }
605                         catch (Exception ex)
606                         {
607                                 throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
608                                         "Invalid value \"{0}\" for key '{1}'.", value, key));
609                         }
610                 }
611
612                 private int DiscoverTcpPortViaSqlMonitor(string ServerName, string InstanceName) 
613                 {
614                         SqlMonitorSocket msock;
615                         msock = new SqlMonitorSocket (ServerName, InstanceName);
616                         int SqlServerPort = msock.DiscoverTcpPort ();
617                         msock = null;
618                         return SqlServerPort;
619                 }
620         
621                 void SetConnectionString (string connectionString)
622                 {
623                         NameValueCollection parameters = new NameValueCollection ();
624                         SetDefaultConnectionParameters (parameters);
625
626                         if ((connectionString == null) || (connectionString.Trim().Length == 0)) {
627                                 this.connectionString = connectionString;
628                                 this.connStringParameters = parameters;
629                                 return;
630                         }
631
632                         connectionString += ";";
633
634                         bool inQuote = false;
635                         bool inDQuote = false;
636                         bool inName = true;
637
638                         string name = String.Empty;
639                         string value = String.Empty;
640                         StringBuilder sb = new StringBuilder ();
641
642                         for (int i = 0; i < connectionString.Length; i += 1) {
643                                 char c = connectionString [i];
644                                 char peek;
645                                 if (i == connectionString.Length - 1)
646                                         peek = '\0';
647                                 else
648                                         peek = connectionString [i + 1];
649
650                                 switch (c) {
651                                 case '\'':
652                                         if (inDQuote)
653                                                 sb.Append (c);
654                                         else if (peek.Equals (c)) {
655                                                 sb.Append (c);
656                                                 i += 1;
657                                         }
658                                         else
659                                                 inQuote = !inQuote;
660                                         break;
661                                 case '"':
662                                         if (inQuote)
663                                                 sb.Append (c);
664                                         else if (peek.Equals (c)) {
665                                                 sb.Append (c);
666                                                 i += 1;
667                                         }
668                                         else
669                                                 inDQuote = !inDQuote;
670                                         break;
671                                 case ';':
672                                         if (inDQuote || inQuote)
673                                                 sb.Append (c);
674                                         else {
675                                                 if (name != String.Empty && name != null) {
676                                                         value = sb.ToString ();
677                                                         SetProperties (name.ToUpper ().Trim() , value);
678                                                         parameters [name.ToUpper ().Trim ()] = value.Trim ();
679                                                 }
680                                                 else if (sb.Length != 0)
681                                                         throw new ArgumentException ("Format of initialization string doesnot conform to specifications");
682                                                 inName = true;
683                                                 name = String.Empty;
684                                                 value = String.Empty;
685                                                 sb = new StringBuilder ();
686                                         }
687                                         break;
688                                 case '=':
689                                         if (inDQuote || inQuote || !inName)
690                                                 sb.Append (c);
691                                         else if (peek.Equals (c)) {
692                                                 sb.Append (c);
693                                                 i += 1;
694
695                                         }
696                                         else {
697                                                 name = sb.ToString ();
698                                                 sb = new StringBuilder ();
699                                                 inName = false;
700                                         }
701                                         break;
702                                 case ' ':
703                                         if (inQuote || inDQuote)
704                                                 sb.Append (c);
705                                         else if (sb.Length > 0 && !peek.Equals (';'))
706                                                 sb.Append (c);
707                                         break;
708                                 default:
709                                         sb.Append (c);
710                                         break;
711                                 }
712                         }
713
714                         connectionString = connectionString.Substring (0 , connectionString.Length-1);
715                         this.connectionString = connectionString;
716                         this.connStringParameters = parameters;
717                 }
718
719                 void SetDefaultConnectionParameters (NameValueCollection parameters)
720                 {
721                         parms.Reset ();
722                         dataSource = "";
723                         connectionTimeout= 15;
724                         connectionReset = true;
725                         pooling = true;
726                         maxPoolSize = 100; 
727                         minPoolSize = 0;
728                         packetSize = 8192; 
729                         
730                         parameters["APPLICATION NAME"] = "Mono SqlClient Data Provider";
731                         parameters["CONNECT TIMEOUT"] = "15";
732                         parameters["CONNECTION LIFETIME"] = "0";
733                         parameters["CONNECTION RESET"] = "true";
734                         parameters["ENLIST"] = "true";
735                         parameters["INTEGRATED SECURITY"] = "false";
736                         parameters["INITIAL CATALOG"] = "";
737                         parameters["MAX POOL SIZE"] = "100";
738                         parameters["MIN POOL SIZE"] = "0";
739                         parameters["NETWORK LIBRARY"] = "dbmssocn";
740                         parameters["PACKET SIZE"] = "8192";
741                         parameters["PERSIST SECURITY INFO"] = "false";
742                         parameters["POOLING"] = "true";
743                         parameters["WORKSTATION ID"] = Dns.GetHostName();
744  #if NET_2_0
745                         async = false;
746                         parameters ["ASYNCHRONOUS PROCESSING"] = "false";
747  #endif
748                 }
749                 
750                 private void SetProperties (string name , string value)
751                 {
752
753                         switch (name) 
754                         {
755                         case "APP" :
756                         case "APPLICATION NAME" :
757                                 parms.ApplicationName = value;
758                                 break;
759                         case "ATTACHDBFILENAME" :
760                         case "EXTENDED PROPERTIES" :
761                         case "INITIAL FILE NAME" :
762                                 parms.AttachDBFileName = value;
763                                 break;
764                         case "TIMEOUT" :
765                         case "CONNECT TIMEOUT" :
766                         case "CONNECTION TIMEOUT" :
767                                 int tmpTimeout = ConvertToInt32 ("connection timeout", value);
768                                 if (tmpTimeout < 0)
769                                         throw new ArgumentException ("Invalid CONNECTION TIMEOUT .. Must be an integer >=0 ");
770                                 else 
771                                         connectionTimeout = tmpTimeout;
772                                 break;
773                         case "CONNECTION LIFETIME" :
774                                 break;
775                         case "CONNECTION RESET" :
776                                 connectionReset = ConvertToBoolean ("connection reset", value);
777                                 break;
778                         case "LANGUAGE" :
779                         case "CURRENT LANGUAGE" :
780                                 parms.Language = value;
781                                 break;
782                         case "DATA SOURCE" :
783                         case "SERVER" :
784                         case "ADDRESS" :
785                         case "ADDR" :
786                         case "NETWORK ADDRESS" :
787                                 dataSource = value;
788                                 break;
789                         case "ENCRYPT":
790                                 if (ConvertToBoolean("encrypt", value))
791                                 {
792                                         throw new NotImplementedException("SSL encryption for"
793                                                 + " data sent between client and server is not"
794                                                 + " implemented.");
795                                 }
796                                 break;
797                         case "ENLIST" :
798                                 if (!ConvertToBoolean("enlist", value))
799                                 {
800                                         throw new NotImplementedException("Disabling the automatic"
801                                                 + " enlistment of connections in the thread's current"
802                                                 + " transaction context is not implemented.");
803                                 }
804                                 break;
805                         case "INITIAL CATALOG" :
806                         case "DATABASE" :
807                                 parms.Database = value;
808                                 break;
809                         case "INTEGRATED SECURITY" :
810                         case "TRUSTED_CONNECTION" :
811                                 parms.DomainLogin = ConvertIntegratedSecurity(value);
812                                 break;
813                         case "MAX POOL SIZE" :
814                                 int tmpMaxPoolSize = ConvertToInt32 ("max pool size" , value);
815                                 if (tmpMaxPoolSize < 0)
816                                         throw new ArgumentException ("Invalid MAX POOL SIZE. Must be a intger >= 0");
817                                 else
818                                         maxPoolSize = tmpMaxPoolSize; 
819                                 break;
820                         case "MIN POOL SIZE" :
821                                 int tmpMinPoolSize = ConvertToInt32 ("min pool size" , value);
822                                 if (tmpMinPoolSize < 0)
823                                         throw new ArgumentException ("Invalid MIN POOL SIZE. Must be a intger >= 0");
824                                 else
825                                         minPoolSize = tmpMinPoolSize;
826                                 break;
827 #if NET_2_0     
828                         case "MULTIPLEACTIVERESULTSETS":
829                                 break;
830                         case "ASYNCHRONOUS PROCESSING" :
831                         case "ASYNC" :
832                                 async = ConvertToBoolean (name, value);
833                                 break;
834 #endif  
835                         case "NET" :
836                         case "NETWORK" :
837                         case "NETWORK LIBRARY" :
838                                 if (!value.ToUpper ().Equals ("DBMSSOCN"))
839                                         throw new ArgumentException ("Unsupported network library.");
840                                 break;
841                         case "PACKET SIZE" :
842                                 int tmpPacketSize = ConvertToInt32 ("packet size", value);
843                                 if (tmpPacketSize < 512 || tmpPacketSize > 32767)
844                                         throw new ArgumentException ("Invalid PACKET SIZE. The integer must be between 512 and 32767");
845                                 else
846                                         packetSize = tmpPacketSize;
847                                 break;
848                         case "PASSWORD" :
849                         case "PWD" :
850                                 parms.Password = value;
851                                 break;
852                         case "PERSISTSECURITYINFO" :
853                         case "PERSIST SECURITY INFO" :
854                                 // FIXME : not implemented
855                                 // throw new NotImplementedException ();
856                                 break;
857                         case "POOLING" :
858                                 pooling = ConvertToBoolean("pooling", value);
859                                 break;
860                         case "UID" :
861                         case "USER" :
862                         case "USER ID" :
863                                 parms.User = value;
864                                 break;
865                         case "WSID" :
866                         case "WORKSTATION ID" :
867                                 parms.Hostname = value;
868                                 break;
869                         default :
870                                 throw new ArgumentException("Keyword not supported :"+name);
871                         }
872                 }
873
874                 static bool IsValidDatabaseName (string database)
875                 {
876                         if ( database == null || database.Trim() == String.Empty || database.Length > 128)
877                                 return false ;
878                         
879                         if (database[0] == '"' && database[database.Length] == '"')
880                                 database = database.Substring (1, database.Length - 2);
881                         else if (Char.IsDigit (database[0]))
882                                 return false;
883
884                         if (database[0] == '_')
885                                 return false;
886
887                         foreach (char c  in database.Substring (1, database.Length - 1))
888                                 if (!Char.IsLetterOrDigit (c) && c != '_' && c != '-')
889                                         return false;
890                         return true;
891                 }
892
893                 private void OnSqlInfoMessage (SqlInfoMessageEventArgs value)
894                 {
895                         if (InfoMessage != null)
896                                 InfoMessage (this, value);
897                 }
898
899                 private void OnStateChange (StateChangeEventArgs value)
900                 {
901                         if (StateChange != null)
902                                 StateChange (this, value);
903                 }
904
905                 private sealed class SqlMonitorSocket : UdpClient 
906                 {
907                         // UDP port that the SQL Monitor listens
908                         private static readonly int SqlMonitorUdpPort = 1434;
909                         private static readonly string SqlServerNotExist = "SQL Server does not exist or access denied";
910
911                         private string server;
912                         private string instance;
913
914                         internal SqlMonitorSocket (string ServerName, string InstanceName) 
915                                 : base (ServerName, SqlMonitorUdpPort) 
916                         {
917                                 server = ServerName;
918                                 instance = InstanceName;
919                         }
920
921                         internal int DiscoverTcpPort () 
922                         {
923                                 int SqlServerTcpPort;
924                                 Client.Blocking = false;
925                                 // send command to UDP 1434 (SQL Monitor) to get
926                                 // the TCP port to connect to the MS SQL server         
927                                 ASCIIEncoding enc = new ASCIIEncoding ();
928                                 Byte[] rawrq = new Byte [instance.Length + 1];
929                                 rawrq[0] = 4;
930                                 enc.GetBytes (instance, 0, instance.Length, rawrq, 1);
931                                 int bytes = Send (rawrq, rawrq.Length);
932
933                                 if (!Active)
934                                         return -1; // Error
935                                 
936                                 bool result;
937                                 result = Client.Poll (100, SelectMode.SelectRead);
938                                 if (result == false)
939                                         return -1; // Error
940
941                                 if (Client.Available <= 0)
942                                         return -1; // Error
943
944                                 IPEndPoint endpoint = new IPEndPoint (Dns.GetHostByName ("localhost").AddressList [0], 0);
945                                 Byte [] rawrs;
946
947                                 rawrs = Receive (ref endpoint);
948
949                                 string rs = Encoding.ASCII.GetString (rawrs);
950
951                                 string[] rawtokens = rs.Split (';');
952                                 Hashtable data = new Hashtable ();
953                                 for (int i = 0; i < rawtokens.Length / 2 && i < 256; i++) {
954                                         data [rawtokens [i * 2]] = rawtokens [ i * 2 + 1];
955                                 }
956                                 if (!data.ContainsKey ("tcp")) 
957                                         throw new NotImplementedException ("Only TCP/IP is supported.");
958
959                                 SqlServerTcpPort = int.Parse ((string) data ["tcp"]);
960                                 Close ();
961
962                                 return SqlServerTcpPort;
963                         }
964                 }
965
966 #if NET_2_0
967                 struct ColumnInfo {
968                         public string name;
969                         public Type type;
970                         public ColumnInfo (string name, Type type)
971                         {
972                                 this.name = name; this.type = type;
973                         }
974                 }
975
976                 static class ReservedWords
977                 {
978                         static readonly string [] reservedWords =
979                         {
980                                 "ADD", "EXCEPT", "PERCENT", "ALL", "EXEC", "PLAN", "ALTER",
981                                   "EXECUTE", "PRECISION", "AND", "EXISTS", "PRIMARY", "ANY",
982                                   "EXIT", "PRINT", "AS", "FETCH", "PROC", "ASC", "FILE",
983                                   "PROCEDURE", "AUTHORIZATION", "FILLFACTOR", "PUBLIC",
984                                   "BACKUP", "FOR", "RAISERROR", "BEGIN", "FOREIGN", "READ",
985                                   "BETWEEN", "FREETEXT", "READTEXT", "BREAK", "FREETEXTTABLE",
986                                   "RECONFIGURE", "BROWSE", "FROM", "REFERENCES", "BULK",
987                                   "FULL", "REPLICATION", "BY", "FUNCTION", "RESTORE",
988                                   "CASCADE", "GOTO", "RESTRICT", "CASE", "GRANT", "RETURN",
989                                   "CHECK", "GROUP", "REVOKE", "CHECKPOINT", "HAVING", "RIGHT",
990                                   "CLOSE", "HOLDLOCK", "ROLLBACK", "CLUSTERED", "IDENTITY",
991                                   "ROWCOUNT", "COALESCE", "IDENTITY_INSERT", "ROWGUIDCOL",
992                                   "COLLATE", "IDENTITYCOL", "RULE", "COLUMN", "IF", "SAVE",
993                                   "COMMIT", "IN", "SCHEMA", "COMPUTE", "INDEX", "SELECT",
994                                   "CONSTRAINT", "INNER", "SESSION_USER", "CONTAINS", "INSERT",
995                                   "SET", "CONTAINSTABLE", "INTERSECT", "SETUSER", "CONTINUE",
996                                   "INTO", "SHUTDOWN", "CONVERT", "IS", "SOME", "CREATE",
997                                   "JOIN", "STATISTICS", "CROSS", "KEY", "SYSTEM_USER",
998                                   "CURRENT", "KILL", "TABLE", "CURRENT_DATE", "LEFT",
999                                   "TEXTSIZE", "CURRENT_TIME", "LIKE", "THEN",
1000                                   "CURRENT_TIMESTAMP", "LINENO", "TO", "CURRENT_USER", "LOAD",
1001                                   "TOP", "CURSOR", "NATIONAL", "TRAN", "DATABASE", "NOCHECK",
1002                                   "TRANSACTION", "DBCC", "NONCLUSTERED", "TRIGGER",
1003                                   "DEALLOCATE", "NOT", "TRUNCATE", "DECLARE", "NULL",
1004                                   "TSEQUAL", "DEFAULT", "NULLIF", "UNION", "DELETE", "OF",
1005                                   "UNIQUE", "DENY", "OFF", "UPDATE", "DESC", "OFFSETS",
1006                                   "UPDATETEXT", "DISK", "ON", "USE", "DISTINCT", "OPEN",
1007                                   "USER", "DISTRIBUTED", "OPENDATASOURCE", "VALUES", "DOUBLE",
1008                                   "OPENQUERY", "VARYING", "DROP", "OPENROWSET", "VIEW",
1009                                   "DUMMY", "OPENXML", "WAITFOR", "DUMP", "OPTION", "WHEN",
1010                                   "ELSE", "OR", "WHERE", "END", "ORDER", "WHILE", "ERRLVL",
1011                                   "OUTER", "WITH", "ESCAPE", "OVER", "WRITETEXT", "ABSOLUTE",
1012                                   "FOUND", "PRESERVE", "ACTION", "FREE", "PRIOR", "ADMIN",
1013                                   "GENERAL", "PRIVILEGES", "AFTER", "GET", "READS",
1014                                   "AGGREGATE", "GLOBAL", "REAL", "ALIAS", "GO", "RECURSIVE",
1015                                   "ALLOCATE", "GROUPING", "REF", "ARE", "HOST", "REFERENCING",
1016                                   "ARRAY", "HOUR", "RELATIVE", "ASSERTION", "IGNORE", "RESULT",
1017                                   "AT", "IMMEDIATE", "RETURNS", "BEFORE", "INDICATOR", "ROLE",
1018                                   "BINARY", "INITIALIZE", "ROLLUP", "BIT", "INITIALLY",
1019                                   "ROUTINE", "BLOB", "INOUT", "ROW", "BOOLEAN", "INPUT",
1020                                   "ROWS", "BOTH", "INT", "SAVEPOINT", "BREADTH", "INTEGER",
1021                                   "SCROLL", "CALL", "INTERVAL", "SCOPE", "CASCADED",
1022                                   "ISOLATION", "SEARCH", "CAST", "ITERATE", "SECOND",
1023                                   "CATALOG", "LANGUAGE", "SECTION", "CHAR", "LARGE",
1024                                   "SEQUENCE", "CHARACTER", "LAST", "SESSION", "CLASS",
1025                                   "LATERAL", "SETS", "CLOB", "LEADING", "SIZE", "COLLATION",
1026                                   "LESS", "SMALLINT", "COMPLETION", "LEVEL", "SPACE",
1027                                   "CONNECT", "LIMIT", "SPECIFIC", "CONNECTION", "LOCAL",
1028                                   "SPECIFICTYPE", "CONSTRAINTS", "LOCALTIME", "SQL",
1029                                   "CONSTRUCTOR", "LOCALTIMESTAMP", "SQLEXCEPTION",
1030                                   "CORRESPONDING", "LOCATOR", "SQLSTATE", "CUBE", "MAP",
1031                                   "SQLWARNING", "CURRENT_PATH", "MATCH", "START",
1032                                   "CURRENT_ROLE", "MINUTE", "STATE", "CYCLE", "MODIFIES",
1033                                   "STATEMENT", "DATA", "MODIFY", "STATIC", "DATE", "MODULE",
1034                                   "STRUCTURE", "DAY", "MONTH", "TEMPORARY", "DEC", "NAMES",
1035                                   "TERMINATE", "DECIMAL", "NATURAL", "THAN", "DEFERRABLE",
1036                                   "NCHAR", "TIME", "DEFERRED", "NCLOB", "TIMESTAMP", "DEPTH",
1037                                   "NEW", "TIMEZONE_HOUR", "DEREF", "NEXT", "TIMEZONE_MINUTE",
1038                                   "DESCRIBE", "NO", "TRAILING", "DESCRIPTOR", "NONE",
1039                                   "TRANSLATION", "DESTROY", "NUMERIC", "TREAT", "DESTRUCTOR",
1040                                   "OBJECT", "TRUE", "DETERMINISTIC", "OLD", "UNDER",
1041                                   "DICTIONARY", "ONLY", "UNKNOWN", "DIAGNOSTICS", "OPERATION",
1042                                   "UNNEST", "DISCONNECT", "ORDINALITY", "USAGE", "DOMAIN",
1043                                   "OUT", "USING", "DYNAMIC", "OUTPUT", "VALUE", "EACH",
1044                                   "PAD", "VARCHAR", "END-EXEC", "PARAMETER", "VARIABLE",
1045                                   "EQUALS", "PARAMETERS", "WHENEVER", "EVERY", "PARTIAL",
1046                                   "WITHOUT", "EXCEPTION", "PATH", "WORK", "EXTERNAL",
1047                                   "POSTFIX", "WRITE", "FALSE", "PREFIX", "YEAR", "FIRST",
1048                                   "PREORDER", "ZONE", "FLOAT", "PREPARE", "ADA", "AVG",
1049                                   "BIT_LENGTH", "CHAR_LENGTH", "CHARACTER_LENGTH", "COUNT",
1050                                   "EXTRACT", "FORTRAN", "INCLUDE", "INSENSITIVE", "LOWER",
1051                                   "MAX", "MIN", "OCTET_LENGTH", "OVERLAPS", "PASCAL",
1052                                   "POSITION", "SQLCA", "SQLCODE", "SQLERROR", "SUBSTRING",
1053                                   "SUM", "TRANSLATE", "TRIM", "UPPER"
1054                         };
1055                         static DataTable instance;
1056                         static public DataTable Instance {
1057                                 get {
1058                                         if (instance == null) {
1059                                                 DataRow row = null;
1060                                                 instance = new DataTable ("ReservedWords");
1061                                                 instance.Columns.Add ("ReservedWord", typeof(string));
1062                                                 foreach (string reservedWord in reservedWords)
1063                                                 {
1064                                                         row = instance.NewRow();
1065
1066                                                         row["ReservedWord"] = reservedWord;
1067                                                         instance.Rows.Add(row);
1068                                                 }
1069                                         }
1070                                         return instance;
1071                                 }
1072                         }
1073                 }
1074
1075                 static class MetaDataCollections
1076                 {
1077                         static readonly ColumnInfo [] columns = {
1078                                 new ColumnInfo ("CollectionName", typeof (string)),
1079                                 new ColumnInfo ("NumberOfRestrictions", typeof (int)),
1080                                 new ColumnInfo ("NumberOfIdentifierParts", typeof (int))
1081                         };
1082
1083                         static readonly object [][] rows = {
1084                                 new object [] {"MetaDataCollections", 0, 0},
1085                                 new object [] {"DataSourceInformation", 0, 0},
1086                                 new object [] {"DataTypes", 0, 0},
1087                                 new object [] {"Restrictions", 0, 0},
1088                                 new object [] {"ReservedWords", 0, 0},
1089                                 new object [] {"Users", 1, 1},
1090                                 new object [] {"Databases", 1, 1},
1091                                 new object [] {"Tables", 4, 3},
1092                                 new object [] {"Columns", 4, 4},
1093                                 new object [] {"Views", 3, 3},
1094                                 new object [] {"ViewColumns", 4, 4},
1095                                 new object [] {"ProcedureParameters", 4, 1},
1096                                 new object [] {"Procedures", 4, 3},
1097                                 new object [] {"ForeignKeys", 4, 3},
1098                                 new object [] {"IndexColumns", 5, 4},
1099                                 new object [] {"Indexes", 4, 3},
1100                                 new object [] {"UserDefinedTypes", 2, 1}
1101                         };
1102
1103                         static DataTable instance;
1104                         static public DataTable Instance {
1105                                 get {
1106                                         if (instance == null) {
1107                                                 instance = new DataTable ("GetSchema");
1108                                                 foreach (ColumnInfo c in columns)
1109                                                         instance.Columns.Add (c.name, c.type);
1110                                                 foreach (object [] row in rows)
1111                                                         instance.LoadDataRow (row, true);
1112                                         }
1113                                         return instance;
1114                                 }
1115                         }
1116                 }
1117
1118                 static class DataTypes
1119                 {
1120                         static readonly ColumnInfo [] columns = {
1121                                 new ColumnInfo ("TypeName", typeof(string)),
1122                                 new ColumnInfo ("ProviderDbType", typeof(int)),
1123                                 new ColumnInfo ("ColumnSize", typeof(long)),
1124                                 new ColumnInfo ("CreateFormat", typeof(string)),
1125                                 new ColumnInfo ("CreateParameters", typeof(string)),
1126                                 new ColumnInfo ("DataType", typeof(string)),
1127                                 new ColumnInfo ("IsAutoIncrementable", typeof(bool)),
1128                                 new ColumnInfo ("IsBestMatch", typeof(bool)),
1129                                 new ColumnInfo ("IsCaseSensitive", typeof(bool)),
1130                                 new ColumnInfo ("IsFixedLength", typeof(bool)),
1131                                 new ColumnInfo ("IsFixedPrecisionScale", typeof(bool)),
1132                                 new ColumnInfo ("IsLong", typeof(bool)),
1133                                 new ColumnInfo ("IsNullable", typeof(bool)),
1134                                 new ColumnInfo ("IsSearchable", typeof(bool)),
1135                                 new ColumnInfo ("IsSearchableWithLike", typeof(bool)),
1136                                 new ColumnInfo ("IsUnsigned", typeof(bool)),
1137                                 new ColumnInfo ("MaximumScale", typeof(short)),
1138                                 new ColumnInfo ("MinimumScale", typeof(short)),
1139                                 new ColumnInfo ("IsConcurrencyType", typeof(bool)),
1140                                 new ColumnInfo ("IsLiteralSupported", typeof(bool)),
1141                                 new ColumnInfo ("LiteralPrefix", typeof(string)),
1142                                 new ColumnInfo ("LiteralSuffix", typeof(string))
1143                         };
1144
1145                         static readonly object [][] rows = {
1146                                 new object [] {"smallint", 16, 5, "smallint", null, "System.Int16", true, true,
1147                                                false, true, true, false, true, true, false, false, null,
1148                                                null, false, null, null, null},
1149                                 new object [] {"int", 8, 10, "int", null, "System.Int32",
1150                                                true, true, false, true, true, false, true, true, false,
1151                                                false, null, null, false, null, null, null},
1152                                 new object [] {"real", 13, 7, "real", null,
1153                                                "System.Single", false, true, false, true, false, false,
1154                                                true, true, false, false, null, null, false, null, null, null},
1155                                 new object [] {"float", 6, 53, "float({0})",
1156                                                "number of bits used to store the mantissa", "System.Double",
1157                                                false, true, false, true, false, false, true, true,
1158                                                false, false, null, null, false, null, null, null},
1159                                 new object [] {"money", 9, 19, "money", null,
1160                                                "System.Decimal", false, false, false, true, true,
1161                                                false, true, true, false, false, null, null, false,
1162                                                null, null, null},
1163                                 new object [] {"smallmoney", 17, 10, "smallmoney", null,
1164                                                "System.Decimal", false, false, false, true, true, false,
1165                                                true, true, false, false, null, null, false, null, null, null},
1166                                 new object [] {"bit", 2, 1, "bit", null, "System.Boolean",
1167                                                false, false, false, true, false, false, true, true,
1168                                                false, null, null, null, false, null, null, null},
1169                                 new object [] {"tinyint", 20, 3, "tinyint", null,
1170                                                "System.SByte", true, true, false, true, true, false,
1171                                                true, true, false, true, null, null, false, null, null, null},
1172                                 new object [] {"bigint", 0, 19, "bigint", null,
1173                                                "System.Int64", true, true, false, true, true, false,
1174                                                true, true, false, false, null, null, false, null, null, null},
1175                                 new object [] {"timestamp", 19, 8, "timestamp", null,
1176                                                "System.Byte[]", false, false, false, true, false, false,
1177                                                false, true, false, null, null, null, true, null, "0x", null},
1178                                 new object [] {"binary", 1, 8000, "binary({0})", "length",
1179                                                "System.Byte[]", false, true, false, true, false, false,
1180                                                true, true, false, null, null, null, false, null, "0x", null},
1181                                 new object [] {"image", 7, 2147483647, "image", null,
1182                                                "System.Byte[]", false, true, false, false, false, true,
1183                                                true, false, false, null, null, null, false, null, "0x", null},
1184                                 new object [] {"text", 18, 2147483647, "text", null,
1185                                                "System.String", false, true, false, false, false, true,
1186                                                true, false, true, null, null, null, false, null, "'", "'"},
1187                                 new object [] {"ntext", 11, 1073741823, "ntext", null,
1188                                                "System.String", false, true, false, false, false, true,
1189                                                true, false, true, null, null, null, false, null, "N'", "'"},
1190                                 new object [] {"decimal", 5, 38, "decimal({0}, {1})",
1191                                                "precision,scale", "System.Decimal", true, true, false,
1192                                                true, false, false, true, true, false, false, 38, 0,
1193                                                false, null, null, null},
1194                                 new object [] {"numeric", 5, 38, "numeric({0}, {1})",
1195                                                "precision,scale", "System.Decimal", true, true, false,
1196                                                true, false, false, true, true, false, false, 38, 0,
1197                                                false, null, null, null},
1198                                 new object [] {"datetime", 4, 23, "datetime", null,
1199                                                "System.DateTime", false, true, false, true, false, false,
1200                                                true, true, true, null, null, null, false, null, "{ts '", "'}"},
1201                                 new object [] {"smalldatetime", 15, 16, "smalldatetime", null,
1202                                                "System.DateTime", false, true, false, true, false, false,
1203                                                true, true, true, null, null, null, false, null, "{ts '", "'}"},
1204                                 new object [] {"sql_variant", 23, null, "sql_variant",
1205                                                null, "System.Object", false, true, false, false, false,
1206                                                false, true, true, false, null, null, null, false, false,
1207                                                null, null},
1208                                 new object [] {"xml", 25, 2147483647, "xml", null,
1209                                                "System.String", false, false, false, false, false, true,
1210                                                true, false, false, null, null, null, false, false, null, null},
1211                                 new object [] {"varchar", 22, 2147483647, "varchar({0})",
1212                                                "max length", "System.String", false, true, false, false,
1213                                                false, false, true, true, true, null, null, null, false,
1214                                                null, "'", "'"},
1215                                 new object [] {"char", 3, 2147483647, "char({0})", "length",
1216                                                "System.String", false, true, false, true, false, false,
1217                                                true, true, true, null, null, null, false, null, "'", "'"},
1218                                 new object [] {"nchar", 10, 1073741823, "nchar({0})", "length",
1219                                                "System.String", false, true, false, true, false, false,
1220                                                true, true, true, null, null, null, false, null, "N'", "'"},
1221                                 new object [] {"nvarchar", 12, 1073741823, "nvarchar({0})", "max length",
1222                                                "System.String", false, true, false, false, false, false, true, true,
1223                                                true, null, null, null, false, null, "N'", "'"},
1224                                 new object [] {"varbinary", 21, 1073741823, "varbinary({0})",
1225                                                "max length", "System.Byte[]", false, true, false, false,
1226                                                false, false, true, true, false, null, null, null, false,
1227                                                null, "0x", null},
1228                                 new object [] {"uniqueidentifier", 14, 16, "uniqueidentifier", null,
1229                                                "System.Guid", false, true, false, true, false, false, true,
1230                                                true, false, null, null, null, false, null, "'", "'"}
1231                         };
1232
1233                         static DataTable instance;
1234                         static public DataTable Instance {
1235                                 get {
1236                                         if (instance == null) {
1237                                                 instance = new DataTable ("DataTypes");
1238                                                 foreach (ColumnInfo c in columns)
1239                                                         instance.Columns.Add (c.name, c.type);
1240                                                 foreach (object [] row in rows)
1241                                                         instance.LoadDataRow (row, true);
1242                                         }
1243                                         return instance;
1244                                 }
1245                         }
1246                 }
1247
1248                 static class Restrictions
1249                 {
1250                         static readonly ColumnInfo [] columns = {
1251                                 new ColumnInfo ("CollectionName", typeof (string)),
1252                                 new ColumnInfo ("RestrictionName", typeof(string)),
1253                                 new ColumnInfo ("ParameterName", typeof(string)),
1254                                 new ColumnInfo ("RestrictionDefault", typeof(string)),
1255                                 new ColumnInfo ("RestrictionNumber", typeof(int))
1256                         };
1257
1258                         static readonly object [][] rows = {
1259                                 new object [] {"Users", "User_Name", "@Name", "name", 1},
1260                                 new object [] {"Databases", "Name", "@Name", "Name", 1},
1261
1262                                 new object [] {"Tables", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1263                                 new object [] {"Tables", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1264                                 new object [] {"Tables", "Table", "@Name", "TABLE_NAME", 3},
1265                                 new object [] {"Tables", "TableType", "@TableType", "TABLE_TYPE", 4},
1266
1267                                 new object [] {"Columns", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1268                                 new object [] {"Columns", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1269                                 new object [] {"Columns", "Table", "@Table", "TABLE_NAME", 3},
1270                                 new object [] {"Columns", "Column", "@Column", "COLUMN_NAME", 4},
1271
1272                                 new object [] {"Views", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1273                                 new object [] {"Views", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1274                                 new object [] {"Views", "Table", "@Table", "TABLE_NAME", 3},
1275
1276                                 new object [] {"ViewColumns", "Catalog", "@Catalog", "VIEW_CATALOG", 1},
1277                                 new object [] {"ViewColumns", "Owner", "@Owner", "VIEW_SCHEMA", 2},
1278                                 new object [] {"ViewColumns", "Table", "@Table", "VIEW_NAME", 3},
1279                                 new object [] {"ViewColumns", "Column", "@Column", "COLUMN_NAME", 4},
1280
1281                                 new object [] {"ProcedureParameters", "Catalog", "@Catalog", "SPECIFIC_CATALOG", 1},
1282                                 new object [] {"ProcedureParameters", "Owner", "@Owner", "SPECIFIC_SCHEMA", 2},
1283                                 new object [] {"ProcedureParameters", "Name", "@Name", "SPECIFIC_NAME", 3},
1284                                 new object [] {"ProcedureParameters", "Parameter", "@Parameter", "PARAMETER_NAME", 4},
1285
1286                                 new object [] {"Procedures", "Catalog", "@Catalog", "SPECIFIC_CATALOG", 1},
1287                                 new object [] {"Procedures", "Owner", "@Owner", "SPECIFIC_SCHEMA", 2},
1288                                 new object [] {"Procedures", "Name", "@Name", "SPECIFIC_NAME", 3},
1289                                 new object [] {"Procedures", "Type", "@Type", "ROUTINE_TYPE", 4},
1290
1291                                 new object [] {"IndexColumns", "Catalog", "@Catalog", "db_name(}", 1},
1292                                 new object [] {"IndexColumns", "Owner", "@Owner", "user_name(}", 2},
1293                                 new object [] {"IndexColumns", "Table", "@Table", "o.name", 3},
1294                                 new object [] {"IndexColumns", "ConstraintName", "@ConstraintName", "x.name", 4},
1295                                 new object [] {"IndexColumns", "Column", "@Column", "c.name", 5},
1296
1297                                 new object [] {"Indexes", "Catalog", "@Catalog", "db_name(}", 1},
1298                                 new object [] {"Indexes", "Owner", "@Owner", "user_name(}", 2},
1299                                 new object [] {"Indexes", "Table", "@Table", "o.name", 3},
1300                                 new object [] {"Indexes", "Name", "@Name", "x.name", 4},
1301
1302                                 new object [] {"UserDefinedTypes", "assembly_name", "@AssemblyName", "assemblies.name", 1},
1303                                 new object [] {"UserDefinedTypes", "udt_name", "@UDTName", "types.assembly_class", 2},
1304
1305                                 new object [] {"ForeignKeys", "Catalog", "@Catalog", "CONSTRAINT_CATALOG", 1},
1306                                 new object [] {"ForeignKeys", "Owner", "@Owner", "CONSTRAINT_SCHEMA", 2},
1307                                 new object [] {"ForeignKeys", "Table", "@Table", "TABLE_NAME", 3},
1308                                 new object [] {"ForeignKeys", "Name", "@Name", "CONSTRAINT_NAME", 4}
1309                         };
1310
1311                         static DataTable instance;
1312                         static public DataTable Instance {
1313                                 get {
1314                                         if (instance == null) {
1315                                                 instance = new DataTable ("Restrictions");
1316                                                 foreach (ColumnInfo c in columns)
1317                                                         instance.Columns.Add (c.name, c.type);
1318                                                 foreach (object [] row in rows)
1319                                                         instance.LoadDataRow (row, true);
1320                                         }
1321                                         return instance;
1322                                 }
1323                         }
1324                 }
1325
1326                 public override DataTable GetSchema ()
1327                 {
1328                         return MetaDataCollections.Instance;
1329                 }
1330
1331                 public override DataTable GetSchema (String collectionName)
1332                 {
1333                         return GetSchema (collectionName, null);
1334                 }
1335
1336                 public override DataTable GetSchema (String collectionName, string [] restrictionValues)
1337                 {
1338                         if (collectionName == null)
1339                                 //LAMESPEC: In MS.NET, if collectionName is null, it throws ArgumentException.
1340                                 throw new ArgumentException ();
1341
1342                         String cName          = null;
1343                         DataTable schemaTable = MetaDataCollections.Instance;
1344                         int length = restrictionValues == null ? 0 : restrictionValues.Length;
1345
1346                         foreach (DataRow row in schemaTable.Rows) {
1347                                 if (String.Compare ((string) row["CollectionName"], collectionName, true) == 0) {
1348                                         if (length > (int) row["NumberOfRestrictions"]) {
1349                                                 throw new ArgumentException ("More restrictions were provided " +
1350                                                                              "than the requested schema ('" +
1351                                                                              row["CollectionName"].ToString () + "') supports");
1352                                         }
1353                                         cName = row["CollectionName"].ToString();
1354                                 }
1355                         }
1356                         if (cName == null)
1357                                 throw new ArgumentException ("The requested collection ('" + collectionName + "') is not defined.");
1358
1359                         SqlCommand command     = null;
1360                         DataTable dataTable    = new DataTable ();
1361                         SqlDataAdapter dataAdapter = new SqlDataAdapter ();
1362
1363                         switch (cName)
1364                         {
1365                         case "Databases":
1366                                 command = new SqlCommand ("select name as database_name, dbid, crdate as create_date " +
1367                                                           "from master.sys.sysdatabases where (name = @Name or (@Name " +
1368                                                           "is null))", this);
1369                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1370                                 break;
1371                         case "ForeignKeys":
1372                                 command = new SqlCommand ("select CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME, " +
1373                                                           "TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE, " +
1374                                                           "IS_DEFERRABLE, INITIALLY_DEFERRED from " +
1375                                                           "INFORMATION_SCHEMA.TABLE_CONSTRAINTS where (CONSTRAINT_CATALOG" +
1376                                                           " = @Catalog or (@Catalog is null)) and (CONSTRAINT_SCHEMA = " +
1377                                                           "@Owner or (@Owner is null)) and (TABLE_NAME = @Table or (" +
1378                                                           "@Table is null)) and (CONSTRAINT_NAME = @Name or (@Name is null))" +
1379                                                           " and CONSTRAINT_TYPE = 'FOREIGN KEY' order by CONSTRAINT_CATALOG," +
1380                                                           " CONSTRAINT_SCHEMA, CONSTRAINT_NAME", this);
1381                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1382                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1383                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1384                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1385                                 break;
1386                         case "Indexes":
1387                                 command = new SqlCommand ("select distinct db_name() as constraint_catalog, " +
1388                                                           "constraint_schema = user_name (o.uid), " +
1389                                                           "constraint_name = x.name, table_catalog = db_name (), " +
1390                                                           "table_schema = user_name (o.uid), table_name = o.name, " +
1391                                                           "index_name  = x.name from sysobjects o, sysindexes x, " +
1392                                                           "sysindexkeys xk where o.type in ('U') and x.id = o.id and " +
1393                                                           "o.id = xk.id and x.indid = xk.indid and xk.keyno = x.keycnt " +
1394                                                           "and (db_name() = @Catalog or (@Catalog is null)) and " +
1395                                                           "(user_name() = @Owner or (@Owner is null)) and (o.name = " +
1396                                                           "@Table or (@Table is null)) and (x.name = @Name or (@Name is null))" +
1397                                                           "order by table_name, index_name", this);
1398                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1399                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1400                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1401                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1402                                 break;
1403                         case "IndexColumns":
1404                                 command = new SqlCommand ("select distinct db_name() as constraint_catalog, " +
1405                                                           "constraint_schema = user_name (o.uid), constraint_name = x.name, " +
1406                                                           "table_catalog = db_name (), table_schema = user_name (o.uid), " +
1407                                                           "table_name = o.name, column_name = c.name, " +
1408                                                           "ordinal_position = convert (int, xk.keyno), keyType = c.xtype, " +
1409                                                           "index_name = x.name from sysobjects o, sysindexes x, syscolumns c, " +
1410                                                           "sysindexkeys xk where o.type in ('U') and x.id = o.id and o.id = c.id " +
1411                                                           "and o.id = xk.id and x.indid = xk.indid and c.colid = xk.colid " +
1412                                                           "and xk.keyno <= x.keycnt and permissions (o.id, c.name) <> 0 " +
1413                                                           "and (db_name() = @Catalog or (@Catalog is null)) and (user_name() " +
1414                                                           "= @Owner or (@Owner is null)) and (o.name = @Table or (@Table is" +
1415                                                           " null)) and (x.name = @ConstraintName or (@ConstraintName is null)) " +
1416                                                           "and (c.name = @Column or (@Column is null)) order by table_name, " +
1417                                                           "index_name", this);
1418                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 8);
1419                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1420                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 13);
1421                                 command.Parameters.Add ("@ConstraintName", SqlDbType.NVarChar, 4000);
1422                                 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1423                                 break;
1424                         case "Procedures":
1425                                 command = new SqlCommand ("select SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, " +
1426                                                           "ROUTINE_CATALOG, ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE, " +
1427                                                           "CREATED, LAST_ALTERED from INFORMATION_SCHEMA.ROUTINES where " +
1428                                                           "(SPECIFIC_CATALOG = @Catalog or (@Catalog is null)) and " +
1429                                                           "(SPECIFIC_SCHEMA = @Owner or (@Owner is null)) and (SPECIFIC_NAME" +
1430                                                           " = @Name or (@Name is null)) and (ROUTINE_TYPE = @Type or (@Type " +
1431                                                           "is null)) order by SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME", this);
1432                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1433                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1434                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1435                                 command.Parameters.Add ("@Type", SqlDbType.NVarChar, 4000);
1436                                 break;
1437                         case "ProcedureParameters":
1438                                 command = new SqlCommand ("select SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, " +
1439                                                           "ORDINAL_POSITION, PARAMETER_MODE, IS_RESULT, AS_LOCATOR, " +
1440                                                           "PARAMETER_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, " +
1441                                                           "CHARACTER_OCTET_LENGTH, COLLATION_CATALOG, COLLATION_SCHEMA, " +
1442                                                           "COLLATION_NAME, CHARACTER_SET_CATALOG, CHARACTER_SET_SCHEMA, " +
1443                                                           "CHARACTER_SET_NAME, NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, " +
1444                                                           "NUMERIC_SCALE, DATETIME_PRECISION, INTERVAL_TYPE, " +
1445                                                           "INTERVAL_PRECISION from INFORMATION_SCHEMA.PARAMETERS where " +
1446                                                           "(SPECIFIC_CATALOG = @Catalog or (@Catalog is null)) and " +
1447                                                           "(SPECIFIC_SCHEMA = @Owner or (@Owner is null)) and (SPECIFIC_NAME = " +
1448                                                           "@Name or (@Name is null)) and (PARAMETER_NAME = @Parameter or (" +
1449                                                           "@Parameter is null)) order by SPECIFIC_CATALOG, SPECIFIC_SCHEMA," +
1450                                                           " SPECIFIC_NAME, PARAMETER_NAME", this);
1451                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1452                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1453                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1454                                 command.Parameters.Add ("@Parameter", SqlDbType.NVarChar, 4000);
1455                                 break;
1456                         case "Tables":
1457                                 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE " +
1458                                                           "from INFORMATION_SCHEMA.TABLES where" +
1459                                                           " (TABLE_CATALOG = @catalog or (@catalog is null)) and " +
1460                                                           "(TABLE_SCHEMA = @owner or (@owner is null))and " +
1461                                                           "(TABLE_NAME = @name or (@name is null)) and " +
1462                                                           "(TABLE_TYPE = @table_type or (@table_type is null))", this);
1463                                 command.Parameters.Add ("@catalog", SqlDbType.NVarChar, 8);
1464                                 command.Parameters.Add ("@owner", SqlDbType.NVarChar, 3);
1465                                 command.Parameters.Add ("@name", SqlDbType.NVarChar, 11);
1466                                 command.Parameters.Add ("@table_type", SqlDbType.NVarChar, 10);
1467                                 break;
1468                         case "Columns":
1469                                 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, " +
1470                                                           "ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, " +
1471                                                           "CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH, " +
1472                                                           "NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, NUMERIC_SCALE, " +
1473                                                           "DATETIME_PRECISION, CHARACTER_SET_CATALOG, CHARACTER_SET_SCHEMA, " +
1474                                                           "CHARACTER_SET_NAME, COLLATION_CATALOG from INFORMATION_SCHEMA.COLUMNS" +
1475                                                           " where (TABLE_CATALOG = @Catalog or (@Catalog is null)) and (" +
1476                                                           "TABLE_SCHEMA = @Owner or (@Owner is null)) and (TABLE_NAME = @table" +
1477                                                           " or (@Table is null)) and (COLUMN_NAME = @column or (@Column is null" +
1478                                                           ")) order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME", this);
1479                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1480                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1481                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1482                                 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1483                                 break;
1484                         case "Users":
1485                                 command = new SqlCommand ("select uid, name as user_name, createdate, updatedate from sysusers" +
1486                                                           " where (name = @Name or (@Name is null))", this);
1487                                 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1488                                 break;
1489                         case "Views":
1490                                 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CHECK_OPTION, " +
1491                                                           "IS_UPDATABLE from INFORMATION_SCHEMA.VIEWS where (TABLE_CATALOG" +
1492                                                           " = @Catalog or (@Catalog is null)) TABLE_SCHEMA = @Owner or " +
1493                                                           "(@Owner is null)) and (TABLE_NAME = @table or (@Table is null))" +
1494                                                           " order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME", this);
1495                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1496                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1497                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1498                                 break;
1499                         case "ViewColumns":
1500                                 command = new SqlCommand ("select VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME, TABLE_CATALOG, " +
1501                                                           "TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME from " +
1502                                                           "INFORMATION_SCHEMA.VIEW_COLUMN_USAGE where (VIEW_CATALOG = " +
1503                                                           "@Catalog (@Catalog is null)) and (VIEW_SCHEMA = @Owner (@Owner" +
1504                                                           " is null)) and (VIEW_NAME = @Table or (@Table is null)) and " +
1505                                                           "(COLUMN_NAME = @Column or (@Column is null)) order by " +
1506                                                           "VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME", this);
1507                                 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1508                                 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1509                                 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1510                                 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1511                                 break;
1512                         case "UserDefinedTypes":
1513                                 command = new SqlCommand ("select assemblies.name as assembly_name, types.assembly_class " +
1514                                                           "as udt_name, ASSEMBLYPROPERTY(assemblies.name, 'VersionMajor') " +
1515                                                           "as version_major, ASSEMBLYPROPERTY(assemblies.name, 'VersionMinor') " +
1516                                                           "as version_minor, ASSEMBLYPROPERTY(assemblies.name, 'VersionBuild') " +
1517                                                           "as version_build, ASSEMBLYPROPERTY(assemblies.name, 'VersionRevision') " +
1518                                                           "as version_revision, ASSEMBLYPROPERTY(assemblies.name, 'CultureInfo') " +
1519                                                           "as culture_info, ASSEMBLYPROPERTY(assemblies.name, 'PublicKey') " +
1520                                                           "as public_key, is_fixed_length, max_length, Create_Date, " +
1521                                                           "Permission_set_desc from sys.assemblies as assemblies join " +
1522                                                           "sys.assembly_types as types on assemblies.assembly_id = types.assembly_id" +
1523                                                           " where (assemblies.name = @AssemblyName or (@AssemblyName is null)) and " +
1524                                                           "(types.assembly_class = @UDTName or (@UDTName is null))",
1525                                                           this);
1526                                 command.Parameters.Add ("@AssemblyName", SqlDbType.NVarChar, 4000);
1527                                 command.Parameters.Add ("@UDTName", SqlDbType.NVarChar, 4000);
1528                                 break;
1529                         case "MetaDataCollections":
1530                                 return MetaDataCollections.Instance;
1531                         case "DataSourceInformation":
1532                                 throw new NotImplementedException ();
1533                         case "DataTypes":
1534                                 return DataTypes.Instance;
1535                         case "ReservedWords":
1536                                 return ReservedWords.Instance;
1537                         case "Restrictions":
1538                                 return Restrictions.Instance;
1539                         }
1540                         for (int i = 0; i < length; i++) {
1541                                 command.Parameters[i].Value = restrictionValues[i];
1542                         }
1543                         dataAdapter.SelectCommand = command;
1544                         dataAdapter.Fill (dataTable);
1545                         return dataTable;
1546                 }
1547 #endif // NET_2_0
1548
1549                 #endregion // Methods
1550
1551 #if NET_2_0
1552                 #region Fields Net 2
1553
1554                 bool async = false;
1555
1556                 #endregion // Fields  Net 2
1557
1558                 #region Properties Net 2
1559
1560 #if !NET_2_0
1561                 [DataSysDescription ("Enable Asynchronous processing, 'Asynchrouse Processing=true/false' in the ConnectionString.")]   
1562 #endif
1563                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1564                 internal bool AsyncProcessing  {
1565                         get { return async; }
1566                 }
1567
1568                 #endregion // Properties Net 2
1569
1570 #endif // NET_2_0
1571
1572         }
1573 }