Merge branch 'master' of git://github.com/mono/mono
[mono.git] / mcs / class / System.Data.OracleClient / System.Data.OracleClient.jvm / OracleCommand.cs
1 //\r
2 // System.Data.OracleClient.OracleCommand\r
3 //\r
4 // Authors:\r
5 //      Konstantin Triger <kostat@mainsoft.com>\r
6 //      Boris Kirzner <borisk@mainsoft.com>\r
7 //      \r
8 // (C) 2005 Mainsoft Corporation (http://www.mainsoft.com)\r
9 //\r
10 \r
11 //\r
12 // Permission is hereby granted, free of charge, to any person obtaining\r
13 // a copy of this software and associated documentation files (the\r
14 // "Software"), to deal in the Software without restriction, including\r
15 // without limitation the rights to use, copy, modify, merge, publish,\r
16 // distribute, sublicense, and/or sell copies of the Software, and to\r
17 // permit persons to whom the Software is furnished to do so, subject to\r
18 // the following conditions:\r
19 // \r
20 // The above copyright notice and this permission notice shall be\r
21 // included in all copies or substantial portions of the Software.\r
22 // \r
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
30 //\r
31 \r
32 \r
33 using System;\r
34 using System.Collections;\r
35 using System.Text;\r
36 using System.Text.RegularExpressions;\r
37 using System.Data;\r
38 using System.Data.Common;\r
39 using System.Data.ProviderBase;\r
40 using System.Globalization;\r
41 \r
42 using java.sql;\r
43 // Cannot use this because it makes ArrayList ambiguous reference\r
44 //using java.util;\r
45 #if !USE_DOTNET_REGEXP\r
46 using java.util.regex;\r
47 #endif\r
48 \r
49 namespace System.Data.OracleClient {\r
50         public sealed class OracleCommand : AbstractDbCommand {\r
51 \r
52                 #region Fields\r
53 #if USE_DOTNET_REGEXP                   \r
54                 internal static readonly Regex NamedParameterStoredProcedureRegExp = new Regex(@"^\s*{?\s*((?<RETVAL>\:\w+)\s*=\s*)?call\s+(?<PROCNAME>(((\[[^\]]*\])|([^\.\(])*)\s*\.\s*){0,2}(\[[^\]]*\]|((\s*[^\.\(\)\{\}\s])+)))\s*(\(\s*(?<USERPARAM>((""([^""]|(""""))*"")|('([^']|(''))*')|[^,])*)?\s*(,\s*(?<USERPARAM>((""([^""]|(""""))*"")|('([^']|(''))*')|[^,])*)\s*)*\))?\s*}?\s*$", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);\r
55 #else\r
56                 internal static readonly Pattern NamedParameterStoredProcedureRegExp = Pattern.compile(@"^\s*\{?\s*(?:(\:\w+)\s*=\s*)?call\s+((?:(?:(?:\[[^\]]*\])|(?:[^\.\(\)\{\}\[\]])*)\s*\.\s*){0,2}(?:\[[^\]]*\]|(?:(?:\s*[^\.\(\)\{\}\[\]])+)))\s*(?:\((.*)\))?\s*\}?\s*$", Pattern.CASE_INSENSITIVE);\r
57 #endif\r
58                 internal static readonly SimpleRegex NamedParameterRegExp = new OracleParamsRegex();\r
59 \r
60 //              internal static readonly int oracleTypeRefCursor = java.sql.Types.OTHER;\r
61                 \r
62                 private int _currentParameterIndex = 0;\r
63                 private ResultSet _currentRefCursor;\r
64 \r
65                 #endregion // Fields\r
66 \r
67                 #region Constructors\r
68 \r
69                 /**\r
70                  * Initializes a new instance of the OracleCommand class.\r
71                  * The base constructor initializes all fields to their default values.\r
72                  * The following table shows initial property values for an instance of SqlCommand.\r
73                  */\r
74                 public OracleCommand() : this(null, null, null) {\r
75                 }\r
76 \r
77                 public OracleCommand(OracleConnection connection) : this(null, connection, null) {\r
78                 }\r
79 \r
80                 /**\r
81                  * Initializes a new instance of the OracleCommand class with the text of the query.\r
82                  * @param cmdText The text of the query.\r
83                  */\r
84                 public OracleCommand(String cmdText) : this(cmdText, null, null) {\r
85                 }\r
86 \r
87                 /**\r
88                  * Initializes a new instance of the OracleCommand class with the text of the query and a SqlConnection.\r
89                  * @param cmdText The text of the query.\r
90                  * @param connection A SqlConnection that represents the connection to an instance of SQL Server.\r
91                  */\r
92                 public OracleCommand(String cmdText, OracleConnection connection) : this(cmdText, connection, null) {\r
93                 }\r
94 \r
95                 /**\r
96                  * Initializes a new instance of the OracleCommand class with the text of the query, a SqlConnection, and the Transaction.\r
97                  * @param cmdText The text of the query.\r
98                  * @param connection A SqlConnection that represents the connection to an instance of SQL Server.\r
99                  * @param transaction The SqlTransaction in which the OracleCommand executes.\r
100                  */\r
101                 public OracleCommand(\r
102                         String cmdText,\r
103                         OracleConnection connection,\r
104                         OracleTransaction transaction)\r
105                         : base(cmdText, connection, transaction) {\r
106                 }\r
107 \r
108                 #endregion // Constructors\r
109 \r
110                 #region Properties\r
111 \r
112                 public new OracleConnection Connection {\r
113                         get { return (OracleConnection)base.Connection; }\r
114                         set { base.Connection = (AbstractDBConnection)value; }\r
115                 }\r
116 \r
117                 public new OracleParameterCollection Parameters {\r
118                         get { \r
119                                 return (OracleParameterCollection)base.Parameters; \r
120                         }\r
121                 }\r
122 \r
123                 public new OracleTransaction Transaction {\r
124                         get { return (OracleTransaction)base.Transaction; }\r
125                         set { base.Transaction = (DbTransaction)value; }\r
126                 }\r
127 \r
128                 protected override bool SkipParameter(DbParameter parameter) {\r
129                         return ((OracleParameter)parameter).OracleType == OracleType.Cursor;\r
130                 }\r
131 \r
132                 protected sealed override ResultSet CurrentResultSet {\r
133                         get { \r
134                                 try {\r
135                                         ResultSet resultSet = base.CurrentResultSet;\r
136  \r
137                                         if (resultSet != null) {\r
138                                                 return resultSet;                                               \r
139                                         }\r
140                                         return CurrentRefCursor;\r
141                                 }\r
142                                 catch(SQLException e) {\r
143                                         throw CreateException(e);\r
144                                 }\r
145                         }\r
146                 }\r
147 \r
148                 private ResultSet CurrentRefCursor {\r
149                         get {\r
150                                 if (_currentParameterIndex < 0) {\r
151                                         NextRefCursor();\r
152                                 }\r
153                                 if (_currentRefCursor == null && _currentParameterIndex < InternalParameters.Count) {\r
154                                         _currentRefCursor = (ResultSet)((CallableStatement)Statement).getObject(_currentParameterIndex + 1);\r
155                                 }\r
156                                 return _currentRefCursor;\r
157                         }\r
158                 }\r
159 \r
160 #if USE_DOTNET_REGEX\r
161                 protected override Regex StoredProcedureRegExp\r
162 #else\r
163                 protected override java.util.regex.Pattern StoredProcedureRegExp {\r
164 #endif\r
165                         get { return NamedParameterStoredProcedureRegExp; }\r
166                 }\r
167 \r
168                 protected override SimpleRegex ParameterRegExp {\r
169                         get { return NamedParameterRegExp; }\r
170                 }\r
171 \r
172                 #endregion // Properties\r
173 \r
174                 #region Methods\r
175 \r
176                 protected override bool NextResultSet() {\r
177                         try { \r
178                                 bool hasMoreResults = base.NextResultSet();\r
179 \r
180                                 if (hasMoreResults) {\r
181                                         return true;\r
182                                 }\r
183                                 else {\r
184                                         return NextRefCursor();\r
185                                 }\r
186                         }\r
187                         catch (SQLException e) {\r
188                                 throw CreateException(e);\r
189                         }\r
190                 }\r
191 \r
192                 private bool NextRefCursor() {\r
193                         _currentRefCursor = null;\r
194                         for (_currentParameterIndex++;InternalParameters.Count > _currentParameterIndex;_currentParameterIndex++) {\r
195                                 OracleParameter param = (OracleParameter)InternalParameters[_currentParameterIndex];\r
196                                 if (param.OracleType == OracleType.Cursor && ((param.Direction & ParameterDirection.Output) == ParameterDirection.Output))\r
197                                         return true;                                            \r
198                         }\r
199                         return false;\r
200                 }\r
201 \r
202                 public new OracleDataReader ExecuteReader() {\r
203                         return (OracleDataReader)ExecuteReader(CommandBehavior.Default);\r
204                 }\r
205 \r
206                 public new OracleDataReader ExecuteReader(CommandBehavior behavior) {\r
207                         return (OracleDataReader)base.ExecuteReader(behavior);\r
208                 }\r
209 \r
210                 public new OracleParameter CreateParameter() {\r
211                         return (OracleParameter)CreateParameterInternal();\r
212                 } \r
213 \r
214                 protected sealed override void CheckParameters() {\r
215                         //TBD\r
216                 }\r
217 \r
218                 protected override AbstractDbParameter GetUserParameter(string parameterName, IList userParametersList, int userParametersListPosition) {\r
219                         for(int i=0; i < userParametersList.Count; i++) {\r
220                                 OracleParameter userParameter = (OracleParameter)userParametersList[i];\r
221                                 if (String.Compare(parameterName, userParameter.InternalPlaceholder.Trim(), true, CultureInfo.InvariantCulture) == 0) {\r
222                                         return userParameter;\r
223                                 }\r
224                         }\r
225 \r
226                         return null;\r
227                 }\r
228 \r
229                 protected override AbstractDbParameter GetReturnParameter (IList userParametersList) {\r
230                         for(int i=0; i < userParametersList.Count; i++) {\r
231                                 AbstractDbParameter userParameter = (AbstractDbParameter)userParametersList[i];\r
232                                 if (userParameter.Direction == ParameterDirection.ReturnValue) {\r
233                                         return userParameter;\r
234                                 }\r
235                         }\r
236 \r
237                         return null; \r
238                 }\r
239 \r
240                 protected sealed override DbParameter CreateParameterInternal() {\r
241                         return new OracleParameter();\r
242                 }\r
243 \r
244                 protected sealed override DbParameterCollection CreateParameterCollection(AbstractDbCommand parent) {\r
245                         return new OracleParameterCollection((OracleCommand)parent);\r
246                 }\r
247 \r
248                 public override object Clone() {\r
249                         OracleCommand clone = (OracleCommand)base.Clone();\r
250                         clone._currentParameterIndex = 0;\r
251                         clone._currentRefCursor = null;\r
252                         return clone;\r
253                 }\r
254 \r
255                 protected override void PrepareInternalParameters() {\r
256                         InternalParameters.Clear();\r
257                         _currentParameterIndex = -1;\r
258                 }\r
259 \r
260                 \r
261                 protected sealed override DbDataReader CreateReader() {\r
262                         return new OracleDataReader(this);\r
263                 }\r
264 \r
265                 protected sealed override SystemException CreateException(SQLException e) {\r
266                         return new OracleException(e,Connection);               \r
267                 }\r
268 \r
269                 public object ExecuteOracleScalar() {\r
270                         throw new NotImplementedException();\r
271                 }\r
272 \r
273 #if SUPPORT_ORACLE_TYPES\r
274                 public int ExecuteOracleNonQuery(\r
275                         out OracleString rowid\r
276                         ) {\r
277                         throw new NotImplementedException();\r
278                 }\r
279 #endif\r
280 \r
281                 #endregion // Methods\r
282       \r
283         }\r
284 }