+2005-12-20 Daniel Morgan <danielmorgan@verizon.net>
+
+ * System.Data.OracleClient/OracleConnectionPoolManager.cs
+ * System.Data.OracleClient/OracleConnectionPool.cs
+ * System.Data.OracleClient/OracleConnection.cs
+ * System.Data.OracleClient/OciGlue.cs
+ * System.Data.OracleClient.Oci/OciEnvironmentHandle.cs
+ * System.Data.OracleClient.Oci/OciErrorHandle.cs
+ * System.Data.OracleClient.Oci/OciServiceHandle.cs
+ * System.Data.OracleClient.Oci/OciSessionHandle.cs: modified
+ - support Integrated Security which is external authentication
+ - dispose of OCI handles properly to prevent SEGSIGV during finalization
+ at application exit
+
2005-12-19 Daniel Morgan <danielmorgan@verizon.net>
* System.Data.OracleClient/OracleConnectionPoolManager.cs
public OciErrorInfo HandleError ()
{
- int errbufSize = 512;
- IntPtr errbuf = Marshal.AllocHGlobal (errbufSize);
-
- OciErrorInfo info;
- info.ErrorCode = 0;
- info.ErrorMessage = String.Empty;
-
- OciCalls.OCIErrorGet (Handle,
- 1,
- IntPtr.Zero,
- out info.ErrorCode,
- errbuf,
- (uint) errbufSize,
- OciHandleType.Environment);
-
- object err = Marshal.PtrToStringAnsi (errbuf);
- if (err != null) {
- string errmsg = (string) err;
- info.ErrorMessage = String.Copy (errmsg);
- Marshal.FreeHGlobal (errbuf);
- }
-
+ OciErrorInfo info = OciErrorHandle.HandleError (this);
return info;
}
}
}
- public OciErrorInfo HandleError ()
+ public static OciErrorInfo HandleError (OciHandle hand)
{
OciErrorInfo info;
info.ErrorCode = 0;
int errbufSize = 4096;
IntPtr errbuf = Marshal.AllocHGlobal (errbufSize);
- OciCalls.OCIErrorGet (this,
+ OciCalls.OCIErrorGet (hand,
1,
IntPtr.Zero,
out info.ErrorCode,
(uint) errbufSize,
OciHandleType.Error);
- //object err = Marshal.PtrToStringAuto (errbuf);\r
byte[] bytea = new byte[errbufSize];\r
Marshal.Copy (errbuf, bytea, 0, errbufSize);\r
errbufSize = 0;\r
+ \r
+ OciHandle h = hand.Parent;\r
+ if (h == null)\r
+ h = hand;\r
+\r
// first call to OCICharSetToUnicode gets the size\r
- OciCalls.OCICharSetToUnicode (Parent, null, bytea, out errbufSize);\r
+ OciCalls.OCICharSetToUnicode (h, null, bytea, out errbufSize);\r
StringBuilder str = new StringBuilder (errbufSize);\r
+ \r
// second call to OCICharSetToUnicode gets the string\r
- OciCalls.OCICharSetToUnicode (Parent, str, bytea, out errbufSize);\r
+ OciCalls.OCICharSetToUnicode (h, str, bytea, out errbufSize);\r
+ \r
string errmsg = String.Empty;\r
if (errbufSize > 0)\r
errmsg = str.ToString ();\r
+ \r
info.ErrorMessage = String.Copy (errmsg);\r
Marshal.FreeHGlobal (errbuf);
return info;
}
+ public OciErrorInfo HandleError ()
+ {
+ return HandleError (this);
+ }
+
#endregion // Methods
}
}
if (!disposed) {
try {
if (disposing) {
- if (server != null)
- server.Dispose ();
- if (session != null)
- session.Dispose ();
+ //if (server != null)
+ // server.Dispose ();
+ //if (session != null)
+ // session.Dispose ();
}
disposed = true;
} finally {
bool disposed = false;
string username;
string password;
+ OciCredentialType credentialType;
#endregion // Fields
set { serviceHandle = value; }
}
- public string Username {
+ internal string Username {
get { return username; }
set { username = value; }
}
- public string Password {
- get { return password; }
+ internal string Password {
+ get { return String.Empty; }
set { password = value; }
}
int status = 0;
- status = OciCalls.OCIAttrSetString (this,
- OciHandleType.Session,
- username,
- (uint) username.Length,
- OciAttributeType.Username,
- errorHandle);
-
- if (status != 0)
- return false;
-
- status = OciCalls.OCIAttrSetString (this,
- OciHandleType.Session,
- password,
- (uint) password.Length,
- OciAttributeType.Password,
- errorHandle);
-
- if (status != 0)
- return false;
+ if (credentialType == OciCredentialType.RDBMS) {
+ status = OciCalls.OCIAttrSetString (this,
+ OciHandleType.Session,
+ username,
+ (uint) username.Length,
+ OciAttributeType.Username,
+ errorHandle);
+
+ if (status != 0)
+ return false;
+
+ status = OciCalls.OCIAttrSetString (this,
+ OciHandleType.Session,
+ password,
+ (uint) password.Length,
+ OciAttributeType.Password,
+ errorHandle);
+
+ if (status != 0)
+ return false;
+ }
status = OciCalls.OCISessionBegin (Service,
errorHandle,
if (!begun)
return;
OciCalls.OCISessionEnd (Service, error, this, 0);
+ begun = false;
}
protected override void Dispose (bool disposing)
{
if (!disposed) {
try {
- EndSession (errorHandle);
+ //EndSession (errorHandle);
disposed = false;
} finally {
base.Dispose (disposing);
throw new OracleException (info.ErrorCode, info.ErrorMessage);
}
- if (!session.BeginSession (OciCredentialType.RDBMS, OciSessionMode.Default, ErrorHandle)) {
+ if (!session.BeginSession (conInfo.CredentialType, OciSessionMode.Default, ErrorHandle)) {
OciErrorInfo info = error.HandleError ();
Disconnect ();
throw new OracleException (info.ErrorCode, info.ErrorMessage);
public void Disconnect()
{
- if (session != null)
+ if (session != null) {
+ session.EndSession (error);
session.Dispose ();
- if (server != null)
+ session = null;
+ }
+ if (server != null) {
+ server.Detach (error);
server.Dispose ();
- if (error != null)
+ server = null;
+ }
+ if (error != null) {
error.Dispose ();
- if (service != null)
+ error = null;
+ }
+ if (service != null) {
service.Dispose ();
- if (environment != null)
+ service = null;
+ }
+ if (environment != null) {
environment.Dispose ();
+ environment = null;
+ }
}
#endregion // Methods
using System.Data.OracleClient.Oci;
using System.Drawing.Design;
using System.EnterpriseServices;
+using System.Globalization;
using System.Text;
namespace System.Data.OracleClient
internal string Password;
internal string Database;
internal string ConnectionString;
+ internal OciCredentialType CredentialType;
}
[DefaultEvent ("InfoMessage")]
conInfo.Username = "";
conInfo.Database = "";
conInfo.Password = "";
+ conInfo.CredentialType = OciCredentialType.RDBMS;
if (connectionString == String.Empty)
return;
// TODO:
break;
case "INTEGRATED SECURITY":
- throw new NotImplementedException ();
+ if (ConvertToBoolean("integrated security", value) == false)
+ conInfo.CredentialType = OciCredentialType.RDBMS;
+ else
+ conInfo.CredentialType = OciCredentialType.External;
+ break;
case "PERSIST SECURITY INFO":
// TODO:
break;
conInfo.Username = value;
break;
case "POOLING" :
- switch (value.ToUpper ()) {
- case "YES":
- case "TRUE":
- pooling = true;
- break;
- case "NO":
- case "FALSE":
- pooling = false;
- break;
- default:
- throw new ArgumentException("Connection parameter not supported: '" + name + "'");
- }
+ pooling = ConvertToBoolean("pooling", value);
break;
default:
throw new ArgumentException("Connection parameter not supported: '" + name + "'");
}
}
+ private bool ConvertToBoolean(string key, string value)
+ {
+ string upperValue = value.ToUpper();
+
+ if (upperValue == "TRUE" ||upperValue == "YES") {
+ return true;
+ }
+ else if (upperValue == "FALSE" || upperValue == "NO") {
+ return false;
+ }
+
+ throw new ArgumentException(string.Format(CultureInfo.InvariantCulture,
+ "Invalid value \"{0}\" for key '{1}'.", value, key));
+ }
+
+
~OracleConnection()
{
Dispose (false);
return manager.CreateConnection (info);
}
- ~OracleConnectionPool ()
+ public void Dispose ()
{
if (list != null) {
- if (list.Count > 0) {
- for (int c = 0; c < list.Count; c++) {
- // There are available connections in the pool
- OciGlue connection = (OciGlue)list [c];
- list.RemoveAt (c);
- if (connection.Connected) {
+ if (list.Count > 0)
+ foreach (OciGlue connection in list)
+ if (connection.Connected)
connection.Disconnect ();
- connection = null;
- }
- }
- }
- }
+ list.Clear ();
+ list = null;
+ }
}
}
}
return oci;
}
+ public void Dispose ()
+ {
+ if (pools != null) {
+ foreach (OracleConnectionPool pool in pools)
+ pool.Dispose ();
+ pools.Clear ();
+ pools = null;
+ }
+ }
+
~OracleConnectionPoolManager ()
{
+ Dispose ();
}
}
}