[bcl] Use RuntimeHelpers.GetHashCode () for getting the hash code of … (#5511)
[mono.git] / mcs / class / System.Data.OracleClient / System.Data.OracleClient.Oci / OciStatementHandle.cs
1 // 
2 // OciStatementHandle.cs 
3 //  
4 // Part of managed C#/.NET library System.Data.OracleClient.dll
5 //
6 // Part of the Mono class libraries at
7 // mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci
8 //
9 // Assembly: System.Data.OracleClient.dll
10 // Namespace: System.Data.OracleClient.Oci
11 // 
12 // Author: 
13 //     Tim Coleman <tim@timcoleman.com>
14 //     Daniel Morgan <danielmorgan@verizon.net>
15 //         
16 // Copyright (C) Tim Coleman, 2003
17 // Copyright (C) Daniel Morgan, 2005
18 // 
19
20 using System;
21 using System.Collections;
22 using System.Runtime.InteropServices;
23
24 namespace System.Data.OracleClient.Oci {
25         internal sealed class OciStatementHandle : OciHandle, IDisposable
26         {
27                 #region Fields
28
29                 int columnCount;
30                 bool disposed = false;
31                 OciErrorHandle errorHandle;
32                 bool moreResults;
33                 OciServiceHandle serviceHandle;
34                 ArrayList values;
35                 ArrayList parm;
36                 OracleCommand command;
37         
38                 #endregion // Fields
39
40                 #region Constructors
41
42                 public OciStatementHandle (OciHandle parent, IntPtr handle)
43                         : base (OciHandleType.Statement, parent, handle)
44                 {
45                         moreResults = false;
46                 }
47
48                 #endregion // Constructors
49
50                 #region Properties
51
52                 public int ColumnCount {
53                         get { return columnCount; }
54                 }
55
56                 public OciErrorHandle ErrorHandle {
57                         get { return errorHandle; }
58                         set { errorHandle = value; }
59                 }
60
61                 public OciServiceHandle Service {
62                         get { return serviceHandle; }
63                         set { serviceHandle = value; }
64                 }
65                 
66                 public ArrayList Values {
67                         get { return values; }
68                 }
69
70                 public OracleCommand Command {
71                         get { return command; }
72                         set { command = value; }
73                 }
74
75                 #endregion // Properties
76
77                 #region Methods
78                 
79                 protected override void Dispose (bool disposing)
80                 {
81                         if (!disposed) {
82                                 disposed = true;
83                                 
84                                 if (disposing) {
85                                         if (values != null) {
86                                                 foreach (OciDefineHandle h in values) 
87                                                         h.Dispose ();
88                                                 values = null;
89                                         }
90                                 }
91                                 base.Dispose (disposing);
92                         }
93                 }
94
95                 public OciParameterDescriptor GetParameter (int position)
96                 {
97                         IntPtr handle = IntPtr.Zero;
98                         int status = 0;
99
100                         status = OciCalls.OCIParamGet (this,
101                                                 OciHandleType.Statement,
102                                                 ErrorHandle,
103                                                 out handle,
104                                                 position + 1);
105
106                         if (status != 0) {
107                                 OciErrorInfo info = ErrorHandle.HandleError ();
108                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
109                         }
110
111                         OciParameterDescriptor output = new OciParameterDescriptor (this, handle);
112                         output.ErrorHandle = ErrorHandle;
113                         if (parm == null)
114                                 parm = new ArrayList();
115                         parm.Add(handle);
116                         return output;
117                 }
118
119                 public OciDefineHandle GetDefineHandle (int position, OracleConnection connection)
120                 {
121                         OciDefineHandle defineHandle = new OciDefineHandle (this, IntPtr.Zero);
122                         defineHandle.ErrorHandle = ErrorHandle;
123                         defineHandle.DefineByPosition (position, connection);
124
125                         return defineHandle;
126                 }
127
128                 void Define ()
129                 {
130                         Define (command.Connection);
131                 }
132
133                 void Define (OracleConnection connection) 
134                 {
135                         values = new ArrayList ();
136                         for (int i = 0; i < columnCount; i += 1)  
137                                 values.Add (GetDefineHandle (i, connection));
138                 }
139
140                 public bool ExecuteQuery (bool schemaOnly)
141                 {
142                         return Execute (false, false, schemaOnly);
143                 }
144
145                 public bool ExecuteNonQuery (bool useAutoCommit)
146                 {
147                         return Execute (true, useAutoCommit, false);
148                 }
149
150                 public bool Execute (bool nonQuery, bool useAutoCommit, bool schemaOnly)
151                 {
152                         int status = 0;
153                         columnCount = 0;
154                         moreResults = false;
155                         int executeMode;
156
157                         if( useAutoCommit)
158                                 executeMode = (int)OciExecuteMode.CommitOnSuccess;
159                         else {
160                                 if (schemaOnly)
161                                         executeMode = (int)OciExecuteMode.DescribeOnly;
162                                 else
163                                         executeMode = (int)OciExecuteMode.Default;
164                         }
165
166                         if (this.disposed) 
167                         {
168                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
169                         }
170
171                         status = OciCalls.OCIStmtExecute (Service,
172                                 Handle,
173                                 ErrorHandle,
174                                 nonQuery,
175                                 0,
176                                 IntPtr.Zero,
177                                 IntPtr.Zero,
178                                 (OciExecuteMode)executeMode);
179
180                         switch (status) {
181                         case OciGlue.OCI_DEFAULT:
182                                 if (!nonQuery) {
183                                         GetColumnCount ();
184                                         Define ();
185                                         moreResults = true;
186                                 }
187                                 break;
188                         case OciGlue.OCI_NO_DATA:
189                                 break;
190                         case OciGlue.OCI_INVALID_HANDLE:
191                                 throw new OracleException (0, "Invalid handle.");
192                         default:
193                                 OciErrorInfo info = ErrorHandle.HandleError ();
194                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
195                         }
196                         return true;
197                 }
198                 
199                 internal void SetupRefCursorResult (OracleConnection connection) 
200                 {
201                         GetColumnCount ();
202                         Define (connection);
203                         moreResults = true;
204                 }
205
206                 void GetColumnCount ()
207                 {
208                         columnCount = GetAttributeInt32 (OciAttributeType.ParameterCount, ErrorHandle);
209                 }
210
211                 public OciStatementType GetStatementType ()
212                 {
213                         return (OciStatementType) GetAttributeUInt16 (OciAttributeType.StatementType, ErrorHandle);
214                 }
215
216                 public bool Fetch ()
217                 {
218                         int status = 0;
219
220                         if (this.disposed) 
221                         {
222                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
223                         }
224
225                         status = OciCalls.OCIStmtFetch (Handle,
226                                 ErrorHandle.Handle,
227                                 1,
228                                 2,
229                                 0);
230                 
231                         switch (status) {
232                         case OciGlue.OCI_NO_DATA:
233                                 moreResults = false;
234                                 foreach (IntPtr h in parm)
235                                         OciCalls.OCIDescriptorFree(h, OciHandleType.Parameter);
236                                 break;
237                         case OciGlue.OCI_DEFAULT:
238                                 moreResults = true;
239                                 break;
240                         case OciGlue.OCI_SUCCESS_WITH_INFO:
241                                 //OciErrorInfo ei = ErrorHandle.HandleError ();
242                                 //command.Connection.CreateInfoMessage (ei);
243                                 moreResults = true;
244                                 break;
245                         default:
246                                 OciErrorInfo info = ErrorHandle.HandleError ();
247                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
248                         }
249
250                         return moreResults;
251                 }
252
253                 public void Prepare (string commandText)
254                 {
255                         int status = 0;
256
257                         if (this.disposed) {
258                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
259                         }
260
261                         int rsize = 0;
262                         byte [] buffer;
263                         
264                         // Get size of buffer
265                         OciCalls.OCIUnicodeToCharSet (Parent, null, commandText, out rsize);
266                         
267                         // Fill buffer
268                         buffer = new byte[rsize];
269                         OciCalls.OCIUnicodeToCharSet (Parent, buffer, commandText, out rsize);
270
271                         // Execute statement
272                         status = OciCalls.OCIStmtPrepare (this,
273                                 ErrorHandle,
274                                 buffer,
275                                 buffer.Length,
276                                 OciStatementLanguage.NTV,
277                                 OciStatementMode.Default);
278
279                         if (status != 0) {
280                                 OciErrorInfo info = ErrorHandle.HandleError ();
281                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
282                         }
283                 }
284
285                 #endregion // Methods
286         }
287 }