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