Author: suresh
Date: 2005-04-07 10:25:50 -0400 (Thu, 07 Apr 2005)
New Revision: 42641

Added:
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs
   trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs
   trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs
Modified:
   trunk/mcs/class/Mono.Data.Tds/ChangeLog
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ITds.cs
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
   trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.dll.sources
   trunk/mcs/class/System.Data/ChangeLog
   trunk/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
   trunk/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
   trunk/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs
   trunk/mcs/class/System.Data/System.Data.dll.sources
Log:
In System.Data/System.Data.SqlClient: Implemented asynchronous command 
execution.
In Mono.Data.Tds: Implemented asynchronous command execution at tds driver 
level.

Implemented by Sureshkumar T  <[EMAIL PROTECTED]> &  Ankit Jain  <[EMAIL 
PROTECTED]>



Modified: trunk/mcs/class/Mono.Data.Tds/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/ChangeLog     2005-04-07 13:37:42 UTC (rev 
42640)
+++ trunk/mcs/class/Mono.Data.Tds/ChangeLog     2005-04-07 14:25:50 UTC (rev 
42641)
@@ -1,3 +1,8 @@
+2005-04-07  Sureshkumar T  <[EMAIL PROTECTED]>
+
+       * Mono.Data.Tds.dll.sources: In Mono.Data.Tds.Protocol
+       Added TdsAsyncResult.cs & TdsAsyncState.cs.
+
 2004-08-14 Geoff Norton <[EMAIL PROTECTED]>
 
         * Mono.Data.Tds.Protocol/TdsComm.cs: 

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog      
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ChangeLog      
2005-04-07 14:25:50 UTC (rev 42641)
@@ -1,3 +1,25 @@
+2005-04-07  Sureshkumar T  <[EMAIL PROTECTED]>
+           Ankit Jain     <[EMAIL PROTECTED]>
+
+       * TdsComm.cs: GetPhysicalPacket is devided further into seperate
+       methods GetPhysicalPacketHeader and
+       GetPhysicalPacketData. Implemented asynchronous ReadPacket method.
+
+       * ITds.cs: Added additional methods for asynchronous operations.
+
+       * Tds.cs: Implemented base methods for asynchronous
+       operations. Version specific derivatives should override for
+       specific operations.
+
+       * Tds70.cs: For stored procedure, "exec" is prefixed by
+       default. Implemented asynchronous method for asynchronous command
+       execution.
+
+       * TdsAsyncState.cs: Added. Internal asynchronous state object.
+
+       * TdsAsyncResult.cs: Added. Internal asynchronous result
+       implementation.
+
 2005-04-04  Sureshkumar T  <[EMAIL PROTECTED]>
 
        * Tds50.cs: Pass parameters to the server. cut & paste from

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ITds.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ITds.cs        
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/ITds.cs        
2005-04-07 14:25:50 UTC (rev 42641)
@@ -104,5 +104,34 @@
                event TdsInternalInfoMessageEventHandler TdsInfoMessage;
 
                #endregion // Events
+
+#if NET_2_0
+                #region Asynchronous Methods
+                IAsyncResult BeginExecuteNonQuery (string sql,
+                                                   TdsMetaParameterCollection 
parameters,
+                                                   AsyncCallback callback,
+                                                   object state);
+                void EndExecuteNonQuery (IAsyncResult ar);
+                IAsyncResult BeginExecuteQuery (string sql,
+                                                   TdsMetaParameterCollection 
parameters,
+                                                   AsyncCallback callback,
+                                                   object state);
+                void EndExecuteQuery (IAsyncResult ar);
+
+                IAsyncResult BeginExecuteProcedure (string prolog,
+                                                                    string 
epilog,
+                                                                    string 
cmdText,
+                                                                    bool 
IsNonQuery,
+                                                                    
TdsMetaParameterCollection parameters,
+                                                                    
AsyncCallback callback,
+                                                                    object 
state);
+                void EndExecuteProcedure (IAsyncResult ar);
+
+                void WaitFor (IAsyncResult ar);
+                void CheckAndThrowException (IAsyncResult ar);
+
+                #endregion //Asynchronous Methods
+#endif // NET_2_0
+
        }
 }

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs 2005-04-07 
13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs 2005-04-07 
14:25:50 UTC (rev 42641)
@@ -1327,5 +1327,118 @@
                }
 
                #endregion // Private Methods
+
+#if NET_2_0
+                #region asynchronous methods
+                protected IAsyncResult BeginExecuteQueryInternal (string sql, 
bool wantResults, 
+                                                          AsyncCallback 
callback, object state)
+                {
+                        moreResults = true;
+                       doneProc = false;
+                       messages.Clear ();
+                       outputParameters.Clear ();
+
+                        TdsAsyncResult ar = new TdsAsyncResult (callback, 
state);
+                        ar.TdsAsyncState.WantResults = wantResults;
+
+                       Comm.StartPacket (TdsPacketType.Query);
+                       Comm.Append (sql);
+                       Comm.SendPacket ();
+
+                        Comm.BeginReadPacket (new 
AsyncCallback(OnBeginExecuteQueryCallback), 
+                                                                    ar);
+                        return ar;
+                }
+                
+                protected void EndExecuteQueryInternal (IAsyncResult ar)
+                {
+                        if (!ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                        TdsAsyncResult result = (TdsAsyncResult) ar;
+                        if (result.IsCompletedWithException)
+                                throw result.Exception;
+                }
+
+                protected void OnBeginExecuteQueryCallback (IAsyncResult ar)
+                {
+                        TdsAsyncResult result = (TdsAsyncResult) ar.AsyncState;
+                        TdsAsyncState tdsState = (TdsAsyncState) 
result.TdsAsyncState;
+
+                        try {
+                                Comm.EndReadPacket (ar);
+                                if (!tdsState.WantResults)
+                                        SkipToEnd ();
+                        } catch (Exception e) {
+                                result.MarkComplete (e);
+                                return;
+                        }
+                        result.MarkComplete ();
+                }
+                
+
+                public virtual IAsyncResult BeginExecuteNonQuery (string sql,
+                                                                  
TdsMetaParameterCollection parameters,
+                                                                  
AsyncCallback callback,
+                                                                  object state)
+                {
+                        // abstract, kept to be backward compatiable.
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+                
+                public virtual void EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+                
+                public virtual IAsyncResult BeginExecuteQuery (string sql,
+                                                                  
TdsMetaParameterCollection parameters,
+                                                                  
AsyncCallback callback,
+                                                                  object state)
+                {
+                        // abstract, kept to be backward compatiable.
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+                
+                public virtual void EndExecuteQuery (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+
+                public virtual IAsyncResult BeginExecuteProcedure (string 
prolog,
+                                                                    string 
epilog,
+                                                                    string 
cmdText,
+                                                                    bool 
IsNonQuery,
+                                                                    
TdsMetaParameterCollection parameters,
+                                                                    
AsyncCallback callback,
+                                                                    object 
state)
+                {
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+                
+                public virtual void EndExecuteProcedure (IAsyncResult ar)
+                {
+                        // abstract method
+                        throw new NotImplementedException ("should not be 
called!");
+                }
+                
+                public void WaitFor (IAsyncResult ar)
+                {
+                        if (! ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                }
+
+                public void CheckAndThrowException (IAsyncResult ar)
+                {
+                        TdsAsyncResult result = (TdsAsyncResult) ar;
+                        if (result.IsCompleted && 
result.IsCompletedWithException)
+                                throw result.Exception;
+                }
+
+                #endregion // asynchronous methods
+#endif // NET_2_0
+
+
        }
 }

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs       
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs       
2005-04-07 14:25:50 UTC (rev 42641)
@@ -144,10 +144,10 @@
                                        }
                                }
                        }
-                       if (count > 0 || exec.Length > 0)
-                               exec = "exec " + exec;
-
-                       return String.Format ("{0}{1}{2}{3} {4}\n{5}", 
declare.ToString (), set.ToString (), exec, procedure, BuildParameters (), 
select.ToString ());  
+                        exec = "exec " + exec;
+                        
+                        string sql = String.Format ("{0}{1}{2}{3} {4}\n{5}", 
declare.ToString (), set.ToString (), exec, procedure, BuildParameters (), 
select.ToString ());
+                       return sql;
                }
 
                public override bool Connect (TdsConnectionParameters 
connectionParameters)
@@ -560,5 +560,75 @@
                }
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Asynchronous Methods
+                public override IAsyncResult BeginExecuteNonQuery (string 
cmdText,
+                                                          
TdsMetaParameterCollection parameters,
+                                                          AsyncCallback 
callback,
+                                                          object state)
+                {
+                        Parameters = parameters;
+                        string sql = cmdText;
+                       if (Parameters != null && Parameters.Count > 0)
+                               sql = BuildExec (cmdText);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, 
false, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+                public override IAsyncResult BeginExecuteQuery (string cmdText,
+                                                                
TdsMetaParameterCollection parameters,
+                                                                AsyncCallback 
callback,
+                                                                object state)
+                {
+                        Parameters = parameters;
+                        string sql = cmdText;
+                       if (Parameters != null && Parameters.Count > 0)
+                               sql = BuildExec (cmdText);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, 
true, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteQuery (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+
+                public override IAsyncResult BeginExecuteProcedure (string 
prolog,
+                                                                    string 
epilog,
+                                                                    string 
cmdText,
+                                                                    bool 
IsNonQuery,
+                                                                    
TdsMetaParameterCollection parameters,
+                                                                    
AsyncCallback callback,
+                                                                    object 
state)
+                {
+
+                        
+                        Parameters = parameters;
+                       string pcall = BuildProcedureCall (cmdText);
+                        string sql = String.Format ("{0};{1};{2};", prolog, 
pcall, epilog);
+
+                        IAsyncResult ar = BeginExecuteQueryInternal (sql, 
!IsNonQuery, callback, state);
+                        return ar;
+                }
+
+                public override void EndExecuteProcedure (IAsyncResult ar)
+                {
+                        EndExecuteQueryInternal (ar);
+                }
+
+
+
+                #endregion // Asynchronous Methods
+#endif // NET_2_0
+
        }
 }

Added: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs      
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncResult.cs      
2005-04-07 14:25:50 UTC (rev 42641)
@@ -0,0 +1,128 @@
+//
+// Mono.Data.Tds.Protocol.TdsAsyncResult.cs
+//
+// Author:
+//   T Sureshkumar <[EMAIL PROTECTED]>
+//   Ankit Jain <[EMAIL PROTECTED]>
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#if NET_2_0
+using System;
+using System.Threading;
+
+namespace Mono.Data.Tds.Protocol
+{
+        internal class TdsAsyncResult : IAsyncResult
+        {
+                private TdsAsyncState _tdsState;
+                private WaitHandle _waitHandle;
+                private bool _completed = false;
+                private bool _completedSyncly = false;
+                private AsyncCallback _userCallback;
+                private object _retValue;
+                private Exception _exception = null;
+
+                public TdsAsyncResult (AsyncCallback userCallback, 
TdsAsyncState tdsState)
+                {
+                        _tdsState = tdsState;
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+
+                public TdsAsyncResult (AsyncCallback userCallback, object 
state)
+                {
+                        _tdsState = new TdsAsyncState (state);
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+                
+
+                public object AsyncState 
+                {
+                        get {   return _tdsState.UserState; }
+                }
+
+                internal TdsAsyncState TdsAsyncState
+                {
+                        get {   return _tdsState; }
+                }
+
+                public WaitHandle AsyncWaitHandle 
+                {
+                        get { return _waitHandle; }
+
+                }
+
+                public bool IsCompleted 
+                {
+                        get {   return _completed; }
+                }
+
+                public bool IsCompletedWithException
+                {
+                        get {   return _exception != null; }
+                }
+
+                public Exception Exception
+                {
+                        get {   return _exception; }
+                }
+
+                public bool CompletedSynchronously 
+                {
+                        get {   return _completedSyncly; }
+                }
+
+                internal object ReturnValue
+                {
+                        get {   return _retValue; }
+                        set {   _retValue = value; }
+                }
+
+                internal void MarkComplete () 
+                {
+                        _completed = true;
+                        _exception = null;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+
+                internal void MarkComplete (Exception e) 
+                {
+                        _completed = true;
+                        _exception = e;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+        }
+}
+
+#endif // NET_2_0

Added: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs       
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsAsyncState.cs       
2005-04-07 14:25:50 UTC (rev 42641)
@@ -0,0 +1,63 @@
+//
+// Mono.Data.Tds.Protocol.TdsAsyncState.cs
+//
+// Author:
+//   T Sureshkumar <[EMAIL PROTECTED]>
+//   Ankit Jain <[EMAIL PROTECTED]>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Net.Sockets;
+
+
+namespace Mono.Data.Tds.Protocol {
+        internal class TdsAsyncState
+        {
+                object  _userState;
+                bool    _wantResults = false;
+
+                public TdsAsyncState (object userState)
+                {
+                        _userState = userState;
+                }
+
+                public object UserState
+                {
+                        get {return _userState;}
+                        set {_userState = value;}
+                }
+
+                public bool WantResults
+                {
+                        get {return _wantResults;}
+                        set {_wantResults = value;}
+                }
+
+        }
+}
+#endif // NET_2_0

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs     
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsComm.cs     
2005-04-07 14:25:50 UTC (rev 42641)
@@ -385,8 +385,14 @@
 
                private void GetPhysicalPacket ()
                {
-                       int nread = 0;
+                        int dataLength = GetPhysicalPacketHeader ();
+                        GetPhysicalPacketData (dataLength);
+               }
 
+                private int GetPhysicalPacketHeader ()
+                {
+                        int nread = 0;
+                                                
                        // read the header
                        while (nread < 8)
                                nread += stream.Read (tmpBuf, nread, 8 - nread);
@@ -406,19 +412,26 @@
                        if (len < 0) {
                                throw new Exception (String.Format ("Confused 
by a length of {0}", len));
                        }
+                        
+                        return len;
 
-                       // now get the data
-                       nread = 0;
-                       while (nread < len) {
-                               nread += stream.Read (inBuffer, nread, len - 
nread);
+                }
+                
+                private void GetPhysicalPacketData (int length)
+                {
+                        // now get the data
+                       int nread = 0;
+                       while (nread < length) {
+                               nread += stream.Read (inBuffer, nread, length - 
nread);
                        }
 
                        packetsReceived++;
 
                        // adjust the bookkeeping info about the incoming buffer
-                       inBufferLength = len;
+                       inBufferLength = length;
                        inBufferIndex = 0;
-               }
+                }
+                
 
                private static int Ntohs (byte[] buf, int offset)
                {
@@ -519,6 +532,59 @@
                }
 
                #endregion // Methods
+#if NET_2_0
+                #region Async Methods
+
+                public IAsyncResult BeginReadPacket (AsyncCallback callback, 
object stateObject)
+               {
+                        TdsAsyncResult ar = new TdsAsyncResult (callback, 
stateObject);
+
+                        stream.BeginRead (tmpBuf, 0, 8, new 
AsyncCallback(OnReadPacketCallback), ar);
+                        return ar;
+               }
+                
+                /// <returns>Packet size in bytes</returns>
+                public int EndReadPacket (IAsyncResult ar)
+                {
+                        if (!ar.IsCompleted)
+                                ar.AsyncWaitHandle.WaitOne ();
+                        return (int) ((TdsAsyncResult) ar).ReturnValue;
+                }
+                
+
+                public void OnReadPacketCallback (IAsyncResult 
socketAsyncResult)
+                {
+                        TdsAsyncResult ar = (TdsAsyncResult) 
socketAsyncResult.AsyncState;
+                        int nread = stream.EndRead (socketAsyncResult);
+                        
+                        while (nread < 8)
+                                nread += stream.Read (tmpBuf, nread, 8 - 
nread);
+
+                       TdsPacketType packetType = (TdsPacketType) tmpBuf[0];
+                       if (packetType != TdsPacketType.Logon && packetType != 
TdsPacketType.Query && packetType != TdsPacketType.Reply) 
+                       {
+                               throw new Exception (String.Format ("Unknown 
packet type {0}", tmpBuf[0]));
+                       }
+
+                       // figure out how many bytes are remaining in this 
packet.
+                       int len = Ntohs (tmpBuf, 2) - 8;
+
+                       if (len >= inBuffer.Length) 
+                               inBuffer = new byte[len];
+
+                       if (len < 0) {
+                               throw new Exception (String.Format ("Confused 
by a length of {0}", len));
+                       }
+
+                        GetPhysicalPacketData (len);
+                        int value = len + 8;
+                        ar.ReturnValue = ((object)value); // packet size
+                        ar.MarkComplete ();
+                }
+                
+                #endregion // Async Methods
+#endif // NET_2_0
+
        }
 
 }

Modified: trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.dll.sources
===================================================================
--- trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.dll.sources     2005-04-07 
13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/Mono.Data.Tds/Mono.Data.Tds.dll.sources     2005-04-07 
14:25:50 UTC (rev 42641)
@@ -31,3 +31,5 @@
 Mono.Data.Tds.Protocol/TdsTimeoutException.cs
 Mono.Data.Tds.Protocol/TdsVersion.cs
 Mono.Data.Tds.Protocol/TODOAttribute.cs
+Mono.Data.Tds.Protocol/TdsAsyncState.cs
+Mono.Data.Tds.Protocol/TdsAsyncResult.cs

Modified: trunk/mcs/class/System.Data/ChangeLog
===================================================================
--- trunk/mcs/class/System.Data/ChangeLog       2005-04-07 13:37:42 UTC (rev 
42640)
+++ trunk/mcs/class/System.Data/ChangeLog       2005-04-07 14:25:50 UTC (rev 
42641)
@@ -1,3 +1,8 @@
+2005-04-07  Sureshkumar T  <[EMAIL PROTECTED]>
+
+       * System.Data.dll.sources: In System.Data.SqlClient
+       Added SqlAsyncState.cs & SqlAsyncResult.cs
+
 2005-04-04  Sureshkumar T  <[EMAIL PROTECTED]>
 
        * System.Data_test.dll.sources: Added

Modified: trunk/mcs/class/System.Data/System.Data.SqlClient/ChangeLog
===================================================================
--- trunk/mcs/class/System.Data/System.Data.SqlClient/ChangeLog 2005-04-07 
13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.SqlClient/ChangeLog 2005-04-07 
14:25:50 UTC (rev 42641)
@@ -1,3 +1,17 @@
+2005-04-07  Sureshkumar T  <[EMAIL PROTECTED]>
+           Ankit Jain     <[EMAIL PROTECTED]>
+
+       * SqlConnection.cs: Implemented additional connection string
+       property "Asynchronous Processing".
+
+       * SqlCommand.cs: Implemented Asynchronous command execution API.
+
+       * SqlAsyncState.cs: A internal state object for asynchronous
+       operations.
+
+       * SqlAsyncResult.cs: Added. Class to hold result for asynchronous
+       queries.
+
 2005-03-28  Sureshkumar T  <[EMAIL PROTECTED]>
 
        * SqlCommand.cs: Execute: Add a semicolon at the end of

Added: trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs 
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncResult.cs 
2005-04-07 14:25:50 UTC (rev 42641)
@@ -0,0 +1,139 @@
+//
+// System.Data.SqlClient.SqlAsyncResult.cs
+//
+// Author:
+//   T Sureshkumar <[EMAIL PROTECTED]>
+//   Ankit Jain <[EMAIL PROTECTED]>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+#if NET_2_0
+using System;
+using System.Threading;
+
+namespace System.Data.SqlClient
+{
+        internal class SqlAsyncResult : IAsyncResult
+        {
+                private SqlAsyncState   _sqlState;
+                private WaitHandle      _waitHandle;
+                private bool            _completed = false;
+                private bool            _completedSyncly = false;
+                private bool            _ended = false;
+                private AsyncCallback   _userCallback = null;
+                private object          _retValue;
+                private string          _endMethod;
+                private IAsyncResult    _internal;
+
+                public SqlAsyncResult (AsyncCallback userCallback, 
SqlAsyncState sqlState)
+                {
+                        _sqlState = sqlState;
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+
+                public SqlAsyncResult (AsyncCallback userCallback, object 
state)
+                {
+                        _sqlState = new SqlAsyncState (state);
+                        _userCallback = userCallback;
+                        _waitHandle = new ManualResetEvent (false);
+                }
+                
+                public object AsyncState 
+                {
+                        get {   return _sqlState.UserState; }
+                }
+
+                internal SqlAsyncState SqlAsyncState
+                {
+                        get {   return _sqlState; }
+                }
+
+                public WaitHandle AsyncWaitHandle 
+                {
+                        get { return _waitHandle; }
+
+                }
+
+                public bool IsCompleted 
+                {
+                        get {   return _completed; }
+                }
+
+                public bool CompletedSynchronously 
+                {
+                        get {   return _completedSyncly; }
+                }
+
+                internal object ReturnValue
+                {
+                        get {   return _retValue; }
+                        set {   _retValue = value; }
+                }
+
+                public string EndMethod
+                {
+                        get {   return _endMethod; }
+                        set {   _endMethod = value; }
+                }
+
+                public bool Ended
+                {
+                        get {   return _ended; }
+                        set {   _ended = value; }
+                }
+
+
+                internal IAsyncResult InternalResult
+                {
+                        get {   return _internal; }
+                        set {   _internal = value; }
+                }
+
+                public AsyncCallback BubbleCallback
+                {
+                        get { return new AsyncCallback (Bubbleback); }
+                        
+                }
+
+                internal void MarkComplete () 
+                {
+                        _completed = true;
+                        ((ManualResetEvent)_waitHandle).Set ();
+
+                        if (_userCallback != null)
+                                _userCallback (this);
+                }
+                
+                public void Bubbleback (IAsyncResult ar)
+                {
+                        this.MarkComplete ();
+                }
+        }
+}
+
+#endif // NET_2_0

Added: trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs  
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.SqlClient/SqlAsyncState.cs  
2005-04-07 14:25:50 UTC (rev 42641)
@@ -0,0 +1,56 @@
+//
+// System.Data.SqlClient.SqlAsyncState.cs
+//
+// Author:
+//   T Sureshkumar <[EMAIL PROTECTED]>
+//   Ankit Jain <[EMAIL PROTECTED]>
+//
+
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+#if NET_2_0
+using System;
+using System.Net.Sockets;
+
+
+namespace System.Data.SqlClient
+{
+        internal class SqlAsyncState
+        {
+                object  _userState;
+
+                public SqlAsyncState (object userState)
+                {
+                        _userState = userState;
+                }
+
+                public object UserState
+                {
+                        get {return _userState;}
+                        set {_userState = value;}
+                }
+        }
+}
+#endif // NET_2_0

Modified: trunk/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs     
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs     
2005-04-07 14:25:50 UTC (rev 42641)
@@ -542,6 +542,12 @@
                                throw new InvalidOperationException ("There is 
already an open DataReader associated with this Connection which must be closed 
first.");
                        if (Connection.XmlReader != null)
                                throw new InvalidOperationException ("There is 
already an open XmlReader associated with this Connection which must be closed 
first.");
+#if NET_2_0
+                        if (method.StartsWith ("Begin") && 
!Connection.AsyncProcessing)
+                                throw new InvalidOperationException ("This 
Connection object is not " + 
+                                                                     "in 
Asynchronous mode. Use 'Asynchronous" +
+                                                                     " 
Processing = true' to set it.");
+#endif // NET_2_0
                }
 
 #if NET_2_0
@@ -579,5 +585,215 @@
 #endif // NET_2_0
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Asynchronous Methods
+
+                internal IAsyncResult BeginExecuteInternal (CommandBehavior 
behavior, 
+                                                            bool wantResults,
+                                                            AsyncCallback 
callback, 
+                                                            object state)
+                {
+                        IAsyncResult ar = null;
+                        Connection.Tds.RecordsAffected = 0;
+                       TdsMetaParameterCollection parms = 
Parameters.MetaParameters;
+                       if (preparedStatement == null) {
+                               bool schemaOnly = ((behavior & 
CommandBehavior.SchemaOnly) > 0);
+                               bool keyInfo = ((behavior & 
CommandBehavior.KeyInfo) > 0);
+
+                               StringBuilder sql1 = new StringBuilder ();
+                               StringBuilder sql2 = new StringBuilder ();
+
+                               if (schemaOnly || keyInfo)
+                                       sql1.Append ("SET FMTONLY OFF;");
+                               if (keyInfo) {
+                                       sql1.Append ("SET NO_BROWSETABLE ON;");
+                                       sql2.Append ("SET NO_BROWSETABLE OFF;");
+                               }
+                               if (schemaOnly) {
+                                       sql1.Append ("SET FMTONLY ON;");
+                                       sql2.Append ("SET FMTONLY OFF;");
+                               }
+
+                               switch (CommandType) {
+                               case CommandType.StoredProcedure:
+                                        string prolog = "";
+                                        string epilog = "";
+                                       if (keyInfo || schemaOnly)
+                                               prolog = sql1.ToString ();
+                                        if (keyInfo || schemaOnly)
+                                               epilog = sql2.ToString ();
+                                        Connection.Tds.BeginExecuteProcedure 
(prolog,
+                                                                              
epilog,
+                                                                              
CommandText,
+                                                                              
!wantResults,
+                                                                              
parms,
+                                                                              
callback,
+                                                                              
state);
+                                                                              
+                                       break;
+                               case CommandType.Text:
+                                       string sql = String.Format 
("{0}{1};{2}", sql1.ToString (), CommandText, sql2.ToString ());
+                                        if (wantResults)
+                                                ar = 
Connection.Tds.BeginExecuteQuery (sql, parms, 
+                                                                               
        callback, state);
+                                        else
+                                                ar = 
Connection.Tds.BeginExecuteNonQuery (sql, parms, callback, state);
+                                       break;
+                               }
+                       }
+                       else 
+                               Connection.Tds.ExecPrepared (preparedStatement, 
parms, CommandTimeout, wantResults);
+
+                        return ar;
+
+                }
+
+                internal void EndExecuteInternal (IAsyncResult ar)
+                {
+                        SqlAsyncResult sqlResult = ( (SqlAsyncResult) ar);
+                        Connection.Tds.WaitFor (sqlResult.InternalResult);
+                        Connection.Tds.CheckAndThrowException 
(sqlResult.InternalResult);
+                }
+
+                public IAsyncResult BeginExecuteNonQuery ()
+                {
+                        return BeginExecuteNonQuery (null, null);
+                }
+
+                public IAsyncResult BeginExecuteNonQuery (AsyncCallback 
callback, object state)
+                {
+                        ValidateCommand ("BeginExecuteNonQuery");
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, 
state);
+                        ar.EndMethod = "EndExecuteNonQuery";
+                        ar.InternalResult = BeginExecuteInternal 
(CommandBehavior.Default, false, ar.BubbleCallback, ar);
+                        return ar;
+                }
+
+                public int EndExecuteNonQuery (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteNonQuery");
+                        EndExecuteInternal (ar);
+                        
+                        int ret;
+                        if (commandType == CommandType.StoredProcedure)
+                                ret = -1;
+                        else {
+                                // .NET documentation says that except for 
INSERT, UPDATE and
+                                // DELETE  where the return value is the 
number of rows affected
+                                // for the rest of the commands the return 
value is -1.        
+                                if 
((CommandText.ToUpper().IndexOf("UPDATE")!=-1) ||
+                                    
(CommandText.ToUpper().IndexOf("INSERT")!=-1) ||   
+                                    
(CommandText.ToUpper().IndexOf("DELETE")!=-1))     
+                                        ret = Connection.Tds.RecordsAffected;
+                                else
+                                        ret = -1;
+                        }
+                        GetOutputParameters ();
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return ret;
+                }
+
+                public IAsyncResult BeginExecuteReader ()
+                {
+                        return BeginExecuteReader (null, null, 
CommandBehavior.Default);
+                }
+
+                public IAsyncResult BeginExecuteReader (CommandBehavior 
behavior)
+                {
+                        return BeginExecuteReader (null, null, behavior);
+                }
+                
+                public IAsyncResult BeginExecuteReader (AsyncCallback 
callback, object state)
+                {
+                        return BeginExecuteReader (callback, state, 
CommandBehavior.Default);
+                }
+
+                public IAsyncResult BeginExecuteReader (AsyncCallback 
callback, object state, CommandBehavior behavior)
+                {
+                        ValidateCommand ("BeginExecuteReader");
+                        this.behavior = behavior;
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, 
state);
+                        ar.EndMethod = "EndExecuteReader";
+                        IAsyncResult tdsResult = BeginExecuteInternal 
(behavior, true, 
+                                                                       
ar.BubbleCallback, state);
+                        ar.InternalResult = tdsResult;
+                        return ar;
+                }
+
+                public SqlDataReader EndExecuteReader (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteReader");
+                        EndExecuteInternal (ar);
+                        SqlDataReader reader = null;
+                        try {
+                                reader = new SqlDataReader (this);
+                       }
+                       catch (TdsTimeoutException e) {
+                                // if behavior is closeconnection, even if it 
throws exception
+                                // the connection has to be closed.
+                                if ((behavior & 
CommandBehavior.CloseConnection) != 0)
+                                        Connection.Close ();
+                                throw SqlException.FromTdsInternalException 
((TdsInternalException) e);
+                       } catch (SqlException) {
+                                // if behavior is closeconnection, even if it 
throws exception
+                                // the connection has to be closed.
+                                if ((behavior & 
CommandBehavior.CloseConnection) != 0)
+                                        Connection.Close ();
+
+                                throw;
+                        }
+
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return reader;
+                }
+
+                public IAsyncResult BeginExecuteXmlReader (AsyncCallback 
callback, object state)
+                {
+                        ValidateCommand ("BeginExecuteXmlReader");
+                        SqlAsyncResult ar = new SqlAsyncResult (callback, 
state);
+                        ar.EndMethod = "EndExecuteXmlReader";
+                        ar.InternalResult = BeginExecuteInternal (behavior, 
true, 
+                                                                       
ar.BubbleCallback, state);
+                        return ar;
+                }
+
+                public XmlReader EndExecuteXmlReader (IAsyncResult ar)
+                {
+                        ValidateAsyncResult (ar, "EndExecuteXmlReader");
+                        EndExecuteInternal (ar);
+                        SqlDataReader reader = new SqlDataReader (this);
+                        SqlXmlTextReader textReader = new SqlXmlTextReader 
(reader);
+                        XmlReader xmlReader = new XmlTextReader (textReader);
+                        ( (SqlAsyncResult) ar).Ended = true;
+                        return xmlReader;
+                }
+
+
+                internal void ValidateAsyncResult (IAsyncResult ar, string 
endMethod)
+                {
+                        if (ar == null)
+                                throw new ArgumentException ("result passed is 
null!");
+                        if (! (ar is SqlAsyncResult))
+                                throw new ArgumentException (String.Format 
("cannot test validity of types {0}",
+                                                                            
ar.GetType ()
+                                                                            ));
+                        SqlAsyncResult result = (SqlAsyncResult) ar;
+                        
+                        if (result.EndMethod != endMethod)
+                                throw new InvalidOperationException 
(String.Format ("Mismatched {0} called for AsyncResult. " + 
+                                                                               
     "Expected call to {1} but {0} is called instead.",
+                                                                               
     endMethod,
+                                                                               
     result.EndMethod
+                                                                               
     ));
+                        if (result.Ended)
+                                throw new InvalidOperationException 
(String.Format ("The method {0}  cannot be called " + 
+                                                                               
     "more than once for the same AsyncResult.",
+                                                                               
     endMethod));
+
+                }
+
+                #endregion // Asynchronous Methods
+#endif // NET_2_0
        }
 }

Modified: trunk/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs
===================================================================
--- trunk/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs  
2005-04-07 13:37:42 UTC (rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs  
2005-04-07 14:25:50 UTC (rev 42641)
@@ -719,6 +719,11 @@
                                parameters["POOLING"] = "true";
                        if (null == parameters.Get ("WORKSTATION ID") && null 
== parameters.Get ("WSID"))
                                parameters["WORKSTATION ID"] = 
Dns.GetHostName();
+#if NET_2_0
+                       if (null == parameters.Get ("ASYNC") &&
+                            null == parameters.Get ("ASYNCHRONOUS PROCESSING"))
+                               parameters ["ASYNCHRONOUS PROCESSING"] = 
"false";
+#endif
                }
 
                private void SetProperties (NameValueCollection parameters)
@@ -789,6 +794,10 @@
 #if NET_2_0
                                case "MULTIPLEACTIVERESULTSETS":
                                        break;
+                                case "ASYNCHRONOUS PROCESSING" :
+                                case "ASYNC" :
+                                        async = ConvertToBoolean (name, value);
+                                        break;
 #endif
                                        case "NET" :
                                        case "NETWORK" :
@@ -918,5 +927,25 @@
                }
 
                #endregion // Methods
+
+#if NET_2_0
+                #region Fields Net 2
+
+                bool async = false;
+
+                #endregion // Fields  Net 2
+
+                #region Properties Net 2
+
+                [DataSysDescription ("Enable Asynchronous processing, 
'Asynchrouse Processing=true/false' in the ConnectionString.")]  
+               [DesignerSerializationVisibility 
(DesignerSerializationVisibility.Hidden)]
+               internal bool AsyncProcessing  {
+                       get { return async; }
+               }
+
+                #endregion // Properties Net 2
+
+#endif // NET_2_0
+
        }
 }

Modified: trunk/mcs/class/System.Data/System.Data.dll.sources
===================================================================
--- trunk/mcs/class/System.Data/System.Data.dll.sources 2005-04-07 13:37:42 UTC 
(rev 42640)
+++ trunk/mcs/class/System.Data/System.Data.dll.sources 2005-04-07 14:25:50 UTC 
(rev 42641)
@@ -295,6 +295,8 @@
 System.Data.SqlClient/SqlNotificationInfo.cs
 System.Data.SqlClient/SqlNotificationSource.cs
 System.Data.SqlClient/ISqlNotificationReceiver.cs
+System.Data.SqlClient/SqlAsyncState.cs
+System.Data.SqlClient/SqlAsyncResult.cs
 System.Data.SqlClient/SqlClientPermission.cs
 System.Data.SqlClient/SqlClientPermissionAttribute.cs
 System.Data.SqlClient/SqlCommand.cs

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to