2 // System.Data.SqlClient.SqlConnection.cs
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)
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
18 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
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:
28 // The above copyright notice and this permission notice shall be
29 // included in all copies or substantial portions of the Software.
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.
41 using Mono.Data.Tds.Protocol;
43 using System.Collections;
44 using System.Collections.Specialized;
45 using System.ComponentModel;
47 using System.Data.Common;
48 using System.EnterpriseServices;
49 using System.Globalization;
51 using System.Net.Sockets;
55 namespace System.Data.SqlClient {
56 [DefaultEvent ("InfoMessage")]
58 public sealed class SqlConnection : DbConnection, IDbConnection, ICloneable
60 public sealed class SqlConnection : Component, IDbConnection, ICloneable
64 bool disposed = false;
66 // The set of SQL connection pools
67 static TdsConnectionPoolManager sqlConnectionPools = new TdsConnectionPoolManager (TdsVersion.tds70);
69 // The current connection pool
70 TdsConnectionPool pool;
72 // The connection string that identifies this connection
73 string connectionString = null;
75 // The transaction object for the current transaction
76 SqlTransaction transaction = null;
78 // Connection parameters
80 TdsConnectionParameters parms = new TdsConnectionParameters ();
81 NameValueCollection connStringParameters = null;
85 int connectionTimeout;
90 bool fireInfoMessageEventOnUserErrors;
91 bool statisticsEnabled;
94 ConnectionState state = ConnectionState.Closed;
96 SqlDataReader dataReader = null;
97 XmlReader xmlReader = null;
106 public SqlConnection ()
107 : this (String.Empty)
111 public SqlConnection (string connectionString)
113 Init (connectionString);
116 private void Init (string connectionString)
118 connectionTimeout = 15; // default timeout
119 dataSource = ""; // default datasource
120 packetSize = 8192; // default packetsize
121 ConnectionString = connectionString;
125 #endregion // Constructors
130 [DataSysDescription ("Information used to connect to a DataSource, such as 'Data Source=x;Initial Catalog=x;Integrated Security=SSPI'.")]
133 [EditorAttribute ("Microsoft.VSDesigner.Data.SQL.Design.SqlConnectionStringEditor, "+ Consts.AssemblyMicrosoft_VSDesigner, "System.Drawing.Design.UITypeEditor, "+ Consts.AssemblySystem_Drawing )]
134 [RecommendedAsConfigurable (true)]
135 [RefreshProperties (RefreshProperties.All)]
136 [MonoTODO("persist security info, encrypt, enlist and , attachdbfilename keyword not implemented")]
141 string ConnectionString {
142 get { return connectionString; }
144 if (state == ConnectionState.Open)
145 throw new InvalidOperationException ("Not Allowed to change ConnectionString property while Connection state is OPEN");
146 SetConnectionString (value);
151 [DataSysDescription ("Current connection timeout value, 'Connect Timeout=X' in the ConnectionString.")]
153 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
159 int ConnectionTimeout {
160 get { return connectionTimeout; }
164 [DataSysDescription ("Current SQL Server database, 'Initial Catalog=X' in the connection string.")]
166 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
173 if (State == ConnectionState.Open)
175 return parms.Database ;
179 internal SqlDataReader DataReader {
180 get { return dataReader; }
181 set { dataReader = value; }
185 [DataSysDescription ("Current SqlServer that the connection is opened to, 'Data Source=X' in the connection string. ")]
189 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
195 get { return dataSource; }
199 [DataSysDescription ("Network packet size, 'Packet Size=x' in the connection string.")]
201 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
202 public int PacketSize {
204 if (State == ConnectionState.Open)
205 return ((Tds)tds).PacketSize ;
212 [DataSysDescription ("Version of the SQL Server accessed by the SqlConnection.")]
214 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
219 string ServerVersion {
221 if (state == ConnectionState.Closed)
222 throw new InvalidOperationException ("Invalid Operation.The Connection is Closed");
224 return tds.ServerVersion;
230 [DataSysDescription ("The ConnectionState indicating whether the connection is open or closed.")]
232 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
237 ConnectionState State {
238 get { return state; }
245 internal SqlTransaction Transaction {
246 get { return transaction; }
247 set { transaction = value; }
251 [DataSysDescription ("Workstation Id, 'Workstation ID=x' in the connection string.")]
253 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
254 public string WorkstationId {
255 get { return parms.Hostname; }
258 internal XmlReader XmlReader {
259 get { return xmlReader; }
260 set { xmlReader = value; }
264 public bool FireInfoMessageEventOnUserErrors {
265 get { return fireInfoMessageEventOnUserErrors; }
266 set { fireInfoMessageEventOnUserErrors = value; }
269 [DefaultValue (false)]
270 public bool StatisticsEnabled {
271 get { return statisticsEnabled; }
272 set { statisticsEnabled = value; }
275 #endregion // Properties
280 [DataSysDescription ("Event triggered when messages arrive from the DataSource.")]
282 public event SqlInfoMessageEventHandler InfoMessage;
285 [DataSysDescription ("Event triggered when the connection changes state.")]
288 new event StateChangeEventHandler StateChange;
294 private void ErrorHandler (object sender, TdsInternalErrorMessageEventArgs e)
296 throw new SqlException (e.Class, e.LineNumber, e.Message, e.Number, e.Procedure, e.Server, "Mono SqlClient Data Provider", e.State);
299 private void MessageHandler (object sender, TdsInternalInfoMessageEventArgs e)
301 OnSqlInfoMessage (CreateSqlInfoMessageEvent (e.Errors));
304 #endregion // Delegates
308 internal string GetConnStringKeyValue (params string [] keys)
310 if (connStringParameters == null || connStringParameters.Count == 0)
312 foreach (string key in keys) {
313 string value = connStringParameters [key];
322 public new SqlTransaction BeginTransaction ()
324 return BeginTransaction (IsolationLevel.ReadCommitted, String.Empty);
327 public new SqlTransaction BeginTransaction (IsolationLevel iso)
329 return BeginTransaction (iso, String.Empty);
332 public SqlTransaction BeginTransaction (string transactionName)
334 return BeginTransaction (IsolationLevel.ReadCommitted, transactionName);
337 public SqlTransaction BeginTransaction (IsolationLevel iso, string transactionName)
339 if (state == ConnectionState.Closed)
340 throw new InvalidOperationException ("The connection is not open.");
341 if (transaction != null)
342 throw new InvalidOperationException ("SqlConnection does not support parallel transactions.");
344 if (iso == IsolationLevel.Chaos)
345 throw new ArgumentException ("Invalid IsolationLevel parameter: must be ReadCommitted, ReadUncommitted, RepeatableRead, or Serializable.");
347 string isolevel = String.Empty;
349 case IsolationLevel.ReadCommitted:
350 isolevel = "READ COMMITTED";
352 case IsolationLevel.ReadUncommitted:
353 isolevel = "READ UNCOMMITTED";
355 case IsolationLevel.RepeatableRead:
356 isolevel = "REPEATABLE READ";
358 case IsolationLevel.Serializable:
359 isolevel = "SERIALIZABLE";
363 tds.Execute (String.Format ("SET TRANSACTION ISOLATION LEVEL {0};BEGIN TRANSACTION {1}", isolevel, transactionName));
365 transaction = new SqlTransaction (this, iso);
373 void ChangeDatabase (string database)
375 if (!IsValidDatabaseName (database))
376 throw new ArgumentException (String.Format ("The database name {0} is not valid.", database));
377 if (state != ConnectionState.Open)
378 throw new InvalidOperationException ("The connection is not open.");
379 tds.Execute (String.Format ("use [{0}]", database));
382 private void ChangeState (ConnectionState currentState)
384 ConnectionState originalState = state;
385 state = currentState;
386 OnStateChange (CreateStateChangeEvent (originalState, currentState));
395 if (transaction != null && transaction.IsOpen)
396 transaction.Rollback ();
398 if (dataReader != null || xmlReader != null) {
399 if(tds != null) tds.SkipToEnd ();
405 if(pool != null) pool.ReleaseConnection (tds);
407 if(tds != null) tds.Disconnect ();
410 tds.TdsErrorMessage -= new TdsInternalErrorMessageEventHandler (ErrorHandler);
411 tds.TdsInfoMessage -= new TdsInternalInfoMessageEventHandler (MessageHandler);
414 ChangeState (ConnectionState.Closed);
417 public new SqlCommand CreateCommand ()
419 SqlCommand command = new SqlCommand ();
420 command.Connection = this;
424 private SqlInfoMessageEventArgs CreateSqlInfoMessageEvent (TdsInternalErrorCollection errors)
426 return new SqlInfoMessageEventArgs (errors);
429 private StateChangeEventArgs CreateStateChangeEvent (ConnectionState originalState, ConnectionState currentState)
431 return new StateChangeEventArgs (originalState, currentState);
434 protected override void Dispose (bool disposing)
441 if (State == ConnectionState.Open)
443 ConnectionString = "";
444 SetDefaultConnectionParameters (this.connStringParameters);
448 base.Dispose (disposing);
452 [MonoTODO ("Not sure what this means at present.")]
454 void EnlistDistributedTransaction (ITransaction transaction)
456 throw new NotImplementedException ();
459 object ICloneable.Clone ()
461 return new SqlConnection (ConnectionString);
464 IDbTransaction IDbConnection.BeginTransaction ()
466 return BeginTransaction ();
469 IDbTransaction IDbConnection.BeginTransaction (IsolationLevel iso)
471 return BeginTransaction (iso);
474 protected override DbTransaction BeginDbTransaction (IsolationLevel level)
476 return (DbTransaction)BeginTransaction (level);
479 protected override DbCommand CreateDbCommand ()
481 return CreateCommand ();
485 IDbCommand IDbConnection.CreateCommand ()
487 return CreateCommand ();
490 void IDisposable.Dispose ()
493 GC.SuppressFinalize (this);
502 string serverName = "";
503 if (state == ConnectionState.Open)
504 throw new InvalidOperationException ("The Connection is already Open (State=Open)");
506 if (connectionString == null || connectionString.Trim().Length == 0)
507 throw new InvalidOperationException ("Connection string has not been initialized.");
511 if(!ParseDataSource (dataSource, out port, out serverName))
512 throw new SqlException(20, 0, "SQL Server does not exist or access denied.", 17, "ConnectionOpen (Connect()).", dataSource, parms.ApplicationName, 0);
513 tds = new Tds70 (serverName, port, PacketSize, ConnectionTimeout);
516 if(!ParseDataSource (dataSource, out port, out serverName))
517 throw new SqlException(20, 0, "SQL Server does not exist or access denied.", 17, "ConnectionOpen (Connect()).", dataSource, parms.ApplicationName, 0);
519 TdsConnectionInfo info = new TdsConnectionInfo (serverName, port, packetSize, ConnectionTimeout, minPoolSize, maxPoolSize);
520 pool = sqlConnectionPools.GetConnectionPool (connectionString, info);
521 tds = pool.GetConnection ();
523 } catch (TdsTimeoutException e) {
524 throw SqlException.FromTdsInternalException ((TdsInternalException) e);
525 }catch (TdsInternalException e) {
526 throw SqlException.FromTdsInternalException (e);
529 tds.TdsErrorMessage += new TdsInternalErrorMessageEventHandler (ErrorHandler);
530 tds.TdsInfoMessage += new TdsInternalInfoMessageEventHandler (MessageHandler);
532 if (!tds.IsConnected) {
538 pool.ReleaseConnection (tds);
541 } else if (connectionReset) {
545 disposed = false; // reset this, so using () would call Close ().
546 ChangeState (ConnectionState.Open);
549 private bool ParseDataSource (string theDataSource, out int thePort, out string theServerName)
552 string theInstanceName = "";
554 if (theDataSource == null)
555 throw new ArgumentException("Format of initialization string does not conform to specifications");
557 thePort = 1433; // default TCP port for SQL Server
561 if ((idx = theDataSource.IndexOf (",")) > -1) {
562 theServerName = theDataSource.Substring (0, idx);
563 string p = theDataSource.Substring (idx + 1);
564 thePort = Int32.Parse (p);
566 else if ((idx = theDataSource.IndexOf ("\\")) > -1) {
567 theServerName = theDataSource.Substring (0, idx);
568 theInstanceName = theDataSource.Substring (idx + 1);
569 // do port discovery via UDP port 1434
570 port = DiscoverTcpPortViaSqlMonitor (theServerName, theInstanceName);
574 else if (theDataSource == "" || theDataSource == "(local)")
575 theServerName = "localhost";
577 theServerName = theDataSource;
582 private bool ConvertIntegratedSecurity (string value)
584 if (value.ToUpper() == "SSPI")
589 return ConvertToBoolean("integrated security", value);
592 private bool ConvertToBoolean(string key, string value)
594 string upperValue = value.ToUpper();
596 if (upperValue == "TRUE" ||upperValue == "YES")
600 else if (upperValue == "FALSE" || upperValue == "NO")
605 throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
606 "Invalid value \"{0}\" for key '{1}'.", value, key));
609 private int ConvertToInt32(string key, string value)
613 return int.Parse(value);
617 throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
618 "Invalid value \"{0}\" for key '{1}'.", value, key));
622 private int DiscoverTcpPortViaSqlMonitor(string ServerName, string InstanceName)
624 SqlMonitorSocket msock;
625 msock = new SqlMonitorSocket (ServerName, InstanceName);
626 int SqlServerPort = msock.DiscoverTcpPort ();
628 return SqlServerPort;
631 void SetConnectionString (string connectionString)
633 NameValueCollection parameters = new NameValueCollection ();
634 SetDefaultConnectionParameters (parameters);
636 if ((connectionString == null) || (connectionString.Trim().Length == 0)) {
637 this.connectionString = connectionString;
638 this.connStringParameters = parameters;
642 connectionString += ";";
644 bool inQuote = false;
645 bool inDQuote = false;
648 string name = String.Empty;
649 string value = String.Empty;
650 StringBuilder sb = new StringBuilder ();
652 for (int i = 0; i < connectionString.Length; i += 1) {
653 char c = connectionString [i];
655 if (i == connectionString.Length - 1)
658 peek = connectionString [i + 1];
664 else if (peek.Equals (c)) {
674 else if (peek.Equals (c)) {
679 inDQuote = !inDQuote;
682 if (inDQuote || inQuote)
685 if (name != String.Empty && name != null) {
686 value = sb.ToString ();
687 SetProperties (name.ToUpper ().Trim() , value);
688 parameters [name.ToUpper ().Trim ()] = value.Trim ();
690 else if (sb.Length != 0)
691 throw new ArgumentException ("Format of initialization string does not conform to specifications");
694 value = String.Empty;
695 sb = new StringBuilder ();
699 if (inDQuote || inQuote || !inName)
701 else if (peek.Equals (c)) {
707 name = sb.ToString ();
708 sb = new StringBuilder ();
713 if (inQuote || inDQuote)
715 else if (sb.Length > 0 && !peek.Equals (';'))
724 connectionString = connectionString.Substring (0 , connectionString.Length-1);
725 this.connectionString = connectionString;
726 this.connStringParameters = parameters;
729 void SetDefaultConnectionParameters (NameValueCollection parameters)
733 connectionTimeout= 15;
734 connectionReset = true;
740 parameters["APPLICATION NAME"] = "Mono SqlClient Data Provider";
741 parameters["CONNECT TIMEOUT"] = "15";
742 parameters["CONNECTION LIFETIME"] = "0";
743 parameters["CONNECTION RESET"] = "true";
744 parameters["ENLIST"] = "true";
745 parameters["INTEGRATED SECURITY"] = "false";
746 parameters["INITIAL CATALOG"] = "";
747 parameters["MAX POOL SIZE"] = "100";
748 parameters["MIN POOL SIZE"] = "0";
749 parameters["NETWORK LIBRARY"] = "dbmssocn";
750 parameters["PACKET SIZE"] = "8192";
751 parameters["PERSIST SECURITY INFO"] = "false";
752 parameters["POOLING"] = "true";
753 parameters["WORKSTATION ID"] = Dns.GetHostName();
756 parameters ["ASYNCHRONOUS PROCESSING"] = "false";
760 private void SetProperties (string name , string value)
766 case "APPLICATION NAME" :
767 parms.ApplicationName = value;
769 case "ATTACHDBFILENAME" :
770 case "EXTENDED PROPERTIES" :
771 case "INITIAL FILE NAME" :
772 parms.AttachDBFileName = value;
775 case "CONNECT TIMEOUT" :
776 case "CONNECTION TIMEOUT" :
777 int tmpTimeout = ConvertToInt32 ("connection timeout", value);
779 throw new ArgumentException ("Invalid CONNECTION TIMEOUT .. Must be an integer >=0 ");
781 connectionTimeout = tmpTimeout;
783 case "CONNECTION LIFETIME" :
785 case "CONNECTION RESET" :
786 connectionReset = ConvertToBoolean ("connection reset", value);
789 case "CURRENT LANGUAGE" :
790 parms.Language = value;
796 case "NETWORK ADDRESS" :
800 if (ConvertToBoolean("encrypt", value))
802 throw new NotImplementedException("SSL encryption for"
803 + " data sent between client and server is not"
808 if (!ConvertToBoolean("enlist", value))
810 throw new NotImplementedException("Disabling the automatic"
811 + " enlistment of connections in the thread's current"
812 + " transaction context is not implemented.");
815 case "INITIAL CATALOG" :
817 parms.Database = value;
819 case "INTEGRATED SECURITY" :
820 case "TRUSTED_CONNECTION" :
821 parms.DomainLogin = ConvertIntegratedSecurity(value);
823 case "MAX POOL SIZE" :
824 int tmpMaxPoolSize = ConvertToInt32 ("max pool size" , value);
825 if (tmpMaxPoolSize < 0)
826 throw new ArgumentException ("Invalid MAX POOL SIZE. Must be a intger >= 0");
828 maxPoolSize = tmpMaxPoolSize;
830 case "MIN POOL SIZE" :
831 int tmpMinPoolSize = ConvertToInt32 ("min pool size" , value);
832 if (tmpMinPoolSize < 0)
833 throw new ArgumentException ("Invalid MIN POOL SIZE. Must be a intger >= 0");
835 minPoolSize = tmpMinPoolSize;
838 case "MULTIPLEACTIVERESULTSETS":
840 case "ASYNCHRONOUS PROCESSING" :
842 async = ConvertToBoolean (name, value);
847 case "NETWORK LIBRARY" :
848 if (!value.ToUpper ().Equals ("DBMSSOCN"))
849 throw new ArgumentException ("Unsupported network library.");
852 int tmpPacketSize = ConvertToInt32 ("packet size", value);
853 if (tmpPacketSize < 512 || tmpPacketSize > 32767)
854 throw new ArgumentException ("Invalid PACKET SIZE. The integer must be between 512 and 32767");
856 packetSize = tmpPacketSize;
860 parms.Password = value;
862 case "PERSISTSECURITYINFO" :
863 case "PERSIST SECURITY INFO" :
864 // FIXME : not implemented
865 // throw new NotImplementedException ();
868 pooling = ConvertToBoolean("pooling", value);
876 case "WORKSTATION ID" :
877 parms.Hostname = value;
880 throw new ArgumentException("Keyword not supported :"+name);
884 static bool IsValidDatabaseName (string database)
886 if ( database == null || database.Trim() == String.Empty || database.Length > 128)
889 if (database[0] == '"' && database[database.Length] == '"')
890 database = database.Substring (1, database.Length - 2);
891 else if (Char.IsDigit (database[0]))
894 if (database[0] == '_')
897 foreach (char c in database.Substring (1, database.Length - 1))
898 if (!Char.IsLetterOrDigit (c) && c != '_' && c != '-')
903 private void OnSqlInfoMessage (SqlInfoMessageEventArgs value)
905 if (InfoMessage != null)
906 InfoMessage (this, value);
909 private new void OnStateChange (StateChangeEventArgs value)
911 if (StateChange != null)
912 StateChange (this, value);
915 private sealed class SqlMonitorSocket : UdpClient
917 // UDP port that the SQL Monitor listens
918 private static readonly int SqlMonitorUdpPort = 1434;
919 //private static readonly string SqlServerNotExist = "SQL Server does not exist or access denied";
921 private string server;
922 private string instance;
924 internal SqlMonitorSocket (string ServerName, string InstanceName)
925 : base (ServerName, SqlMonitorUdpPort)
928 instance = InstanceName;
931 internal int DiscoverTcpPort ()
933 int SqlServerTcpPort;
934 Client.Blocking = false;
935 // send command to UDP 1434 (SQL Monitor) to get
936 // the TCP port to connect to the MS SQL server
937 ASCIIEncoding enc = new ASCIIEncoding ();
938 Byte[] rawrq = new Byte [instance.Length + 1];
940 enc.GetBytes (instance, 0, instance.Length, rawrq, 1);
941 int bytes = Send (rawrq, rawrq.Length);
947 result = Client.Poll (100, SelectMode.SelectRead);
951 if (Client.Available <= 0)
954 IPEndPoint endpoint = new IPEndPoint (Dns.GetHostByName ("localhost").AddressList [0], 0);
957 rawrs = Receive (ref endpoint);
959 string rs = Encoding.ASCII.GetString (rawrs);
961 string[] rawtokens = rs.Split (';');
962 Hashtable data = new Hashtable ();
963 for (int i = 0; i < rawtokens.Length / 2 && i < 256; i++) {
964 data [rawtokens [i * 2]] = rawtokens [ i * 2 + 1];
966 if (!data.ContainsKey ("tcp"))
967 throw new NotImplementedException ("Only TCP/IP is supported.");
969 SqlServerTcpPort = int.Parse ((string) data ["tcp"]);
972 return SqlServerTcpPort;
980 public ColumnInfo (string name, Type type)
982 this.name = name; this.type = type;
986 static class ReservedWords
988 static readonly string [] reservedWords =
990 "ADD", "EXCEPT", "PERCENT", "ALL", "EXEC", "PLAN", "ALTER",
991 "EXECUTE", "PRECISION", "AND", "EXISTS", "PRIMARY", "ANY",
992 "EXIT", "PRINT", "AS", "FETCH", "PROC", "ASC", "FILE",
993 "PROCEDURE", "AUTHORIZATION", "FILLFACTOR", "PUBLIC",
994 "BACKUP", "FOR", "RAISERROR", "BEGIN", "FOREIGN", "READ",
995 "BETWEEN", "FREETEXT", "READTEXT", "BREAK", "FREETEXTTABLE",
996 "RECONFIGURE", "BROWSE", "FROM", "REFERENCES", "BULK",
997 "FULL", "REPLICATION", "BY", "FUNCTION", "RESTORE",
998 "CASCADE", "GOTO", "RESTRICT", "CASE", "GRANT", "RETURN",
999 "CHECK", "GROUP", "REVOKE", "CHECKPOINT", "HAVING", "RIGHT",
1000 "CLOSE", "HOLDLOCK", "ROLLBACK", "CLUSTERED", "IDENTITY",
1001 "ROWCOUNT", "COALESCE", "IDENTITY_INSERT", "ROWGUIDCOL",
1002 "COLLATE", "IDENTITYCOL", "RULE", "COLUMN", "IF", "SAVE",
1003 "COMMIT", "IN", "SCHEMA", "COMPUTE", "INDEX", "SELECT",
1004 "CONSTRAINT", "INNER", "SESSION_USER", "CONTAINS", "INSERT",
1005 "SET", "CONTAINSTABLE", "INTERSECT", "SETUSER", "CONTINUE",
1006 "INTO", "SHUTDOWN", "CONVERT", "IS", "SOME", "CREATE",
1007 "JOIN", "STATISTICS", "CROSS", "KEY", "SYSTEM_USER",
1008 "CURRENT", "KILL", "TABLE", "CURRENT_DATE", "LEFT",
1009 "TEXTSIZE", "CURRENT_TIME", "LIKE", "THEN",
1010 "CURRENT_TIMESTAMP", "LINENO", "TO", "CURRENT_USER", "LOAD",
1011 "TOP", "CURSOR", "NATIONAL", "TRAN", "DATABASE", "NOCHECK",
1012 "TRANSACTION", "DBCC", "NONCLUSTERED", "TRIGGER",
1013 "DEALLOCATE", "NOT", "TRUNCATE", "DECLARE", "NULL",
1014 "TSEQUAL", "DEFAULT", "NULLIF", "UNION", "DELETE", "OF",
1015 "UNIQUE", "DENY", "OFF", "UPDATE", "DESC", "OFFSETS",
1016 "UPDATETEXT", "DISK", "ON", "USE", "DISTINCT", "OPEN",
1017 "USER", "DISTRIBUTED", "OPENDATASOURCE", "VALUES", "DOUBLE",
1018 "OPENQUERY", "VARYING", "DROP", "OPENROWSET", "VIEW",
1019 "DUMMY", "OPENXML", "WAITFOR", "DUMP", "OPTION", "WHEN",
1020 "ELSE", "OR", "WHERE", "END", "ORDER", "WHILE", "ERRLVL",
1021 "OUTER", "WITH", "ESCAPE", "OVER", "WRITETEXT", "ABSOLUTE",
1022 "FOUND", "PRESERVE", "ACTION", "FREE", "PRIOR", "ADMIN",
1023 "GENERAL", "PRIVILEGES", "AFTER", "GET", "READS",
1024 "AGGREGATE", "GLOBAL", "REAL", "ALIAS", "GO", "RECURSIVE",
1025 "ALLOCATE", "GROUPING", "REF", "ARE", "HOST", "REFERENCING",
1026 "ARRAY", "HOUR", "RELATIVE", "ASSERTION", "IGNORE", "RESULT",
1027 "AT", "IMMEDIATE", "RETURNS", "BEFORE", "INDICATOR", "ROLE",
1028 "BINARY", "INITIALIZE", "ROLLUP", "BIT", "INITIALLY",
1029 "ROUTINE", "BLOB", "INOUT", "ROW", "BOOLEAN", "INPUT",
1030 "ROWS", "BOTH", "INT", "SAVEPOINT", "BREADTH", "INTEGER",
1031 "SCROLL", "CALL", "INTERVAL", "SCOPE", "CASCADED",
1032 "ISOLATION", "SEARCH", "CAST", "ITERATE", "SECOND",
1033 "CATALOG", "LANGUAGE", "SECTION", "CHAR", "LARGE",
1034 "SEQUENCE", "CHARACTER", "LAST", "SESSION", "CLASS",
1035 "LATERAL", "SETS", "CLOB", "LEADING", "SIZE", "COLLATION",
1036 "LESS", "SMALLINT", "COMPLETION", "LEVEL", "SPACE",
1037 "CONNECT", "LIMIT", "SPECIFIC", "CONNECTION", "LOCAL",
1038 "SPECIFICTYPE", "CONSTRAINTS", "LOCALTIME", "SQL",
1039 "CONSTRUCTOR", "LOCALTIMESTAMP", "SQLEXCEPTION",
1040 "CORRESPONDING", "LOCATOR", "SQLSTATE", "CUBE", "MAP",
1041 "SQLWARNING", "CURRENT_PATH", "MATCH", "START",
1042 "CURRENT_ROLE", "MINUTE", "STATE", "CYCLE", "MODIFIES",
1043 "STATEMENT", "DATA", "MODIFY", "STATIC", "DATE", "MODULE",
1044 "STRUCTURE", "DAY", "MONTH", "TEMPORARY", "DEC", "NAMES",
1045 "TERMINATE", "DECIMAL", "NATURAL", "THAN", "DEFERRABLE",
1046 "NCHAR", "TIME", "DEFERRED", "NCLOB", "TIMESTAMP", "DEPTH",
1047 "NEW", "TIMEZONE_HOUR", "DEREF", "NEXT", "TIMEZONE_MINUTE",
1048 "DESCRIBE", "NO", "TRAILING", "DESCRIPTOR", "NONE",
1049 "TRANSLATION", "DESTROY", "NUMERIC", "TREAT", "DESTRUCTOR",
1050 "OBJECT", "TRUE", "DETERMINISTIC", "OLD", "UNDER",
1051 "DICTIONARY", "ONLY", "UNKNOWN", "DIAGNOSTICS", "OPERATION",
1052 "UNNEST", "DISCONNECT", "ORDINALITY", "USAGE", "DOMAIN",
1053 "OUT", "USING", "DYNAMIC", "OUTPUT", "VALUE", "EACH",
1054 "PAD", "VARCHAR", "END-EXEC", "PARAMETER", "VARIABLE",
1055 "EQUALS", "PARAMETERS", "WHENEVER", "EVERY", "PARTIAL",
1056 "WITHOUT", "EXCEPTION", "PATH", "WORK", "EXTERNAL",
1057 "POSTFIX", "WRITE", "FALSE", "PREFIX", "YEAR", "FIRST",
1058 "PREORDER", "ZONE", "FLOAT", "PREPARE", "ADA", "AVG",
1059 "BIT_LENGTH", "CHAR_LENGTH", "CHARACTER_LENGTH", "COUNT",
1060 "EXTRACT", "FORTRAN", "INCLUDE", "INSENSITIVE", "LOWER",
1061 "MAX", "MIN", "OCTET_LENGTH", "OVERLAPS", "PASCAL",
1062 "POSITION", "SQLCA", "SQLCODE", "SQLERROR", "SUBSTRING",
1063 "SUM", "TRANSLATE", "TRIM", "UPPER"
1065 static DataTable instance;
1066 static public DataTable Instance {
1068 if (instance == null) {
1070 instance = new DataTable ("ReservedWords");
1071 instance.Columns.Add ("ReservedWord", typeof(string));
1072 foreach (string reservedWord in reservedWords)
1074 row = instance.NewRow();
1076 row["ReservedWord"] = reservedWord;
1077 instance.Rows.Add(row);
1085 static class MetaDataCollections
1087 static readonly ColumnInfo [] columns = {
1088 new ColumnInfo ("CollectionName", typeof (string)),
1089 new ColumnInfo ("NumberOfRestrictions", typeof (int)),
1090 new ColumnInfo ("NumberOfIdentifierParts", typeof (int))
1093 static readonly object [][] rows = {
1094 new object [] {"MetaDataCollections", 0, 0},
1095 new object [] {"DataSourceInformation", 0, 0},
1096 new object [] {"DataTypes", 0, 0},
1097 new object [] {"Restrictions", 0, 0},
1098 new object [] {"ReservedWords", 0, 0},
1099 new object [] {"Users", 1, 1},
1100 new object [] {"Databases", 1, 1},
1101 new object [] {"Tables", 4, 3},
1102 new object [] {"Columns", 4, 4},
1103 new object [] {"Views", 3, 3},
1104 new object [] {"ViewColumns", 4, 4},
1105 new object [] {"ProcedureParameters", 4, 1},
1106 new object [] {"Procedures", 4, 3},
1107 new object [] {"ForeignKeys", 4, 3},
1108 new object [] {"IndexColumns", 5, 4},
1109 new object [] {"Indexes", 4, 3},
1110 new object [] {"UserDefinedTypes", 2, 1}
1113 static DataTable instance;
1114 static public DataTable Instance {
1116 if (instance == null) {
1117 instance = new DataTable ("GetSchema");
1118 foreach (ColumnInfo c in columns)
1119 instance.Columns.Add (c.name, c.type);
1120 foreach (object [] row in rows)
1121 instance.LoadDataRow (row, true);
1128 static class DataTypes
1130 static readonly ColumnInfo [] columns = {
1131 new ColumnInfo ("TypeName", typeof(string)),
1132 new ColumnInfo ("ProviderDbType", typeof(int)),
1133 new ColumnInfo ("ColumnSize", typeof(long)),
1134 new ColumnInfo ("CreateFormat", typeof(string)),
1135 new ColumnInfo ("CreateParameters", typeof(string)),
1136 new ColumnInfo ("DataType", typeof(string)),
1137 new ColumnInfo ("IsAutoIncrementable", typeof(bool)),
1138 new ColumnInfo ("IsBestMatch", typeof(bool)),
1139 new ColumnInfo ("IsCaseSensitive", typeof(bool)),
1140 new ColumnInfo ("IsFixedLength", typeof(bool)),
1141 new ColumnInfo ("IsFixedPrecisionScale", typeof(bool)),
1142 new ColumnInfo ("IsLong", typeof(bool)),
1143 new ColumnInfo ("IsNullable", typeof(bool)),
1144 new ColumnInfo ("IsSearchable", typeof(bool)),
1145 new ColumnInfo ("IsSearchableWithLike", typeof(bool)),
1146 new ColumnInfo ("IsUnsigned", typeof(bool)),
1147 new ColumnInfo ("MaximumScale", typeof(short)),
1148 new ColumnInfo ("MinimumScale", typeof(short)),
1149 new ColumnInfo ("IsConcurrencyType", typeof(bool)),
1150 new ColumnInfo ("IsLiteralSupported", typeof(bool)),
1151 new ColumnInfo ("LiteralPrefix", typeof(string)),
1152 new ColumnInfo ("LiteralSuffix", typeof(string))
1155 static readonly object [][] rows = {
1156 new object [] {"smallint", 16, 5, "smallint", null, "System.Int16", true, true,
1157 false, true, true, false, true, true, false, false, null,
1158 null, false, null, null, null},
1159 new object [] {"int", 8, 10, "int", null, "System.Int32",
1160 true, true, false, true, true, false, true, true, false,
1161 false, null, null, false, null, null, null},
1162 new object [] {"real", 13, 7, "real", null,
1163 "System.Single", false, true, false, true, false, false,
1164 true, true, false, false, null, null, false, null, null, null},
1165 new object [] {"float", 6, 53, "float({0})",
1166 "number of bits used to store the mantissa", "System.Double",
1167 false, true, false, true, false, false, true, true,
1168 false, false, null, null, false, null, null, null},
1169 new object [] {"money", 9, 19, "money", null,
1170 "System.Decimal", false, false, false, true, true,
1171 false, true, true, false, false, null, null, false,
1173 new object [] {"smallmoney", 17, 10, "smallmoney", null,
1174 "System.Decimal", false, false, false, true, true, false,
1175 true, true, false, false, null, null, false, null, null, null},
1176 new object [] {"bit", 2, 1, "bit", null, "System.Boolean",
1177 false, false, false, true, false, false, true, true,
1178 false, null, null, null, false, null, null, null},
1179 new object [] {"tinyint", 20, 3, "tinyint", null,
1180 "System.SByte", true, true, false, true, true, false,
1181 true, true, false, true, null, null, false, null, null, null},
1182 new object [] {"bigint", 0, 19, "bigint", null,
1183 "System.Int64", true, true, false, true, true, false,
1184 true, true, false, false, null, null, false, null, null, null},
1185 new object [] {"timestamp", 19, 8, "timestamp", null,
1186 "System.Byte[]", false, false, false, true, false, false,
1187 false, true, false, null, null, null, true, null, "0x", null},
1188 new object [] {"binary", 1, 8000, "binary({0})", "length",
1189 "System.Byte[]", false, true, false, true, false, false,
1190 true, true, false, null, null, null, false, null, "0x", null},
1191 new object [] {"image", 7, 2147483647, "image", null,
1192 "System.Byte[]", false, true, false, false, false, true,
1193 true, false, false, null, null, null, false, null, "0x", null},
1194 new object [] {"text", 18, 2147483647, "text", null,
1195 "System.String", false, true, false, false, false, true,
1196 true, false, true, null, null, null, false, null, "'", "'"},
1197 new object [] {"ntext", 11, 1073741823, "ntext", null,
1198 "System.String", false, true, false, false, false, true,
1199 true, false, true, null, null, null, false, null, "N'", "'"},
1200 new object [] {"decimal", 5, 38, "decimal({0}, {1})",
1201 "precision,scale", "System.Decimal", true, true, false,
1202 true, false, false, true, true, false, false, 38, 0,
1203 false, null, null, null},
1204 new object [] {"numeric", 5, 38, "numeric({0}, {1})",
1205 "precision,scale", "System.Decimal", true, true, false,
1206 true, false, false, true, true, false, false, 38, 0,
1207 false, null, null, null},
1208 new object [] {"datetime", 4, 23, "datetime", null,
1209 "System.DateTime", false, true, false, true, false, false,
1210 true, true, true, null, null, null, false, null, "{ts '", "'}"},
1211 new object [] {"smalldatetime", 15, 16, "smalldatetime", null,
1212 "System.DateTime", false, true, false, true, false, false,
1213 true, true, true, null, null, null, false, null, "{ts '", "'}"},
1214 new object [] {"sql_variant", 23, null, "sql_variant",
1215 null, "System.Object", false, true, false, false, false,
1216 false, true, true, false, null, null, null, false, false,
1218 new object [] {"xml", 25, 2147483647, "xml", null,
1219 "System.String", false, false, false, false, false, true,
1220 true, false, false, null, null, null, false, false, null, null},
1221 new object [] {"varchar", 22, 2147483647, "varchar({0})",
1222 "max length", "System.String", false, true, false, false,
1223 false, false, true, true, true, null, null, null, false,
1225 new object [] {"char", 3, 2147483647, "char({0})", "length",
1226 "System.String", false, true, false, true, false, false,
1227 true, true, true, null, null, null, false, null, "'", "'"},
1228 new object [] {"nchar", 10, 1073741823, "nchar({0})", "length",
1229 "System.String", false, true, false, true, false, false,
1230 true, true, true, null, null, null, false, null, "N'", "'"},
1231 new object [] {"nvarchar", 12, 1073741823, "nvarchar({0})", "max length",
1232 "System.String", false, true, false, false, false, false, true, true,
1233 true, null, null, null, false, null, "N'", "'"},
1234 new object [] {"varbinary", 21, 1073741823, "varbinary({0})",
1235 "max length", "System.Byte[]", false, true, false, false,
1236 false, false, true, true, false, null, null, null, false,
1238 new object [] {"uniqueidentifier", 14, 16, "uniqueidentifier", null,
1239 "System.Guid", false, true, false, true, false, false, true,
1240 true, false, null, null, null, false, null, "'", "'"}
1243 static DataTable instance;
1244 static public DataTable Instance {
1246 if (instance == null) {
1247 instance = new DataTable ("DataTypes");
1248 foreach (ColumnInfo c in columns)
1249 instance.Columns.Add (c.name, c.type);
1250 foreach (object [] row in rows)
1251 instance.LoadDataRow (row, true);
1258 static class Restrictions
1260 static readonly ColumnInfo [] columns = {
1261 new ColumnInfo ("CollectionName", typeof (string)),
1262 new ColumnInfo ("RestrictionName", typeof(string)),
1263 new ColumnInfo ("ParameterName", typeof(string)),
1264 new ColumnInfo ("RestrictionDefault", typeof(string)),
1265 new ColumnInfo ("RestrictionNumber", typeof(int))
1268 static readonly object [][] rows = {
1269 new object [] {"Users", "User_Name", "@Name", "name", 1},
1270 new object [] {"Databases", "Name", "@Name", "Name", 1},
1272 new object [] {"Tables", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1273 new object [] {"Tables", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1274 new object [] {"Tables", "Table", "@Name", "TABLE_NAME", 3},
1275 new object [] {"Tables", "TableType", "@TableType", "TABLE_TYPE", 4},
1277 new object [] {"Columns", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1278 new object [] {"Columns", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1279 new object [] {"Columns", "Table", "@Table", "TABLE_NAME", 3},
1280 new object [] {"Columns", "Column", "@Column", "COLUMN_NAME", 4},
1282 new object [] {"Views", "Catalog", "@Catalog", "TABLE_CATALOG", 1},
1283 new object [] {"Views", "Owner", "@Owner", "TABLE_SCHEMA", 2},
1284 new object [] {"Views", "Table", "@Table", "TABLE_NAME", 3},
1286 new object [] {"ViewColumns", "Catalog", "@Catalog", "VIEW_CATALOG", 1},
1287 new object [] {"ViewColumns", "Owner", "@Owner", "VIEW_SCHEMA", 2},
1288 new object [] {"ViewColumns", "Table", "@Table", "VIEW_NAME", 3},
1289 new object [] {"ViewColumns", "Column", "@Column", "COLUMN_NAME", 4},
1291 new object [] {"ProcedureParameters", "Catalog", "@Catalog", "SPECIFIC_CATALOG", 1},
1292 new object [] {"ProcedureParameters", "Owner", "@Owner", "SPECIFIC_SCHEMA", 2},
1293 new object [] {"ProcedureParameters", "Name", "@Name", "SPECIFIC_NAME", 3},
1294 new object [] {"ProcedureParameters", "Parameter", "@Parameter", "PARAMETER_NAME", 4},
1296 new object [] {"Procedures", "Catalog", "@Catalog", "SPECIFIC_CATALOG", 1},
1297 new object [] {"Procedures", "Owner", "@Owner", "SPECIFIC_SCHEMA", 2},
1298 new object [] {"Procedures", "Name", "@Name", "SPECIFIC_NAME", 3},
1299 new object [] {"Procedures", "Type", "@Type", "ROUTINE_TYPE", 4},
1301 new object [] {"IndexColumns", "Catalog", "@Catalog", "db_name(}", 1},
1302 new object [] {"IndexColumns", "Owner", "@Owner", "user_name(}", 2},
1303 new object [] {"IndexColumns", "Table", "@Table", "o.name", 3},
1304 new object [] {"IndexColumns", "ConstraintName", "@ConstraintName", "x.name", 4},
1305 new object [] {"IndexColumns", "Column", "@Column", "c.name", 5},
1307 new object [] {"Indexes", "Catalog", "@Catalog", "db_name(}", 1},
1308 new object [] {"Indexes", "Owner", "@Owner", "user_name(}", 2},
1309 new object [] {"Indexes", "Table", "@Table", "o.name", 3},
1310 new object [] {"Indexes", "Name", "@Name", "x.name", 4},
1312 new object [] {"UserDefinedTypes", "assembly_name", "@AssemblyName", "assemblies.name", 1},
1313 new object [] {"UserDefinedTypes", "udt_name", "@UDTName", "types.assembly_class", 2},
1315 new object [] {"ForeignKeys", "Catalog", "@Catalog", "CONSTRAINT_CATALOG", 1},
1316 new object [] {"ForeignKeys", "Owner", "@Owner", "CONSTRAINT_SCHEMA", 2},
1317 new object [] {"ForeignKeys", "Table", "@Table", "TABLE_NAME", 3},
1318 new object [] {"ForeignKeys", "Name", "@Name", "CONSTRAINT_NAME", 4}
1321 static DataTable instance;
1322 static public DataTable Instance {
1324 if (instance == null) {
1325 instance = new DataTable ("Restrictions");
1326 foreach (ColumnInfo c in columns)
1327 instance.Columns.Add (c.name, c.type);
1328 foreach (object [] row in rows)
1329 instance.LoadDataRow (row, true);
1336 public override DataTable GetSchema ()
1338 return MetaDataCollections.Instance;
1341 public override DataTable GetSchema (String collectionName)
1343 return GetSchema (collectionName, null);
1346 public override DataTable GetSchema (String collectionName, string [] restrictionValues)
1348 if (collectionName == null)
1349 //LAMESPEC: In MS.NET, if collectionName is null, it throws ArgumentException.
1350 throw new ArgumentException ();
1352 String cName = null;
1353 DataTable schemaTable = MetaDataCollections.Instance;
1354 int length = restrictionValues == null ? 0 : restrictionValues.Length;
1356 foreach (DataRow row in schemaTable.Rows) {
1357 if (String.Compare ((string) row["CollectionName"], collectionName, true) == 0) {
1358 if (length > (int) row["NumberOfRestrictions"]) {
1359 throw new ArgumentException ("More restrictions were provided " +
1360 "than the requested schema ('" +
1361 row["CollectionName"].ToString () + "') supports");
1363 cName = row["CollectionName"].ToString();
1367 throw new ArgumentException ("The requested collection ('" + collectionName + "') is not defined.");
1369 SqlCommand command = null;
1370 DataTable dataTable = new DataTable ();
1371 SqlDataAdapter dataAdapter = new SqlDataAdapter ();
1376 command = new SqlCommand ("select name as database_name, dbid, crdate as create_date " +
1377 "from master.sys.sysdatabases where (name = @Name or (@Name " +
1379 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1382 command = new SqlCommand ("select CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME, " +
1383 "TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE, " +
1384 "IS_DEFERRABLE, INITIALLY_DEFERRED from " +
1385 "INFORMATION_SCHEMA.TABLE_CONSTRAINTS where (CONSTRAINT_CATALOG" +
1386 " = @Catalog or (@Catalog is null)) and (CONSTRAINT_SCHEMA = " +
1387 "@Owner or (@Owner is null)) and (TABLE_NAME = @Table or (" +
1388 "@Table is null)) and (CONSTRAINT_NAME = @Name or (@Name is null))" +
1389 " and CONSTRAINT_TYPE = 'FOREIGN KEY' order by CONSTRAINT_CATALOG," +
1390 " CONSTRAINT_SCHEMA, CONSTRAINT_NAME", this);
1391 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1392 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1393 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1394 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1397 command = new SqlCommand ("select distinct db_name() as constraint_catalog, " +
1398 "constraint_schema = user_name (o.uid), " +
1399 "constraint_name = x.name, table_catalog = db_name (), " +
1400 "table_schema = user_name (o.uid), table_name = o.name, " +
1401 "index_name = x.name from sysobjects o, sysindexes x, " +
1402 "sysindexkeys xk where o.type in ('U') and x.id = o.id and " +
1403 "o.id = xk.id and x.indid = xk.indid and xk.keyno = x.keycnt " +
1404 "and (db_name() = @Catalog or (@Catalog is null)) and " +
1405 "(user_name() = @Owner or (@Owner is null)) and (o.name = " +
1406 "@Table or (@Table is null)) and (x.name = @Name or (@Name is null))" +
1407 "order by table_name, index_name", this);
1408 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1409 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1410 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1411 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1413 case "IndexColumns":
1414 command = new SqlCommand ("select distinct db_name() as constraint_catalog, " +
1415 "constraint_schema = user_name (o.uid), constraint_name = x.name, " +
1416 "table_catalog = db_name (), table_schema = user_name (o.uid), " +
1417 "table_name = o.name, column_name = c.name, " +
1418 "ordinal_position = convert (int, xk.keyno), keyType = c.xtype, " +
1419 "index_name = x.name from sysobjects o, sysindexes x, syscolumns c, " +
1420 "sysindexkeys xk where o.type in ('U') and x.id = o.id and o.id = c.id " +
1421 "and o.id = xk.id and x.indid = xk.indid and c.colid = xk.colid " +
1422 "and xk.keyno <= x.keycnt and permissions (o.id, c.name) <> 0 " +
1423 "and (db_name() = @Catalog or (@Catalog is null)) and (user_name() " +
1424 "= @Owner or (@Owner is null)) and (o.name = @Table or (@Table is" +
1425 " null)) and (x.name = @ConstraintName or (@ConstraintName is null)) " +
1426 "and (c.name = @Column or (@Column is null)) order by table_name, " +
1427 "index_name", this);
1428 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 8);
1429 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1430 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 13);
1431 command.Parameters.Add ("@ConstraintName", SqlDbType.NVarChar, 4000);
1432 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1435 command = new SqlCommand ("select SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, " +
1436 "ROUTINE_CATALOG, ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE, " +
1437 "CREATED, LAST_ALTERED from INFORMATION_SCHEMA.ROUTINES where " +
1438 "(SPECIFIC_CATALOG = @Catalog or (@Catalog is null)) and " +
1439 "(SPECIFIC_SCHEMA = @Owner or (@Owner is null)) and (SPECIFIC_NAME" +
1440 " = @Name or (@Name is null)) and (ROUTINE_TYPE = @Type or (@Type " +
1441 "is null)) order by SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME", this);
1442 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1443 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1444 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1445 command.Parameters.Add ("@Type", SqlDbType.NVarChar, 4000);
1447 case "ProcedureParameters":
1448 command = new SqlCommand ("select SPECIFIC_CATALOG, SPECIFIC_SCHEMA, SPECIFIC_NAME, " +
1449 "ORDINAL_POSITION, PARAMETER_MODE, IS_RESULT, AS_LOCATOR, " +
1450 "PARAMETER_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, " +
1451 "CHARACTER_OCTET_LENGTH, COLLATION_CATALOG, COLLATION_SCHEMA, " +
1452 "COLLATION_NAME, CHARACTER_SET_CATALOG, CHARACTER_SET_SCHEMA, " +
1453 "CHARACTER_SET_NAME, NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, " +
1454 "NUMERIC_SCALE, DATETIME_PRECISION, INTERVAL_TYPE, " +
1455 "INTERVAL_PRECISION from INFORMATION_SCHEMA.PARAMETERS where " +
1456 "(SPECIFIC_CATALOG = @Catalog or (@Catalog is null)) and " +
1457 "(SPECIFIC_SCHEMA = @Owner or (@Owner is null)) and (SPECIFIC_NAME = " +
1458 "@Name or (@Name is null)) and (PARAMETER_NAME = @Parameter or (" +
1459 "@Parameter is null)) order by SPECIFIC_CATALOG, SPECIFIC_SCHEMA," +
1460 " SPECIFIC_NAME, PARAMETER_NAME", this);
1461 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1462 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1463 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1464 command.Parameters.Add ("@Parameter", SqlDbType.NVarChar, 4000);
1467 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE " +
1468 "from INFORMATION_SCHEMA.TABLES where" +
1469 " (TABLE_CATALOG = @catalog or (@catalog is null)) and " +
1470 "(TABLE_SCHEMA = @owner or (@owner is null))and " +
1471 "(TABLE_NAME = @name or (@name is null)) and " +
1472 "(TABLE_TYPE = @table_type or (@table_type is null))", this);
1473 command.Parameters.Add ("@catalog", SqlDbType.NVarChar, 8);
1474 command.Parameters.Add ("@owner", SqlDbType.NVarChar, 3);
1475 command.Parameters.Add ("@name", SqlDbType.NVarChar, 11);
1476 command.Parameters.Add ("@table_type", SqlDbType.NVarChar, 10);
1479 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, " +
1480 "ORDINAL_POSITION, COLUMN_DEFAULT, IS_NULLABLE, DATA_TYPE, " +
1481 "CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH, " +
1482 "NUMERIC_PRECISION, NUMERIC_PRECISION_RADIX, NUMERIC_SCALE, " +
1483 "DATETIME_PRECISION, CHARACTER_SET_CATALOG, CHARACTER_SET_SCHEMA, " +
1484 "CHARACTER_SET_NAME, COLLATION_CATALOG from INFORMATION_SCHEMA.COLUMNS" +
1485 " where (TABLE_CATALOG = @Catalog or (@Catalog is null)) and (" +
1486 "TABLE_SCHEMA = @Owner or (@Owner is null)) and (TABLE_NAME = @table" +
1487 " or (@Table is null)) and (COLUMN_NAME = @column or (@Column is null" +
1488 ")) order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME", this);
1489 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1490 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1491 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1492 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1495 command = new SqlCommand ("select uid, name as user_name, createdate, updatedate from sysusers" +
1496 " where (name = @Name or (@Name is null))", this);
1497 command.Parameters.Add ("@Name", SqlDbType.NVarChar, 4000);
1500 command = new SqlCommand ("select TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CHECK_OPTION, " +
1501 "IS_UPDATABLE from INFORMATION_SCHEMA.VIEWS where (TABLE_CATALOG" +
1502 " = @Catalog or (@Catalog is null)) TABLE_SCHEMA = @Owner or " +
1503 "(@Owner is null)) and (TABLE_NAME = @table or (@Table is null))" +
1504 " order by TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME", this);
1505 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1506 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1507 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1510 command = new SqlCommand ("select VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME, TABLE_CATALOG, " +
1511 "TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME from " +
1512 "INFORMATION_SCHEMA.VIEW_COLUMN_USAGE where (VIEW_CATALOG = " +
1513 "@Catalog (@Catalog is null)) and (VIEW_SCHEMA = @Owner (@Owner" +
1514 " is null)) and (VIEW_NAME = @Table or (@Table is null)) and " +
1515 "(COLUMN_NAME = @Column or (@Column is null)) order by " +
1516 "VIEW_CATALOG, VIEW_SCHEMA, VIEW_NAME", this);
1517 command.Parameters.Add ("@Catalog", SqlDbType.NVarChar, 4000);
1518 command.Parameters.Add ("@Owner", SqlDbType.NVarChar, 4000);
1519 command.Parameters.Add ("@Table", SqlDbType.NVarChar, 4000);
1520 command.Parameters.Add ("@Column", SqlDbType.NVarChar, 4000);
1522 case "UserDefinedTypes":
1523 command = new SqlCommand ("select assemblies.name as assembly_name, types.assembly_class " +
1524 "as udt_name, ASSEMBLYPROPERTY(assemblies.name, 'VersionMajor') " +
1525 "as version_major, ASSEMBLYPROPERTY(assemblies.name, 'VersionMinor') " +
1526 "as version_minor, ASSEMBLYPROPERTY(assemblies.name, 'VersionBuild') " +
1527 "as version_build, ASSEMBLYPROPERTY(assemblies.name, 'VersionRevision') " +
1528 "as version_revision, ASSEMBLYPROPERTY(assemblies.name, 'CultureInfo') " +
1529 "as culture_info, ASSEMBLYPROPERTY(assemblies.name, 'PublicKey') " +
1530 "as public_key, is_fixed_length, max_length, Create_Date, " +
1531 "Permission_set_desc from sys.assemblies as assemblies join " +
1532 "sys.assembly_types as types on assemblies.assembly_id = types.assembly_id" +
1533 " where (assportemblies.name = @AssemblyName or (@AssemblyName is null)) and " +
1534 "(types.assembly_class = @UDTName or (@UDTName is null))",
1536 command.Parameters.Add ("@AssemblyName", SqlDbType.NVarChar, 4000);
1537 command.Parameters.Add ("@UDTName", SqlDbType.NVarChar, 4000);
1539 case "MetaDataCollections":
1540 return MetaDataCollections.Instance;
1541 case "DataSourceInformation":
1542 throw new NotImplementedException ();
1544 return DataTypes.Instance;
1545 case "ReservedWords":
1546 return ReservedWords.Instance;
1547 case "Restrictions":
1548 return Restrictions.Instance;
1550 for (int i = 0; i < length; i++) {
1551 command.Parameters[i].Value = restrictionValues[i];
1553 dataAdapter.SelectCommand = command;
1554 dataAdapter.Fill (dataTable);
1558 public static void ChangePassword (string connectionString, string newPassword)
1560 if (connectionString == null || newPassword == null || newPassword == String.Empty)
1561 throw new ArgumentNullException ();
1562 if (newPassword.Length > 128)
1563 throw new ArgumentException ("The value of newPassword exceeds its permittable length which is 128");
1564 using (SqlConnection conn = new SqlConnection (connectionString)) {
1566 conn.tds.Execute (String.Format ("sp_password '{0}', '{1}', '{2}'",
1567 conn.parms.Password, newPassword, conn.parms.User));
1572 #endregion // Methods
1575 #region Fields Net 2
1579 #endregion // Fields Net 2
1581 #region Properties Net 2
1584 [DataSysDescription ("Enable Asynchronous processing, 'Asynchrouse Processing=true/false' in the ConnectionString.")]
1586 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
1587 internal bool AsyncProcessing {
1588 get { return async; }
1591 #endregion // Properties Net 2