2003-12-13 Tim Coleman <tim@timcoleman.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 OCIAttrGetByte (IntPtr trgthndlp,
88                                                         uint trghndltyp,
89                                                         out byte attributep,
90                                                         IntPtr sizep,
91                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
92                                                         IntPtr errhp);
93
94                 [DllImport ("oci", EntryPoint = "OCIAttrGet")]
95                 public static extern int OCIAttrGetInt32 (IntPtr trgthndlp,
96                                                         uint trghndltyp,
97                                                         out int attributep,
98                                                         IntPtr sizep,
99                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
100                                                         IntPtr errhp);
101
102                 [DllImport ("oci")]
103                 public static extern int OCIErrorGet (IntPtr hndlp,
104                                                         uint recordno,
105                                                         IntPtr sqlstate,
106                                                         out int errcodep,
107                                                         IntPtr bufp,
108                                                         uint bufsize,
109                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType type);
110
111                 public void CreateConnection (OracleConnectionInfo conInfo) 
112                 {
113                         environment = new OciEnvironmentHandle (OciEnvironmentMode.NoUserCallback);
114                         if (environment.Handle == IntPtr.Zero)
115                                 throw new OracleException (0, "Could not allocate the Oracle environment.");
116
117                         service = (OciServiceHandle) environment.Allocate (OciHandleType.Service);
118                         if (service == null) {
119                                 OciErrorInfo info = environment.HandleError ();
120                                 Disconnect ();
121                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
122                         }
123
124                         error = (OciErrorHandle) environment.Allocate (OciHandleType.Error);
125                         if (error == null) {
126                                 OciErrorInfo info = environment.HandleError ();
127                                 Disconnect ();
128                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
129                         }
130                         service.ErrorHandle = error;
131
132                         server = (OciServerHandle) environment.Allocate (OciHandleType.Server);
133                         if (server == null) {
134                                 OciErrorInfo info = environment.HandleError ();
135                                 Disconnect ();
136                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
137                         }
138                         server.ErrorHandle = error;
139                         server.TNSName = conInfo.Database;
140
141                         session = (OciSessionHandle) environment.Allocate (OciHandleType.Session);
142                         if (session == null) {
143                                 OciErrorInfo info = environment.HandleError ();
144                                 Disconnect ();
145                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
146                         }
147                         session.ErrorHandle = error;
148                         session.Username = conInfo.Username;
149                         session.Password = conInfo.Password;
150                         session.Service = service;
151                                 
152                         if (!server.Attach ()) {
153                                 OciErrorInfo info = error.HandleError ();
154                                 Disconnect ();
155                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
156                         }
157
158                         if (!service.SetServer (server)) {
159                                 OciErrorInfo info = error.HandleError ();
160                                 Disconnect ();
161                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
162                         }
163
164                         if (!session.Begin (OciCredentialType.RDBMS, OciSessionMode.Default)) {
165                                 OciErrorInfo info = error.HandleError ();
166                                 Disconnect ();
167                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
168                         }
169
170
171                         if (!service.SetSession (session)) {
172                                 OciErrorInfo info = error.HandleError ();
173                                 Disconnect ();
174                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
175                         }
176
177                         connected = true;
178                 }
179
180                 public OciStatementHandle CreateStatement ()
181                 {
182                         OciStatementHandle statement = (OciStatementHandle) environment.Allocate (OciHandleType.Statement);
183                         if (statement == null) {
184                                 OciErrorInfo info = environment.HandleError ();
185                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
186                         }
187                         statement.ErrorHandle = error;
188                         statement.Service = service;
189
190                         return statement;       
191                 }
192
193                 public OciTransactionHandle CreateTransaction ()
194                 {
195                         OciTransactionHandle transaction = (OciTransactionHandle) environment.Allocate (OciHandleType.Transaction);
196                         if (transaction == null) {
197                                 OciErrorInfo info = environment.HandleError ();
198                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
199                         }
200                         transaction.ErrorHandle = error;
201                         transaction.Service = service;
202
203                         return transaction;
204                 }
205
206                 public void Disconnect() 
207                 {
208                         if (session != null)
209                                 session.Dispose ();
210                         if (server != null)
211                                 server.Dispose ();
212                         if (error != null)
213                                 error.Dispose ();
214                         if (service != null)
215                                 service.Dispose ();
216                         if (environment != null)
217                                 environment.Dispose ();
218                 }
219         }
220 }