Explorar o código

2005-12-20 Daniel Morgan <[email protected]>

	* 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

svn path=/trunk/mcs/; revision=54672
Daniel Morgan %!s(int64=20) %!d(string=hai) anos
pai
achega
f0565901b2

+ 14 - 0
mcs/class/System.Data.OracleClient/ChangeLog

@@ -1,3 +1,17 @@
+2005-12-20  Daniel Morgan <[email protected]>
+
+	* 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 <[email protected]>
 
 	* System.Data.OracleClient/OracleConnectionPoolManager.cs

+ 1 - 22
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciEnvironmentHandle.cs

@@ -50,28 +50,7 @@ namespace System.Data.OracleClient.Oci {
 
 		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;
 		}
 

+ 17 - 5
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciErrorHandle.cs

@@ -47,7 +47,7 @@ namespace System.Data.OracleClient.Oci {
 			}
 		}
 
-		public OciErrorInfo HandleError () 
+		public static OciErrorInfo HandleError (OciHandle hand) 
 		{
 			OciErrorInfo info;
 			info.ErrorCode = 0;
@@ -56,7 +56,7 @@ namespace System.Data.OracleClient.Oci {
 			int errbufSize = 4096;
 			IntPtr errbuf = Marshal.AllocHGlobal (errbufSize);
 
-			OciCalls.OCIErrorGet (this, 
+			OciCalls.OCIErrorGet (hand, 
 				1,
 				IntPtr.Zero,
 				out info.ErrorCode,
@@ -64,24 +64,36 @@ namespace System.Data.OracleClient.Oci {
 				(uint) errbufSize,
 				OciHandleType.Error);
 
-			//object err = Marshal.PtrToStringAuto (errbuf);
 			byte[] bytea = new byte[errbufSize];
 			Marshal.Copy (errbuf, bytea, 0, errbufSize);
 			errbufSize = 0;
+			
+			OciHandle h = hand.Parent;
+			if (h == null)
+				h = hand;
+
 			// first call to OCICharSetToUnicode gets the size
-			OciCalls.OCICharSetToUnicode (Parent, null, bytea, out errbufSize);
+			OciCalls.OCICharSetToUnicode (h, null, bytea, out errbufSize);
 			StringBuilder str = new StringBuilder (errbufSize);
+			
 			// second call to OCICharSetToUnicode gets the string
-			OciCalls.OCICharSetToUnicode (Parent, str, bytea, out errbufSize);
+			OciCalls.OCICharSetToUnicode (h, str, bytea, out errbufSize);
+			
 			string errmsg = String.Empty;
 			if (errbufSize > 0)
 				errmsg = str.ToString ();
+			
 			info.ErrorMessage = String.Copy (errmsg);
 			Marshal.FreeHGlobal (errbuf);
 
 			return info;
 		}
 
+		public OciErrorInfo HandleError () 
+		{
+			return HandleError (this);
+		}
+
 		#endregion // Methods
 	}
 }

+ 4 - 4
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciServiceHandle.cs

@@ -56,10 +56,10 @@ namespace System.Data.OracleClient.Oci {
 			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 {

+ 27 - 23
mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciSessionHandle.cs

@@ -29,6 +29,7 @@ namespace System.Data.OracleClient.Oci {
 		bool disposed = false;
 		string username;
 		string password;
+		OciCredentialType credentialType;
 
 		#endregion // Fields
 
@@ -48,13 +49,13 @@ namespace System.Data.OracleClient.Oci {
 			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; }
 		}
 
@@ -68,25 +69,27 @@ namespace System.Data.OracleClient.Oci {
 
 			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,
@@ -107,13 +110,14 @@ namespace System.Data.OracleClient.Oci {
 			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);

+ 18 - 6
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OciGlue.cs

@@ -132,7 +132,7 @@ namespace System.Data.OracleClient.Oci {
 				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);
@@ -175,16 +175,28 @@ namespace System.Data.OracleClient.Oci {
 
 		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

+ 25 - 13
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleConnection.cs

@@ -32,6 +32,7 @@ using System.Data;
 using System.Data.OracleClient.Oci;
 using System.Drawing.Design;
 using System.EnterpriseServices;
+using System.Globalization;
 using System.Text;
 
 namespace System.Data.OracleClient 
@@ -42,6 +43,7 @@ namespace System.Data.OracleClient
 		internal string Password;
 		internal string Database;
 		internal string ConnectionString;
+		internal OciCredentialType CredentialType;
 	}
 
 	[DefaultEvent ("InfoMessage")]
@@ -351,6 +353,7 @@ namespace System.Data.OracleClient
 			conInfo.Username = "";
 			conInfo.Database = "";
 			conInfo.Password = "";
+			conInfo.CredentialType = OciCredentialType.RDBMS;
 
 			if (connectionString == String.Empty)
 				return;
@@ -420,7 +423,11 @@ namespace System.Data.OracleClient
 					// 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;
@@ -443,18 +450,7 @@ namespace System.Data.OracleClient
 					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 + "'");
@@ -462,6 +458,22 @@ namespace System.Data.OracleClient
 			}
 		}
 
+		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);

+ 7 - 12
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleConnectionPool.cs

@@ -97,21 +97,16 @@ namespace System.Data.OracleClient
 			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;
+			}			
 		}
 	}
 }

+ 11 - 0
mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleConnectionPoolManager.cs

@@ -58,8 +58,19 @@ namespace System.Data.OracleClient
 			return oci;
 		}
 
+		public void Dispose () 
+		{
+			if (pools != null) {
+				foreach (OracleConnectionPool pool in pools)
+					pool.Dispose ();
+				pools.Clear ();
+				pools = null;
+			}
+		}
+
 		~OracleConnectionPoolManager () 
 		{
+			Dispose ();
 		}
 	}
 }