List:Commits« Previous MessageNext Message »
From:rburnett Date:September 12 2006 11:58pm
Subject:Connector/NET commit: r335 - in trunk: TestSuite mysqlclient
View as plain text  
Modified:
   trunk/TestSuite/CommandTests.cs
   trunk/mysqlclient/MySql.Data.2005.csproj
   trunk/mysqlclient/Resources.resx
   trunk/mysqlclient/command.cs
Log:
Implemented WL 3427 - MySqlCommand.commandTimeout



Modified: trunk/TestSuite/CommandTests.cs
===================================================================
--- trunk/TestSuite/CommandTests.cs	2006-09-05 15:05:30 UTC (rev 334)
+++ trunk/TestSuite/CommandTests.cs	2006-09-12 21:58:33 UTC (rev 335)
@@ -416,6 +416,31 @@
             // now cancel the command
             cmd.Cancel();
         }
+
+        [Test]
+        public void Timeout()
+        {
+            // first we need a routine that will run for a bit
+            execSQL("CREATE PROCEDURE spTest() BEGIN SET @start=NOW()+0; REPEAT SET
@end=NOW()-@start; " +
+                "UNTIL @end >= 5000 END REPEAT; SELECT @start, @end; END");
+
+            DateTime start = DateTime.Now;
+            try
+            {
+                MySqlCommand cmd = new MySqlCommand("spTest", conn);
+                cmd.CommandType = CommandType.StoredProcedure;
+                cmd.CommandTimeout = 15;
+                cmd.ExecuteNonQuery();
+                Assert.Fail("Should not get to this point");
+            }
+            catch (MySqlException ex) {
+                TimeSpan ts = DateTime.Now.Subtract(start);
+                Assert.IsTrue(ex.Message.StartsWith("Timeout expired"));
+                Assert.IsTrue(ts.TotalSeconds < 20);
+            }
+
+
+        }
 	}
 
 

Modified: trunk/mysqlclient/MySql.Data.2005.csproj
===================================================================
--- trunk/mysqlclient/MySql.Data.2005.csproj	2006-09-05 15:05:30 UTC (rev 334)
+++ trunk/mysqlclient/MySql.Data.2005.csproj	2006-09-12 21:58:33 UTC (rev 335)
@@ -102,7 +102,6 @@
     </Compile>
     <Compile Include="CommandBuilder.cs">
     </Compile>
-    <Compile Include="CommandMonitor.cs" />
     <Compile Include="common\ContextString.cs" />
     <Compile Include="common\NamedPipeStream.cs" />
     <Compile Include="common\NativeMethods.cs" />

Modified: trunk/mysqlclient/Resources.resx
===================================================================
--- trunk/mysqlclient/Resources.resx	2006-09-05 15:05:30 UTC (rev 334)
+++ trunk/mysqlclient/Resources.resx	2006-09-12 21:58:33 UTC (rev 335)
@@ -261,4 +261,10 @@
   <data name="CancelNotSupported" xml:space="preserve">
     <value>Canceling an active query is only supported on MySQL 5.0.0 and above.
</value>
   </data>
+  <data name="Timeout" xml:space="preserve">
+    <value>Timeout expired.  The timeout period elapsed prior to completion of the
operation or the server is not responding.</value>
+  </data>
+  <data name="CancelNeeds50" xml:space="preserve">
+    <value>Canceling an executing query requires MySQL 5.0 or higher.</value>
+  </data>
 </root>
\ No newline at end of file

Modified: trunk/mysqlclient/command.cs
===================================================================
--- trunk/mysqlclient/command.cs	2006-09-05 15:05:30 UTC (rev 334)
+++ trunk/mysqlclient/command.cs	2006-09-12 21:58:33 UTC (rev 335)
@@ -26,6 +26,8 @@
 using System.Text;
 using MySql.Data.Common;
 using System.ComponentModel;
+using System.Threading;
+using System.Diagnostics;
 
 namespace MySql.Data.MySqlClient
 {
@@ -47,8 +49,11 @@
 		private int					cursorPageSize;
 		private IAsyncResult		asyncResult;
         private bool                designTimeVisible;
-        internal Int64 lastInsertedId;
-        private Statement statement;
+        internal Int64              lastInsertedId;
+        private Statement           statement;
+        private int                 commandTimeout;
+        private bool                canCancel;
+        private bool                timedOut;
 
 		/// <include file='docs/mysqlcommand.xml' path='docs/ctor1/*'/>
 		public MySqlCommand()
@@ -60,7 +65,10 @@
 			updatedRowSource = UpdateRowSource.Both;
 			cursorPageSize = 0;
             cmdText = String.Empty;
-		}
+            commandTimeout = 30;
+            canCancel = false;
+            timedOut = false;
+        }
 
 		/// <include file='docs/mysqlcommand.xml' path='docs/ctor2/*'/>
 		public MySqlCommand(string cmdText) : this()
@@ -123,26 +131,21 @@
 			get { return (int)updatedRowCount; }
 		}
 
-/*        internal int StatementId
-        {
-            get
-            {
-                if (this.preparedStatement == null)
-                    return -1;
-                return (preparedStatement.StatementId);
-            }
-        }*/
-
 		/// <include file='docs/mysqlcommand.xml' path='docs/CommandTimeout/*'/>
 #if !CF
 		[Category("Misc")]
 		[Description("Time to wait for command to execute")]
+        [DefaultValue(30)]
 #endif
 		public override int CommandTimeout
 		{
-			// TODO: support this
-			get  { return 0; }
-			set  { if (value != 0) throw new NotSupportedException(); }
+            get { return commandTimeout; }
+            set 
+            {
+                if (!connection.driver.Version.isAtLeast(5, 0, 0))
+                    throw new NotSupportedException(Resources.CancelNeeds50);
+                commandTimeout = value; 
+            }
 		}
 
 		/// <include file='docs/mysqlcommand.xml' path='docs/CommandType/*'/>
@@ -237,17 +240,22 @@
             MySqlConnection c = new
MySqlConnection(connection.Settings.GetConnectionString(true));
             try
             {
+                Trace.WriteLine("connstr = " + c.ConnectionString);
                 c.Open();
                 MySqlCommand cmd = new MySqlCommand(String.Format("KILL QUERY {0}",
                     connection.ServerThread), c);
                 cmd.ExecuteNonQuery();
             }
+            catch (Exception)
+            {
+                throw;
+            }
             finally
             {
                 if (c != null)
                     c.Close();
             }
-		}
+        }
 
 		/// <summary>
 		/// Creates a new instance of a <see cref="MySqlParameter"/> object.
@@ -310,6 +318,15 @@
 			return ExecuteReader(CommandBehavior.Default);
 		}
 
+        private void TimeoutExpired(object commandObject)
+        {
+            MySqlCommand cmd = (commandObject as MySqlCommand);
+            if (cmd.canCancel)
+            {
+                cmd.timedOut = true;
+                cmd.Cancel();
+            }
+        }
 
 		/// <include file='docs/mysqlcommand.xml' path='docs/ExecuteReader1/*'/>
 		public new MySqlDataReader ExecuteReader(CommandBehavior behavior)
@@ -344,18 +361,33 @@
             {
                 MySqlDataReader reader = new MySqlDataReader(this, statement, behavior);
 
+                // start a threading timer on our command timeout 
+                timedOut = false;
+                if (connection.driver.Version.isAtLeast(5, 0, 0))
+                {
+                    TimerCallback timerDelegate =
+                        new TimerCallback(TimeoutExpired);
+                    Timer t = new Timer(timerDelegate, this, this.CommandTimeout * 1000,
Timeout.Infinite);
+                }
+
                 // execute the statement
                 statement.Execute(Parameters);
 
+                canCancel = true;
                 reader.NextResult();
+                canCancel = false;
                 connection.Reader = reader;
                 return reader;
             }
             catch (MySqlException ex)
             {
                 // if we caught an exception because of a cancel, then just return null
-                if (ex.ErrorCode == 1317)
+                if (ex.Number == 1317)
+                {
+                    if (timedOut)
+                        throw new MySqlException(Resources.Timeout);
                     return null;
+                }
                 throw;
             }
 		}

Thread
Connector/NET commit: r335 - in trunk: TestSuite mysqlclientrburnett12 Sep