2003-02-16 Daniel Morgan <danmorg@sc.rr.com>
[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 <danmorg@sc.rr.com>
18 //     Tim Coleman <tim@timcoleman.com>
19 //         
20 // Copyright (C) Daniel Morgan, 2002
21 // Copyright (C) Tim Coleman, 2002
22 // 
23
24 using System;
25 using System.Runtime.InteropServices;
26 using System.Text;
27
28 namespace System.Data.OracleClient.Oci {
29         internal sealed class OciGlue 
30         {
31                 bool connected;
32                 OciEnvironmentHandle environment;
33                 OciErrorHandle error;
34                 OciServerHandle server;
35                 OciServiceHandle service;
36                 OciSessionHandle session;
37
38                 public bool Connected {
39                         get { return connected; }
40                 }
41
42                 // other codes
43                 public const int OCI_DEFAULT = 0;
44                 public const int OCI_SUCCESS = 0;
45                 public const int OCI_SUCCESS_WITH_INFO = 1;
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;
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                 [DllImport ("oci", EntryPoint = "OCIAttrSet")]
55                 public static extern int OCIAttrSet (IntPtr trgthndlp,
56                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
57                                                         IntPtr attributep,
58                                                         uint size,
59                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
60                                                         IntPtr errhp);
61
62                 [DllImport ("oci", EntryPoint = "OCIAttrSet")]
63                 public static extern int OCIAttrSetString (IntPtr trgthndlp,
64                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
65                                                         string attributep,
66                                                         uint size,
67                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
68                                                         IntPtr errhp);
69
70                 [DllImport ("oci")]
71                 public static extern int OCIAttrGet (IntPtr trgthndlp,
72                                                         uint trghndltyp,
73                                                         out IntPtr attributep,
74                                                         out int sizep,
75                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
76                                                         IntPtr errhp);
77
78                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
79                 public static extern int OCIAttrGetBool (IntPtr trgthndlp,
80                                                         uint trghndltyp,
81                                                         out bool attributep,
82                                                         IntPtr sizep,
83                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
84                                                         IntPtr errhp);
85
86                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
87                 public static extern int OCIAttrGetSByte (IntPtr trgthndlp,
88                         uint trghndltyp,
89                         out sbyte attributep,
90                         IntPtr sizep,
91                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
92                         IntPtr errhp);
93
94                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
95                 public static extern int OCIAttrGetByte (IntPtr trgthndlp,
96                                                         uint trghndltyp,
97                                                         out byte attributep,
98                                                         IntPtr sizep,
99                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
100                                                         IntPtr errhp);
101
102                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
103                 public static extern int OCIAttrGetUInt16 (IntPtr trgthndlp,
104                                                         uint trghndltyp,
105                                                         out ushort attributep,
106                                                         IntPtr sizep,
107                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
108                                                         IntPtr errhp);
109
110                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
111                 public static extern int OCIAttrGetInt32 (IntPtr trgthndlp,
112                                                         uint trghndltyp,
113                                                         out int attributep,
114                                                         IntPtr sizep,
115                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
116                                                         IntPtr errhp);
117
118                 [DllImport ("oci")]
119                 public static extern int OCIErrorGet (IntPtr hndlp,
120                                                         uint recordno,
121                                                         IntPtr sqlstate,
122                                                         out int errcodep,
123                                                         IntPtr bufp,
124                                                         uint bufsize,
125                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType type);
126
127                 public void CreateConnection (OracleConnectionInfo conInfo) 
128                 {
129                         environment = new OciEnvironmentHandle (OciEnvironmentMode.NoUserCallback);
130                         if (environment.Handle == IntPtr.Zero)
131                                 throw new OracleException (0, "Could not allocate the Oracle environment.");
132
133                         service = (OciServiceHandle) environment.Allocate (OciHandleType.Service);
134                         if (service == null) {
135                                 OciErrorInfo info = environment.HandleError ();
136                                 Disconnect ();
137                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
138                         }
139
140                         error = (OciErrorHandle) environment.Allocate (OciHandleType.Error);
141                         if (error == null) {
142                                 OciErrorInfo info = environment.HandleError ();
143                                 Disconnect ();
144                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
145                         }
146                         service.ErrorHandle = error;
147
148                         server = (OciServerHandle) environment.Allocate (OciHandleType.Server);
149                         if (server == null) {
150                                 OciErrorInfo info = environment.HandleError ();
151                                 Disconnect ();
152                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
153                         }
154                         server.ErrorHandle = error;
155                         server.TNSName = conInfo.Database;
156
157                         session = (OciSessionHandle) environment.Allocate (OciHandleType.Session);
158                         if (session == null) {
159                                 OciErrorInfo info = environment.HandleError ();
160                                 Disconnect ();
161                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
162                         }
163                         session.ErrorHandle = error;
164                         session.Username = conInfo.Username;
165                         session.Password = conInfo.Password;
166                         session.Service = service;
167                                 
168                         if (!server.Attach ()) {
169                                 OciErrorInfo info = error.HandleError ();
170                                 Disconnect ();
171                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
172                         }
173
174                         if (!service.SetServer (server)) {
175                                 OciErrorInfo info = error.HandleError ();
176                                 Disconnect ();
177                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
178                         }
179
180                         if (!session.Begin (OciCredentialType.RDBMS, OciSessionMode.Default)) {
181                                 OciErrorInfo info = error.HandleError ();
182                                 Disconnect ();
183                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
184                         }
185
186
187                         if (!service.SetSession (session)) {
188                                 OciErrorInfo info = error.HandleError ();
189                                 Disconnect ();
190                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
191                         }
192
193                         connected = true;
194                 }
195
196                 public OciStatementHandle CreateStatement ()
197                 {
198                         OciStatementHandle statement = (OciStatementHandle) environment.Allocate (OciHandleType.Statement);
199                         if (statement == null) {
200                                 OciErrorInfo info = environment.HandleError ();
201                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
202                         }
203                         statement.ErrorHandle = error;
204                         statement.Service = service;
205
206                         return statement;       
207                 }
208
209                 public OciTransactionHandle CreateTransaction ()
210                 {
211                         OciTransactionHandle transaction = (OciTransactionHandle) environment.Allocate (OciHandleType.Transaction);
212                         if (transaction == null) {
213                                 OciErrorInfo info = environment.HandleError ();
214                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
215                         }
216                         transaction.ErrorHandle = error;
217                         transaction.Service = service;
218
219                         return transaction;
220                 }
221
222                 public void Disconnect() 
223                 {
224                         if (session != null)
225                                 session.Dispose ();
226                         if (server != null)
227                                 server.Dispose ();
228                         if (error != null)
229                                 error.Dispose ();
230                         if (service != null)
231                                 service.Dispose ();
232                         if (environment != null)
233                                 environment.Dispose ();
234                 }
235         }
236 }