Merge pull request #2721 from ludovic-henry/fix-mono_ms_ticks
[mono.git] / mcs / class / System.Data.OracleClient / System.Data.OracleClient / OracleConnection.cs
1 //
2 // OracleConnection.cs 
3 //
4 // Part of the Mono class libraries at
5 // mcs/class/System.Data.OracleClient/System.Data.OracleClient
6 //
7 // Assembly: System.Data.OracleClient.dll
8 // Namespace: System.Data.OracleClient
9 //
10 // Authors: 
11 //    Daniel Morgan <monodanmorg@yahoo.com>
12 //    Tim Coleman <tim@timcoleman.com>
13 //    Hubert FONGARNAND <informatique.internet@fiducial.fr>
14 //    Marek Safar <marek.safar@gmail.com>
15 //
16 // Copyright (C) Daniel Morgan, 2002, 2005, 2006, 2009
17 // Copyright (C) Tim Coleman, 2003
18 // Copyright (C) Hubert FONGARNAND, 2005
19 //
20 // Original source code for setting ConnectionString 
21 // by Tim Coleman <tim@timcoleman.com>
22 //
23 // Copyright (C) Tim Coleman, 2002
24 //
25 // Licensed under the MIT/X11 License.
26 //
27
28 //#define ORACLE_DATA_ACCESS
29 // define ORACLE_DATA_ACCESS for Oracle.DataAccess functionality
30 // otherwise it defaults to Microsoft's System.Data.OracleClient
31
32 using System;
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.ComponentModel;
36 using System.Data;
37 using System.Data.OracleClient.Oci;
38 using System.Drawing.Design;
39 using System.EnterpriseServices;
40 using System.Globalization;
41 using System.Text;
42
43 //#if ORACLE_DATA_ACCESS
44 //namespace Oracle.DataAccess
45 //#else
46 namespace System.Data.OracleClient
47 //#endif
48 {
49         internal struct OracleConnectionInfo
50         {
51                 internal string Username;
52                 internal string Password;
53                 internal string Database;
54                 internal string ConnectionString;
55                 internal OciCredentialType CredentialType;
56                 internal bool SetNewPassword;
57                 internal string NewPassword;
58         }
59
60         [DefaultEvent ("InfoMessage")]
61         public sealed class OracleConnection :
62                 Common.DbConnection, ICloneable
63         {
64                 #region Fields
65
66                 OciGlue oci;
67                 ConnectionState state;
68                 OracleConnectionInfo conInfo;
69                 OracleTransaction transaction;
70                 string connectionString = String.Empty;
71                 string parsedConnectionString;
72                 OracleDataReader dataReader;
73                 bool pooling = true;
74                 static OracleConnectionPoolManager pools = new OracleConnectionPoolManager ();
75                 OracleConnectionPool pool;
76                 int minPoolSize;
77                 int maxPoolSize = 100;
78                 byte persistSecurityInfo = 1;
79                 bool disposed;
80                 IFormatProvider format_info;
81
82                 #endregion // Fields
83
84                 #region Constructors
85
86                 public OracleConnection ()
87                 {
88                         state = ConnectionState.Closed;
89                 }
90
91                 public OracleConnection (string connectionString)
92                         : this()
93                 {
94                         SetConnectionString (connectionString, false);
95                 }
96
97                 #endregion // Constructors
98
99                 #region Properties
100
101                 [MonoTODO ("Currently not respected.")]
102                 public override int ConnectionTimeout {
103                         get { return 0; }
104                 }
105
106                 [Browsable (false)]
107                 [EditorBrowsable (EditorBrowsableState.Never)]
108                 public override string Database {
109                         [MonoTODO]
110                         get { return String.Empty; }
111                 }
112
113                 internal OracleDataReader DataReader {
114                         get { return dataReader; }
115                         set { dataReader = value; }
116                 }
117
118                 internal OciEnvironmentHandle Environment {
119                         get { return oci.Environment; }
120                 }
121
122                 internal OciErrorHandle ErrorHandle {
123                         get { return oci.ErrorHandle; }
124                 }
125
126                 internal OciServiceHandle ServiceContext {
127                         get { return oci.ServiceContext; }
128                 }
129
130                 internal OciSessionHandle Session {
131                         get { return oci.SessionHandle; }
132                 }
133
134                 [Browsable (false)]
135                 [MonoTODO]
136                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
137                 public
138                 override
139                 string DataSource {
140                         get {
141                                 return conInfo.Database;
142                         }
143                 }
144
145                 [Browsable (false)]
146                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
147                 public
148                 override
149                 ConnectionState State {
150                         get { return state; }
151                 }
152
153                 [DefaultValue ("")]
154                 [SettingsBindableAttribute (true)]
155                 [RefreshProperties (RefreshProperties.All)]
156                 [Editor ("Microsoft.VSDesigner.Data.Oracle.Design.OracleConnectionStringEditor, " + Consts.AssemblyMicrosoft_VSDesigner, typeof(UITypeEditor))]
157                 public
158                 override
159                 string ConnectionString {
160                         get {
161                                 if (parsedConnectionString == null)
162                                         return string.Empty;
163                                 return parsedConnectionString;
164                         }
165                         set {
166                                 SetConnectionString (value, false);
167                         }
168                 }
169
170                 [MonoTODO]
171                 [Browsable (false)]
172                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
173                 public
174                 override
175                 string ServerVersion {
176                         get {
177                                 if (this.State != ConnectionState.Open)
178                                         throw new System.InvalidOperationException ("Invalid operation. The connection is closed.");
179                                 return GetOracleVersion ();
180                         }
181                 }
182
183                 internal string GetOracleVersion ()
184                 {
185                         byte[] buffer = new Byte[256];
186                         uint bufflen = (uint) buffer.Length;
187
188                         IntPtr sh = oci.ServiceContext;
189                         IntPtr eh = oci.ErrorHandle;
190
191                         OciCalls.OCIServerVersion (sh, eh, ref buffer,  bufflen, OciHandleType.Service);
192                         
193                         // Get length of returned string
194                         int     rsize = 0;
195                         IntPtr  env = oci.Environment;
196                         OciCalls.OCICharSetToUnicode (env, null, buffer, out rsize);
197                         
198                         // Get string
199                         StringBuilder ret = new StringBuilder(rsize);
200                         OciCalls.OCICharSetToUnicode (env, ret, buffer, out rsize);
201
202                         return ret.ToString ();
203                 }
204
205                 internal OciGlue Oci {
206                         get { return oci; }
207                 }
208
209                 internal OracleTransaction Transaction {
210                         get { return transaction; }
211                         set { transaction = value; }
212                 }
213                 
214                 #endregion // Properties
215
216                 #region Methods
217
218                 public
219                 new
220                 OracleTransaction BeginTransaction ()
221                 {
222                         return BeginTransaction (IsolationLevel.ReadCommitted);
223                 }
224
225                 public
226                 new
227                 OracleTransaction BeginTransaction (IsolationLevel il)
228                 {
229                         if (state == ConnectionState.Closed)
230                                 throw new InvalidOperationException ("The connection is not open.");
231                         if (transaction != null)
232                                 throw new InvalidOperationException ("OracleConnection does not support parallel transactions.");
233
234                         OciTransactionHandle transactionHandle = oci.CreateTransaction ();
235                         if (transactionHandle == null) 
236                                 throw new Exception("Error: Unable to start transaction");
237                         else {
238                                 transactionHandle.Begin ();
239                                 transaction = new OracleTransaction (this, il, transactionHandle);
240                         }
241
242                         return transaction;
243                 }
244
245                 [MonoTODO]
246                 public override void ChangeDatabase (string value)
247                 {
248                         throw new NotImplementedException ();
249                 }
250
251                 public
252                 new
253                 OracleCommand CreateCommand ()
254                 {
255                         OracleCommand command = new OracleCommand ();
256                         command.Connection = this;
257                         return command;
258                 }
259
260                 [MonoTODO]
261                 object ICloneable.Clone ()
262                 {
263                         OracleConnection con = new OracleConnection ();
264                         con.SetConnectionString (connectionString, true);
265                         // TODO: what other properties need to be cloned?
266                         return con;
267                 }
268
269
270                 [MonoTODO]
271                 protected override void Dispose (bool disposing)
272                 {
273                         if (!disposed) {
274                                 if (State == ConnectionState.Open)
275                                         Close ();
276                                 dataReader = null;
277                                 transaction = null;
278                                 oci = null;
279                                 pool = null;
280                                 conInfo.Username = string.Empty;
281                                 conInfo.Database = string.Empty;
282                                 conInfo.Password = string.Empty;
283                                 connectionString = null;
284                                 parsedConnectionString = null;
285                                 base.Dispose (disposing);
286                                 disposed = true;
287                         }
288                 }
289
290                 [MonoTODO]
291                 public void EnlistDistributedTransaction (ITransaction distributedTransaction)
292                 {
293                         throw new NotImplementedException ();
294                 }
295
296                 // Get NLS_DATE_FORMAT string from Oracle server
297                 internal string GetSessionDateFormat ()
298                 {
299                         // 23 is 22 plus 1 for NUL terminated character
300                         // a DATE format has a max size of 22
301                         return GetNlsInfo (Session, 23, OciNlsServiceType.DATEFORMAT);
302                 }
303
304                 // Get NLS Info
305                 //
306                 // handle = OciEnvironmentHandle or OciSessionHandle
307                 // bufflen = Length of byte buffer to allocate to retrieve the NLS info
308                 // item = OciNlsServiceType enum value
309                 //
310                 // if unsure how much you need, use OciNlsServiceType.MAXBUFSZ
311                 internal string GetNlsInfo (OciHandle handle, uint bufflen, OciNlsServiceType item)
312                 {
313                         byte[] buffer = new Byte[bufflen];
314
315                         OciCalls.OCINlsGetInfo (handle, ErrorHandle, 
316                                 ref buffer, bufflen, (ushort) item);
317
318                         // Get length of returned string
319                         int rsize = 0;
320                         OciCalls.OCICharSetToUnicode (Environment, null, buffer, out rsize);
321                         
322                         // Get string
323                         StringBuilder ret = new StringBuilder (rsize);
324                         OciCalls.OCICharSetToUnicode (Environment, ret, buffer, out rsize);
325
326                         return ret.ToString ();
327                 }
328
329                 // An instance of IFormatProvider for locale - independent IFormattable.ToString () in Bind ()
330                 [MonoTODO("Handle other culture-specific informations, restrict buffer sizes")]
331                 internal IFormatProvider SessionFormatProvider {
332                         get {
333                                 if (format_info == null && state == ConnectionState.Open) {
334                                         NumberFormatInfo numberFormatInfo = new NumberFormatInfo ();
335                                         numberFormatInfo.NumberGroupSeparator
336                                         = GetNlsInfo (Session, (uint)OciNlsServiceType.MAXBUFSZ, OciNlsServiceType.GROUP);
337                                         numberFormatInfo.NumberDecimalSeparator
338                                         = GetNlsInfo (Session, (uint)OciNlsServiceType.MAXBUFSZ, OciNlsServiceType.DECIMAL);
339                                         numberFormatInfo.CurrencyGroupSeparator
340                                         = GetNlsInfo (Session, (uint)OciNlsServiceType.MAXBUFSZ, OciNlsServiceType.MONGROUP);
341                                         numberFormatInfo.CurrencyDecimalSeparator
342                                         = GetNlsInfo (Session, (uint)OciNlsServiceType.MAXBUFSZ, OciNlsServiceType.MONDECIMAL);
343                                         format_info = numberFormatInfo;
344                                 }
345                                 return format_info;
346                         }
347                 }
348
349                 public
350                 override
351                 void Open ()
352                 {
353                         if (State == ConnectionState.Open)
354                                 return;
355
356                         PersistSecurityInfo ();
357
358                         if (!pooling || conInfo.SetNewPassword == true) {
359                                 oci = new OciGlue ();
360                                 oci.CreateConnection (conInfo);
361                         } else {
362                                 pool = pools.GetConnectionPool (conInfo, minPoolSize, maxPoolSize);
363                                 oci = pool.GetConnection ();
364                         }
365                         state = ConnectionState.Open;
366
367                         CreateStateChange (ConnectionState.Closed, ConnectionState.Open);
368                 }
369
370 #if ORACLE_DATA_ACCESS
371                 public void OpenWithNewPassword (string newPassword) 
372                 {
373                         if (State == ConnectionState.Open)
374                                 throw new InvalidOperationException ();
375
376                         conInfo.SetNewPassword = true;
377                         conInfo.NewPassword = newPassword;
378
379                         Open ();
380
381                         conInfo.SetNewPassword = false;
382                         conInfo.NewPassword = string.Empty;
383                         conInfo.Password = newPassword;
384                 }
385 #endif
386
387                 internal void CreateInfoMessage (OciErrorInfo info)
388                 {
389                         OracleInfoMessageEventArgs a = new OracleInfoMessageEventArgs (info);
390                         OnInfoMessage (a);
391                 }
392
393                 private void OnInfoMessage (OracleInfoMessageEventArgs e)
394                 {
395                         if (InfoMessage != null)
396                                 InfoMessage (this, e);
397                 }
398
399                 internal void CreateStateChange (ConnectionState original, ConnectionState current)
400                 {
401                         StateChangeEventArgs a = new StateChangeEventArgs (original, current);
402                         OnStateChange (a);
403                 }
404
405
406                 public
407                 override
408                 void Close ()
409                 {
410                         if (transaction != null)
411                                 transaction.Rollback ();
412
413                         if (!pooling)
414                                 oci.Disconnect ();
415                         else if (pool != null)
416                                 pool.ReleaseConnection (oci);
417
418                         state = ConnectionState.Closed;
419                         CreateStateChange (ConnectionState.Open, ConnectionState.Closed);
420                 }
421
422                 protected override Common.DbTransaction BeginDbTransaction (IsolationLevel isolationLevel)
423                 {
424                         return BeginTransaction (isolationLevel);
425                 }
426                 
427                 protected override Common.DbCommand CreateDbCommand ()
428                 {
429                         return CreateCommand ();
430                 }
431
432                 private void PersistSecurityInfo ()
433                 {
434                         // persistSecurityInfo:
435                         // 0 = true/yes
436                         // 1 = false/no (have not parsed out password yet)
437                         // 2 = like 1, but have parsed out password
438
439                         if (persistSecurityInfo == 0 || persistSecurityInfo == 2)
440                                 return;
441
442                         persistSecurityInfo = 2;
443
444                         if (connectionString == null || connectionString.Length == 0)
445                                 return;
446
447                         string conString = connectionString + ";";
448
449                         bool inQuote = false;
450                         bool inDQuote = false;
451                         int inParen = 0;
452
453                         string name = String.Empty;
454                         StringBuilder sb = new StringBuilder ();
455                         int nStart = 0;
456                         int nFinish = 0;
457                         int i = -1;
458
459                         foreach (char c in conString) {
460                                 i ++;
461
462                                 switch (c) {
463                                 case '\'':
464                                         inQuote = !inQuote;
465                                         break;
466                                 case '"' :
467                                         inDQuote = !inDQuote;
468                                         break;
469                                 case '(':
470                                         inParen++;
471                                         sb.Append (c);
472                                         break;
473                                 case ')':
474                                         inParen--;
475                                         sb.Append (c);
476                                         break;
477                                 case ';' :
478                                         if (!inDQuote && !inQuote) {
479                                                 if (name != String.Empty && name != null) {
480                                                         name = name.ToUpper ().Trim ();
481                                                         if (name.Equals ("PASSWORD") || name.Equals ("PWD")) {
482                                                                 nFinish = i;
483                                                                 string part1 = String.Empty;
484                                                                 string part3 = String.Empty;
485                                                                 sb = new StringBuilder ();
486                                                                 if (nStart > 0) {
487                                                                         part1 = conString.Substring (0, nStart);
488                                                                         if (part1[part1.Length - 1] == ';')
489                                                                                 part1 = part1.Substring (0, part1.Length - 1);
490                                                                         sb.Append (part1);
491                                                                 }
492                                                                 if (!part1.Equals (String.Empty))
493                                                                         sb.Append (';');
494                                                                 if (conString.Length - nFinish - 1 > 0) {
495                                                                         part3 = conString.Substring (nFinish, conString.Length - nFinish);
496                                                                         if (part3[0] == ';')  
497                                                                                 part3 = part3.Substring(1, part3.Length - 1);
498                                                                         sb.Append (part3);
499                                                                 }
500                                                                 parsedConnectionString = sb.ToString ();
501                                                                 return;
502                                                         }
503                                                 }
504                                                 name = String.Empty;
505                                                 sb = new StringBuilder ();
506                                                 nStart = i;
507                                                 nFinish = i;
508                                         }
509                                         else
510                                                 sb.Append (c);
511                                         break;
512                                 case '=' :
513                                         if (!inDQuote && !inQuote && inParen == 0) {
514                                                 name = sb.ToString ();
515                                                 sb = new StringBuilder ();
516                                         }
517                                         else
518                                                 sb.Append (c);
519                                         break;
520                                 default:
521                                         sb.Append (c);
522                                         break;
523                                 }
524                         }
525                 }
526
527                 internal void SetConnectionString (string connectionString, bool persistSecurity)
528                 {
529                         persistSecurityInfo = 1;
530
531                         conInfo.Username = string.Empty;
532                         conInfo.Database = string.Empty;
533                         conInfo.Password = string.Empty;
534                         conInfo.CredentialType = OciCredentialType.RDBMS;
535                         conInfo.SetNewPassword = false;
536                         conInfo.NewPassword = string.Empty;
537
538                         if (connectionString == null || connectionString.Length == 0) {
539                                 this.connectionString = connectionString;
540                                 this.parsedConnectionString = connectionString;
541                                 return;
542                         }
543
544                         this.connectionString = String.Copy (connectionString);
545                         this.parsedConnectionString = this.connectionString;
546
547                         connectionString += ";";
548                         NameValueCollection parameters = new NameValueCollection ();
549
550                         bool inQuote = false;
551                         bool inDQuote = false;
552                         int inParen = 0;
553
554                         string name = String.Empty;
555                         string value = String.Empty;
556                         StringBuilder sb = new StringBuilder ();
557
558                         foreach (char c in connectionString) {
559                                 switch (c) {
560                                 case '\'':
561                                         inQuote = !inQuote;
562                                         break;
563                                 case '"' :
564                                         inDQuote = !inDQuote;
565                                         break;
566                                 case '(':
567                                         inParen++;
568                                         sb.Append (c);
569                                         break;
570                                 case ')':
571                                         inParen--;
572                                         sb.Append (c);
573                                         break;
574                                 case ';' :
575                                         if (!inDQuote && !inQuote) {
576                                                 if (name != String.Empty && name != null) {
577                                                         name = name.ToUpper ().Trim ();
578                                                         value = sb.ToString ().Trim ();
579                                                         parameters [name] = value;
580                                                 }
581                                                 name = String.Empty;
582                                                 value = String.Empty;
583                                                 sb = new StringBuilder ();
584                                         }
585                                         else
586                                                 sb.Append (c);
587                                         break;
588                                 case '=' :
589                                         if (!inDQuote && !inQuote && inParen == 0) {
590                                                 name = sb.ToString ();
591                                                 sb = new StringBuilder ();
592                                         }
593                                         else
594                                                 sb.Append (c);
595                                         break;
596                                 default:
597                                         sb.Append (c);
598                                         break;
599                                 }
600                         }
601
602                         SetProperties (parameters);
603
604                         conInfo.ConnectionString = this.connectionString;
605
606                         if (persistSecurity)
607                                 PersistSecurityInfo ();
608                 }
609
610                 private void SetProperties (NameValueCollection parameters)
611                 {
612                         string value;
613                         foreach (string name in parameters) {
614                                 value = parameters[name];
615
616                                 switch (name) {
617                                 case "UNICODE":
618                                         break;
619                                 case "ENLIST":
620                                         break;
621                                 case "CONNECTION LIFETIME":
622                                         // TODO:
623                                         break;
624                                 case "INTEGRATED SECURITY":
625                                         if (!ConvertToBoolean ("integrated security", value))
626                                                 conInfo.CredentialType = OciCredentialType.RDBMS;
627                                         else
628                                                 conInfo.CredentialType = OciCredentialType.External;
629                                         break;
630                                 case "PERSIST SECURITY INFO":
631                                         if (!ConvertToBoolean ("persist security info", value))
632                                                 persistSecurityInfo = 1;
633                                         else
634                                                 persistSecurityInfo = 0;
635                                         break;
636                                 case "MIN POOL SIZE":
637                                         minPoolSize = int.Parse (value);
638                                         break;
639                                 case "MAX POOL SIZE":
640                                         maxPoolSize = int.Parse (value);
641                                         break;
642                                 case "DATA SOURCE" :
643                                 case "SERVER" :
644                                         conInfo.Database = value;
645                                         break;
646                                 case "PASSWORD" :
647                                 case "PWD" :
648                                         conInfo.Password = value;
649                                         break;
650                                 case "UID" :
651                                 case "USER ID" :
652                                         conInfo.Username = value;
653                                         break;
654                                 case "POOLING" :
655                                         pooling = ConvertToBoolean("pooling", value);
656                                         break;
657                                 default:
658                                         throw new ArgumentException("Connection parameter not supported: '" + name + "'");
659                                 }
660                         }
661                 }
662
663                 private bool ConvertToBoolean(string key, string value)
664                 {
665                         string upperValue = value.ToUpper();
666
667                         if (upperValue == "TRUE" || upperValue == "YES") {
668                                 return true;
669                         } else if (upperValue == "FALSE" || upperValue == "NO") {
670                                 return false;
671                         }
672
673                         throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
674                                 "Invalid value \"{0}\" for key '{1}'.", value, key));
675                 }
676
677                 #endregion // Methods
678
679                 public event OracleInfoMessageEventHandler InfoMessage;
680
681                 public override DataTable GetSchema ()
682                 {
683                         if (State != ConnectionState.Open)
684                                 throw new InvalidOperationException ("Invalid operation.  The connection is closed.");
685
686                         return GetSchemaMetaDataCollections ();
687                 }
688
689                 public override DataTable GetSchema (String collectionName)
690                 {
691                         return GetSchema (collectionName, null);
692                 }
693
694                 public override DataTable GetSchema (String collectionName, string [] restrictionValues)
695                 {
696                         if (State != ConnectionState.Open)
697                                 throw new InvalidOperationException ("Invalid operation.  The connection is closed.");
698
699                         int restrictionsCount = 0;
700                         if (restrictionValues != null)
701                                 restrictionsCount = restrictionValues.Length;
702
703                         DataTable metaTable = GetSchemaMetaDataCollections ();
704                         foreach (DataRow row in metaTable.Rows) {
705                                 if (String.Compare (row ["CollectionName"].ToString (), collectionName, true) == 0) {
706                                     int restrictions = (int)row ["NumberOfRestrictions"];
707                                     if (restrictionsCount > restrictions)
708                                         throw new ArgumentException ("More restrictions were provided than needed.");
709                                 }
710                         }
711
712                         switch (collectionName.ToUpper ()) {
713                         case "METADATACOLLECTIONS":
714                                 return metaTable;
715                         case "DATASOURCEINFORMATION":
716                                 return GetSchemaDataSourceInformation ();
717                         case "DATATYPES":
718                                 return GetSchemaDataTypes ();
719                         case "RESTRICTIONS":
720                                 return GetSchemaRestrictions ();
721                         case "RESERVEDWORDS":
722                                 return GetSchemaReservedWords ();
723                         case "USERS":
724                                 return GetSchemaUsers (restrictionValues);
725                         case "TABLES":
726                                 return GetSchemaTables (restrictionValues);
727                         case "COLUMNS":
728                                 return GetSchemaColumns (restrictionValues);
729                         case "VIEWS":
730                                 return GetSchemaViews (restrictionValues);
731                         case "SYNONYMS":
732                                 return GetSchemaSynonyms (restrictionValues);
733                         case "SEQUENCES":
734                                 return GetSchemaSequences (restrictionValues);
735                         case "FUNCTIONS":
736                                 return GetSchemaProcedures (restrictionValues, "FUNCTION");
737                         case "PACKAGES":
738                                 return GetSchemaProcedures (restrictionValues, "PACKAGE");
739                         case "PACKAGEBODIES":
740                                 return GetSchemaProcedures (restrictionValues, "PACKAGE BODY");
741                         case "PROCEDURES":
742                                 return GetSchemaProcedures (restrictionValues, "PROCEDURE");
743                         case "PROCEDUREPARAMETERS":
744                                 throw new NotImplementedException (collectionName); // see ALL_ARGUMENTS
745                         case "ARGUMENTS":
746                                 throw new NotImplementedException (collectionName); // see ALL_ARGUMENTS
747                         case "INDEXCOLUMNS":
748                                 throw new NotImplementedException (collectionName); // see ALL_IND_COLS
749                         case "INDEXES":
750                                 throw new NotImplementedException (collectionName); // see ALL_INDEXES
751                         case "UNIQUEKEYS":
752                                 throw new NotImplementedException (collectionName); // see ALL_CONSTRAINTS and CONSTRAINT_TYPE of U
753                         case "PRIMARYKEYS":
754                                 throw new NotImplementedException (collectionName); // see ALL_CONSTRAINTS and CONSTRAINT_TYPE of P
755                         case "FOREIGNKEYS":
756                                 throw new NotImplementedException (collectionName); // see ALL_CONSTRAINTS and CONSTRAINT_TYPE of R
757                         case "FOREIGNKEYCOLUMNS":
758                                 throw new NotImplementedException (collectionName); // see ALL_CONS_COLUMNS
759                         }
760
761                         throw new ArgumentException ("The requested collection is not defined.");
762                 }
763
764                 static DataTable metaDataCollections = null;
765                 DataTable GetSchemaMetaDataCollections ()
766                 {
767                         if (metaDataCollections != null)
768                                 return metaDataCollections;
769
770                         DataTable dt = new DataTable ();
771
772                         dt.Columns.Add ("CollectionName", typeof(System.String));
773                         dt.Columns.Add ("NumberOfRestrictions", typeof(System.Int32));
774                         dt.Columns.Add ("NumberOfIdentifierParts", typeof(System.Int32));
775
776                         dt.LoadDataRow (new object [] { "MetaDataCollections", 0, 0 }, true);
777                         dt.LoadDataRow (new object [] { "DataSourceInformation", 0, 0 }, true);
778                         dt.LoadDataRow (new object [] { "DataTypes", 0, 0 }, true);
779                         dt.LoadDataRow (new object [] { "Restrictions", 0, 0 }, true);
780                         dt.LoadDataRow (new object [] { "ReservedWords", 0, 0 }, true);
781                         dt.LoadDataRow (new object [] { "Users", 1, 1 }, true);
782                         dt.LoadDataRow (new object [] { "Tables", 2, 2 }, true);
783                         dt.LoadDataRow (new object [] { "Columns", 3, 3 }, true);
784                         dt.LoadDataRow (new object [] { "Views", 2, 2 }, true);
785                         dt.LoadDataRow (new object [] { "Synonyms", 2, 2 }, true);
786                         dt.LoadDataRow (new object [] { "Sequences", 2, 2 }, true);
787                         dt.LoadDataRow (new object [] { "ProcedureParameters", 2, 2 }, true);
788                         dt.LoadDataRow (new object [] { "Functions", 2, 2 }, true);
789                         dt.LoadDataRow (new object [] { "IndexColumns", 5, 3 }, true);
790                         dt.LoadDataRow (new object [] { "Indexes", 4, 2 }, true);
791                         dt.LoadDataRow (new object [] { "Packages", 2, 2 }, true);
792                         dt.LoadDataRow (new object [] { "PackageBodies", 2, 2 }, true);
793                         dt.LoadDataRow (new object [] { "Arguments", 4, 4 }, true);
794                         dt.LoadDataRow (new object [] { "Procedures", 2, 2 }, true);
795                         dt.LoadDataRow (new object [] { "UniqueKeys", 3, 3 }, true);
796                         dt.LoadDataRow (new object [] { "PrimaryKeys", 3, 3 }, true);
797                         dt.LoadDataRow (new object [] { "ForeignKeys", 3, 3 }, true);
798                         dt.LoadDataRow (new object [] { "ForeignKeyColumns", 3, 2 }, true);
799
800                         return dt;
801                 }
802
803                 DataTable GetSchemaRestrictions ()
804                 {
805                         DataTable dt = new DataTable ();
806
807                         dt.Columns.Add ("CollectionName", typeof (System.String));
808                         dt.Columns.Add ("RestrictionName", typeof (System.String));
809                         dt.Columns.Add ("ParameterName", typeof (System.String));
810                         dt.Columns.Add ("RestrictionDefault", typeof (System.String));
811                         dt.Columns.Add ("RestrictionNumber", typeof (System.Int32));
812
813                         dt.LoadDataRow (new object [] { "Users", "UserName", "NAME", "USERNAME", 1 }, true);
814                         dt.LoadDataRow (new object [] { "Tables", "Owner", "OWNER", "OWNER", 1 }, true);
815                         dt.LoadDataRow (new object [] { "Tables", "Table", "TABLENAME", "TABLE_NAME", 2 }, true);
816                         dt.LoadDataRow (new object [] { "Columns", "Owner", "OWNER", "OWNER", 1 }, true);
817                         dt.LoadDataRow (new object [] { "Columns", "Table", "TABLENAME", "TABLE_NAME", 2 }, true);
818                         dt.LoadDataRow (new object [] { "Columns", "Column", "COLUMNNAME", "COLUMN_NAME", 3 }, true);
819                         dt.LoadDataRow (new object [] { "Views", "Owner", "OWNER", "OWNER", 1 }, true);
820                         dt.LoadDataRow (new object [] { "Views", "View", "VIEWNAME", "VIEW_NAME", 2 }, true);
821                         dt.LoadDataRow (new object [] { "Synonyms", "Owner", "OWNER", "OWNER", 1 }, true);
822                         dt.LoadDataRow (new object [] { "Synonyms", "Synonym", "SYNONYMNAME", "SYNONYM_NAME", 2 }, true);
823                         dt.LoadDataRow (new object [] { "Sequences", "Owner", "OWNER", "SEQUENCE_OWNER", 1 }, true);
824                         dt.LoadDataRow (new object [] { "Sequences", "Sequence", "SEQUENCE", "SEQUENCE_NAME", 2 }, true);
825                         dt.LoadDataRow (new object [] { "ProcedureParameters", "Owner", "OWNER", "OWNER", 1 }, true);
826                         dt.LoadDataRow (new object [] { "ProcedureParameters", "ObjectName", "OBJECTNAME", "OBJECT_NAME", 2 }, true);
827                         dt.LoadDataRow (new object [] { "Functions", "Owner", "OWNER", "OWNER", 1 }, true);
828                         dt.LoadDataRow (new object [] { "Functions", "Name", "NAME", "OBJECT_NAME", 2 }, true);
829                         dt.LoadDataRow (new object [] { "IndexColumns", "Owner", "OWNER", "INDEX_OWNER", 1 }, true);
830                         dt.LoadDataRow (new object [] { "IndexColumns", "Name", "NAME", "INDEX_NAME", 2 }, true);
831                         dt.LoadDataRow (new object [] { "IndexColumns", "TableOwner", "TABLEOWNER", "TABLE_OWNER", 3 }, true);
832                         dt.LoadDataRow (new object [] { "IndexColumns", "TableName", "TABLENAME", "TABLE_NAME", 4 }, true);
833                         dt.LoadDataRow (new object [] { "IndexColumns", "Column", "COLUMNNAME", "COLUMN_NAME", 5 }, true);
834                         dt.LoadDataRow (new object [] { "Indexes", "Owner", "OWNER", "OWNER", 1 }, true);
835                         dt.LoadDataRow (new object [] { "Indexes", "Name", "NAME", "INDEX_NAME", 2 }, true);
836                         dt.LoadDataRow (new object [] { "Indexes", "TableOwner", "TABLEOWNER", "TABLE_OWNER", 3 }, true);
837                         dt.LoadDataRow (new object [] { "Indexes", "TableName", "TABLENAME", "TABLE_NAME", 4 }, true);
838                         dt.LoadDataRow (new object [] { "Packages", "Owner", "OWNER", "OWNER", 1 }, true);
839                         dt.LoadDataRow (new object [] { "Packages", "Name", "PACKAGENAME", "OBJECT_NAME", 2 }, true);
840                         dt.LoadDataRow (new object [] { "PackageBodies", "Owner", "OWNER", "OWNER", 1 }, true);
841                         dt.LoadDataRow (new object [] { "PackageBodies", "Name", "NAME", "OBJECT_NAME", 2 }, true);
842                         dt.LoadDataRow (new object [] { "Arguments", "Owner", "OWNER", "OWNER", 1 }, true);
843                         dt.LoadDataRow (new object [] { "Arguments", "PackageName", "PACKAGENAME", "PACKAGE_NAME", 2 }, true);
844                         dt.LoadDataRow (new object [] { "Arguments", "ObjectName", "OBJECTNAME", "OBJECT_NAME", 3 }, true);
845                         dt.LoadDataRow (new object [] { "Arguments", "ArgumentName", "ARGUMENTNAME", "ARGUMENT_NAME", 4 }, true);
846                         dt.LoadDataRow (new object [] { "Procedures", "Owner", "OWNER", "OWNER", 1 }, true);
847                         dt.LoadDataRow (new object [] { "Procedures", "Name", "NAME", "OBJECT_NAME", 2 }, true);
848                         dt.LoadDataRow (new object [] { "UniqueKeys", "Owner", "OWNER", "OWNER", 1 }, true);
849                         dt.LoadDataRow (new object [] { "UniqueKeys", "Table_Name", "TABLENAME", "TABLE_NAME", 2 }, true);
850                         dt.LoadDataRow (new object [] { "UniqueKeys", "Constraint_Name", "CONSTRAINTNAME", "CONSTRAINT_NAME", 3 }, true);
851                         dt.LoadDataRow (new object [] { "PrimaryKeys", "Owner", "OWNER", "OWNER", 1 }, true);
852                         dt.LoadDataRow (new object [] { "PrimaryKeys", "Table_Name", "TABLENAME", "TABLE_NAME", 2 }, true);
853                         dt.LoadDataRow (new object [] { "PrimaryKeys", "Constraint_Name", "CONSTRAINTNAME", "CONSTRAINT_NAME", 3 }, true);
854                         dt.LoadDataRow (new object [] { "ForeignKeys", "Foreign_Key_Owner", "OWNER", "FKCON.OWNER", 1 }, true);
855                         dt.LoadDataRow (new object [] { "ForeignKeys", "Foreign_Key_Table_Name", "TABLENAME", "FKCON.TABLE_NAME", 2 }, true);
856                         dt.LoadDataRow (new object [] { "ForeignKeys", "Foreign_Key_Constraint_Name", "CONSTRAINTNAME", "FKCON.CONSTRAINT_NAME", 3 }, true);
857                         dt.LoadDataRow (new object [] { "ForeignKeyColumns", "Owner", "OWNER", "FKCOLS.OWNER", 1 }, true);
858                         dt.LoadDataRow (new object [] { "ForeignKeyColumns", "Table_Name", "TABLENAME", "FKCOLS.TABLE_NAME", 2 }, true);
859                         dt.LoadDataRow (new object [] { "ForeignKeyColumns", "Constraint_Name", "CONSTRAINTNAME", "FKCOLS.CONSTRAINT_NAME", 3 }, true);
860
861                         return dt;
862                 }
863
864                 DataTable GetSchemaTables (string [] restrictionValues)
865                 {
866                         OracleCommand cmd = CreateCommand ();
867
868                         // TODO: determine whether a table is a System or a User type
869                         cmd.CommandText = "SELECT OWNER, TABLE_NAME, DECODE(OWNER, 'SYS', 'System', 'User') AS TYPE " +
870                                 " FROM SYS.ALL_TABLES " +
871                                 " WHERE (OWNER = :POWNER OR :POWNER IS NULL) " +
872                                 " AND (TABLE_NAME = :PTABLE_NAME OR :PTABLE_NAME IS NULL) " +
873                                 " ORDER BY OWNER, TABLE_NAME";
874
875                         cmd.Parameters.Add (":POWNER", OracleType.VarChar, 30).Value = DBNull.Value;
876                         cmd.Parameters.Add (":PTABLE_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
877
878                         return GetSchemaDataTable (cmd, restrictionValues);
879                 }
880
881                 DataTable GetSchemaColumns (string [] restrictionValues)
882                 {
883                         OracleCommand cmd = CreateCommand();
884
885                         cmd.CommandText = "SELECT OWNER, TABLE_NAME, COLUMN_NAME, COLUMN_ID AS ID, DATA_TYPE AS DATATYPE, " +
886                                 " DATA_LENGTH AS LENGTH, DATA_PRECISION AS PRECISION, DATA_SCALE AS SCALE, NULLABLE " +
887                                 " FROM SYS.ALL_TAB_COLUMNS " +
888                                 " WHERE (OWNER = :POWNER OR :POWNER IS NULL) " +
889                                 " AND (TABLE_NAME = :PTABLE_NAME OR :PTABLE_NAME IS NULL) " +
890                                 " AND (COLUMN_NAME = 'ENAME' OR :PCOLUMN_NAME IS NULL) " +
891                                 " ORDER BY OWNER, TABLE_NAME, COLUMN_ID;"; 
892
893                         cmd.Parameters.Add (":POWNER", OracleType.VarChar, 30).Value = DBNull.Value;
894                         cmd.Parameters.Add (":PTABLE_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
895                         cmd.Parameters.Add (":PCOLUMN_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
896
897                         return GetSchemaDataTable (cmd, restrictionValues);
898                 }
899
900                 DataTable GetSchemaViews (string [] restrictionValues)
901                 {
902                         OracleCommand cmd = CreateCommand ();
903
904                         cmd.CommandText = "SELECT OWNER,VIEW_NAME,TEXT_LENGTH,TEXT,TYPE_TEXT_LENGTH,TYPE_TEXT,OID_TEXT_LENGTH,OID_TEXT, " +
905                                 "   VIEW_TYPE_OWNER,VIEW_TYPE,SUPERVIEW_NAME " +
906                                 " FROM SYS.ALL_VIEWS " +
907                                 " WHERE (OWNER = :POWNER OR :POWNER IS NULL) " +
908                                 " AND (VIEW_NAME = :PVIEW_NAME OR :PVIEW_NAME IS NULL) " +
909                                 " ORDER BY OWNER, VIEW_NAME";
910
911                         cmd.Parameters.Add (":POWNER", OracleType.VarChar, 30).Value = DBNull.Value;
912                         cmd.Parameters.Add (":PVIEW_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
913
914                         return GetSchemaDataTable (cmd, restrictionValues);
915                 }
916
917                 DataTable GetSchemaUsers (string [] restrictionValues)
918                 {
919                         OracleCommand cmd = CreateCommand ();
920
921                         cmd.CommandText = "SELECT USERNAME AS NAME, USER_ID AS ID, CREATED AS CREATEDATE " +
922                                 " FROM SYS.ALL_USERS " +
923                                 " WHERE (USERNAME = :PUSERNAME OR :PUSERNAME IS NULL)";
924
925                         cmd.Parameters.Add (":PUSERNAME", OracleType.VarChar, 30).Value = DBNull.Value;
926
927                         return GetSchemaDataTable (cmd, restrictionValues);
928                 }
929
930                 DataTable GetSchemaSynonyms (string [] restrictionValues)
931                 {
932                         OracleCommand cmd = CreateCommand ();
933
934                         cmd.CommandText = "SELECT OWNER, SYNONYM_NAME, TABLE_OWNER, TABLE_NAME, DB_LINK " + 
935                                 " FROM SYS.ALL_SYNONYMS " +
936                                 " WHERE (OWNER = :POWNER OR :POWNER IS NULL) " +
937                                 " AND (SYNONYM_NAME = :PSYNONYM_NAME OR :PSYNONYM_NAME IS NULL) " +
938                                 " ORDER BY OWNER, SYNONYM_NAME";
939
940                         cmd.Parameters.Add (":POWNER", OracleType.VarChar, 30).Value = DBNull.Value;
941                         cmd.Parameters.Add (":PSYNONYM_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
942
943                         return GetSchemaDataTable (cmd, restrictionValues);
944                 }
945
946                 DataTable GetSchemaSequences (string [] restrictionValues)
947                 {
948                         OracleCommand cmd = CreateCommand ();
949
950                         cmd.CommandText = "SELECT SEQUENCE_OWNER, SEQUENCE_NAME, MIN_VALUE, MAX_VALUE, " +
951                                 "   INCREMENT_BY, CYCLE_FLAG, ORDER_FLAG, CACHE_SIZE, LAST_NUMBER " +
952                                 " FROM SYS.ALL_SEQUENCES " +
953                                 " WHERE (SEQUENCE_OWNER = :PSEQUENCE_OWNER OR :PSEQUENCE_OWNER IS NULL) " +
954                                 " AND (SEQUENCE_NAME = :PSEQUENCE_NAME OR :PSEQUENCE_NAME IS NULL) " +
955                                 " ORDER BY SEQUENCE_OWNER, SEQUENCE_NAME";
956
957                         cmd.Parameters.Add (":SEQUENCE_OWNER", OracleType.VarChar, 30).Value = DBNull.Value;
958                         cmd.Parameters.Add (":SEQUENCE_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
959
960                         return GetSchemaDataTable (cmd, restrictionValues);
961                 }
962
963                 DataTable GetSchemaProcedures(string [] restrictionValues, string objType)
964                 {
965                         OracleCommand cmd = CreateCommand ();
966
967                         cmd.CommandText = "SELECT OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, LAST_DDL_TIME, " +
968                                 "    TIMESTAMP, STATUS, TEMPORARY, GENERATED, SECONDARY, CREATED " +
969                                 " FROM ALL_OBJECTS " +
970                                 " WHERE OBJECT_TYPE = '" + objType + "' " +
971                                 " AND (OWNER = :POWNER OR :POWNER IS NULL) " +
972                                 " AND (OBJECT_NAME = :POBJECT_NAME OR :POBJECT_NAME IS NULL) " +
973                                 " ORDER BY OWNER, OBJECT_NAME, SUBOBJECT_NAME";
974
975                         cmd.Parameters.Add (":POWNER", OracleType.VarChar, 30).Value = DBNull.Value;
976                         cmd.Parameters.Add (":POBJECT_NAME", OracleType.VarChar, 30).Value = DBNull.Value;
977
978                         return GetSchemaDataTable (cmd, restrictionValues);
979                 }
980
981                 DataTable GetSchemaDataSourceInformation ()
982                 {
983                         DataTable dt = new DataTable ();
984
985                         dt.Columns.Add ("CompositeIdentifierSeparatorPattern", typeof (System.String));
986                         dt.Columns.Add ("DataSourceProductName", typeof (System.String));
987                         dt.Columns.Add ("DataSourceProductVersion", typeof (System.String));
988                         dt.Columns.Add ("DataSourceProductVersionNormalized", typeof (System.String));
989                         dt.Columns.Add ("GroupByBehavior", typeof (System.Data.Common.GroupByBehavior));
990                         dt.Columns.Add ("IdentifierPattern", typeof (System.String));
991                         dt.Columns.Add ("IdentifierCase", typeof (System.Data.Common.IdentifierCase));
992                         dt.Columns.Add ("OrderByColumnsInSelect", typeof (System.Boolean));
993                         dt.Columns.Add ("ParameterMarkerFormat", typeof (System.String));
994                         dt.Columns.Add ("ParameterMarkerPattern", typeof (System.String));
995                         dt.Columns.Add ("ParameterNameMaxLength", typeof (System.Int32));
996                         dt.Columns.Add ("ParameterNamePattern", typeof (System.String));
997                         dt.Columns.Add ("QuotedIdentifierPattern", typeof (System.String));
998                         dt.Columns.Add ("QuotedIdentifierCase", typeof (System.Data.Common.IdentifierCase));
999                         dt.Columns.Add ("StatementSeparatorPattern", typeof (System.String));
1000                         dt.Columns.Add ("StringLiteralPattern", typeof (System.String));
1001                         dt.Columns.Add ("SupportedJoinOperators", typeof (System.Data.Common.SupportedJoinOperators));
1002
1003                         string ver = ServerVersion;
1004                         string [] ver2 = ver.Substring (0, ver.IndexOf (' ')).Split (new char [] { '.' });
1005                         StringBuilder sb = new StringBuilder();
1006                         for (int i = 0; i < ver2.Length; i++) {
1007                                 if (i > 0) {
1008                                     sb.Append (".");
1009                                 }
1010
1011                                 sb.AppendFormat ("{0:00}", Int32.Parse (ver2 [i]));
1012                         }
1013                         sb.Append (' ');
1014                         ver = sb.ToString ();
1015
1016                         dt.LoadDataRow (new object [] { "@|\\.", 
1017                                 "Oracle", 
1018                                 ServerVersion, 
1019                                 ver, 
1020                                 3, 
1021                                 "^[\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}__#$][\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}\\p{Nd}__#$]*$", 
1022                                 1, 
1023                                 false, 
1024                                 ":{0}", 
1025                                 ":([\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}__#$][\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}\\p{Nd}__#$]*)", 
1026                                 30,
1027                                 "^[\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}__#$][\\p{Lo}\\p{Lu}\\p{Ll}\\p{Lm}\\p{Nd}__#$]*$", 
1028                                 "\"^(([^\"]|\"\")*)$\"", 
1029                                 2, 
1030                                 DBNull.Value, 
1031                                 "'(([^']|'')*)'", 15 }, 
1032                                 true);
1033
1034                         return dt;
1035                 }
1036
1037                 DataTable GetSchemaDataTypes ()
1038                 {
1039                         DataTable dt = new DataTable ();
1040
1041                         dt.Columns.Add ("TypeName", typeof (System.String));
1042                         dt.Columns.Add ("ProviderDbType", typeof (System.Int32));
1043                         dt.Columns.Add ("ColumnSize", typeof (System.Int64));
1044                         dt.Columns.Add ("CreateFormat", typeof (System.String));
1045                         dt.Columns.Add ("CreateParameters", typeof (System.String));
1046                         dt.Columns.Add ("DataType", typeof (System.String));
1047                         dt.Columns.Add ("IsAutoIncrementable", typeof (System.Boolean));
1048                         dt.Columns.Add ("IsBestMatch", typeof (System.Boolean));
1049                         dt.Columns.Add ("IsCaseSensitive", typeof (System.Boolean));
1050                         dt.Columns.Add ("IsFixedLength", typeof (System.Boolean));
1051                         dt.Columns.Add ("IsFixedPrecisionScale", typeof (System.Boolean));
1052                         dt.Columns.Add ("IsLong", typeof (System.Boolean));
1053                         dt.Columns.Add ("IsNullable", typeof (System.Boolean));
1054                         dt.Columns.Add ("IsSearchable", typeof (System.Boolean));
1055                         dt.Columns.Add ("IsSearchableWithLike", typeof (System.Boolean));
1056                         dt.Columns.Add ("IsUnsigned", typeof (System.Boolean));
1057                         dt.Columns.Add ("MaximumScale", typeof (System.Int16));
1058                         dt.Columns.Add ("MinimumScale", typeof (System.Int16));
1059                         dt.Columns.Add ("IsConcurrencyType", typeof (System.Boolean));
1060                         dt.Columns.Add ("IsLiteralSupported", typeof (System.Boolean));
1061                         dt.Columns.Add ("LiteralPrefix", typeof (System.String));
1062                         dt.Columns.Add ("LiteralSuffix", typeof (System.String));
1063
1064                         dt.LoadDataRow (new object [] { "BFILE", 1, 4294967296, "BFILE", DBNull.Value, "System.Byte[]", false, false, false, false, false, true, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1065                         dt.LoadDataRow (new object [] { "BLOB", 2, 4294967296, "BLOB", DBNull.Value, "System.Byte[]", false, false, false, false, false, true, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1066                         dt.LoadDataRow (new object [] { "CHAR", 3, 2000, "CHAR({0})", "size", "System.String", false, false, true, true, false, false, true, true, true, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "'", "'" }, true);
1067                         dt.LoadDataRow (new object [] { "CLOB", 4, 4294967296, "CLOB", DBNull.Value, "System.String", false, true, true, false, false, false, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1068                         dt.LoadDataRow (new object [] { "DATE", 6, 19, "DATE", DBNull.Value, "System.DateTime", false, true, false, true, false, false, true, true, true, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_DATE('", "','YYYY-MM-DD HH24:MI:SS')" }, true);
1069                         dt.LoadDataRow (new object [] { "FLOAT", 29, 38, "FLOAT", DBNull.Value, "System.Decimal", false, true, false, true, false, false, true, true, true, false, DBNull.Value, DBNull.Value, false, true, DBNull.Value, DBNull.Value }, true);
1070                         dt.LoadDataRow (new object [] { "INTERVAL DAY TO SECOND", 7, 0, "INTERVAL DAY({0}) TO SECOND({1})", "dayprecision,secondsprecision", "System.TimeSpan", false, true, false, true, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_DSINTERVAL('", "')" }, true);
1071                         dt.LoadDataRow (new object [] { "INTERVAL YEAR TO MONTH", 8, 0, "INTERVAL YEAR({0}) TO MONTH", "yearprecision", "System.Int32", false, false, false, true, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_YMINTERVAL('", "')" }, true);
1072                         dt.LoadDataRow (new object [] { "LONG", 10, 2147483647, "LONG", DBNull.Value, "System.String", false, false, false, false, false, true, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1073                         dt.LoadDataRow (new object [] { "LONG RAW", 9, 2147483647, "LONG RAW", DBNull.Value, "System.Byte[]", false, false, false, false, false, true, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1074                         dt.LoadDataRow (new object [] { "NCHAR", 11, 2000, "NCHAR({0})", "size", "System.String", false, false, true, true, false, false, true, true, true, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "N'", "'" }, true);
1075                         dt.LoadDataRow (new object [] { "NCLOB", 12, 4294967296, "NCLOB", DBNull.Value, "System.String", false, false, true, false, false, true, true, false, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1076                         dt.LoadDataRow (new object [] { "NUMBER", 13, 38, "NUMBER ({0},{1})", "precision,scale", "System.Decimal", false, true, false, true, false, false, true, true, true, false, 127, -84, false, true, "", "" }, true);
1077                         dt.LoadDataRow (new object [] { "NVARCHAR2", 14, 4000, "NVARCHAR2({0})", "size", "System.String", false, false, true, false, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "N'", "'" }, true);
1078                         dt.LoadDataRow (new object [] { "RAW", 15, 2000, "RAW({0})", "size", "System.Byte[]", false, true, false, false, true, false, true, true, true, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "HEXTORAW('", "')" }, true);
1079                         dt.LoadDataRow (new object [] { "ROWID", 16, 3950, "ROWID", DBNull.Value, "System.String", true, false, false, false, false, false, false, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, false, DBNull.Value, DBNull.Value }, true);
1080                         dt.LoadDataRow (new object [] { "TIMESTAMP", 18, 27, "TIMESTAMP({0})", "precision of fractional seconds", "System.DateTime", false, false, false, true, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_TIMESTAMP('", "','YYYY-MM-DD HH24:MI:SS.FF')" }, true);
1081                         dt.LoadDataRow (new object [] { "TIMESTAMP WITH LOCAL TIME ZONE", 19, 27, "TIMESTAMP({0} WITH LOCAL TIME ZONE)", "precision of fractional seconds", "System.DateTime", false, false, false, true, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_TIMESTAMP_TZ('", "','YYYY-MM-DD HH24:MI:SS.FF')" }, true);
1082                         dt.LoadDataRow (new object [] { "TIMESTAMP WITH TIME ZONE", 20, 34, "TIMESTAMP({0} WITH TIME ZONE)", "precision of fractional seconds", "System.DateTime", false, false, false, true, false, false, true, true, false, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "TO_TIMESTAMP_TZ('", "','YYYY-MM-DD HH24:MI:SS.FF TZH:TZM')" }, true);
1083                         dt.LoadDataRow (new object [] { "VARCHAR2", 22, 4000, "VARCHAR2({0})", "size", "System.String", false, false, true, false, true, false, true, true, true, DBNull.Value, DBNull.Value, DBNull.Value, false, true, "'", "'" }, true);
1084
1085                         return dt;
1086                 }
1087
1088                 DataTable GetSchemaReservedWords ()
1089                 {
1090                         DataTable dt = new DataTable ();
1091
1092                         dt.Columns.Add ("ReservedWord", typeof (System.String));
1093
1094                         dt.LoadDataRow (new object [] { "ACCESS" }, true);
1095                         dt.LoadDataRow (new object [] { "ADD" }, true);
1096                         dt.LoadDataRow (new object [] { "ALL" }, true);
1097                         dt.LoadDataRow (new object [] { "ALTER" }, true);
1098                         dt.LoadDataRow (new object [] { "AND" }, true);
1099                         dt.LoadDataRow (new object [] { "ANY" }, true);
1100                         dt.LoadDataRow (new object [] { "AS" }, true);
1101                         dt.LoadDataRow (new object [] { "ASC" }, true);
1102                         dt.LoadDataRow (new object [] { "AUDIT" }, true);
1103                         dt.LoadDataRow (new object [] { "BETWEEN" }, true);
1104                         dt.LoadDataRow (new object [] { "BY" }, true);
1105                         dt.LoadDataRow (new object [] { "CHAR" }, true);
1106                         dt.LoadDataRow (new object [] { "CHECK" }, true);
1107                         dt.LoadDataRow (new object [] { "CLUSTER" }, true);
1108                         dt.LoadDataRow (new object [] { "COLUMN" }, true);
1109                         dt.LoadDataRow (new object [] { "COMMENT" }, true);
1110                         dt.LoadDataRow (new object [] { "COMPRESS" }, true);
1111                         dt.LoadDataRow (new object [] { "CONNECT" }, true);
1112                         dt.LoadDataRow (new object [] { "CREATE" }, true);
1113                         dt.LoadDataRow (new object [] { "CURRENT" }, true);
1114                         dt.LoadDataRow (new object [] { "DATE" }, true);
1115                         dt.LoadDataRow (new object [] { "DECIMAL" }, true);
1116                         dt.LoadDataRow (new object [] { "DEFAULT" }, true);
1117                         dt.LoadDataRow (new object [] { "DELETE" }, true);
1118                         dt.LoadDataRow (new object [] { "DESC" }, true);
1119                         dt.LoadDataRow (new object [] { "DISTINCT" }, true);
1120                         dt.LoadDataRow (new object [] { "DROP" }, true);
1121                         dt.LoadDataRow (new object [] { "ELSE" }, true);
1122                         dt.LoadDataRow (new object [] { "EXCLUSIVE" }, true);
1123                         dt.LoadDataRow (new object [] { "EXISTS" }, true);
1124                         dt.LoadDataRow (new object [] { "FILE" }, true);
1125                         dt.LoadDataRow (new object [] { "FLOAT" }, true);
1126                         dt.LoadDataRow (new object [] { "FOR" }, true);
1127                         dt.LoadDataRow (new object [] { "FROM" }, true);
1128                         dt.LoadDataRow (new object [] { "GRANT" }, true);
1129                         dt.LoadDataRow (new object [] { "GROUP" }, true);
1130                         dt.LoadDataRow (new object [] { "HAVING" }, true);
1131                         dt.LoadDataRow (new object [] { "IDENTIFIED" }, true);
1132                         dt.LoadDataRow (new object [] { "IMMEDIATE" }, true);
1133                         dt.LoadDataRow (new object [] { "IN" }, true);
1134                         dt.LoadDataRow (new object [] { "INCREMENT" }, true);
1135                         dt.LoadDataRow (new object [] { "INDEX" }, true);
1136                         dt.LoadDataRow (new object [] { "INITAL" }, true);
1137                         dt.LoadDataRow (new object [] { "INSERT" }, true);
1138                         dt.LoadDataRow (new object [] { "INTEGER" }, true);
1139                         dt.LoadDataRow (new object [] { "INTERSECT" }, true);
1140                         dt.LoadDataRow (new object [] { "INTO" }, true);
1141                         dt.LoadDataRow (new object [] { "IS" }, true);
1142                         dt.LoadDataRow (new object [] { "LEVEL" }, true);
1143                         dt.LoadDataRow (new object [] { "LIKE" }, true);
1144                         dt.LoadDataRow (new object [] { "LOCK" }, true);
1145                         dt.LoadDataRow (new object [] { "LONG" }, true);
1146                         dt.LoadDataRow (new object [] { "MAXEXTENTS" }, true);
1147                         dt.LoadDataRow (new object [] { "MINUS" }, true);
1148                         dt.LoadDataRow (new object [] { "MLSLABEL" }, true);
1149                         dt.LoadDataRow (new object [] { "MODE" }, true);
1150                         dt.LoadDataRow (new object [] { "MODIFY" }, true);
1151                         dt.LoadDataRow (new object [] { "NOAUDIT" }, true);
1152                         dt.LoadDataRow (new object [] { "NOCOMPRESS" }, true);
1153                         dt.LoadDataRow (new object [] { "NOT" }, true);
1154                         dt.LoadDataRow (new object [] { "NOWAIT" }, true);
1155                         dt.LoadDataRow (new object [] { "NULL" }, true);
1156                         dt.LoadDataRow (new object [] { "NUMBER" }, true);
1157                         dt.LoadDataRow (new object [] { "OF" }, true);
1158                         dt.LoadDataRow (new object [] { "OFFLINE" }, true);
1159                         dt.LoadDataRow (new object [] { "ON" }, true);
1160                         dt.LoadDataRow (new object [] { "ONLINE" }, true);
1161                         dt.LoadDataRow (new object [] { "OPTION" }, true);
1162                         dt.LoadDataRow (new object [] { "OR" }, true);
1163                         dt.LoadDataRow (new object [] { "ORDER" }, true);
1164                         dt.LoadDataRow (new object [] { "PCTFREE" }, true);
1165                         dt.LoadDataRow (new object [] { "PRIOR" }, true);
1166                         dt.LoadDataRow (new object [] { "PRIVILEGES" }, true);
1167                         dt.LoadDataRow (new object [] { "PUBLIC" }, true);
1168                         dt.LoadDataRow (new object [] { "RAW" }, true);
1169                         dt.LoadDataRow (new object [] { "RENAME" }, true);
1170                         dt.LoadDataRow (new object [] { "RESOURCE" }, true);
1171                         dt.LoadDataRow (new object [] { "REVOKE" }, true);
1172                         dt.LoadDataRow (new object [] { "ROW" }, true);
1173                         dt.LoadDataRow (new object [] { "ROWID" }, true);
1174                         dt.LoadDataRow (new object [] { "ROWNUM" }, true);
1175                         dt.LoadDataRow (new object [] { "ROWS" }, true);
1176                         dt.LoadDataRow (new object [] { "SELECT" }, true);
1177                         dt.LoadDataRow (new object [] { "SESSION" }, true);
1178                         dt.LoadDataRow (new object [] { "SET" }, true);
1179                         dt.LoadDataRow (new object [] { "SHARE" }, true);
1180                         dt.LoadDataRow (new object [] { "SIZE" }, true);
1181                         dt.LoadDataRow (new object [] { "SMALLINT" }, true);
1182                         dt.LoadDataRow (new object [] { "START" }, true);
1183                         dt.LoadDataRow (new object [] { "SUCCESSFUL" }, true);
1184                         dt.LoadDataRow (new object [] { "SYNONYM" }, true);
1185                         dt.LoadDataRow (new object [] { "SYSDATE" }, true);
1186                         dt.LoadDataRow (new object [] { "TABLE" }, true);
1187                         dt.LoadDataRow (new object [] { "THEN" }, true);
1188                         dt.LoadDataRow (new object [] { "TO" }, true);
1189                         dt.LoadDataRow (new object [] { "TRIGGER" }, true);
1190                         dt.LoadDataRow (new object [] { "UID" }, true);
1191                         dt.LoadDataRow (new object [] { "UNION" }, true);
1192                         dt.LoadDataRow (new object [] { "UNIQUE" }, true);
1193                         dt.LoadDataRow (new object [] { "UPDATE" }, true);
1194                         dt.LoadDataRow (new object [] { "USER" }, true);
1195                         dt.LoadDataRow (new object [] { "VALIDATE" }, true);
1196                         dt.LoadDataRow (new object [] { "VALUES" }, true);
1197                         dt.LoadDataRow (new object [] { "VARCHAR" }, true);
1198                         dt.LoadDataRow (new object [] { "VARCHAR2" }, true);
1199                         dt.LoadDataRow (new object [] { "VIEW" }, true);
1200                         dt.LoadDataRow (new object [] { "WHENEVER" }, true);
1201                         dt.LoadDataRow (new object [] { "WHERE" }, true);
1202                         dt.LoadDataRow (new object [] { "WITH" }, true);
1203
1204                         return dt;
1205                 }
1206
1207                 DataTable GetSchemaDataTable (OracleCommand cmd, string [] restrictionValues)
1208                 {
1209                         if (restrictionValues != null) {
1210                                 for (int i = 0; i < restrictionValues.Length; i++)
1211                                         cmd.Parameters [i].Value = restrictionValues [i];
1212                         }
1213
1214                         OracleDataAdapter adapter = new OracleDataAdapter (cmd);
1215                         DataTable dt = new DataTable ();
1216                         adapter.Fill (dt);
1217
1218                         return dt;
1219                 }
1220         }
1221 }
1222
1223