Modified:
trunk/CHANGES
trunk/TestSuite/BaseTest.cs
trunk/TestSuite/CharacterSetTests.cs
trunk/TestSuite/CommandBuilderTests.cs
trunk/TestSuite/ConnectionTests.cs
trunk/TestSuite/CultureTests.cs
trunk/TestSuite/DataTypeTests.cs
trunk/TestSuite/ParameterTests.cs
trunk/TestSuite/StoredProcedure.cs
trunk/TestSuite/Syntax.cs
trunk/mysqlclient/CharSetMap.cs
trunk/mysqlclient/CommandBuilder.cs
trunk/mysqlclient/CommandResult.cs
trunk/mysqlclient/ConnectionString.cs
trunk/mysqlclient/Driver.cs
trunk/mysqlclient/MySqlStream.cs
trunk/mysqlclient/MySqlStreamWriter.cs
trunk/mysqlclient/StoredProcedure.cs
trunk/mysqlclient/Types/MySqlDateTime.cs
trunk/mysqlclient/Types/MySqlDecimal.cs
trunk/mysqlclient/command.cs
trunk/mysqlclient/common/StreamCreator.cs
trunk/mysqlclient/datareader.cs
trunk/mysqlclient/nativedriver.cs
trunk/mysqlclient/parameter.cs
trunk/mysqlclient/parameter_collection.cs
Log:
Merge from old 1.0 tree (revision 108) to current trunk.
Modified: trunk/CHANGES
===================================================================
--- trunk/CHANGES 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/CHANGES 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,4 +1,4 @@
-- Version 1.1.0
+- Version 1.1.0
Bug #6214 CommandText: Question mark in comment line is being parsed as a parameter [fixed]
Implemented intial usage advisor
Merged cursor support in
@@ -8,6 +8,51 @@
Embedded server is now working (libmysqld.dll)
Added internal implemention of SHA1 so we don't have to distribute the OpenNetCF on mobile devices
+- Version 1.0.5
+ Bug #8667 OUT parameters are not being valued [fixed]
+ Bug #8574 MySQLCommandBuilder unable to support inline functions [fixed]
+ Bug #8509 MySqlDataAdapter.FillSchema does not interpret unsigned integer [fixed]
+ Bug #8630 Executing a query with the SchemaOnly option reads the entire resultset [fixed]
+ Bug #7398 MySqlParameterCollection doesn't allow parameters without filled in names [fixed]
+ Fixed problem parsing stored procedure parameter defs such as OUT val INT UNSIGNED
+ Bug #7623 Adding MySqlParameter causes error if MySqlDbType is Decimal [fixed]
+ Now supports the new decimal type introduced in 5.0.3
+ Bug #8929 Timestamp values with a date > 10/29/9997 cause problems [fixed]
+ Bug #8514 CURRENT_TIMESTAMP default not respected [fixed]
+ Bug #9237 MySqlDataReader.AffectedRecords not set to -1 [fixed]
+ Bug #9262 Floating point numbers boundary conditions (MinValue/MaxValue)
+ (added code but really this isn't a bug)
+ Bug #7951 Error reading a timestamp column
+ Bug #10644 Cannot call a stored function directly from Connector/Net
+ Bug #9722 Connector does not recognize parameters separated by a linefeed
+ Bug #10281 Clone issue with MySqlConnection
+ Bug #11450 Connector/Net, current database and stored procedures
+ Fixed bug where adding parameter objects that had been independently constructed did not work right.
+ Bug #11490 certain incorrect queries trigger connection must be valid and open message
+ Bug #8228 turkish character set causing the error [fixed]
+ Bug #8387 Connecting with NAMES and character_set_results can be up to 18 times slower.
+ Improved this by only issuing a SET NAMES if character_set_client or
+ character_set_connection is different than what we are wanting.
+
+ Bug #8382 Commandbuilder does not handle queries to other databases than the default one-
+ fixed this one with the help of a patch from Henrik Johnson.
+
+ Bug #10637 Fail connect to specified MySql Hosts
+ The problem was that we were using BeginConnect/EndConnect to implement connect
+ timeout. Each one of these uses a worker thread from the .NET thread pool. This
+ thread pool only has a default of 25 threads so on a very heavily loaded system,
+ it's possible it could run out. Connect has now been recoded to not use a
+ worker thread.
+
+ Bug #11542 Call to Stored Procedure throws exception when SP has no arguments [fixed]
+
+ Bug #11294 Wrong data type getting values from grouping functions on integers
+ with mysql-5 [this was fixed with earlier bug]
+
+ Bug #11621 connector does not support charset cp1250 [fixed]
+
+ Bug #11550 Adding decimal parameters problem [fixed]
+
1-20-05 - Version 1.0.4
Bug #7243 calling prepare causing exception [fixed]
@@ -138,8 +183,8 @@
- Fixed persist security info case problem
- Fixed GetBool so that 1, true, "true", and "yes" all count as trueWL# 2024 Make parameter mark configurable
- Added the "old syntax" connection string parameter to allow use of @ parameter marker
- - Fixed Bug- - Fixed Bug+ - Fixed Bug #4658 MySqlCommandBuilder
+ - Fixed Bug #4864 ByteFX.MySqlClient caches passwords if 'Persist Security Info' is false
- Updated license banner in all source files to include FLOSS exception
- Added new .Types namespace and implementations for most current MySql types
- Added MySqlField41 as a subclass of MySqlField
@@ -595,7 +640,7 @@
* Update connection string designer to support Use Compression flag
2/15/2003
-* Fixed string encoding so that European characters like +* Fixed string encoding so that European characters like ä will work correctly
2/9/2003
* Creating base classes to aid in building new data providers
Modified: trunk/TestSuite/BaseTest.cs
===================================================================
--- trunk/TestSuite/BaseTest.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/BaseTest.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -38,12 +38,22 @@
protected string user;
protected string password;
protected string nopassuser;
+ protected string otherkeys;
public BaseTest()
{
csAdditions = ";pooling=false";
}
+ protected string GetConnectionString(bool includedb)
+ {
+ if (includedb)
+ return String.Format("server={0};user id={1};password={2};database=test;" +
+ "persist security info=true;{3}{4}", host, user, password, otherkeys, csAdditions );
+ return String.Format("server={0};user id={1};password={2};" +
+ "persist security info=true;{3}{4}", host, user, password, otherkeys, csAdditions );
+ }
+
protected void Open()
{
try
@@ -52,10 +62,8 @@
user = ConfigurationSettings.AppSettings["user"];
password = ConfigurationSettings.AppSettings["password"];
nopassuser = ConfigurationSettings.AppSettings["nopassuser"];
- string other = ConfigurationSettings.AppSettings["otherkeys"];
- string connString = String.Format("server={0};user id={1};password={2};database=test;persist security info=true;{3}",
- host, user, password, other );
- connString += csAdditions;
+ otherkeys = ConfigurationSettings.AppSettings["otherkeys"];
+ string connString = GetConnectionString(true);
conn = new MySqlConnection( connString );
conn.Open();
}
Modified: trunk/TestSuite/CharacterSetTests.cs
===================================================================
--- trunk/TestSuite/CharacterSetTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/CharacterSetTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,80 +1,126 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-using System;
-using System.Data;
-using System.IO;
-using System.Globalization;
-using System.Threading;
-using NUnit.Framework;
-
-namespace MySql.Data.MySqlClient.Tests
-{
- [TestFixture()]
- public class CharacterSetTests : BaseTest
- {
- [TestFixtureSetUp]
- public void FixtureSetup()
- {
- csAdditions = ";pooling=false";
- Open();
- }
-
- [TestFixtureTearDown]
- public void FixtureTeardown()
- {
- Close();
- }
-
- [Test]
- public void UseFunctions()
- {
- execSQL("DROP TABLE IF EXISTS Test");
- execSQL("CREATE TABLE Test ( valid char, UserCode varchar(100), password varchar(100) ) CHARSET latin1");
-
- MySqlConnection c = new MySqlConnection( conn.ConnectionString + ";charset=latin1" );
- c.Open();
- MySqlCommand cmd = new MySqlCommand("SELECT valid FROM Test WHERE Valid = 'Y' AND " +
- "UserCode = 'username' AND Password = AES_ENCRYPT('Password','abc')", c);
- object o = cmd.ExecuteScalar();
- c.Close();
- }
-
-
- [Test]
- public void Latin1Connection()
- {
- if (! Is41 && ! Is50) return;
-
- execSQL("DROP TABLE IF EXISTS Test");
- execSQL("CREATE TABLE Test (id INT, name VARCHAR(200)) CHARSET latin1");
- execSQL("INSERT INTO Test VALUES( 1, _latin1 'Test')");
-
- MySqlConnection c = new MySqlConnection( conn.ConnectionString + ";charset=latin1" );
- c.Open();
-
- MySqlCommand cmd = new MySqlCommand("SELECT id FROM Test WHERE name LIKE 'Test'", c);
- object id = cmd.ExecuteScalar();
- Assert.AreEqual( 1, id );
- c.Close();
- }
-
- }
-}
++
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Modified: trunk/TestSuite/CommandBuilderTests.cs
===================================================================
--- trunk/TestSuite/CommandBuilderTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/CommandBuilderTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -118,5 +118,31 @@
Assert.AreEqual( "Test2", dt.Rows[0]["name"] );
}
+ /// <summary>
+ /// Bug #8382 Commandbuilder does not handle queries to other databases than the default one-
+ /// </summary>
+ [Test]
+ public void DifferentDatabase()
+ {
+ execSQL("INSERT INTO test (id, name) VALUES (1,'test1')");
+ execSQL("INSERT INTO test (id, name) VALUES (2,'test2')");
+ execSQL("INSERT INTO test (id, name) VALUES (3,'test3')");
+
+ conn.ChangeDatabase("mysql");
+
+ MySqlDataAdapter da = new MySqlDataAdapter("SELECT id, name FROM test.test", conn);
+ MySqlCommandBuilder cb = new MySqlCommandBuilder(da);
+ DataSet ds = new DataSet();
+ da.Fill(ds);
+
+ ds.Tables[0].Rows[0]["id"] = 4;
+ DataSet changes = ds.GetChanges();
+ da.Update(changes);
+ ds.Merge( changes );
+ ds.AcceptChanges();
+
+ conn.ChangeDatabase("test");
+ }
+
}
}
Modified: trunk/TestSuite/ConnectionTests.cs
===================================================================
--- trunk/TestSuite/ConnectionTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/ConnectionTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -19,6 +19,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using System.Data;
using MySql.Data.MySqlClient;
using NUnit.Framework;
using System.Configuration;
@@ -147,6 +148,7 @@
{
MySqlConnection c = new MySqlConnection( conn.ConnectionString + ";pooling=false" );
c.Open();
+ Assert.IsTrue(c.State == ConnectionState.Open);
Assert.AreEqual( "test", c.Database.ToLower() );
@@ -214,5 +216,14 @@
Assert.Fail( ex.Message );
}
}
+ /// <summary>
+ /// Bug #10281 Clone issue with MySqlConnection
+ /// </summary>
+ [Test()]
+ public void TestConnectionClone()
+ {
+ MySqlConnection c = new MySqlConnection();
+ MySqlConnection clone = (MySqlConnection) ((ICloneable)c).Clone();
+ }
}
}
Modified: trunk/TestSuite/CultureTests.cs
===================================================================
--- trunk/TestSuite/CultureTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/CultureTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -100,6 +100,30 @@
}
}
+ /// <summary>
+ /// Bug #8228 turkish character set causing the error
+ /// </summary>
+ [Test]
+ public void Turkish()
+ {
+ CultureInfo curCulture = Thread.CurrentThread.CurrentCulture;
+ CultureInfo curUICulture = Thread.CurrentThread.CurrentUICulture;
+ CultureInfo c = new CultureInfo("tr-TR");
+ Thread.CurrentThread.CurrentCulture = c;
+ Thread.CurrentThread.CurrentUICulture = c;
+ try
+ {
+ MySqlConnection newConn = new MySqlConnection(GetConnectionString(true));
+ newConn.Open();
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+
+ Thread.CurrentThread.CurrentCulture = c;
+ Thread.CurrentThread.CurrentUICulture = c;
+ }
}
}
Modified: trunk/TestSuite/DataTypeTests.cs
===================================================================
--- trunk/TestSuite/DataTypeTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/DataTypeTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -310,20 +310,65 @@
Assert.AreEqual( MySqlDbType.Int16, p.MySqlDbType );
}
+ /// <summary>
+ /// Bug #7951 - Error reading timestamp column
+ /// </summary>
[Test]
public void Timestamp()
{
execSQL("DROP TABLE IF EXISTS test");
- execSQL("CREATE TABLE test (id int, ts TIMESTAMP)");
- execSQL("INSERT INTO test (id) VALUES (1)");
+ execSQL("CREATE TABLE test (id int, dt DATETIME, ts2 TIMESTAMP(2), ts4 TIMESTAMP(4), " +
+ "ts6 TIMESTAMP(6), ts8 TIMESTAMP(8), ts10 TIMESTAMP(10), ts12 TIMESTAMP(12), " +
+ "ts14 TIMESTAMP(14))");
+ execSQL("INSERT INTO test (id, dt, ts2, ts4, ts6, ts8, ts10, ts12, ts14) " +
+ "VALUES (1, Now(), Now(), Now(), Now(), Now(), Now(), Now(), Now())");
- DateTime now = DateTime.Now;
MySqlDataAdapter da = new MySqlDataAdapter( "SELECT * FROM test", conn);
DataTable dt = new DataTable();
da.Fill(dt);
+ DateTime now = (DateTime)dt.Rows[0]["dt"];
Assert.AreEqual( 1, dt.Rows[0]["id"] );
- Assert.AreEqual( now.Date, ((DateTime)dt.Rows[0]["ts"]).Date );
+
+ DateTime ts2 = (DateTime)dt.Rows[0]["ts2"];
+ Assert.AreEqual( now.Year, ts2.Year );
+
+ DateTime ts4 = (DateTime)dt.Rows[0]["ts4"];
+ Assert.AreEqual( now.Year, ts4.Year );
+ Assert.AreEqual( now.Month, ts4.Month );
+
+ DateTime ts6 = (DateTime)dt.Rows[0]["ts6"];
+ Assert.AreEqual( now.Year, ts6.Year );
+ Assert.AreEqual( now.Month, ts6.Month );
+ Assert.AreEqual( now.Day, ts6.Day );
+
+ DateTime ts8 = (DateTime)dt.Rows[0]["ts8"];
+ Assert.AreEqual( now.Year, ts8.Year );
+ Assert.AreEqual( now.Month, ts8.Month );
+ Assert.AreEqual( now.Day, ts8.Day );
+
+ DateTime ts10 = (DateTime)dt.Rows[0]["ts10"];
+ Assert.AreEqual( now.Year, ts10.Year );
+ Assert.AreEqual( now.Month, ts10.Month );
+ Assert.AreEqual( now.Day, ts10.Day );
+ Assert.AreEqual( now.Hour, ts10.Hour );
+ Assert.AreEqual( now.Minute, ts10.Minute );
+
+ DateTime ts12 = (DateTime)dt.Rows[0]["ts12"];
+ Assert.AreEqual( now.Year, ts12.Year );
+ Assert.AreEqual( now.Month, ts12.Month );
+ Assert.AreEqual( now.Day, ts12.Day );
+ Assert.AreEqual( now.Hour, ts12.Hour );
+ Assert.AreEqual( now.Minute, ts12.Minute );
+ Assert.AreEqual( now.Second, ts12.Second );
+
+ DateTime ts14 = (DateTime)dt.Rows[0]["ts14"];
+ Assert.AreEqual( now.Year, ts14.Year );
+ Assert.AreEqual( now.Month, ts14.Month );
+ Assert.AreEqual( now.Day, ts14.Day );
+ Assert.AreEqual( now.Hour, ts14.Hour );
+ Assert.AreEqual( now.Minute, ts14.Minute );
+ Assert.AreEqual( now.Second, ts14.Second );
}
@@ -382,6 +427,39 @@
execSQL( "DROP TABLE IF EXISTS foo");
}
+/* [Test]
+ public void TypeBoundaries()
+ {
+ execSQL("DROP TABLE IF EXISTS Test");
+ execSQL("CREATE TABLE Test ( MaxDouble DOUBLE, MinDouble DOUBLE, MaxFloat FLOAT, MinFloat FLOAT )");
+
+ MySqlCommand cmd = new MySqlCommand(
+ "INSERT Test (MaxDouble, MinDouble, MaxFloat, MinFloat) VALUES " +
+ "(?maxDouble, ?minDouble, ?maxFloat, ?minFloat)", conn);
+ cmd.Parameters.Add("?maxDouble", MySqlDouble.MaxValue);
+ cmd.Parameters.Add("?minDouble", MySqlDouble.MinValue);
+ cmd.Parameters.Add("?maxFloat", MySqlFloat.MaxValue);
+ cmd.Parameters.Add("?minFloat", MySqlFloat.MinValue);
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT * FROM Test";
+ try
+ {
+ using (MySqlDataReader reader = cmd.ExecuteReader())
+ {
+ reader.Read();
+ Assert.AreEqual(MySqlDouble.MaxValue, reader.GetDouble(0));
+ Assert.AreEqual(MySqlDouble.MinValue, reader.GetDouble(1));
+ Assert.AreEqual(MySqlFloat.MaxValue, reader.GetFloat(2));
+ Assert.AreEqual(MySqlFloat.MinValue, reader.GetFloat(3));
+ }
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ }*/
+
[Test]
public void BitAndDecimal()
{
@@ -410,5 +488,70 @@
}
}
- }
+ /// <summary>
+ /// Bug #10486 MySqlDataAdapter.Update error for decimal column
+ /// </summary>
+ [Test]
+ public void UpdateDecimalColumns()
+ {
+ execSQL("DROP TABLE IF EXISTS test");
+ execSQL("CREATE TABLE test (id int not null auto_increment primary key, " +
+ "dec1 decimal(10,1))");
+
+ MySqlDataAdapter da = new MySqlDataAdapter("SELECT * FROM test", conn);
+ MySqlCommandBuilder cb = new MySqlCommandBuilder(da);
+ DataTable dt = new DataTable();
+ da.Fill(dt);
+ DataRow row = dt.NewRow();
+ row["id"] = DBNull.Value;
+ row["dec1"] = 23.4;
+ dt.Rows.Add(row);
+ da.Update(dt);
+
+ dt.Clear();
+ da.Fill(dt);
+ Assert.AreEqual(1, dt.Rows.Count);
+ Assert.AreEqual(1, dt.Rows[0]["id"]);
+ Assert.AreEqual(23.4, dt.Rows[0]["dec1"]);
+ }
+
+ [Test]
+ public void DecimalTests()
+ {
+ execSQL("DROP TABLE IF EXISTS test");
+ execSQL("CREATE TABLE test (val decimal(10,1))");
+
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO test VALUES(?dec)", conn);
+ cmd.Parameters.Add("?dec", (decimal)2.4);
+ Assert.AreEqual(1, cmd.ExecuteNonQuery());
+
+ cmd.Prepare();
+ Assert.AreEqual(1, cmd.ExecuteNonQuery());
+
+ cmd.CommandText = "SELECT * FROM test";
+ MySqlDataReader reader = null;
+ try
+ {
+ reader = cmd.ExecuteReader();
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader[0] is Decimal);
+ Assert.AreEqual(2.4, reader[0]);
+
+ Assert.IsTrue(reader.Read());
+ Assert.IsTrue(reader[0] is Decimal);
+ Assert.AreEqual(2.4, reader[0]);
+
+ Assert.IsFalse(reader.Read());
+ Assert.IsFalse(reader.NextResult());
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ if (reader != null) reader.Close();
+ }
+ }
+ }
}
Modified: trunk/TestSuite/ParameterTests.cs
===================================================================
--- trunk/TestSuite/ParameterTests.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/ParameterTests.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,281 +1,308 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-using System;
-using System.Data;
-using MySql.Data.MySqlClient;
-using NUnit.Framework;
-
-namespace MySql.Data.MySqlClient.Tests
-{
- /// <summary>
- /// Summary description for ConnectionTests.
- /// </summary>
- [TestFixture]
- public class ParameterTests : BaseTest
- {
- [TestFixtureSetUp]
- public void SetUp()
- {
- Open();
- execSQL("DROP TABLE IF EXISTS Test; CREATE TABLE Test (id INT NOT NULL, name VARCHAR(100), dt DATETIME, tm TIME, ts TIMESTAMP, PRIMARY KEY(id))");
- }
-
- [TestFixtureTearDown]
- public void TearDown()
- {
- Close();
- }
-
- [Test()]
- public void TestUserVariables()
- {
- MySqlCommand cmd = new MySqlCommand("SET @myvar = 'test'", conn);
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "SELECT @myvar";
- MySqlDataReader reader = cmd.ExecuteReader();
- try
- {
- Assert.AreEqual( true, reader.Read());
- Assert.AreEqual( "test", reader.GetValue(0));
- }
- catch (Exception ex)
- {
- Assert.Fail( ex.Message );
- }
- finally
- {
- reader.Close();
- }
- }
-
- [Test()]
- public void TestQuoting()
- {
- MySqlCommand cmd = new MySqlCommand("", conn);
- cmd.CommandText = "INSERT INTO Test VALUES (?id, ?name, NULL,NULL,NULL)";
- cmd.Parameters.Add( new MySqlParameter("?id", 1));
- cmd.Parameters.Add( new MySqlParameter("?name", "my ' value"));
- cmd.ExecuteNonQuery();
-
- cmd.Parameters[0].Value = 2;
- cmd.Parameters[1].Value = @"my "" value";
- cmd.ExecuteNonQuery();
-
- cmd.Parameters[0].Value = 3;
- cmd.Parameters[1].Value = @"my ` value";
- cmd.ExecuteNonQuery();
-
- cmd.Parameters[0].Value = 4;
- cmd.Parameters[1].Value = @"my - cmd.ExecuteNonQuery();
-
- cmd.Parameters[0].Value = 5;
- cmd.Parameters[1].Value = @"my \ value";
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "SELECT * FROM Test";
- MySqlDataReader reader = null;
- try
- {
- reader = cmd.ExecuteReader();
- reader.Read();
- Assert.AreEqual( "my ' value", reader.GetString(1));
- reader.Read();
- Assert.AreEqual( @"my "" value", reader.GetString(1));
- reader.Read();
- Assert.AreEqual( "my ` value", reader.GetString(1));
- reader.Read();
- Assert.AreEqual( "my - reader.Read();
- Assert.AreEqual( @"my \ value", reader.GetString(1));
- }
- catch (Exception ex)
- {
- Assert.Fail( ex.Message );
- }
- finally
- {
- if (reader != null) reader.Close();
- }
- }
-
- [Test()]
- public void TestDateTimeParameter()
- {
- MySqlCommand cmd = new MySqlCommand("", conn);
-
- TimeSpan time = new TimeSpan(0, 1, 2, 3);
- DateTime dt = new DateTime( 2003, 11, 11, 1, 2, 3 );
- cmd.CommandText = "INSERT INTO Test VALUES (1, 'test', ?dt, ?time, NULL)";
- cmd.Parameters.Add( new MySqlParameter("?time", time));
- cmd.Parameters.Add( new MySqlParameter("?dt", dt));
- int cnt = cmd.ExecuteNonQuery();
- Assert.AreEqual( 1, cnt, "Insert count" );
-
- cmd = new MySqlCommand("SELECT tm, dt, ts FROM Test WHERE id=1", conn);
- MySqlDataReader reader = cmd.ExecuteReader();
- reader.Read();
- TimeSpan time2 = (TimeSpan)reader.GetValue(0);
- Assert.AreEqual( time, time2 );
-
- DateTime dt2 = reader.GetDateTime(1);
- Assert.AreEqual( dt, dt2 );
-
- DateTime ts2 = reader.GetDateTime(2);
- reader.Close();
-
- // now check the timestamp column. We won't check the minute or second for obvious reasons
- DateTime now = DateTime.Now;
- Assert.AreEqual( now.Year, ts2.Year );
- Assert.AreEqual( now.Month, ts2.Month );
- Assert.AreEqual( now.Day, ts2.Day );
- Assert.AreEqual( now.Hour, ts2.Hour );
-
- // now we'll set some nulls and see how they are handled
- cmd = new MySqlCommand("UPDATE Test SET tm=?ts, dt=?dt WHERE id=1", conn);
- cmd.Parameters.Add( new MySqlParameter("?ts", DBNull.Value ));
- cmd.Parameters.Add( new MySqlParameter("?dt", DBNull.Value));
- cnt = cmd.ExecuteNonQuery();
- Assert.AreEqual( 1, cnt, "Update null count" );
-
- cmd = new MySqlCommand("SELECT tm, dt FROM Test WHERE id=1", conn);
- reader = cmd.ExecuteReader();
- reader.Read();
- object tso = reader.GetValue(0);
- object dto = reader.GetValue(1);
- Assert.AreEqual( DBNull.Value, tso, "Time column" );
- Assert.AreEqual( DBNull.Value, dto, "DateTime column" );
-
- reader.Close();
-
- cmd.CommandText = "DELETE FROM Test WHERE id=1";
- cmd.ExecuteNonQuery();
- }
-
- [Test()]
- public void NestedQuoting()
- {
- MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES(1, 'this is ?\"my value\"')", conn);
- int count = cmd.ExecuteNonQuery();
- Assert.AreEqual( 1, count );
- }
-
- [Test()]
- public void SetDbType()
- {
- try
- {
- IDbConnection conn2 = (IDbConnection)conn;
- IDbCommand cmd = conn.CreateCommand();
- IDbDataParameter prm = cmd.CreateParameter();
- prm.DbType = DbType.Int32;
- Assert.AreEqual( DbType.Int32, prm.DbType );
- }
- catch (Exception ex)
- {
- Assert.Fail( ex.Message );
- }
- }
-
- [Test()]
- public void UseOldSyntax()
- {
- string connStr = conn.ConnectionString + ";old syntax=yes;pooling=false";
- MySqlConnection conn2 = new MySqlConnection(connStr);
- conn2.Open();
-
- MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (@id, @name)", conn2);
- cmd.Parameters.Add( "@id", 33 );
- cmd.Parameters.Add( "@name", "Test" );
- cmd.ExecuteNonQuery();
-
- MySqlDataReader reader = null;
- try
- {
- cmd.CommandText = "SELECT * FROM Test";
- reader = cmd.ExecuteReader();
- reader.Read();
- Assert.AreEqual( 33, reader.GetInt32(0) );
- Assert.AreEqual( "Test", reader.GetString(1) );
- }
- catch( Exception ex)
- {
- Assert.Fail( ex.Message );
- }
- finally
- {
- if (reader != null) reader.Close();
- conn2.Close();
- }
- }
-
- [Test()]
- [ExpectedException(typeof(ArgumentException))]
- public void NullParameterObject()
- {
- MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?name)", conn);
- cmd.Parameters.Add( null );
- }
-
- [Test()]
- public void NullParameterValue()
- {
- MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?name)", conn);
- cmd.Parameters.Add( new MySqlParameter("?name", null));
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "SELECT name FROM Test WHERE id=1";
- object name = cmd.ExecuteScalar();
- Assert.AreEqual( DBNull.Value, name );
- }
-
- [Test()]
- public void OddCharsInParameterNames()
- {
- MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?nam$es)", conn);
- cmd.Parameters.Add( new MySqlParameter("?nam$es", "Test"));
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "INSERT INTO Test (id, name) VALUES (2, ?nam_es)";
- cmd.Parameters.Clear();
- cmd.Parameters.Add( new MySqlParameter("?nam_es", "Test2"));
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "INSERT INTO Test (id, name) VALUES (3, ?nam.es)";
- cmd.Parameters.Clear();
- cmd.Parameters.Add( new MySqlParameter("?nam.es", "Test3"));
- cmd.ExecuteNonQuery();
-
- cmd.CommandText = "SELECT name FROM Test WHERE id=1";
- object name = cmd.ExecuteScalar();
- Assert.AreEqual( "Test", name );
-
- cmd.CommandText = "SELECT name FROM Test WHERE id=2";
- name = cmd.ExecuteScalar();
- Assert.AreEqual( "Test2", name );
-
- cmd.CommandText = "SELECT name FROM Test WHERE id=3";
- name = cmd.ExecuteScalar();
- Assert.AreEqual( "Test3", name );
- }
- }
-}
+// Copyright (C) 2004 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
+using System.Data;
+using MySql.Data.MySqlClient;
+using NUnit.Framework;
+
+namespace MySql.Data.MySqlClient.Tests
+{
+ /// <summary>
+ /// Summary description for ConnectionTests.
+ /// </summary>
+ [TestFixture]
+ public class ParameterTests : BaseTest
+ {
+ [TestFixtureSetUp]
+ public void SetUp()
+ {
+ Open();
+ execSQL("DROP TABLE IF EXISTS Test; CREATE TABLE Test (id INT NOT NULL, name VARCHAR(100), dt DATETIME, tm TIME, ts TIMESTAMP, PRIMARY KEY(id))");
+ }
+
+ [TestFixtureTearDown]
+ public void TearDown()
+ {
+ Close();
+ }
+
+ [Test()]
+ public void TestUserVariables()
+ {
+ MySqlCommand cmd = new MySqlCommand("SET @myvar = 'test'", conn);
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT @myvar";
+ MySqlDataReader reader = cmd.ExecuteReader();
+ try
+ {
+ Assert.AreEqual( true, reader.Read());
+ Assert.AreEqual( "test", reader.GetValue(0));
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail( ex.Message );
+ }
+ finally
+ {
+ reader.Close();
+ }
+ }
+
+ [Test()]
+ public void TestQuoting()
+ {
+ MySqlCommand cmd = new MySqlCommand("", conn);
+ cmd.CommandText = "INSERT INTO Test VALUES (?id, ?name, NULL,NULL,NULL)";
+ cmd.Parameters.Add( new MySqlParameter("?id", 1));
+ cmd.Parameters.Add( new MySqlParameter("?name", "my ' value"));
+ cmd.ExecuteNonQuery();
+
+ cmd.Parameters[0].Value = 2;
+ cmd.Parameters[1].Value = @"my "" value";
+ cmd.ExecuteNonQuery();
+
+ cmd.Parameters[0].Value = 3;
+ cmd.Parameters[1].Value = @"my ` value";
+ cmd.ExecuteNonQuery();
+
+ cmd.Parameters[0].Value = 4;
+ cmd.Parameters[1].Value = @"my + cmd.ExecuteNonQuery();
+
+ cmd.Parameters[0].Value = 5;
+ cmd.Parameters[1].Value = @"my \ value";
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT * FROM Test";
+ MySqlDataReader reader = null;
+ try
+ {
+ reader = cmd.ExecuteReader();
+ reader.Read();
+ Assert.AreEqual( "my ' value", reader.GetString(1));
+ reader.Read();
+ Assert.AreEqual( @"my "" value", reader.GetString(1));
+ reader.Read();
+ Assert.AreEqual( "my ` value", reader.GetString(1));
+ reader.Read();
+ Assert.AreEqual( "my + reader.Read();
+ Assert.AreEqual( @"my \ value", reader.GetString(1));
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail( ex.Message );
+ }
+ finally
+ {
+ if (reader != null) reader.Close();
+ }
+ }
+
+ [Test()]
+ public void TestDateTimeParameter()
+ {
+ MySqlCommand cmd = new MySqlCommand("", conn);
+
+ TimeSpan time = new TimeSpan(0, 1, 2, 3);
+ DateTime dt = new DateTime( 2003, 11, 11, 1, 2, 3 );
+ cmd.CommandText = "INSERT INTO Test VALUES (1, 'test', ?dt, ?time, NULL)";
+ cmd.Parameters.Add( new MySqlParameter("?time", time));
+ cmd.Parameters.Add( new MySqlParameter("?dt", dt));
+ int cnt = cmd.ExecuteNonQuery();
+ Assert.AreEqual( 1, cnt, "Insert count" );
+
+ cmd = new MySqlCommand("SELECT tm, dt, ts FROM Test WHERE id=1", conn);
+ MySqlDataReader reader = cmd.ExecuteReader();
+ reader.Read();
+ TimeSpan time2 = (TimeSpan)reader.GetValue(0);
+ Assert.AreEqual( time, time2 );
+
+ DateTime dt2 = reader.GetDateTime(1);
+ Assert.AreEqual( dt, dt2 );
+
+ DateTime ts2 = reader.GetDateTime(2);
+ reader.Close();
+
+ // now check the timestamp column. We won't check the minute or second for obvious reasons
+ DateTime now = DateTime.Now;
+ Assert.AreEqual( now.Year, ts2.Year );
+ Assert.AreEqual( now.Month, ts2.Month );
+ Assert.AreEqual( now.Day, ts2.Day );
+ Assert.AreEqual( now.Hour, ts2.Hour );
+
+ // now we'll set some nulls and see how they are handled
+ cmd = new MySqlCommand("UPDATE Test SET tm=?ts, dt=?dt WHERE id=1", conn);
+ cmd.Parameters.Add( new MySqlParameter("?ts", DBNull.Value ));
+ cmd.Parameters.Add( new MySqlParameter("?dt", DBNull.Value));
+ cnt = cmd.ExecuteNonQuery();
+ Assert.AreEqual( 1, cnt, "Update null count" );
+
+ cmd = new MySqlCommand("SELECT tm, dt FROM Test WHERE id=1", conn);
+ reader = cmd.ExecuteReader();
+ reader.Read();
+ object tso = reader.GetValue(0);
+ object dto = reader.GetValue(1);
+ Assert.AreEqual( DBNull.Value, tso, "Time column" );
+ Assert.AreEqual( DBNull.Value, dto, "DateTime column" );
+
+ reader.Close();
+
+ cmd.CommandText = "DELETE FROM Test WHERE id=1";
+ cmd.ExecuteNonQuery();
+ }
+
+ [Test()]
+ public void NestedQuoting()
+ {
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES(1, 'this is ?\"my value\"')", conn);
+ int count = cmd.ExecuteNonQuery();
+ Assert.AreEqual( 1, count );
+ }
+
+ [Test()]
+ public void SetDbType()
+ {
+ try
+ {
+ IDbConnection conn2 = (IDbConnection)conn;
+ IDbCommand cmd = conn.CreateCommand();
+ IDbDataParameter prm = cmd.CreateParameter();
+ prm.DbType = DbType.Int32;
+ Assert.AreEqual( DbType.Int32, prm.DbType );
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail( ex.Message );
+ }
+ }
+
+ [Test()]
+ public void UseOldSyntax()
+ {
+ string connStr = conn.ConnectionString + ";old syntax=yes;pooling=false";
+ MySqlConnection conn2 = new MySqlConnection(connStr);
+ conn2.Open();
+
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (@id, @name)", conn2);
+ cmd.Parameters.Add( "@id", 33 );
+ cmd.Parameters.Add( "@name", "Test" );
+ cmd.ExecuteNonQuery();
+
+ MySqlDataReader reader = null;
+ try
+ {
+ cmd.CommandText = "SELECT * FROM Test";
+ reader = cmd.ExecuteReader();
+ reader.Read();
+ Assert.AreEqual( 33, reader.GetInt32(0) );
+ Assert.AreEqual( "Test", reader.GetString(1) );
+ }
+ catch( Exception ex)
+ {
+ Assert.Fail( ex.Message );
+ }
+ finally
+ {
+ if (reader != null) reader.Close();
+ conn2.Close();
+ }
+ }
+
+ [Test()]
+ [ExpectedException(typeof(ArgumentException))]
+ public void NullParameterObject()
+ {
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?name)", conn);
+ cmd.Parameters.Add( null );
+ }
+
+ /// <summary>
+ /// Bug #7398 MySqlParameterCollection doesn't allow parameters without filled in names
+ /// </summary>
+ [Test]
+ public void AllowUnnamedParameters()
+ {
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO test (id,name) VALUES (?id, ?name)", conn);
+
+ MySqlParameter p = new MySqlParameter();
+ p.ParameterName = "?id";
+ p.Value = 1;
+ cmd.Parameters.Add(p);
+
+ p = new MySqlParameter();
+ p.ParameterName = "?name";
+ p.Value = "test";
+ cmd.Parameters.Add(p);
+
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT id FROM test";
+ Assert.AreEqual(1, cmd.ExecuteScalar());
+
+ cmd.CommandText = "SELECT name FROM test";
+ Assert.AreEqual( "test", cmd.ExecuteScalar());
+ }
+
+ [Test()]
+ public void NullParameterValue()
+ {
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?name)", conn);
+ cmd.Parameters.Add( new MySqlParameter("?name", null));
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT name FROM Test WHERE id=1";
+ object name = cmd.ExecuteScalar();
+ Assert.AreEqual( DBNull.Value, name );
+ }
+
+ [Test()]
+ public void OddCharsInParameterNames()
+ {
+ MySqlCommand cmd = new MySqlCommand("INSERT INTO Test (id, name) VALUES (1, ?nam$es)", conn);
+ cmd.Parameters.Add( new MySqlParameter("?nam$es", "Test"));
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "INSERT INTO Test (id, name) VALUES (2, ?nam_es)";
+ cmd.Parameters.Clear();
+ cmd.Parameters.Add( new MySqlParameter("?nam_es", "Test2"));
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "INSERT INTO Test (id, name) VALUES (3, ?nam.es)";
+ cmd.Parameters.Clear();
+ cmd.Parameters.Add( new MySqlParameter("?nam.es", "Test3"));
+ cmd.ExecuteNonQuery();
+
+ cmd.CommandText = "SELECT name FROM Test WHERE id=1";
+ object name = cmd.ExecuteScalar();
+ Assert.AreEqual( "Test", name );
+
+ cmd.CommandText = "SELECT name FROM Test WHERE id=2";
+ name = cmd.ExecuteScalar();
+ Assert.AreEqual( "Test2", name );
+
+ cmd.CommandText = "SELECT name FROM Test WHERE id=3";
+ name = cmd.ExecuteScalar();
+ Assert.AreEqual( "Test3", name );
+ }
+ }
+}
Modified: trunk/TestSuite/StoredProcedure.cs
===================================================================
--- trunk/TestSuite/StoredProcedure.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/StoredProcedure.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -237,6 +237,7 @@
"BEGIN SELECT * FROM mysql.db; END" );
MySqlCommand cmd = new MySqlCommand("spTest", conn);
+ cmd.Parameters.Add("?a", 3);
cmd.CommandType = CommandType.StoredProcedure;
MySqlDataReader reader = cmd.ExecuteReader();
Assert.AreEqual( true, reader.Read() );
@@ -353,12 +354,29 @@
}
[Test]
+ public void ExecuteWithCreate()
+ {
+ if (! Is50) return;
+
+ // create our procedure
+ string sql = "CREATE PROCEDURE spTest(IN var INT) BEGIN SELECT var; END; call spTest(?v)";
+
+ MySqlCommand cmd = new MySqlCommand(sql, conn);
+ cmd.Parameters.Add(new MySqlParameter("?v", 33));
+ object val = cmd.ExecuteScalar();
+ Assert.AreEqual( 33, val );
+ }
+
+ /// <summary>
+ /// Bug #9722 Connector does not recognize parameters separated by a linefeed
+ /// </summary>
+ [Test]
public void OtherProcSigs()
{
if (! Is50) return;
// create our procedure
- execSQL( "CREATE PROCEDURE spTest( IN valin DECIMAL(10,2), IN val2 INT ) BEGIN SELECT valin; END" );
+ execSQL( "CREATE PROCEDURE spTest(IN \r\nvalin DECIMAL(10,2),\nIN val2 INT) BEGIN SELECT valin; END" );
MySqlCommand cmd = new MySqlCommand("spTest", conn);
cmd.CommandType = CommandType.StoredProcedure;
@@ -366,7 +384,76 @@
cmd.Parameters.Add( "?val2", 4 );
object val = cmd.ExecuteScalar();
Assert.AreEqual( 20.4, val );
+
+ // create our second procedure
+ execSQL("DROP PROCEDURE spTest");
+ execSQL("CREATE PROCEDURE spTest( \r\n) BEGIN SELECT 4; END" );
+ cmd.Parameters.Clear();
+ val = cmd.ExecuteScalar();
+ Assert.AreEqual(4, val);
}
+
+ /// <summary>
+ /// Bug #10644 Cannot call a stored function directly from Connector/Net
+ /// </summary>
+ [Test]
+ public void CallingStoredFunctionasProcedure()
+ {
+ if (! Is50) return;
+
+ execSQL("DROP FUNCTION IF EXISTS spFunc");
+ execSQL("CREATE FUNCTION spFunc(valin int) RETURNS INT BEGIN return valin * 2; END");
+ MySqlCommand cmd = new MySqlCommand("spFunc", conn);
+ cmd.CommandType = CommandType.StoredProcedure;
+ cmd.Parameters.Add("?valin", 22);
+ cmd.Parameters.Add("retval", MySqlDbType.Int32);
+ cmd.Parameters[1].Direction = ParameterDirection.ReturnValue;
+ cmd.ExecuteNonQuery();
+ Assert.AreEqual(44, cmd.Parameters[1].Value);
+ }
+
+ /// <summary>
+ /// Bug #11450 Connector/Net, current database and stored procedures
+ /// </summary>
+ [Test]
+ public void NoDefaultDatabase()
+ {
+ if (! Is50) return;
+
+ // create our procedure
+ execSQL("DROP PROCEDURE IF EXISTS spTest");
+ execSQL("CREATE PROCEDURE spTest() BEGIN SELECT 4; END" );
+
+ string newConnStr = GetConnectionString(false);
+ MySqlConnection c = new MySqlConnection(newConnStr);
+ try
+ {
+ c.Open();
+ MySqlCommand cmd2 = new MySqlCommand("use test", c);
+ cmd2.ExecuteNonQuery();
+
+ MySqlCommand cmd = new MySqlCommand("spTest", c);
+ cmd.CommandType = CommandType.StoredProcedure;
+ object val = cmd.ExecuteScalar();
+ Assert.AreEqual(4, val);
+
+ cmd2.CommandText = "use mysql";
+ cmd2.ExecuteNonQuery();
+
+ cmd.CommandText = "test.spTest";
+ val = cmd.ExecuteScalar();
+ Assert.AreEqual(4, val);
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ c.Close();
+ }
+
+ }
}
}
Modified: trunk/TestSuite/Syntax.cs
===================================================================
--- trunk/TestSuite/Syntax.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/TestSuite/Syntax.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -206,7 +206,34 @@
[Test]
public void Sum()
{
- execSQL("DROP TABLE IF EXISTS Test");
+ execSQL("DROP TABLE IF EXISTS test");
+
+ execSQL("CREATE TABLE test (field1 mediumint(9) default '0', field2 float(9,3) " +
+ "default '0.000', field3 double(15,3) default '0.000') engine=innodb " +
+ "default charset=utf8");
+ execSQL("INSERT INTO test values (1,1,1)");
+
+ MySqlDataReader reader = null;
+
+ MySqlCommand cmd2 = new MySqlCommand("SELECT sum(field2) FROM test", conn);
+ try
+ {
+ reader = cmd2.ExecuteReader();
+ reader.Read();
+ object o = reader[0];
+ Assert.AreEqual(1, o);
+ }
+ catch (Exception ex)
+ {
+ Assert.Fail(ex.Message);
+ }
+ finally
+ {
+ if (reader != null) reader.Close();
+ reader = null;
+ }
+
+ execSQL("DROP TABLE IF EXISTS test");
execSQL("CREATE TABLE Test (id int, count int)");
execSQL("INSERT INTO Test VALUES (1, 21)");
execSQL("INSERT INTO Test VALUES (1, 33)");
@@ -214,7 +241,6 @@
execSQL("INSERT INTO Test VALUES (1, 40)");
MySqlCommand cmd = new MySqlCommand("SELECT id, SUM(count) FROM Test GROUP BY id", conn);
- MySqlDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
Modified: trunk/mysqlclient/CharSetMap.cs
===================================================================
--- trunk/mysqlclient/CharSetMap.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/CharSetMap.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -76,21 +76,22 @@
{
mapping = new Hashtable();
- mapping.Add( "big5", "big5" ); // Traditional Chinese
- mapping.Add( "sjis", "sjis" ); // Shift-JIS
- mapping.Add( "gb2312", "gb2312" );
- mapping.Add( "latin1", "latin1" );
- mapping.Add( "latin2", "latin2" );
- mapping.Add( "latin3", "latin3" );
- mapping.Add( "latin4", "latin4" );
- mapping.Add( "latin5", "latin5" );
- mapping.Add( "greek", "greek" );
- mapping.Add( "hebrew", "hebrew" );
- mapping.Add( "utf8", "utf-8" );
- mapping.Add( "ucs2", "UTF-16BE" );
- mapping.Add( "cp1251", 1251 );
- mapping.Add( "tis620", 874 );
- mapping.Add( "binary", "latin1" );
+ mapping.Add("big5", "big5"); // Traditional Chinese
+ mapping.Add("sjis", "sjis"); // Shift-JIS
+ mapping.Add("gb2312", "gb2312");
+ mapping.Add("latin1", "latin1");
+ mapping.Add("latin2", "latin2");
+ mapping.Add("latin3", "latin3");
+ mapping.Add("latin4", "latin4");
+ mapping.Add("latin5", "latin5");
+ mapping.Add("greek", "greek");
+ mapping.Add("hebrew", "hebrew");
+ mapping.Add("utf8", "utf-8");
+ mapping.Add("ucs2", "UTF-16BE");
+ mapping.Add("cp1251", 1251);
+ mapping.Add("tis620", 874);
+ mapping.Add("binary", "latin1");
+ mapping.Add("cp1250", 1250);
// relatively sure about
/* mapping.Add( "default", 0 );
Modified: trunk/mysqlclient/CommandBuilder.cs
===================================================================
--- trunk/mysqlclient/CommandBuilder.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/CommandBuilder.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,447 +1,468 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-using System;
+// Copyright (C) 2004 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+using System;
using System.ComponentModel;
-using System.Data.Common;
-using System.Data;
-using System.Text;
-
-namespace MySql.Data.MySqlClient
-{
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/class/*'/>
-#if DESIGN
- [ToolboxItem(false)]
- [System.ComponentModel.DesignerCategory("Code")]
-#endif
- public sealed class MySqlCommandBuilder : DbCommandBuilder
- {
- private MySqlDataAdapter _adapter;
- private string _QuotePrefix;
- private string _QuoteSuffix;
- private DataTable _schema;
- private string _tableName;
-
- private MySqlCommand _updateCmd;
- private MySqlCommand _insertCmd;
- private MySqlCommand _deleteCmd;
-
- private char marker = '?';
- private bool lastOneWins;
-
- #region Constructors
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor/*'/>
- public MySqlCommandBuilder()
- {
- _QuotePrefix = _QuoteSuffix = "`";
- this.lastOneWins = false;
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor1/*'/>
- public MySqlCommandBuilder(bool lastOneWins)
- {
- _QuotePrefix = _QuoteSuffix = "`";
- this.lastOneWins = lastOneWins;
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor2/*'/>
- public MySqlCommandBuilder( MySqlDataAdapter adapter ) : this()
- {
- DataAdapter = adapter;
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor3/*'/>
- public MySqlCommandBuilder( MySqlDataAdapter adapter, bool lastOneWins ) : this(lastOneWins)
- {
- DataAdapter = adapter;
- }
-
- #endregion
-
- #region Properties
-
- /// <include file='docs/mysqlcommandBuilder.xml' path='docs/DataAdapter/*'/>
- public MySqlDataAdapter DataAdapter
- {
- get { return _adapter; }
- set
- {
- if (_adapter != null)
- {
- _adapter.RowUpdating -= new MySqlRowUpdatingEventHandler( OnRowUpdating );
- }
- _adapter = value;
- _adapter.RowUpdating += new MySqlRowUpdatingEventHandler( OnRowUpdating );
- }
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/QuotePrefix/*'/>
- public string QuotePrefix
- {
- get { return _QuotePrefix; }
- set { _QuotePrefix = value; }
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/QuoteSuffix/*'/>
- public string QuoteSuffix
- {
- get { return _QuoteSuffix; }
- set { _QuoteSuffix = value; }
- }
-
- #endregion
-
- #region Public Methods
- /// <summary>
- /// Retrieves parameter information from the stored procedure specified in the MySqlCommand and populates the Parameters collection of the specified MySqlCommand object.
- /// This method is not currently supported since stored procedures are not available in MySql.
- /// </summary>
- /// <param name="command">The MySqlCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the MySqlCommand.</param>
- /// <exception cref="InvalidOperationException">The command text is not a valid stored procedure name.</exception>
- public static void DeriveParameters(MySqlCommand command)
- {
- throw new MySqlException("DeriveParameters is not supported (due to MySql not supporting SP)");
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetDeleteCommand/*'/>
- public MySqlCommand GetDeleteCommand()
- {
- if (_schema == null)
- GenerateSchema();
- return CreateDeleteCommand();
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetInsertCommand/*'/>
- public MySqlCommand GetInsertCommand()
- {
- if (_schema == null)
- GenerateSchema();
- return CreateInsertCommand();
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetUpdateCommand/*'/>
- public MySqlCommand GetUpdateCommand()
- {
- if (_schema == null)
- GenerateSchema();
- return CreateUpdateCommand();
- }
-
- /// <include file='docs/MySqlCommandBuilder.xml' path='docs/RefreshSchema/*'/>
- public void RefreshSchema()
- {
- _schema = null;
- _insertCmd = null;
- _deleteCmd = null;
- _updateCmd = null;
- this._tableName = null;
- }
- #endregion
-
- #region Private Methods
-
- private void GenerateSchema()
- {
- // set the parameter marker
- MySqlConnection conn = (MySqlConnection)_adapter.SelectCommand.Connection;
- marker = conn.ParameterMarker;
-
- if (_adapter == null)
- throw new MySqlException("Improper MySqlCommandBuilder state: adapter is null");
- if (_adapter.SelectCommand == null)
- throw new MySqlException("Improper MySqlCommandBuilder state: adapter's SelectCommand is null");
-
- MySqlDataReader dr = _adapter.SelectCommand.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo);
- _schema = dr.GetSchemaTable();
- dr.Close();
-
- // make sure we got at least one unique or key field and count base table names
- bool hasKeyOrUnique=false;
-
- foreach (DataRow row in _schema.Rows)
- {
- if (true == (bool)row["IsKey"] || true == (bool)row["IsUnique"])
- hasKeyOrUnique=true;
- if (_tableName == null)
- _tableName = (string)row["BaseTableName"];
- else if (_tableName != (string)row["BaseTableName"])
- throw new InvalidOperationException("MySqlCommandBuilder does not support multi-table statements");
- }
- if (! hasKeyOrUnique)
- throw new InvalidOperationException("MySqlCommandBuilder cannot operate on tables with no unique or key columns");
- }
-
- private string Quote(string table_or_column)
- {
- if (_QuotePrefix == null || _QuoteSuffix == null)
- return table_or_column;
- return _QuotePrefix + table_or_column + _QuoteSuffix;
- }
-
- protected override string GetParameterName(string columnName)
- {
- string colName = columnName.Replace(" ", "");
- return colName;
- }
-
- private MySqlParameter CreateParameter(DataRow row, bool Original)
- {
- MySqlParameter p;
- string colName = GetParameterName( row["ColumnName"].ToString() );
- MySqlDbType type = (MySqlDbType)row["ProviderType"];
-
- if (Original)
- p = new MySqlParameter( "Original_" + colName, type, ParameterDirection.Input,
- (string)row["ColumnName"], DataRowVersion.Original, DBNull.Value );
- else
- p = new MySqlParameter( colName, type, ParameterDirection.Input,
- (string)row["ColumnName"], DataRowVersion.Current, DBNull.Value );
- return p;
- }
-
- private MySqlCommand CreateBaseCommand()
- {
- MySqlCommand cmd = new MySqlCommand();
- cmd.Connection = _adapter.SelectCommand.Connection;
- cmd.CommandTimeout = _adapter.SelectCommand.CommandTimeout;
- cmd.Transaction = _adapter.SelectCommand.Transaction;
- return cmd;
- }
-
- private MySqlCommand CreateDeleteCommand()
- {
- if (_deleteCmd != null) return _deleteCmd;
-
- MySqlCommand cmd = CreateBaseCommand();
-
- cmd.CommandText = "DELETE FROM " + Quote(_tableName) +
- " WHERE " + CreateOriginalWhere(cmd);
-
- _deleteCmd = cmd;
- return cmd;
- }
-
- private string CreateFinalSelect(bool forinsert)
- {
- StringBuilder sel = new StringBuilder();
- StringBuilder where = new StringBuilder();
-
- foreach (DataRow row in _schema.Rows)
- {
- string colname = Quote(row["ColumnName"].ToString());
- string parmName = GetParameterName( row["ColumnName"].ToString() );
-
- if (sel.Length > 0)
- sel.Append(", ");
- sel.Append( colname );
- if ((bool)row["IsKey"] == false) continue;
- if (where.Length > 0)
- where.Append(" AND ");
- where.Append( "(" + colname + "=" );
- if (forinsert)
- {
- if ((bool)row["IsAutoIncrement"])
- where.Append("last_insert_id()");
- else if ((bool)row["IsKey"])
- where.Append( marker + parmName);
- }
- else
- {
- where.Append(marker + "Original_" + parmName);
- }
- where.Append(")");
- }
- return "SELECT " + sel.ToString() + " FROM " + Quote(_tableName) +
- " WHERE " + where.ToString();
- }
-
- private string CreateOriginalWhere(MySqlCommand cmd)
- {
- StringBuilder wherestr = new StringBuilder();
-
- foreach (DataRow row in _schema.Rows)
- {
- // if we are doing last one wins and this column is not a key or is not
- // unique, then we don't care about it
- if (true != (bool)row["IsKey"] && true != (bool)row["IsUnique"] && lastOneWins)
- continue;
-
- if (! IncludedInWhereClause(row)) continue;
-
- // first update the where clause since it will contain all parameters
-// if (wherestr.Length > 0)
-// wherestr.Append(" AND ");
- string colname = Quote((string)row["ColumnName"]);
-
- MySqlParameter op = CreateParameter(row, true);
- cmd.Parameters.Add(op);
-
- wherestr.Append( colname + " <=> " + marker + op.ParameterName + " AND ");
-// if ((bool)row["AllowDBNull"] == true)
-// wherestr.Append( " or (" + colname + " IS NULL and ?" + op.ParameterName + " IS NULL)");
- //wherestr.Append(")");
- }
- wherestr.Remove( wherestr.Length-5, 5 ); // remove the trailling " AND "
- return wherestr.ToString();
- }
-
- private MySqlCommand CreateUpdateCommand()
- {
- if (_updateCmd != null) return _updateCmd;
-
- MySqlCommand cmd = CreateBaseCommand();
-
- StringBuilder setstr = new StringBuilder();
-
- foreach (DataRow schemaRow in _schema.Rows)
- {
- string colname = Quote((string)schemaRow["ColumnName"]);
-
- if (! IncludedInUpdate(schemaRow)) continue;
-
- if (setstr.Length > 0)
- setstr.Append(", ");
-
- MySqlParameter p = CreateParameter(schemaRow, false);
- cmd.Parameters.Add(p);
-
- setstr.Append( colname + "=" + marker + p.ParameterName );
- }
-
- cmd.CommandText = "UPDATE " + Quote(_tableName) + " SET " + setstr.ToString() +
- " WHERE " + CreateOriginalWhere(cmd);
- cmd.CommandText += "; " + CreateFinalSelect(false);
-
- _updateCmd = cmd;
- return cmd;
- }
-
- private MySqlCommand CreateInsertCommand()
- {
- if (_insertCmd != null) return _insertCmd;
-
- MySqlCommand cmd = CreateBaseCommand();
-
- StringBuilder setstr = new StringBuilder();
- StringBuilder valstr = new StringBuilder();
- foreach (DataRow schemaRow in _schema.Rows)
- {
- string colname = Quote((string)schemaRow["ColumnName"]);
-
- if (!IncludedInInsert(schemaRow)) continue;
-
- if (setstr.Length > 0)
- {
- setstr.Append(", ");
- valstr.Append(", ");
- }
-
- MySqlParameter p = CreateParameter(schemaRow, false);
- cmd.Parameters.Add(p);
-
- setstr.Append( colname );
- valstr.Append( marker + p.ParameterName );
- }
-
- cmd.CommandText = "INSERT INTO " + Quote(_tableName) + " (" + setstr.ToString() + ") " +
- " VALUES (" + valstr.ToString() + ")";
- cmd.CommandText += "; " + CreateFinalSelect(true);
-
- _insertCmd = cmd;
- return cmd;
- }
-
- private bool IncludedInInsert (DataRow schemaRow)
- {
- // If the parameter has one of these properties, then we don't include it in the insert:
- // AutoIncrement, Hidden, Expression, RowVersion, ReadOnly
-
- if ((bool) schemaRow ["IsAutoIncrement"])
- return false;
- /* if ((bool) schemaRow ["IsHidden"])
- return false;
- if ((bool) schemaRow ["IsExpression"])
- return false;*/
- if ((bool) schemaRow ["IsRowVersion"])
- return false;
- if ((bool) schemaRow ["IsReadOnly"])
- return false;
- return true;
- }
-
- private bool IncludedInUpdate (DataRow schemaRow)
- {
- // If the parameter has one of these properties, then we don't include it in the insert:
- // AutoIncrement, Hidden, RowVersion
-
- if ((bool) schemaRow ["IsAutoIncrement"])
- return false;
- // if ((bool) schemaRow ["IsHidden"])
- // return false;
- if ((bool) schemaRow ["IsRowVersion"])
- return false;
- return true;
- }
-
- private bool IncludedInWhereClause (DataRow schemaRow)
- {
- // if ((bool) schemaRow ["IsLong"])
- // return false;
- return true;
- }
-
- private void SetParameterValues(MySqlCommand cmd, DataRow dataRow)
- {
- foreach (MySqlParameter p in cmd.Parameters)
- {
- if (p.SourceVersion == DataRowVersion.Original)
-// if (p.ParameterName.Length >= 8 && p.ParameterName.Substring(0, 8).Equals("Original"))
- p.Value = dataRow[ p.SourceColumn, DataRowVersion.Original ];
- else
- p.Value = dataRow[ p.SourceColumn, DataRowVersion.Current ];
- }
- }
-
- private void OnRowUpdating(object sender, MySqlRowUpdatingEventArgs args)
- {
- // make sure we are still to proceed
- if (args.Status != UpdateStatus.Continue) return;
-
- if (_schema == null)
- GenerateSchema();
-
- if (StatementType.Delete == args.StatementType)
- args.Command = CreateDeleteCommand();
- else if (StatementType.Update == args.StatementType)
- args.Command = CreateUpdateCommand();
- else if (StatementType.Insert == args.StatementType)
- args.Command = CreateInsertCommand();
- else if (StatementType.Select == args.StatementType)
- return;
-
- SetParameterValues(args.Command, args.Row);
- }
+using System.Data.Common;
+using System.Data;
+using System.Text;
+
+namespace MySql.Data.MySqlClient
+{
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/class/*'/>
+#if DESIGN
+ [ToolboxItem(false)]
+ [System.ComponentModel.DesignerCategory("Code")]
+#endif
+ public sealed class MySqlCommandBuilder : DbCommandBuilder
+ {
+ private MySqlDataAdapter _adapter;
+ private string _QuotePrefix;
+ private string _QuoteSuffix;
+ private DataTable _schema;
+ private string tableName;
+ private string schemaName;
+
+ private MySqlCommand _updateCmd;
+ private MySqlCommand _insertCmd;
+ private MySqlCommand _deleteCmd;
+
+ private char marker = '?';
+ private bool lastOneWins;
+
+ #region Constructors
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor/*'/>
+ public MySqlCommandBuilder()
+ {
+ _QuotePrefix = _QuoteSuffix = "`";
+ this.lastOneWins = false;
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor1/*'/>
+ public MySqlCommandBuilder(bool lastOneWins)
+ {
+ _QuotePrefix = _QuoteSuffix = "`";
+ this.lastOneWins = lastOneWins;
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor2/*'/>
+ public MySqlCommandBuilder( MySqlDataAdapter adapter ) : this()
+ {
+ DataAdapter = adapter;
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/Ctor3/*'/>
+ public MySqlCommandBuilder( MySqlDataAdapter adapter, bool lastOneWins ) : this(lastOneWins)
+ {
+ DataAdapter = adapter;
+ }
+
#endregion
+ #region Properties
+ /// <include file='docs/mysqlcommandBuilder.xml' path='docs/DataAdapter/*'/>
+ public MySqlDataAdapter DataAdapter
+ {
+ get { return _adapter; }
+ set
+ {
+ if (_adapter != null)
+ {
+ _adapter.RowUpdating -= new MySqlRowUpdatingEventHandler( OnRowUpdating );
+ }
+ _adapter = value;
+ _adapter.RowUpdating += new MySqlRowUpdatingEventHandler( OnRowUpdating );
+ }
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/QuotePrefix/*'/>
+ public string QuotePrefix
+ {
+ get { return _QuotePrefix; }
+ set { _QuotePrefix = value; }
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/QuoteSuffix/*'/>
+ public string QuoteSuffix
+ {
+ get { return _QuoteSuffix; }
+ set { _QuoteSuffix = value; }
+ }
+
+ private string TableName
+ {
+ get
+ {
+ if (schemaName != null)
+ return Quote(schemaName) + "." + Quote(tableName);
+ return Quote(tableName);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods
+ /// <summary>
+ /// Retrieves parameter information from the stored procedure specified in the MySqlCommand and populates the Parameters collection of the specified MySqlCommand object.
+ /// This method is not currently supported since stored procedures are not available in MySql.
+ /// </summary>
+ /// <param name="command">The MySqlCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the MySqlCommand.</param>
+ /// <exception cref="InvalidOperationException">The command text is not a valid stored procedure name.</exception>
+ public static void DeriveParameters(MySqlCommand command)
+ {
+ throw new MySqlException("DeriveParameters is not supported (due to MySql not supporting SP)");
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetDeleteCommand/*'/>
+ public MySqlCommand GetDeleteCommand()
+ {
+ if (_schema == null)
+ GenerateSchema();
+ return CreateDeleteCommand();
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetInsertCommand/*'/>
+ public MySqlCommand GetInsertCommand()
+ {
+ if (_schema == null)
+ GenerateSchema();
+ return CreateInsertCommand();
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/GetUpdateCommand/*'/>
+ public MySqlCommand GetUpdateCommand()
+ {
+ if (_schema == null)
+ GenerateSchema();
+ return CreateUpdateCommand();
+ }
+
+ /// <include file='docs/MySqlCommandBuilder.xml' path='docs/RefreshSchema/*'/>
+ public void RefreshSchema()
+ {
+ _schema = null;
+ _insertCmd = null;
+ _deleteCmd = null;
+ _updateCmd = null;
+ tableName = null;
+ schemaName = null;
+ }
+ #endregion
+
+ #region Private Methods
+
+ private void GenerateSchema()
+ {
+ // set the parameter marker
+ MySqlConnection conn = (MySqlConnection)_adapter.SelectCommand.Connection;
+ marker = conn.ParameterMarker;
+
+ if (_adapter == null)
+ throw new MySqlException("Improper MySqlCommandBuilder state: adapter is null");
+ if (_adapter.SelectCommand == null)
+ throw new MySqlException("Improper MySqlCommandBuilder state: adapter's SelectCommand is null");
+
+ MySqlDataReader dr = _adapter.SelectCommand.ExecuteReader(CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo);
+ _schema = dr.GetSchemaTable();
+ dr.Close();
+
+ // make sure we got at least one unique or key field and count base table names
+ bool hasKeyOrUnique=false;
+
+ foreach (DataRow row in _schema.Rows)
+ {
+ string rowTableName = (string)row["BaseTableName"];
+ string rowSchemaName = (string)row["BaseSchemaName"];
+
+ if (true == (bool)row["IsKey"] || true == (bool)row["IsUnique"])
+ hasKeyOrUnique=true;
+
+ if (tableName == null)
+ {
+ schemaName = (string)row["BaseSchemaName"];
+ tableName = (string)row["BaseTableName"];
+ }
+ else if (tableName != rowTableName && rowTableName != null && rowTableName.Length > 0)
+ throw new InvalidOperationException("MySqlCommandBuilder does not support multi-table statements");
+ else if (schemaName != rowSchemaName && rowSchemaName != null && rowSchemaName.Length > 0)
+ throw new InvalidOperationException("MySqlCommandBuilder does not support multi-schema statements");
+ }
+ if (! hasKeyOrUnique)
+ throw new InvalidOperationException("MySqlCommandBuilder cannot operate on tables with no unique or key columns");
+ }
+
+ private string Quote(string table_or_column)
+ {
+ if (_QuotePrefix == null || _QuoteSuffix == null)
+ return table_or_column;
+ return _QuotePrefix + table_or_column + _QuoteSuffix;
+ }
+
+ protected override string GetParameterName(string columnName)
+ {
+ string colName = columnName.Replace(" ", "");
+ return colName;
+ }
+
+ private MySqlParameter CreateParameter(DataRow row, bool Original)
+ {
+ MySqlParameter p;
+ string colName = GetParameterName( row["ColumnName"].ToString() );
+ MySqlDbType type = (MySqlDbType)row["ProviderType"];
+
+ if (Original)
+ p = new MySqlParameter( "Original_" + colName, type, ParameterDirection.Input,
+ (string)row["ColumnName"], DataRowVersion.Original, DBNull.Value );
+ else
+ p = new MySqlParameter( colName, type, ParameterDirection.Input,
+ (string)row["ColumnName"], DataRowVersion.Current, DBNull.Value );
+ return p;
+ }
+
+ private MySqlCommand CreateBaseCommand()
+ {
+ MySqlCommand cmd = new MySqlCommand();
+ cmd.Connection = _adapter.SelectCommand.Connection;
+ cmd.CommandTimeout = _adapter.SelectCommand.CommandTimeout;
+ cmd.Transaction = _adapter.SelectCommand.Transaction;
+ return cmd;
+ }
+
+ private MySqlCommand CreateDeleteCommand()
+ {
+ if (_deleteCmd != null) return _deleteCmd;
+
+ MySqlCommand cmd = CreateBaseCommand();
+
+ cmd.CommandText = "DELETE FROM " + TableName +
+ " WHERE " + CreateOriginalWhere(cmd);
+
+ _deleteCmd = cmd;
+ return cmd;
+ }
+
+ private string CreateFinalSelect(bool forinsert)
+ {
+ StringBuilder sel = new StringBuilder();
+ StringBuilder where = new StringBuilder();
+
+ foreach (DataRow row in _schema.Rows)
+ {
+ string colname = Quote(row["ColumnName"].ToString());
+ string parmName = GetParameterName( row["ColumnName"].ToString() );
+
+ if (sel.Length > 0)
+ sel.Append(", ");
+ sel.Append( colname );
+ if ((bool)row["IsKey"] == false) continue;
+ if (where.Length > 0)
+ where.Append(" AND ");
+ where.Append( "(" + colname + "=" );
+ if (forinsert)
+ {
+ if ((bool)row["IsAutoIncrement"])
+ where.Append("last_insert_id()");
+ else if ((bool)row["IsKey"])
+ where.Append( marker + parmName);
+ }
+ else
+ {
+ where.Append(marker + "Original_" + parmName);
+ }
+ where.Append(")");
+ }
+ return "SELECT " + sel.ToString() + " FROM " + TableName +
+ " WHERE " + where.ToString();
+ }
+
+ private string CreateOriginalWhere(MySqlCommand cmd)
+ {
+ StringBuilder wherestr = new StringBuilder();
+
+ foreach (DataRow row in _schema.Rows)
+ {
+ // if we are doing last one wins and this column is not a key or is not
+ // unique, then we don't care about it
+ if (true != (bool)row["IsKey"] && true != (bool)row["IsUnique"] && lastOneWins)
+ continue;
+
+ if (! IncludedInWhereClause(row)) continue;
+
+ // first update the where clause since it will contain all parameters
+// if (wherestr.Length > 0)
+// wherestr.Append(" AND ");
+ string colname = Quote((string)row["ColumnName"]);
+
+ MySqlParameter op = CreateParameter(row, true);
+ cmd.Parameters.Add(op);
+
+ wherestr.Append( colname + " <=> " + marker + op.ParameterName + " AND ");
+// if ((bool)row["AllowDBNull"] == true)
+// wherestr.Append( " or (" + colname + " IS NULL and ?" + op.ParameterName + " IS NULL)");
+ //wherestr.Append(")");
+ }
+ wherestr.Remove( wherestr.Length-5, 5 ); // remove the trailling " AND "
+ return wherestr.ToString();
+ }
+
+ private MySqlCommand CreateUpdateCommand()
+ {
+ if (_updateCmd != null) return _updateCmd;
+
+ MySqlCommand cmd = CreateBaseCommand();
+
+ StringBuilder setstr = new StringBuilder();
+
+ foreach (DataRow schemaRow in _schema.Rows)
+ {
+ string colname = Quote((string)schemaRow["ColumnName"]);
+
+ if (! IncludedInUpdate(schemaRow)) continue;
+
+ if (setstr.Length > 0)
+ setstr.Append(", ");
+
+ MySqlParameter p = CreateParameter(schemaRow, false);
+ cmd.Parameters.Add(p);
+
+ setstr.Append( colname + "=" + marker + p.ParameterName );
+ }
+
+ cmd.CommandText = "UPDATE " + TableName + " SET " + setstr.ToString() +
+ " WHERE " + CreateOriginalWhere(cmd);
+ cmd.CommandText += "; " + CreateFinalSelect(false);
+
+ _updateCmd = cmd;
+ return cmd;
+ }
+
+ private MySqlCommand CreateInsertCommand()
+ {
+ if (_insertCmd != null) return _insertCmd;
+
+ MySqlCommand cmd = CreateBaseCommand();
+
+ StringBuilder setstr = new StringBuilder();
+ StringBuilder valstr = new StringBuilder();
+ foreach (DataRow schemaRow in _schema.Rows)
+ {
+ string colname = Quote((string)schemaRow["ColumnName"]);
+
+ if (!IncludedInInsert(schemaRow)) continue;
+
+ if (setstr.Length > 0)
+ {
+ setstr.Append(", ");
+ valstr.Append(", ");
+ }
+
+ MySqlParameter p = CreateParameter(schemaRow, false);
+ cmd.Parameters.Add(p);
+
+ setstr.Append( colname );
+ valstr.Append( marker + p.ParameterName );
+ }
+
+ cmd.CommandText = "INSERT INTO " + TableName + " (" + setstr.ToString() + ") " +
+ " VALUES (" + valstr.ToString() + ")";
+ cmd.CommandText += "; " + CreateFinalSelect(true);
+
+ _insertCmd = cmd;
+ return cmd;
+ }
+
+ private bool IncludedInInsert (DataRow schemaRow)
+ {
+ // If the parameter has one of these properties, then we don't include it in the insert:
+ // AutoIncrement, Hidden, Expression, RowVersion, ReadOnly
+
+ if ((bool) schemaRow ["IsAutoIncrement"])
+ return false;
+ /* if ((bool) schemaRow ["IsHidden"])
+ return false;
+ if ((bool) schemaRow ["IsExpression"])
+ return false;*/
+ if ((bool) schemaRow ["IsRowVersion"])
+ return false;
+ if ((bool) schemaRow ["IsReadOnly"])
+ return false;
+ return true;
+ }
+
+ private bool IncludedInUpdate (DataRow schemaRow)
+ {
+ // If the parameter has one of these properties, then we don't include it in the insert:
+ // AutoIncrement, Hidden, RowVersion
+
+ if ((bool) schemaRow ["IsAutoIncrement"])
+ return false;
+ // if ((bool) schemaRow ["IsHidden"])
+ // return false;
+ if ((bool) schemaRow ["IsRowVersion"])
+ return false;
+ return true;
+ }
+
+ private bool IncludedInWhereClause (DataRow schemaRow)
+ {
+ // if ((bool) schemaRow ["IsLong"])
+ // return false;
+ return true;
+ }
+
+ private void SetParameterValues(MySqlCommand cmd, DataRow dataRow)
+ {
+ foreach (MySqlParameter p in cmd.Parameters)
+ {
+ if (p.SourceVersion == DataRowVersion.Original)
+// if (p.ParameterName.Length >= 8 && p.ParameterName.Substring(0, 8).Equals("Original"))
+ p.Value = dataRow[ p.SourceColumn, DataRowVersion.Original ];
+ else
+ p.Value = dataRow[ p.SourceColumn, DataRowVersion.Current ];
+ }
+ }
+
+ private void OnRowUpdating(object sender, MySqlRowUpdatingEventArgs args)
+ {
+ // make sure we are still to proceed
+ if (args.Status != UpdateStatus.Continue) return;
+
+ if (_schema == null)
+ GenerateSchema();
+
+ if (StatementType.Delete == args.StatementType)
+ args.Command = CreateDeleteCommand();
+ else if (StatementType.Update == args.StatementType)
+ args.Command = CreateUpdateCommand();
+ else if (StatementType.Insert == args.StatementType)
+ args.Command = CreateInsertCommand();
+ else if (StatementType.Select == args.StatementType)
+ return;
+
+ SetParameterValues(args.Command, args.Row);
+ }
+ #endregion
+
+
protected override void ApplyParameterInfo(DbParameter parameter, DataRow row, StatementType statementType, bool whereClause)
{
throw new Exception("The method or operation is not implemented.");
@@ -461,5 +482,5 @@
{
throw new Exception("The method or operation is not implemented.");
}
-}
-}
+}
+}
Modified: trunk/mysqlclient/CommandResult.cs
===================================================================
--- trunk/mysqlclient/CommandResult.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/CommandResult.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -31,7 +31,7 @@
{
private Driver driver;
- private ulong affectedRows;
+ private long affectedRows;
private long fieldCount;
private long lastInsertId;
@@ -50,6 +50,7 @@
driver = d;
this.isBinary = isBinary;
dataRowOpen = false;
+ affectedRows = -1;
ReadNextResult(true);
statementId = 0;
}
@@ -89,7 +90,7 @@
set { fieldCount = value; }
}
- public ulong AffectedRows
+ public long AffectedRows
{
get { return affectedRows; }
set { affectedRows = value; }
@@ -137,9 +138,7 @@
public bool ReadNextResult(bool isFirst)
{
- ulong rows = 0;
- readSchema = false;
- readRows = false;
+ long rows = 0;
while (driver.ReadResult( ref fieldCount, ref rows, ref lastInsertId ))
{
@@ -147,12 +146,25 @@
// while ( driver.HasMoreResults || isFirst )
// {
// fieldCount = (ulong)driver.ReadResult( ref rows, ref lastInsertId );
- affectedRows += rows;
+ if (rows != -1)
+ {
+ if (affectedRows == -1) affectedRows = 0;
+ affectedRows += rows;
+ }
// if (isFirst) isFirst = false;
- if (IsResultSet) return true;
+ if (IsResultSet)
+ {
+ readSchema = false;
+ readRows = false;
+ return true;
+ }
}
+ // if our batch resulted in warnings, then report them now
+ if (driver.HasWarnings)
+ driver.ReportWarnings();
+
driver.IsProcessing = false;
return false;
}
Modified: trunk/mysqlclient/ConnectionString.cs
===================================================================
--- trunk/mysqlclient/ConnectionString.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/ConnectionString.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -382,7 +382,8 @@
foreach (string key in values.Keys)
{
- if (!values[key].Equals( defaultValues[key]))
+ if (values[key] != null && defaultValues[key] != null &&
+ !values[key].Equals( defaultValues[key]))
cStr += key + "=" + values[key] + ";";
}
Modified: trunk/mysqlclient/Driver.cs
===================================================================
--- trunk/mysqlclient/Driver.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/Driver.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -45,6 +45,7 @@
protected MySqlConnection connection;
protected bool processing;
protected Hashtable charSets;
+ protected bool hasWarnings;
public Driver(MySqlConnectionString settings)
{
@@ -54,6 +55,7 @@
threadId = -1;
serverCharSetIndex = -1;
serverCharSet = null;
+ hasWarnings = false;
}
#region Properties
@@ -96,6 +98,11 @@
get { return serverStatus; }
}
+ public bool HasWarnings
+ {
+ get { return hasWarnings; }
+ }
+
#endregion
public bool IsTooOld()
@@ -187,7 +194,14 @@
// want results in
if (version.isAtLeast(4,1,0))
{
- cmd.CommandText = "SET NAMES " + charSet + "; SET character_set_results=NULL";
+ cmd.CommandText = "SET character_set_results=NULL";
+ string clientCharSet = (string)serverProps["character_set_client"];
+ string connCharSet = (string)serverProps["character_set_connection"];
+ if ((clientCharSet != null && clientCharSet != charSet) ||
+ (connCharSet != null && connCharSet != charSet))
+ {
+ cmd.CommandText = "SET NAMES " + charSet + ";" + cmd.CommandText;
+ }
cmd.ExecuteNonQuery();
}
@@ -215,7 +229,8 @@
charSets = new Hashtable();
while (reader.Read())
{
- charSets[ Convert.ToInt32(reader["id"]) ] = reader["charset"];
+ charSets[ Convert.ToInt32(reader["id"]) ] =
+ reader.GetString(reader.GetOrdinal("charset"));
}
}
catch (Exception ex)
@@ -229,29 +244,29 @@
}
}
- public void ShowWarnings(int count)
+ public void ReportWarnings()
{
- if (count == 0 ||
- (serverStatus & (ServerStatusFlags.MoreResults | ServerStatusFlags.AnotherQuery )) != 0 ) return;
+ ArrayList errors = new ArrayList();
- MySqlError[] errors = new MySqlError[count];
-
MySqlCommand cmd = new MySqlCommand("SHOW WARNINGS", connection);
MySqlDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
- int i = 0;
while (reader.Read())
{
- errors[i++] = new MySqlError( reader.GetString(0), reader.GetUInt32(1), reader.GetString(2) );
+ errors.Add(new MySqlError(reader.GetString(0),
+ reader.GetUInt32(1), reader.GetString(2)));
}
reader.Close();
- if (i == 0) return; // MySQL resets warnings before each statement, so a batch could indicate
- // warnings when there aren't any
+ hasWarnings = false;
+ // MySQL resets warnings before each statement, so a batch could indicate
+ // warnings when there aren't any
+ if (errors.Count == 0) return;
+
MySqlInfoMessageEventArgs args = new MySqlInfoMessageEventArgs();
- args.errors = errors;
+ args.errors = (MySqlError[])errors.ToArray(typeof(MySqlError));
if (connection != null)
connection.OnInfoMessage( args );
@@ -273,12 +288,11 @@
public abstract PreparedStatement Prepare( string sql, string[] names );
public abstract void Reset();
public abstract CommandResult SendQuery( byte[] bytes, int length, bool consume );
- public abstract bool ReadResult( ref long fieldCount, ref ulong affectedRows, ref long lastInsertId );
- public abstract bool OpenDataRow(int fieldCount, bool isBinary, int statementId);
- public abstract IMySqlValue ReadFieldValue( int index, MySqlField field, IMySqlValue value );
- public abstract CommandResult ExecuteStatement( byte[] bytes, int statementId, int cursorPageSize );
- public abstract void SkipField(IMySqlValue valObject );
-
+ public abstract long ReadResult( ref long affectedRows, ref long lastInsertId );
+ public abstract bool OpenDataRow(int fieldCount, bool isBinary);
+ public abstract MySqlValue ReadFieldValue( int index, MySqlField field, MySqlValue value );
+ public abstract CommandResult ExecuteStatement( byte[] bytes );
+ public abstract void SkipField(MySqlValue valObject );
public abstract void ReadFieldMetadata( int count, ref MySqlField[] fields );
public abstract bool Ping();
#endregion
Modified: trunk/mysqlclient/MySqlStream.cs
===================================================================
--- trunk/mysqlclient/MySqlStream.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/MySqlStream.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,21 +1,21 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
+// Copyright (C) 2004 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
Modified: trunk/mysqlclient/MySqlStreamWriter.cs
===================================================================
--- trunk/mysqlclient/MySqlStreamWriter.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/MySqlStreamWriter.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,21 +1,21 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
+// Copyright (C) 2004 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
Modified: trunk/mysqlclient/StoredProcedure.cs
===================================================================
--- trunk/mysqlclient/StoredProcedure.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/StoredProcedure.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -19,6 +19,7 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
+using System.Data;
using MySql.Data.Common;
namespace MySql.Data.MySqlClient
@@ -39,20 +40,38 @@
connection = conn;
}
- private string GetParameterList( string spName )
+ private string GetParameterList(string spName, bool isProc)
{
+ MySqlCommand cmd = new MySqlCommand();
+ cmd.Connection = connection;
+
+ int dotIndex = spName.IndexOf(".");
// query the mysql.proc table for the procedure parameter list
- string sql = String.Format("SELECT param_list FROM mysql.proc WHERE db=_latin1 {0}db AND name=_latin1 {0}name",
- connection.ParameterMarker);
- MySqlCommand cmd = new MySqlCommand(sql, connection);
- cmd.Parameters.Add("db", connection.Database);
+ // if our spname as a dot in it, then we assume the first part is the
+ // database name. If there is no dot, then we use database() as
+ // the current database.
+ if (dotIndex == -1)
+ cmd.CommandText = "SELECT param_list FROM mysql.proc WHERE db=database() ";
+ else
+ {
+ string db = spName.Substring(0, dotIndex);
+ cmd.Parameters.Add("db", db);
+ spName = spName.Substring(dotIndex+1, spName.Length - dotIndex-1);
+ cmd.CommandText = String.Format("SELECT param_list FROM mysql.proc " +
+ "WHERE db=_latin1 {0}db ", connection.ParameterMarker);
+ }
+
+ cmd.CommandText += String.Format("AND name=_latin1 {0}name AND type='{1}'",
+ connection.ParameterMarker, isProc ? "PROCEDURE" : "FUNCTION");
+
+ //cmd.Parameters.Add("db", connection.Database);
cmd.Parameters.Add("name", spName);
MySqlDataReader reader = null;
try
{
reader = cmd.ExecuteReader();
- reader.Read();
+ if (!reader.Read()) return null;
return reader.GetString(0);
}
catch (Exception ex)
@@ -66,28 +85,46 @@
}
}
+ private string GetReturnParameter(MySqlCommand cmd)
+ {
+ foreach (MySqlParameter p in cmd.Parameters)
+ if (p.Direction == ParameterDirection.ReturnValue)
+ return hash + p.ParameterName;
+ return null;
+ }
+
+ private string PrepareAsFunction(MySqlCommand cmd)
+ {
+ return null;
+ }
+
/// <summary>
/// Creates the proper command text for executing the given stored procedure
/// </summary>
/// <param name="spName"></param>
/// <returns></returns>
- public string Prepare( string spName )
+ public string Prepare(MySqlCommand cmd)
{
+ // if we have a return value paramter, then we treat it as a
+ // stored function
+ string retParm = GetReturnParameter(cmd);
+ bool isProc = retParm == null;
+
string setStr = String.Empty;
- string sqlStr = "call " + spName + "(";
+ string sqlStr = String.Empty;
outSelect = String.Empty;
try
{
- string param_list = GetParameterList( spName );
+ string param_list = GetParameterList(cmd.CommandText, isProc);
if (param_list != null && param_list.Length > 0)
{
string[] paramDefs = Utility.ContextSplit( param_list, ",", "()" );
- //string[] paramDefs = param_list.Split(',');
foreach (string paramDef in paramDefs)
{
- string[] parts = Utility.ContextSplit( paramDef.ToLower(), " \t", "");
+ string[] parts = Utility.ContextSplit( paramDef.ToLower(), " \t\r\n", "");
+ if (parts.Length == 0) continue;
string direction = parts.Length == 3 ? parts[0] : "in";
string vName = parts.Length == 3 ? parts[1] : parts[0];
@@ -109,15 +146,22 @@
}
}
}
- sqlStr = sqlStr.TrimEnd(' ', ',') + ")";
+ sqlStr = sqlStr.TrimEnd(' ', ',');
outSelect = outSelect.TrimEnd(' ', ',');
+ if (isProc)
+ sqlStr = "call " + cmd.CommandText + "(" + sqlStr + ")";
+ else
+ {
+ sqlStr = "set @" + retParm + "=" + cmd.CommandText + "(" + sqlStr + ")";
+ outSelect = "@" + retParm;
+ }
if (setStr.Length > 0)
sqlStr = setStr + sqlStr;
return sqlStr;
}
catch (Exception ex)
{
- throw new MySqlException("Exception trying to retrieve parameter info for " + spName + ": " + ex.Message, ex);
+ throw new MySqlException("Exception trying to retrieve parameter info for " + cmd.CommandText + ": " + ex.Message, ex);
}
}
Modified: trunk/mysqlclient/Types/MySqlDateTime.cs
===================================================================
--- trunk/mysqlclient/Types/MySqlDateTime.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/Types/MySqlDateTime.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -247,9 +247,7 @@
private MySqlDateTime Parse40Timestamp( string s )
{
- int[] vals = new int[6];
- int pos = 0;
- int index = 0;
+ string format = "yy";
while (s.Length > pos)
{
Modified: trunk/mysqlclient/Types/MySqlDecimal.cs
===================================================================
--- trunk/mysqlclient/Types/MySqlDecimal.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/Types/MySqlDecimal.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -161,7 +161,7 @@
}
else
{
- writer.WriteLenString( v.ToString(numberFormat) );
+ writer.WriteStringNoNull(v.ToString(numberFormat));
}
}
Modified: trunk/mysqlclient/command.cs
===================================================================
--- trunk/mysqlclient/command.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/command.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,21 +1,21 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
+// Copyright (C) 2004-2005 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
@@ -186,14 +186,8 @@
#endif
public override UpdateRowSource UpdatedRowSource
{
- get
- {
- return updatedRowSource;
- }
- set
- {
- updatedRowSource = value;
- }
+ get { return updatedRowSource; }
+ set { updatedRowSource = value; }
}
#endregion
@@ -279,8 +273,11 @@
// if (preparedStatement.ExecutionCount != 0) return null;
result = preparedStatement.Execute( parameters, cursorPageSize );
- if (updateCount == -1) updateCount = 0;
- updateCount += (long)result.AffectedRows;
+ if (! result.IsResultSet)
+ {
+ if (updateCount == -1) updateCount = 0;
+ updateCount += (long)result.AffectedRows;
+ }
}
else while (sqlBuffers.Count > 0)
{
@@ -292,12 +289,13 @@
sqlBuffers.RemoveAt( 0 );
}
- if (updateCount == -1)
- updateCount = 0;
+ if (result.AffectedRows != -1)
+ {
+ if (updateCount == -1)
+ updateCount = 0;
- updateCount += (long)result.AffectedRows;
-
- if (result.IsResultSet) break;
+ updateCount += (long)result.AffectedRows;
+ }
}
if (result.IsResultSet)
@@ -367,6 +365,7 @@
if (0 != (behavior & CommandBehavior.SchemaOnly))
{
+ sql = String.Format("SET SQL_SELECT_LIMIT=0;{0};SET sql_select_limit=-1;", cmdText);
}
if (0 != (behavior & CommandBehavior.SingleRow))
@@ -715,3 +714,4 @@
}
}
}
+
Modified: trunk/mysqlclient/common/StreamCreator.cs
===================================================================
--- trunk/mysqlclient/common/StreamCreator.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/common/StreamCreator.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,21 +1,21 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
+// Copyright (C) 2004-2005 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
@@ -35,10 +35,12 @@
/// </summary>
internal class StreamCreator
{
+ private const uint FIONBIO = 0x8004667e;
string hostList;
uint port;
string pipeName;
int timeOut;
+ ManualResetEvent evnt;
public StreamCreator( string hosts, uint port, string pipeName)
{
@@ -47,6 +49,7 @@
hostList = "localhost";
this.port = port;
this.pipeName = pipeName;
+ evnt = new ManualResetEvent(false);
}
public Stream GetStream(int timeOut)
@@ -54,7 +57,7 @@
this.timeOut = timeOut;
if (hostList.StartsWith("/"))
- return CreateUnixSocketStream();
+ return CreateSocketStream(null, 0, true);
string [] dnsHosts = hostList.Split('&');
ArrayList ipAddresses = new ArrayList();
@@ -83,7 +86,7 @@
if ( pipeName != null )
stream = CreateNamedPipeStream( (string)hostNames[index] );
else
- stream = CreateSocketStream( (IPAddress)ipAddresses[index], port );
+ stream = CreateSocketStream( (IPAddress)ipAddresses[index], port, false );
if (stream != null) return stream;
index++;
@@ -93,27 +96,6 @@
return stream;
}
- private Stream CreateUnixSocketStream()
- {
-#if! __MonoCS__ && !WINDOWS
-
- Socket socket = new Socket (AddressFamily.Unix, SocketType.Stream, ProtocolType.IP);
-
- try
- {
- UnixEndPoint endPoint = new UnixEndPoint (hostList[0]);
- socket.Connect (endPoint);
- return new NetworkStream (socket, true);
- }
- catch (Exception ex)
- {
- return null;
- }
-#else
- throw new PlatformNotSupportedException ("Unix sockets are only supported on this platform");
-#endif
- }
-
private Stream CreateNamedPipeStream( string hostname )
{
string pipePath;
@@ -138,32 +120,30 @@
}
}
- private Stream CreateSocketStream( IPAddress ip, uint port )
+ private Stream CreateSocketStream( IPAddress ip, uint port, bool unix )
{
- Socket socket = new Socket(AddressFamily.InterNetwork,
- SocketType.Stream, ProtocolType.Tcp);
-
try
{
//
// Lets try to connect
- IPEndPoint endPoint = new IPEndPoint( ip, (int)port);
+ EndPoint endPoint;
+#if __MonoCS__ && !WINDOWS
+ if (unix)
+ endPoint = new UnixEndPoint(hostList[0]);
+ else
+#else
+ endPoint = new IPEndPoint(ip, port);
+ if (unix)
+ throw new PlatformNotSupportedException ("Unix sockets are not supported on Windows.");
+#endif
- IAsyncResult iar = socket.BeginConnect( endPoint,
- new AsyncCallback(ConnectSocketCallback), socket );
-
- int timeLeft = this.timeOut*1000;
- while (! socket.Connected && timeLeft > 0)
- {
- Thread.Sleep(100);
- timeLeft -= 100;
- }
- if (! socket.Connected) return null;
-
-
- socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1 );
- return new NetworkStream( socket, true );
- }
+ SocketStream ss = unix ?
+ new SocketStream(AddressFamily.Unix, SocketType.Stream, ProtocolType.IP) :
+ new new SocketStream(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ ss.Connect(endPoint, timeOut);
+ ss.Socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1);
+ return ss;
+ }
catch (Exception)
{
return null;
Modified: trunk/mysqlclient/datareader.cs
===================================================================
--- trunk/mysqlclient/datareader.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/datareader.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,21 +1,21 @@
-// Copyright (C) 2004 MySQL AB
-//
-// This program is free software; you can redistribute it and/or modify
-// it under the terms of the GNU General Public License version 2 as published by
-// the Free Software Foundation
-//
-// There are special exceptions to the terms and conditions of the GPL
-// as it is applied to this software. View the full text of the
-// exception in file EXCEPTIONS in the directory of this software
-// distribution.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
+// Copyright (C) 2004-2005 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL
+// as it is applied to this software. View the full text of the
+// exception in file EXCEPTIONS in the directory of this software
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
@@ -311,8 +311,16 @@
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDateTime/*'/>
public override DateTime GetDateTime(int index)
{
- MySqlDateTime val = (MySqlDateTime)GetFieldValue(index); //IMySqlValue val = GetFieldValue(index);
- return val.Value;
+ IMySqlValue val = GetFieldValue(index);
+ if (val is MySqlDateTime)
+ return (val as MySqlDateTime).Value;
+ else if (val is MySqlString)
+ {
+ MySqlDateTime d = new MySqlDateTime( MySqlDbType.Datetime );
+ d = d.ParseMySql( (val as MySqlString).Value, true );
+ return d.GetDateTime();
+ }
+ throw new NotSupportedException( "Unable to convert from type " + val.GetType().ToString() + " to DateTime" );
}
/// <include file='docs/MySqlDataReader.xml' path='docs/GetDecimal/*'/>
@@ -410,9 +418,10 @@
if (! isOpen)
throw new Exception("No current query in data reader");
+ name = name.ToLower(System.Globalization.CultureInfo.InvariantCulture);
for (int i=0; i < fields.Length; i ++)
{
- if (fields[i].ColumnName.ToLower().Equals(name.ToLower()))
+ if (fields[i].ColumnName.ToLower(System.Globalization.CultureInfo.InvariantCulture) == name)
return i;
}
@@ -426,6 +435,8 @@
/// <returns></returns>
public override DataTable GetSchemaTable()
{
+ if (schemaTable != null) return schemaTable;
+
// Only Results from SQL SELECT Queries
// get a DataTable for schema of the result
// otherwise, DataTable is null reference
@@ -481,14 +492,15 @@
r["IsUnique"] = f.IsUnique || f.IsPrimaryKey;
r["IsKey"] = f.IsPrimaryKey;
r["IsAutoIncrement"] = f.IsAutoIncrement;
- r["BaseSchemaName"] = null;
- r["BaseCatalogName"] = null;
- r["BaseTableName"] = f.TableName;
- r["BaseColumnName"] = f.ColumnName;
+ r["BaseSchemaName"] = f.DatabaseName;
+ r["BaseCatalogName"] = f.DatabaseName;
+ r["BaseTableName"] = f.RealTableName;
+ r["BaseColumnName"] = f.OriginalColumnName;
dataTableSchema.Rows.Add( r );
}
+ SchemaTableColumn = dataTableSchema;
return dataTableSchema;
}
@@ -641,6 +653,8 @@
return false;
}
+ SchemaTableColumn = null;
+
// When executing query statements, the result byte that is returned
// from MySql is the column count. That is why we reference the LastResult
// property here to dimension our field array
Modified: trunk/mysqlclient/nativedriver.cs
===================================================================
--- trunk/mysqlclient/nativedriver.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/nativedriver.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -1,4 +1,4 @@
-// Copyright (C) 2004 MySQL AB
+// Copyright (C) 2004-2005 MySQL AB
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as published by
@@ -388,8 +388,8 @@
if (isOpen)
ExecuteCommand( DBCmd.QUIT, null, 0 );
+ writer.Close();
reader.Close();
- writer.Stream.Close();
base.Close();
}
@@ -445,7 +445,6 @@
{
string serverMessage = reader.ReadLenString();
}
- ShowWarnings( warningCount );
}
return true;
}
@@ -659,7 +658,6 @@
{
int warningCount = reader.ReadInteger(2);
serverStatus = (ServerStatusFlags)reader.ReadInteger(2);
- ShowWarnings(warningCount);
// if we are at the end of this cursor based resultset, then we remove
// the last row sent status flag so our next fetch doesn't abort early
Modified: trunk/mysqlclient/parameter.cs
===================================================================
--- trunk/mysqlclient/parameter.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/parameter.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -19,11 +19,11 @@
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
-using System.Data;
+using System.Data;
using System.Data.Common;
using System.Text;
using System.Reflection;
-using MySql.Data.Types;
+using MySql.Data.Types;
using MySql.Data.Common;
#if DESIGN
using System.ComponentModel;
@@ -52,6 +52,7 @@
private byte scale;
private MySqlDbType mySqlDbType;
private DbType dbType;
+ private bool inferType;
#region Constructors
@@ -60,6 +61,7 @@
/// </summary>
public MySqlParameter()
{
+ inferType = true;
}
/// <summary>
@@ -71,7 +73,6 @@
{
ParameterName = parameterName;
Value = value;
- SetTypeFromValue();
}
/// <summary>
@@ -157,7 +158,11 @@
public override DbType DbType
{
get { return dbType; }
- set { SetDbType( value ); }
+ set
+ {
+ SetDbType( value );
+ inferType = false;
+ }
}
/// <summary>
@@ -194,7 +199,11 @@
public MySqlDbType MySqlDbType
{
get { return mySqlDbType; }
- set { SetMySqlDbType( value ); }
+ set
+ {
+ SetMySqlDbType( value );
+ inferType = false;
+ }
}
/// <summary>
@@ -206,12 +215,7 @@
public override String ParameterName
{
get { return paramName; }
- set
- {
- paramName = value;
- if (paramName[0] == '?' || paramName[0] == '@')
- paramName = paramName.Substring(1, paramName.Length-1);
- }
+ set { paramName = value; }
}
/// <summary>
@@ -291,6 +295,8 @@
size = (value as Byte[]).Length;
else if (value is String)
size = (value as string).Length;
+ if (inferType)
+ SetTypeFromValue();
}
}
@@ -490,35 +496,35 @@
return base.ConvertTo(context, culture, value, destinationType);
}
}
-#endif
-
- public override int Offset
- {
- get
- {
- throw new Exception("The method or operation is not implemented.");
- }
- set
- {
- throw new Exception("The method or operation is not implemented.");
- }
- }
-
- public override void ResetDbType()
- {
- throw new Exception("The method or operation is not implemented.");
- }
-
- public override bool SourceColumnNullMapping
- {
- get
- {
- throw new Exception("The method or operation is not implemented.");
- }
- set
- {
- throw new Exception("The method or operation is not implemented.");
- }
- }
+#endif
+
+ public override int Offset
+ {
+ get
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ set
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
+
+ public override void ResetDbType()
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+
+ public override bool SourceColumnNullMapping
+ {
+ get
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ set
+ {
+ throw new Exception("The method or operation is not implemented.");
+ }
+ }
}
}
Modified: trunk/mysqlclient/parameter_collection.cs
===================================================================
--- trunk/mysqlclient/parameter_collection.cs 2005-08-26 15:10:38 UTC (rev 168)
+++ trunk/mysqlclient/parameter_collection.cs 2005-08-26 18:26:31 UTC (rev 169)
@@ -45,6 +45,14 @@
set { paramMarker = value; }
}
+ private int InternalIndexOf(string name)
+ {
+ int index = IndexOf(name);
+ if (index != -1) return index;
+ throw new MySqlException("A MySqlParameter with ParameterName '" + name +
+ "' is not contained by this MySqlParameterCollection.");
+ }
+
#region ICollection support
/// <summary>
@@ -186,13 +194,7 @@
/// <returns>true if the collection contains the parameter; otherwise, false.</returns>
public bool Contains(string name)
{
- if (name[0] == paramMarker)
- name = name.Substring(1, name.Length-1);
- foreach (MySqlParameter p in _parms)
- {
- if (p.ParameterName.ToLower().Equals( name.ToLower() )) return true;
- }
- return false;
+ return IndexOf(name) != -1;
}
/// <summary>
@@ -200,26 +202,29 @@
/// </summary>
/// <param name="parameterName">The name of the <see cref="MySqlParameter"/> object to retrieve. </param>
/// <returns>The zero-based location of the <see cref="MySqlParameter"/> in the collection.</returns>
- public int IndexOf( string parameterName )
+ public int IndexOf(string parameterName)
{
if (parameterName[0] == paramMarker)
parameterName = parameterName.Substring(1, parameterName.Length-1);
+ parameterName = parameterName.ToLower();
for (int x=0; x < _parms.Count; x++)
{
MySqlParameter p = (MySqlParameter)_parms[x];
- if (p.ParameterName.ToLower().Equals( parameterName.ToLower() )) return x;
+ string listName = p.ParameterName;
+ if (listName[0] == paramMarker)
+ listName = listName.Substring(1, listName.Length-1);
+ if (listName.ToLower() == parameterName) return x;
}
- throw new MySqlException("Parameter '" + parameterName + "' not found in collection");
+ return -1;
}
/// <summary>
/// Removes the specified <see cref="MySqlParameter"/> from the collection using the parameter name.
/// </summary>
/// <param name="name">The name of the <see cref="MySqlParameter"/> object to retrieve. </param>
- public void RemoveAt( string name )
+ public void RemoveAt(string name)
{
- int index = IndexOf( name );
- _parms.RemoveAt(index);
+ _parms.RemoveAt(InternalIndexOf(name));
}
object IDataParameterCollection.this[string name]
@@ -259,8 +264,8 @@
/// </summary>
public MySqlParameter this[string name]
{
- get { return (MySqlParameter)_parms[ IndexOf( name ) ]; }
- set { _parms[ IndexOf( name ) ] = value; }
+ get { return (MySqlParameter)_parms[ InternalIndexOf( name ) ]; }
+ set { _parms[ InternalIndexOf( name ) ] = value; }
}
/// <summary>
| Thread |
|---|
| • Connector/NET commit: r169 - in trunk: . TestSuite mysqlclient mysqlclient/Types mysqlclient/common | rburnett | 26 Aug |