* roottypes.cs: Rename from tree.cs.
[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                 OracleCommand command;
36         
37                 #endregion // Fields
38
39                 #region Constructors
40
41                 public OciStatementHandle (OciHandle parent, IntPtr handle)
42                         : base (OciHandleType.Statement, parent, handle)
43                 {
44                         moreResults = false;
45                 }
46
47                 #endregion // Constructors
48
49                 #region Properties
50
51                 public int ColumnCount {
52                         get { return columnCount; }
53                 }
54
55                 public OciErrorHandle ErrorHandle {
56                         get { return errorHandle; }
57                         set { errorHandle = value; }
58                 }
59
60                 public OciServiceHandle Service {
61                         get { return serviceHandle; }
62                         set { serviceHandle = value; }
63                 }
64                 
65                 public ArrayList Values {
66                         get { return values; }
67                 }
68
69                 public OracleCommand Command {
70                         get { return command; }
71                         set { command = value; }
72                 }
73
74                 #endregion // Properties
75
76                 #region Methods
77                 
78                 protected override void Dispose (bool disposing)
79                 {
80                         if (!disposed) {
81                                 disposed = true;
82                                 
83                                 if (disposing) {
84                                         if (values != null) {
85                                                 foreach (OciDefineHandle h in values)
86                                                         h.Dispose ();
87                                                 values = null;
88                                         }
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                         return output;
114                 }
115
116                 public OciDefineHandle GetDefineHandle (int position)
117                 {
118                         OciDefineHandle defineHandle = new OciDefineHandle (this, IntPtr.Zero);
119                         defineHandle.ErrorHandle = ErrorHandle;
120                         defineHandle.DefineByPosition (position);
121
122                         return defineHandle;
123                 }
124
125                 void Define ()
126                 {
127                         values = new ArrayList ();
128                         for (int i = 0; i < columnCount; i += 1)  
129                                 values.Add (GetDefineHandle (i));
130                 }
131
132                 public bool ExecuteQuery (bool schemaOnly)
133                 {
134                         return Execute (false, false, schemaOnly);
135                 }
136
137                 public bool ExecuteNonQuery (bool useAutoCommit)
138                 {
139                         return Execute (true, useAutoCommit, false);
140                 }
141
142                 public bool Execute (bool nonQuery, bool useAutoCommit, bool schemaOnly)
143                 {
144                         int status = 0;
145                         columnCount = 0;
146                         moreResults = false;
147                         int executeMode;
148
149                         if( useAutoCommit)
150                                 executeMode = (int)OciExecuteMode.CommitOnSuccess;
151                         else {
152                                 if (schemaOnly)
153                                         executeMode = (int)OciExecuteMode.DescribeOnly;
154                                 else
155                                         executeMode = (int)OciExecuteMode.Default;
156                         }
157
158                         if (this.disposed) \r
159                         {
160                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
161                         }
162
163                         status = OciCalls.OCIStmtExecute (Service,
164                                 Handle,
165                                 ErrorHandle,
166                                 nonQuery,
167                                 0,
168                                 IntPtr.Zero,
169                                 IntPtr.Zero,
170                                 (OciExecuteMode)executeMode);
171
172                         switch (status) {
173                         case OciGlue.OCI_DEFAULT:
174                                 if (!nonQuery) {
175                                         GetColumnCount ();
176                                         Define ();
177                                         moreResults = true;
178                                 }
179                                 break;
180                         case OciGlue.OCI_NO_DATA:
181                                 break;
182                         case OciGlue.OCI_INVALID_HANDLE:
183                                 throw new OracleException (0, "Invalid handle.");
184                         default:
185                                 OciErrorInfo info = ErrorHandle.HandleError ();
186                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
187                         }
188                         return true;
189                 }
190                 
191                 internal void SetupRefCursorResult () 
192                 {
193                         GetColumnCount ();
194                         Define ();
195                         moreResults = true;
196                 }
197
198                 void GetColumnCount ()
199                 {
200                         columnCount = GetAttributeInt32 (OciAttributeType.ParameterCount, ErrorHandle);
201                 }
202
203                 public OciStatementType GetStatementType ()
204                 {
205                         return (OciStatementType) GetAttributeUInt16 (OciAttributeType.StatementType, ErrorHandle);
206                 }
207
208                 public bool Fetch ()
209                 {
210                         int status = 0;
211
212                         if (this.disposed) \r
213                         {
214                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
215                         }
216
217                         status = OciCalls.OCIStmtFetch (Handle,
218                                 ErrorHandle.Handle,
219                                 1,
220                                 2,
221                                 0);
222                 
223                         switch (status) {
224                         case OciGlue.OCI_NO_DATA:
225                                 moreResults = false;
226                                 break;
227                         case OciGlue.OCI_DEFAULT:
228                                 moreResults = true;
229                                 break;
230                         case OciGlue.OCI_SUCCESS_WITH_INFO:\r
231                                 //OciErrorInfo ei = ErrorHandle.HandleError ();\r
232                                 //command.Connection.CreateInfoMessage (ei);\r
233                                 moreResults = true;\r
234                                 break;
235                         default:
236                                 OciErrorInfo info = ErrorHandle.HandleError ();
237                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
238                         }
239
240                         return moreResults;
241                 }
242
243                 public void Prepare (string commandText)
244                 {
245                         int status = 0;
246
247                         if (this.disposed) {
248                                 throw new InvalidOperationException ("StatementHandle is already disposed.");
249                         }
250
251                         int rsize = 0;
252                         byte [] buffer;
253                         
254                         // Get size of buffer
255                         OciCalls.OCIUnicodeToCharSet (Parent, null, commandText, out rsize);
256                         
257                         // Fill buffer
258                         buffer = new byte[rsize];
259                         OciCalls.OCIUnicodeToCharSet (Parent, buffer, commandText, out rsize);
260
261                         // Execute statement
262                         status = OciCalls.OCIStmtPrepare (this,
263                                 ErrorHandle,
264                                 buffer,
265                                 buffer.Length,
266                                 OciStatementLanguage.NTV,
267                                 OciStatementMode.Default);
268
269                         if (status != 0) {
270                                 OciErrorInfo info = ErrorHandle.HandleError ();
271                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
272                         }
273                 }
274
275                 #endregion // Methods
276         }
277 }