2003-12-16 Joerg Rosenkranz <joergr@voelcker.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                 #region Fields
32
33                 bool connected;
34                 OciEnvironmentHandle environment;
35                 OciErrorHandle error;
36                 OciServerHandle server;
37                 OciServiceHandle service;
38                 OciSessionHandle session;
39
40                 // other codes
41                 public const int OCI_DEFAULT = 0;
42                 public const int OCI_SUCCESS = 0;
43                 public const int OCI_SUCCESS_WITH_INFO = 1;
44                 public const int OCI_RESERVED_FOR_INT_USE = 200;
45                 public const int OCI_NO_DATA = 100;
46                 public const int OCI_ERROR = -1;
47                 public const int OCI_INVALID_HANDLE = -2;
48                 public const int OCI_NEED_DATA = 99;
49                 public const int OCI_STILL_EXECUTING = -3123;
50                 public const int OCI_CONTINUE = -24200;
51
52                 #endregion // Fields
53
54                 #region Properties
55
56                 public bool Connected {
57                         get { return connected; }
58                 }
59
60                 public OciEnvironmentHandle Environment {
61                         get { return environment; }
62                 }
63
64                 public OciErrorHandle ErrorHandle {
65                         get { return error; }
66                 }
67
68                 public OciServiceHandle ServiceContext {
69                         get { return service; }
70                 }
71
72                 #endregion // Properties
73
74                 #region Methods
75
76                 [DllImport ("oci", EntryPoint = "OCIAttrSet")]
77                 public static extern int OCIAttrSet (IntPtr trgthndlp,
78                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
79                                                         IntPtr attributep,
80                                                         uint size,
81                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
82                                                         IntPtr errhp);
83
84                 [DllImport ("oci", EntryPoint = "OCIAttrSet")]
85                 public static extern int OCIAttrSetString (IntPtr trgthndlp,
86                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType trghndltyp,
87                                                         string attributep,
88                                                         uint size,
89                                                         [MarshalAs (UnmanagedType.U4)] OciAttributeType attrtype,
90                                                         IntPtr errhp);
91
92                 [DllImport ("oci")]
93                 public static extern int OCIErrorGet (IntPtr hndlp,
94                                                         uint recordno,
95                                                         IntPtr sqlstate,
96                                                         out int errcodep,
97                                                         IntPtr bufp,
98                                                         uint bufsize,
99                                                         [MarshalAs (UnmanagedType.U4)] OciHandleType type);
100
101                 public void CreateConnection (OracleConnectionInfo conInfo) 
102                 {
103                         environment = new OciEnvironmentHandle (OciEnvironmentMode.NoUserCallback);
104                         if (environment.Handle == IntPtr.Zero)
105                                 throw new OracleException (0, "Could not allocate the Oracle environment.");
106
107                         service = (OciServiceHandle) environment.Allocate (OciHandleType.Service);
108                         if (service == null) {
109                                 OciErrorInfo info = environment.HandleError ();
110                                 Disconnect ();
111                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
112                         }
113
114                         error = (OciErrorHandle) environment.Allocate (OciHandleType.Error);
115                         if (error == null) {
116                                 OciErrorInfo info = environment.HandleError ();
117                                 Disconnect ();
118                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
119                         }
120                         service.ErrorHandle = error;
121
122                         server = (OciServerHandle) environment.Allocate (OciHandleType.Server);
123                         if (server == null) {
124                                 OciErrorInfo info = environment.HandleError ();
125                                 Disconnect ();
126                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
127                         }
128
129                         session = (OciSessionHandle) environment.Allocate (OciHandleType.Session);
130                         if (session == null) {
131                                 OciErrorInfo info = environment.HandleError ();
132                                 Disconnect ();
133                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
134                         }
135                         session.Username = conInfo.Username;
136                         session.Password = conInfo.Password;
137                         session.Service = service;
138                                 
139                         if (!server.Attach (conInfo.Database, ErrorHandle)) {
140                                 OciErrorInfo info = error.HandleError ();
141                                 Disconnect ();
142                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
143                         }
144
145                         if (!service.SetServer (server)) {
146                                 OciErrorInfo info = error.HandleError ();
147                                 Disconnect ();
148                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
149                         }
150
151                         if (!session.BeginSession (OciCredentialType.RDBMS, OciSessionMode.Default, ErrorHandle)) {
152                                 OciErrorInfo info = error.HandleError ();
153                                 Disconnect ();
154                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
155                         }
156
157
158                         if (!service.SetSession (session)) {
159                                 OciErrorInfo info = error.HandleError ();
160                                 Disconnect ();
161                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
162                         }
163
164                         connected = true;
165                 }
166
167                 public OciStatementHandle CreateStatement ()
168                 {
169                         OciStatementHandle statement = (OciStatementHandle) environment.Allocate (OciHandleType.Statement);
170                         if (statement == null) {
171                                 OciErrorInfo info = environment.HandleError ();
172                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
173                         }
174                         statement.ErrorHandle = error;
175                         statement.Service = service;
176
177                         return statement;       
178                 }
179
180                 public OciTransactionHandle CreateTransaction ()
181                 {
182                         OciTransactionHandle transaction = (OciTransactionHandle) environment.Allocate (OciHandleType.Transaction);
183                         if (transaction == null) {
184                                 OciErrorInfo info = environment.HandleError ();
185                                 throw new OracleException (info.ErrorCode, info.ErrorMessage);
186                         }
187                         transaction.ErrorHandle = error;
188                         transaction.Service = service;
189
190                         return transaction;
191                 }
192
193                 public void Disconnect() 
194                 {
195                         if (session != null)
196                                 session.Dispose ();
197                         if (server != null)
198                                 server.Dispose ();
199                         if (error != null)
200                                 error.Dispose ();
201                         if (service != null)
202                                 service.Dispose ();
203                         if (environment != null)
204                                 environment.Dispose ();
205                 }
206
207                 #endregion // Methods
208         }
209 }