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