Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / class / System.Data.OracleClient / System.Data.OracleClient / OciGlue.cs
1 // 
2 // ociglue.cs - provides glue between 
3 //              managed C#/.NET System.Data.OracleClient.dll and 
4 //              unmanaged native c library oci.dll
5 //              to be used in Mono System.Data.OracleClient as
6 //              the Oracle 8i data provider.
7 //  
8 // Part of managed C#/.NET library System.Data.OracleClient.dll
9 //
10 // Part of the Mono class libraries at
11 // mcs/class/System.Data.OracleClient/System.Data.OracleClient.OCI
12 //
13 // Assembly: System.Data.OracleClient.dll
14 // Namespace: System.Data.OracleClient.Oci
15 // 
16 // Authors: 
17 //     Daniel Morgan <monodanmorg@yahoo.com>
18 //     Tim Coleman <tim@timcoleman.com>
19 //         
20 // Copyright (C) Daniel Morgan, 2002, 2009
21 // Copyright (C) Tim Coleman, 2002
22 // 
23
24 //#define ORACLE_DATA_ACCESS
25
26 using System;
27 using System.Runtime.InteropServices;
28 using System.Text;
29
30 namespace System.Data.OracleClient.Oci {
31         internal sealed class OciGlue 
32         {
33                 #region Fields
34
35                 bool connected;
36                 OciEnvironmentHandle environment;
37                 OciErrorHandle error;
38                 OciServerHandle server;
39                 OciServiceHandle service;
40                 OciSessionHandle session;
41
42                 // OCI Return Codes
43                 public const int OCI_DEFAULT = 0;
44                 public const int OCI_SUCCESS = 0;
45                 public const int OCI_SUCCESS_WITH_INFO = 1; // Diagnostic or Warning message - call OCIErrorGet 
46                 public const int OCI_RESERVED_FOR_INT_USE = 200;
47                 public const int OCI_NO_DATA = 100;
48                 public const int OCI_ERROR = -1; // use error handle to get error code and description - call OCIErrorGet
49                 public const int OCI_INVALID_HANDLE = -2;
50                 public const int OCI_NEED_DATA = 99;
51                 public const int OCI_STILL_EXECUTING = -3123;
52                 public const int OCI_CONTINUE = -24200;
53
54                 #endregion // Fields
55
56                 #region Properties
57
58                 public bool Connected {
59                         get { return connected; }
60                 }
61
62                 public OciEnvironmentHandle Environment {
63                         get { return environment; }
64                 }
65
66                 public OciErrorHandle ErrorHandle {
67                         get { return error; }
68                 }
69
70                 public OciServiceHandle ServiceContext {
71                         get { return service; }
72                 }
73
74                 public OciServerHandle ServerHandle {
75                         get { return server; }
76                 }
77
78                 public OciSessionHandle SessionHandle {
79                         get { return session; }
80                 }
81
82                 #endregion // Properties
83
84                 #region Methods
85
86                 public void CreateConnection (OracleConnectionInfo conInfo) 
87                 {
88                         environment = new OciEnvironmentHandle (OciEnvironmentMode.Threaded | OciEnvironmentMode.NoUserCallback);
89
90                         if (environment.Handle == IntPtr.Zero)
91                                 throw new OracleException (0, "Could not allocate the Oracle environment.");
92
93                         service = (OciServiceHandle) environment.Allocate (OciHandleType.Service);
94                         if (service == null) {
95                                 OciErrorInfo info = environment.HandleError ();
96                                 Disconnect ();
97                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
98                         }
99
100                         error = (OciErrorHandle) environment.Allocate (OciHandleType.Error);
101                         if (error == null) {
102                                 OciErrorInfo info = environment.HandleError ();
103                                 Disconnect ();
104                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
105                         }
106                         service.ErrorHandle = error;
107
108                         server = (OciServerHandle) environment.Allocate (OciHandleType.Server);
109                         if (server == null) {
110                                 OciErrorInfo info = environment.HandleError ();
111                                 Disconnect ();
112                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
113                         }
114
115                         session = (OciSessionHandle) environment.Allocate (OciHandleType.Session);
116                         if (session == null) {
117                                 OciErrorInfo info = environment.HandleError ();
118                                 Disconnect ();
119                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
120                         }
121                         session.Username = conInfo.Username;
122                         session.Password = conInfo.Password;
123                         session.Service = service;
124                                 
125                         if (!server.Attach (conInfo.Database, ErrorHandle)) {
126                                 OciErrorInfo info = error.HandleError ();
127                                 Disconnect ();
128                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
129                         }
130
131                         if (!service.SetServer (server)) {
132                                 OciErrorInfo info = error.HandleError ();
133                                 Disconnect ();
134                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
135                         }
136
137 #if ORACLE_DATA_ACCESS
138                         if (conInfo.SetNewPassword == true) {
139                                 // open with new password
140                                 if (!service.SetSession (session)) {
141                                         OciErrorInfo info = error.HandleError ();
142                                         Disconnect ();
143                                         throw new OracleException (info.ErrorCode, info.ErrorMessage);
144                                 }
145                                 if (!service.ChangePassword (conInfo.NewPassword, error)) {
146                                         OciErrorInfo info = error.HandleError ();
147                                         Disconnect ();
148                                         throw new OracleException (info.ErrorCode, info.ErrorMessage);
149                                 }
150                                 conInfo.Password = conInfo.NewPassword;
151                                 conInfo.SetNewPassword = false;
152                                 conInfo.NewPassword = string.Empty;
153                         } else {
154 #endif
155                                 // open normally
156                                 if (!session.BeginSession (conInfo.CredentialType, OciSessionMode.Default, ErrorHandle)) {
157                                         OciErrorInfo info = error.HandleError ();
158                                         Disconnect ();
159                                         throw new OracleException (info.ErrorCode, info.ErrorMessage);
160                                 }
161
162                                 if (!service.SetSession (session)) {
163                                         OciErrorInfo info = error.HandleError ();
164                                         Disconnect ();
165                                         throw new OracleException (info.ErrorCode, info.ErrorMessage);
166                                 }
167 #if ORACLE_DATA_ACCESS
168                         }
169 #endif
170                         connected = true;
171                 }
172
173                 public OciStatementHandle CreateStatement ()
174                 {
175                         OciStatementHandle statement = (OciStatementHandle) environment.Allocate (OciHandleType.Statement);
176                         if (statement == null) {
177                                 OciErrorInfo info = environment.HandleError ();
178                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
179                         }
180                         statement.ErrorHandle = error;
181                         statement.Service = service;
182
183                         return statement;       
184                 }
185
186                 public OciTransactionHandle CreateTransaction ()
187                 {
188                         OciTransactionHandle transaction = (OciTransactionHandle) environment.Allocate (OciHandleType.Transaction);
189                         if (transaction == null) {
190                                 OciErrorInfo info = environment.HandleError ();
191                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
192                         }
193                         transaction.ErrorHandle = error;
194                         transaction.Service = service;
195
196                         return transaction;
197                 }
198
199                 public void Disconnect() 
200                 {
201                         if (session != null) {
202                                 session.EndSession (error);
203                                 session.Dispose ();
204                                 session = null;
205                         }
206                         if (server != null) {
207                                 server.Detach (error);
208                                 server.Dispose ();
209                                 server = null;
210                         }
211                         if (error != null) {
212                                 error.Dispose ();
213                                 error = null;
214                         }
215                         if (service != null) {
216                                 service.Dispose ();
217                                 service = null;
218                         }
219                         if (environment != null) {
220                                 environment.Dispose ();
221                                 environment = null;
222                         }
223                 }
224
225                 public static string ReturnCodeToString (int status) 
226                 {
227                         switch (status) {
228                         case OCI_DEFAULT:
229                                 return "OCI_DEFAULT or OCI_SUCCESS"; // both are zero
230                         case OCI_SUCCESS_WITH_INFO:
231                                 return "OCI_SUCCESS_WITH_INFO"; 
232                         case OCI_RESERVED_FOR_INT_USE:
233                                 return "OCI_RESERVED_FOR_INT_USE";
234                         case OCI_NO_DATA:
235                                 return "OCI_NO_DATA";
236                         case OCI_ERROR:
237                                 return "OCI_ERROR";
238                         case OCI_INVALID_HANDLE:
239                                 return "OCI_INVALID_HANDLE";
240                         case OCI_NEED_DATA:
241                                 return "OCI_NEED_DATA";
242                         case OCI_STILL_EXECUTING:
243                                 return "OCI_STILL_EXECUTING";
244                         case OCI_CONTINUE:
245                                 return "OCI_CONTINUE";
246                         }
247                         return "Unknown Error";
248                 }
249
250                 #endregion // Methods
251         }
252 }
253